#include <stdio.h>
#include <mach/mach.h>
#include <servers/bootstrap.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
void sender() {
// 从 bootstrap 中查询并获取一个 mach port
mach_port_t port;
// 这里利用 bootstarp_look_up 函数在 bootstrap 中找名字为 io.github.0xc4m3l 的程序
//( 所以这里我们要先向 bootstrap 注册我们的接受程序 io.github.0xc4m3l
// 因为我们注册到 bootstrap 中的 io.github.0xc4m3l 名字的 mach port 是有 send right 的
// bootstrap 会将所注册的 mach port 的 send right 复制给我们的 sender
if (bootstrap_look_up(bootstrapPort, "io.github.0xc4m3l", &port) != KERN_SUCCESS) {
return EXIT_FAILURE;
}
printf("bootstrap_look_up() returned port right name %d\\n", port);
// 这是我们要返送的 信息的结构体
struct {
mach_msg_header_t header;
char texts[20];
int integer;
} message;
message.header.msgh_bits = MACH_MSGH_BITS_SET(
/* remote */ MACH_MSG_TYPE_COPY_SEND,
/* local */ 0,
/* voucher */ 0,
/* other */ 0); // 设置下面对应 port 的 mach 信息类型
message.header.msgh_remote_port = port; // 设置发送端口为目标 port
message.header.msgh_local_port = MACH_PORT_NULL; // 没有辅助端口
message.header.msgh_size = sizeof(message);
strcpy(message.texts, "0xc4m3l_texts");
message.integer = 123;
// 将其发送
mach_msg_return_t mr = mach_msg_send(&message.header);
assert(mr == KERN_SUCCESS);
printf("message is sent.\\n ============ \\n");
}
void receiver() {
// 创建一个带有接收权限的 mach port
mach_port_t port;
// 利用 mach_port_allocate 创建一个 有指定权限的 mach port
// 第二个参数 指定为 拥有 RECVIVE 的权限
// 权限有这几种
/*
- `MACH_PORT_RIGHT_RECEIVE`:创建一个新端口,且当前只有接收权限
- `MACH_PORT_RIGHT_PORT_SET`:创建一个空的端口集,其中端口集里没有任何成员
- `MACH_PORT_RIGHT_DEAD_NAME` :创建一个新的 dead name
*/
kern_return_t kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port);
assert(kr == KERN_SUCCESS);
printf("mach_port_allocate() created port right name %d\\n", port);
// 给该 port 再增加一个发送权限
kr = mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND);
assert (kr == KERN_SUCCESS);
printf("mach_port_insert_right() inserted a send right\\n");
// 将我们这个端口 注册到 bootstrap 从而让我们的 sender 能查询到
// 保存在一个 itk_registered 数组中
kr = bootstrap_register(bootstrap_port, "io.github.0xc4m3l", port);
assert (kr == KERN_SUCCESS);
printf("bootstrap_register()'ed our port\\n");
// 等待接受的 message 格式
struct {
mach_msg_header_t header;
char texts[20];
int integer;
mach_msg_trailer_t trailer;
} message;
message.header.msgh_size = sizeof(message);
message.header.msgh_local_port = port;
kr = mach_msg_receive(&message.header);
assert (kr == KERN_SUCCESS);
printf("Got a message\\n ============\\n");
printf("Text: %s, number: %d\\n", message.texts, message.integer);
}
int main(int argc, const char * argv[]) {
if(fork() == 0) {
// 等待 receiver 注册好 port 后再发送信息
sleep(1);
sender();
}
else {
receiver();
}
return 0;
}
