Setup complex mach message header
<p>I'm trying to setup a mach message for sending a string out of line using mach IPC. However I get an <code>(ipc/send) invalid msg-header</code> error when trying to send the out of line message.</p>
<p>Here's the message structure.</p>
<pre><code>struct ool_msg
{
    mach_msg_header_t header;
    mach_msg_body_t body;
    mach_msg_ool_descriptor_t data;
    mach_msg_type_number_t count;
};
</code></pre>
<p>I'm setting up the header like this. The variable <code>msg</code> below is a <code>struct ool_msg</code>.</p>
<pre><code>hdr = &amp;(msg.header);
hdr-&gt;msgh_bits = MACH_MSGH_BITS_LOCAL(MACH_MSG_TYPE_COPY_SEND);
hdr-&gt;msgh_bits |= MACH_MSGH_BITS_COMPLEX;
hdr-&gt;msgh_size = sizeof(msg);
hdr-&gt;msgh_local_port = MACH_PORT_NULL;
hdr-&gt;msgh_remote_port = port;
</code></pre>
<p>This is how I setup up the rest of the Mach message.</p>
<pre><code>msg.body.msgh_descriptor_count = 1;
msg.data.address = string;
msg.data.size = strlen(string) + 1;
msg.data.deallocate = FALSE;
msg.data.copy = MACH_MSG_VIRTUAL_COPY;
msg.data.type = MACH_MSG_OOL_DESCRIPTOR;
msg.count = msg.data.size;
</code></pre>
<p>So how do I correctly setup the message header for OOL Mach IPC?</p>
<h1>Edit</h1>
<p>Here's a program that reproduces my problem.</p>
<pre><code>#include &lt;stdio.h&gt;
#include &lt;mach/mach.h&gt;

static char *string = &quot;123456789&quot;;

struct ool_msg
{
    mach_msg_header_t header;
    mach_msg_body_t body;
    mach_msg_ool_descriptor_t data;
    mach_msg_type_number_t count;
};

int main(void)
{
    kern_return_t err;
    struct ool_msg msg;
    mach_msg_header_t *hdr;
    mach_port_t port = MACH_PORT_NULL;

    err = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &amp;port);
    if(err != KERN_SUCCESS)
    {
        mach_error(&quot;Can't allocate mach port\n&quot;, err);
        return (-1);
    }

    err = mach_port_insert_right(mach_task_self(), port, port,
                                 MACH_MSG_TYPE_MAKE_SEND);
    if(err != KERN_SUCCESS)
    {
        mach_error(&quot;Can't insert port right\n&quot;, err);
        return (-1);
    }

    hdr = &amp;(msg.header);
    hdr-&gt;msgh_bits = MACH_MSGH_BITS_LOCAL(MACH_MSG_TYPE_COPY_SEND);
    hdr-&gt;msgh_bits |= MACH_MSGH_BITS_COMPLEX;
    hdr-&gt;msgh_size = sizeof(msg);
    hdr-&gt;msgh_local_port = MACH_PORT_NULL;
    hdr-&gt;msgh_remote_port = port;

    msg.body.msgh_descriptor_count = 1;
    msg.data.address = string;
    msg.data.size = strlen(string) + 1;
    msg.data.deallocate = FALSE;
    msg.data.copy = MACH_MSG_VIRTUAL_COPY;
    msg.data.type = MACH_MSG_OOL_DESCRIPTOR;
    msg.count = msg.data.size;

    err = mach_msg(hdr,
                  MACH_SEND_MSG,
                  hdr-&gt;msgh_size,
                  0,
                  MACH_PORT_NULL,
                  MACH_MSG_TIMEOUT_NONE,
                  MACH_PORT_NULL);
    if(err != KERN_SUCCESS)
    {
        mach_error(&quot;Can't send mach msg\n&quot;, err);
        return (-1);
    }

    return (0);
}
</code></pre>