1

我正在尝试接收与复杂的马赫消息一起发送的字符串。更具体地说,是线外内存(OOL)消息。不幸的是,互联网上或印刷品上几乎没有 OOL mach 消息的文档或示例。例如http://www.amazon.com/Mac-OS-Internals-Systems-Approach/dp/0321278542在第 1091 页上有一个发送 OOL 消息的部分示例,但没有接收 OOL 消息的示例。

收到 mach 消息时,我没有收到错误,即mach_msg()返回成功,但发送的字符串是NULL而不是"123456789". 那么如何正确接收在 OOL mach 消息中发送的数据呢?

#include <stdio.h>
#include <mach/mach.h>

static char *string = "123456789";

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;
    struct ool_msg recv_msg;
    mach_msg_header_t *hdr;
    mach_port_t port = MACH_PORT_NULL;

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

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

    hdr = &(msg.header);
    hdr->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND);
    hdr->msgh_bits |= MACH_MSGH_BITS_COMPLEX;
    hdr->msgh_size = sizeof(msg);
    hdr->msgh_local_port = MACH_PORT_NULL;
    hdr->msgh_remote_port = port;

    msg.body.msgh_descriptor_count = 1;
    msg.data.address = string;
    msg.data.size = (mach_msg_size_t)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->msgh_size,
                  0,
                  MACH_PORT_NULL,
                  MACH_MSG_TIMEOUT_NONE,
                  MACH_PORT_NULL);
    if(err != KERN_SUCCESS)
    {
        mach_error("Can't send mach msg\n", err);
        return (-1);
    }

    recv_msg.header.msgh_size = sizeof(struct ool_msg);

    err = mach_msg(&recv_msg.header, MACH_RCV_LARGE | MACH_RCV_INTERRUPT,
                   0, sizeof(recv_msg), port,
                   MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); 
    if(err != KERN_SUCCESS)
    {
        mach_error("Can't recieve message\n", err); 
        return (-1); 
    }

    printf("data: %s\n", recv_msg.data.address);

    return (0);
}
4

0 回答 0