]> git.saurik.com Git - apple/libdispatch.git/blob - testing/mach_server.c
libdispatch-84.5.3.tar.gz
[apple/libdispatch.git] / testing / mach_server.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <launch.h>
4 #include <dispatch/dispatch.h>
5 #include <mach/mach.h>
6 #include <mach/mach_port.h>
7 #include <asl.h>
8 #include <mach-o/dyld.h>
9 #include <limits.h>
10
11 void
12 load(void)
13 {
14 launch_data_t msg, config, dict, array, val;
15
16 config = launch_data_alloc(LAUNCH_DATA_DICTIONARY);
17
18 val = launch_data_new_string("com.apple.test.mach-server");
19 launch_data_dict_insert(config, val, LAUNCH_JOBKEY_LABEL);
20
21 val = launch_data_new_bool(1);
22 dict = launch_data_alloc(LAUNCH_DATA_DICTIONARY);
23 launch_data_dict_insert(dict, val, "com.apple.test.mach-server");
24 launch_data_dict_insert(config, dict, LAUNCH_JOBKEY_MACHSERVICES);
25
26 char path[PATH_MAX];
27 uint32_t size = sizeof(path);
28 _NSGetExecutablePath(path, &size);
29
30 array = launch_data_alloc(LAUNCH_DATA_ARRAY);
31 val = launch_data_new_string(path);
32 launch_data_array_set_index(array, val, 0);
33 val = launch_data_new_string("-launchd");
34 launch_data_array_set_index(array, val, 1);
35 launch_data_dict_insert(config, array, LAUNCH_JOBKEY_PROGRAMARGUMENTS);
36
37
38 msg = launch_data_alloc(LAUNCH_DATA_DICTIONARY);
39 launch_data_dict_insert(msg, config, LAUNCH_KEY_SUBMITJOB);
40 fprintf(stderr, "loading launchd job com.apple.test.mach-server\n");
41 msg = launch_msg(msg);
42 if (msg && launch_data_get_type(config) == LAUNCH_DATA_ERRNO) {
43 fprintf(stderr, "launch load failed: %s\n", strerror(launch_data_get_errno(msg)));
44 } else {
45 fprintf(stderr, "successful\n");
46 }
47 }
48
49 mach_port_t
50 checkin(void)
51 {
52 launch_data_t config = NULL, checkin = NULL;
53 checkin = launch_data_new_string(LAUNCH_KEY_CHECKIN);
54 config = launch_msg(checkin);
55 if (!config || launch_data_get_type(config) == LAUNCH_DATA_ERRNO)
56 return MACH_PORT_NULL;
57
58 launch_data_t svc;
59 svc = launch_data_dict_lookup(config, LAUNCH_JOBKEY_MACHSERVICES);
60 if (!svc) return MACH_PORT_NULL;
61
62 svc = launch_data_dict_lookup(svc, "com.apple.test.mach-server");
63 if (!svc) return MACH_PORT_NULL;
64
65 mach_port_t mp = launch_data_get_machport(svc);
66 return mp;
67 }
68
69
70 #include <CoreFoundation/CoreFoundation.h>
71
72 void my_cf_callback(CFMachPortRef mp, void *msg, CFIndex size, void *info)
73 {
74 char *payload = (char *)((uintptr_t)msg + sizeof(mach_msg_header_t));
75 asl_log(NULL, NULL, ASL_LEVEL_NOTICE, "message received: %s %s", payload, (char *)info);
76 }
77
78 DISPATCH_CFMACHPORT_CALLBACK_DECL(my_mig_callback, my_cf_callback);
79
80 struct strmsg {
81 mach_msg_header_t header;
82 char payload[32];
83 mach_msg_security_trailer_t trailer;
84 };
85
86 int
87 client(int argc, char* argv[])
88 {
89 mach_port_t mp;
90 kern_return_t kr;
91 struct strmsg msg;
92
93 char *str = (argc > 1) ? argv[1] : "<unspecified>";
94
95 kr = bootstrap_look_up(bootstrap_port, "com.apple.test.mach-server",
96 &mp);
97 printf("lookup %s\n", !kr ? "successful" : mach_error_string(kr));
98
99 strlcpy(msg.payload, str, sizeof(msg.payload));
100 msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND,MACH_MSG_TYPE_MAKE_SEND_ONCE);
101 msg.header.msgh_size = round_msg(sizeof(msg.header) + strlen(msg.payload) + 1);
102 msg.header.msgh_remote_port = mp;
103 msg.header.msgh_local_port = MACH_PORT_NULL;
104 msg.header.msgh_id = 0x12345678;
105 kr = mach_msg(&msg.header, MACH_SEND_MSG, msg.header.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
106 printf("client send %s\n", !kr ? "successful" : mach_error_string(kr));
107 }
108
109 int main(int argc, char* argv[])
110 {
111 if (argc > 1 && strcmp(argv[1], "-launchd") == 0) {
112 mach_port_t mp = checkin();
113 printf("checkin %s\n", mp ? "successful" : "failed");
114 if (mp) {
115 kern_return_t kr;
116 kr = mach_port_set_context(mach_task_self(), mp, (mach_vm_address_t)"phear");
117
118 dispatch_source_t mig = dispatch_source_mig_create(mp, 0 /* max msg size */,
119 NULL, dispatch_get_main_queue(), my_mig_callback);
120 dispatch_main();
121 }
122 } else if (argc > 1) {
123 client(argc, argv);
124 } else {
125 // load the job
126 load();
127 }
128
129 return 0;
130 }
131