+
+ const mach_header_xx *dyld(NULL);
+ if (dyld == NULL)
+ dyld = Library(baton, "/usr/lib/system/libdyld.dylib");
+ if (dyld == NULL)
+ dyld = Library(baton, "/usr/lib/libSystem.B.dylib");
+
+ char *(*$dlerror)();
+ cyset($dlerror, "_dlerror", dyld);
+
+ void *(*$dlopen)(const char *, int);
+ cyset($dlopen, "_dlopen", dyld);
+
+ void *handle($dlopen(baton->library, RTLD_LAZY | RTLD_LOCAL));
+ if (handle == NULL) {
+ $strlcpy(baton->error, $dlerror(), sizeof(baton->error));
+ return NULL;
+ }
+
+ void *(*$dlsym)(void *, const char *);
+ cyset($dlsym, "_dlsym", dyld);
+
+ void (*CYHandleServer)(pid_t, char *, size_t);
+ CYHandleServer = reinterpret_cast<void (*)(pid_t, char *, size_t)>($dlsym(handle, "CYHandleServer"));
+ if (CYHandleServer == NULL) {
+ $strlcpy(baton->error, $dlerror(), sizeof(baton->error));
+ return NULL;
+ }
+
+ CYHandleServer(baton->pid, baton->error, sizeof(baton->error));
+ return NULL;
+}
+
+extern "C" void Start(Baton *baton) {
+ struct _pthread self;
+ $bzero(&self, sizeof(self));
+
+ const mach_header_xx *pthread(NULL);
+ if (pthread == NULL)
+ pthread = Library(baton, "/usr/lib/system/libsystem_pthread.dylib");
+ if (pthread == NULL)
+ pthread = Library(baton, "/usr/lib/system/libsystem_c.dylib");
+ if (pthread == NULL)
+ pthread = Library(baton, "/usr/lib/libSystem.B.dylib");
+
+ void (*$__pthread_set_self)(void **);
+ cyset($__pthread_set_self, "___pthread_set_self", pthread);
+
+ self.tsd[0] = &self;
+ $__pthread_set_self(&self.tsd[0]);
+
+ int (*$pthread_attr_init)(pthread_attr_t *);
+ cyset($pthread_attr_init, "_pthread_attr_init", pthread);
+
+#if 0
+ pthread_attr_t attr;
+ $pthread_attr_init(&attr);
+
+ int (*$pthread_attr_setdetachstate)(pthread_attr_t *, int);
+ cyset($pthread_attr_setdetachstate, "_pthread_attr_setdetachstate", pthread);
+
+ $pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+#endif
+
+ int (*$pthread_create)(pthread_t *, const pthread_attr_t *, void *(*)(void *), void *);
+ cyset($pthread_create, "_pthread_create", pthread);
+
+ pthread_t thread;
+ $pthread_create(&thread, NULL, &Routine, baton);
+
+#if 0
+ int (*$pthread_attr_destroy)(pthread_attr_t *);
+ cyset($pthread_attr_destroy, "_pthread_attr_destroy", pthread);
+
+ $pthread_attr_destroy(&attr);
+#endif
+
+ int (*$pthread_join)(pthread_t, void **);
+ cyset($pthread_join, "_pthread_join", pthread);
+
+ void *status;
+ $pthread_join(thread, &status);
+
+ const mach_header_xx *kernel(NULL);
+ if (kernel == NULL)
+ kernel = Library(baton, "/usr/lib/system/libsystem_kernel.dylib");
+ if (kernel == NULL)
+ kernel = Library(baton, "/usr/lib/libSystem.B.dylib");
+
+ mach_port_t (*$mach_thread_self)();
+ cyset($mach_thread_self, "_mach_thread_self", kernel);
+
+ kern_return_t (*$thread_terminate)(thread_act_t);
+ cyset($thread_terminate, "_thread_terminate", kernel);
+
+ $thread_terminate($mach_thread_self());