static void wait_for_servers(void) { int i; int retry_count = 10; mach_port_t bsport, servport; kern_return_t ret; /* find server port */ ret = task_get_bootstrap_port(mach_task_self(), &bsport); if (KERN_SUCCESS != ret) { mach_error("task_get_bootstrap_port(): ", ret); exit(1); } while (retry_count-- > 0) { for (i = 0; i < num_servers; i++) { ret = bootstrap_look_up(bsport, server_port_name[i], &servport); if (ret != KERN_SUCCESS) { break; } } if (ret == KERN_SUCCESS) return; usleep(100 * 1000); /* 100ms */ } fprintf(stderr, "Server(s) failed to register\n"); exit(1); }
int main() { kern_return_t err; mach_port_t bootstrap; struct trivfs_control *fsys; task_get_bootstrap_port(mach_task_self(), &bootstrap); if (bootstrap == MACH_PORT_NULL) { printf("bootstrap.\n"); } err = trivfs_startup(bootstrap, 0, 0, 0, 0, 0, &fsys); if (err) { printf("the trivfs_startup.\n"); } ports_manage_port_operations_one_thread(fsys -> pi.bucket, demuxer, 0); return 0; }
/* send our task port to the server */ static void send_server_task_port(void) { mach_port_t bootstrap_port, wineserver_port; kern_return_t kret; struct { mach_msg_header_t header; mach_msg_body_t body; mach_msg_port_descriptor_t task_port; } msg; if (task_get_bootstrap_port(mach_task_self(), &bootstrap_port) != KERN_SUCCESS) return; kret = bootstrap_look_up(bootstrap_port, (char*)wine_get_server_dir(), &wineserver_port); if (kret != KERN_SUCCESS) fatal_error( "cannot find the server port: 0x%08x\n", kret ); mach_port_deallocate(mach_task_self(), bootstrap_port); msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0) | MACH_MSGH_BITS_COMPLEX; msg.header.msgh_size = sizeof(msg); msg.header.msgh_remote_port = wineserver_port; msg.header.msgh_local_port = MACH_PORT_NULL; msg.body.msgh_descriptor_count = 1; msg.task_port.name = mach_task_self(); msg.task_port.disposition = MACH_MSG_TYPE_COPY_SEND; msg.task_port.type = MACH_MSG_PORT_DESCRIPTOR; kret = mach_msg_send(&msg.header); if (kret != KERN_SUCCESS) server_protocol_error( "mach_msg_send failed: 0x%08x\n", kret ); mach_port_deallocate(mach_task_self(), wineserver_port); }
static Boolean __CFMessagePortNativeSetNameLocal(CFMachPortRef port, uint8_t *portname) { mach_port_t bp; kern_return_t ret; task_get_bootstrap_port(mach_task_self(), &bp); ret = bootstrap_register(bp, portname, CFMachPortGetPort(port)); return (ret == KERN_SUCCESS) ? true : false; }
int main (int argc, char **argv) { struct ps_context *pc; mach_port_t bootstrap; error_t err; opt_clk_tck = OPT_CLK_TCK; opt_stat_mode = OPT_STAT_MODE; opt_fake_self = OPT_FAKE_SELF; opt_kernel_pid = OPT_KERNEL_PID; opt_anon_owner = OPT_ANON_OWNER; err = argp_parse (&argp, argc, argv, 0, 0, 0); if (err) error (1, err, "Could not parse command line"); err = ps_context_create (getproc (), &pc); if (err) error (1, err, "Could not create libps context"); task_get_bootstrap_port (mach_task_self (), &bootstrap); if (bootstrap == MACH_PORT_NULL) error (1, 0, "Must be started as a translator"); netfs_init (); err = root_make_node (pc, &netfs_root_node); if (err) error (1, err, "Could not create the root node"); netfs_startup (bootstrap, 0); netfs_server_loop (); assert (0 /* netfs_server_loop returned after all */); }
Boolean IOUPSMIGServerIsRunning(mach_port_t * bootstrap_port_ref, mach_port_t * upsd_port_ref) { mach_port_t active = MACH_PORT_NULL; kern_return_t kern_result = KERN_SUCCESS; mach_port_t bootstrap_port; if (bootstrap_port_ref && (*bootstrap_port_ref != MACH_PORT_NULL)) { bootstrap_port = *bootstrap_port_ref; } else { /* Get the bootstrap server port */ kern_result = task_get_bootstrap_port(mach_task_self(), &bootstrap_port); if (kern_result != KERN_SUCCESS) { return false; } if (bootstrap_port_ref) { *bootstrap_port_ref = bootstrap_port; } } /* Check "upsd" server status */ kern_result = bootstrap_look_up( bootstrap_port, kIOUPSPlugInServerName, &active); if (BOOTSTRAP_SUCCESS == kern_result) { return true; } else { // For any result other than SUCCESS, we presume the server is // not running. We expect the most common failure result to be: // kern_result == BOOTSTRAP_UNKNOWN_SERVICE return false; } }
int main(int argc, char *argv[]) { int err; mach_port_t bootstrap; struct trivfs_control *fsys; if (argc > 1) { fprintf(stderr, "Usage: settrans [opts] node %s\n", program_invocation_name); exit (1); } task_get_bootstrap_port (mach_task_self (), &bootstrap); if (bootstrap == MACH_PORT_NULL) error(2, 0, "Must be started as a translator"); /* Reply to our parent */ err = trivfs_startup (bootstrap, 0, 0, 0, 0, 0,&fsys); mach_port_deallocate (mach_task_self (), bootstrap); if (err) { return (0); } ports_manage_port_operations_one_thread (fsys->pi.bucket, demuxer, 0); return 0; }
int main (int argc, char *argv[]) { error_t err; mach_port_t bootstrap; struct dev device; struct storeio_argp_params params; bzero (&device, sizeof device); mutex_init (&device.lock); params.dev = &device; argp_parse (&argp, argc, argv, 0, 0, ¶ms); task_get_bootstrap_port (mach_task_self (), &bootstrap); if (bootstrap == MACH_PORT_NULL) error (2, 0, "Must be started as a translator"); /* Reply to our parent */ err = trivfs_startup (bootstrap, 0, 0, 0, 0, 0, &storeio_fsys); if (err) error (3, err, "trivfs_startup"); storeio_fsys->hook = &device; /* Launch. */ ports_manage_port_operations_multithread (storeio_fsys->pi.bucket, trivfs_demuxer, 30*1000, 5*60*1000, 0); return 0; }
int main (int argc, char **argv) { error_t err; mach_port_t bootstrap; argp_parse (&argp, argc, argv, 0, 0, 0); if (MACH_PORT_VALID (opt_device_master)) { err = open_console (opt_device_master); assert_perror (err); mach_port_deallocate (mach_task_self (), opt_device_master); } save_argv = argv; task_get_bootstrap_port (mach_task_self (), &bootstrap); if (bootstrap == MACH_PORT_NULL) error (2, 0, "Must be started as a translator"); /* Fetch our proc server port for easy use. If we are booting, it is not set yet and `getproc' returns MACH_PORT_NULL; we reset PROCSERVER in S_exec_init (below). */ procserver = getproc (); err = trivfs_add_port_bucket (&port_bucket); if (err) error (1, 0, "error creating port bucket"); err = trivfs_add_control_port_class (&trivfs_control_class); if (err) error (1, 0, "error creating control port class"); err = trivfs_add_protid_port_class (&trivfs_protid_class); if (err) error (1, 0, "error creating protid port class"); execboot_portclass = ports_create_class (deadboot, NULL); /* Reply to our parent. */ err = trivfs_startup (bootstrap, 0, trivfs_control_class, port_bucket, trivfs_protid_class, port_bucket, &fsys); /* Reply to our parent. */ err = trivfs_startup (bootstrap, 0, trivfs_control_class, port_bucket, trivfs_protid_class, port_bucket, &fsys); mach_port_deallocate (mach_task_self (), bootstrap); if (err) error (3, err, "Contacting parent"); /* Launch. */ ports_manage_port_operations_multithread (port_bucket, exec_demuxer, 2 * 60 * 1000, 0, 0); return 0; }
int main (int argc, char **argv) { error_t err; mach_port_t bootstrap; struct trivfs_control *fsys; fifo_pipe_class = stream_pipe_class; argp_parse (&argp, argc, argv, 0, 0, 0); task_get_bootstrap_port (mach_task_self (), &bootstrap); if (bootstrap == MACH_PORT_NULL) error (1, 0, "must be started as a translator"); /* Reply to our parent */ err = trivfs_startup (bootstrap, 0, 0, 0, 0, 0, &fsys); mach_port_deallocate (mach_task_self (), bootstrap); if (err) error (3, err, "Contacting parent"); /* Launch. */ do { ports_enable_class (fsys->protid_class); ports_manage_port_operations_multithread (fsys->pi.bucket, trivfs_demuxer, 30*1000, 5*60*1000, 0); } while (ports_count_class (fsys->protid_class) > 0); return 0; }
/* main */ int main (int argc, char *argv[]) { error_t err; mach_port_t bootstrap; struct trivfs_control *fsys; err = argp_parse(&argp, argc, argv, 0, NULL, NULL); if (err) { error(1, err, "argp_parse"); } task_get_bootstrap_port(mach_task_self(), &bootstrap); if (bootstrap == MACH_PORT_NULL) { error(1, 0, "must be started as translator"); } /* reply to our parent */ err = trivfs_startup(bootstrap, 0, NULL, NULL, NULL, NULL, &fsys); if (err) { error(3, err, "trivfs_startup"); } /* launch translator */ init_logging(); info("start oss translator"); info("init rump"); rump_init(); debug("open rump audio device"); audio_fd = rump_sys_open(RUMP_AUDIO_DEVICE, O_WRONLY); if (audio_fd < 0) { err("rump_open(%s, O_WRONLY): %s", RUMP_AUDIO_DEVICE, rump_strerror(errno)); return EIO; } /* set default parameters */ audio_info_t info; AUDIO_INITINFO(&info); info.play.sample_rate = 44100; info.play.channels = 1; info.play.precision = 16; info.play.encoding = AUDIO_ENCODING_LINEAR; info.play.samples = 0; if (rump_sys_ioctl(audio_fd, AUDIO_SETINFO, &info)) { err("rump_sys_ioctl AUDIO_SETINFO: %s", rump_strerror(errno)); return EIO; } /* wait for orders */ info("wait for orders"); ports_manage_port_operations_one_thread(fsys->pi.bucket, oss_demuxer, 0); return 0; }
static SInt32 _CFUserNotificationSendRequest(CFAllocatorRef allocator, CFStringRef sessionID, mach_port_t replyPort, SInt32 token, CFTimeInterval timeout, CFOptionFlags flags, CFDictionaryRef dictionary) { CFDictionaryRef modifiedDictionary = NULL; SInt32 retval = ERR_SUCCESS, itimeout = (timeout > 0.0 && timeout < INT_MAX) ? (SInt32)timeout : 0; CFDataRef data; mach_msg_base_t *msg = NULL; mach_port_t bootstrapPort = MACH_PORT_NULL, serverPort = MACH_PORT_NULL; CFIndex size; char namebuffer[MAX_PORT_NAME_LENGTH + 1]; strlcpy(namebuffer, NOTIFICATION_PORT_NAME, sizeof(namebuffer)); if (sessionID) { char sessionid[MAX_PORT_NAME_LENGTH + 1]; CFIndex len = MAX_PORT_NAME_LENGTH - sizeof(NOTIFICATION_PORT_NAME) - sizeof(NOTIFICATION_PORT_NAME_SUFFIX); CFStringGetBytes(sessionID, CFRangeMake(0, CFStringGetLength(sessionID)), kCFStringEncodingUTF8, 0, false, (uint8_t *)sessionid, len, &size); sessionid[len - 1] = '\0'; strlcat(namebuffer, NOTIFICATION_PORT_NAME_SUFFIX, sizeof(namebuffer)); strlcat(namebuffer, sessionid, sizeof(namebuffer)); } retval = task_get_bootstrap_port(mach_task_self(), &bootstrapPort); if (ERR_SUCCESS == retval && MACH_PORT_NULL != bootstrapPort) retval = bootstrap_look_up2(bootstrapPort, namebuffer, &serverPort, 0, 0); if (ERR_SUCCESS == retval && MACH_PORT_NULL != serverPort) { modifiedDictionary = _CFUserNotificationModifiedDictionary(allocator, dictionary, token, itimeout, _CFProcessNameString()); if (modifiedDictionary) { data = CFPropertyListCreateXMLData(allocator, modifiedDictionary); if (data) { size = sizeof(mach_msg_base_t) + ((CFDataGetLength(data) + 3) & (~0x3)); msg = (mach_msg_base_t *)CFAllocatorAllocate(kCFAllocatorSystemDefault, size, 0); if (__CFOASafe) __CFSetLastAllocationEventName(msg, "CFUserNotification (temp)"); if (msg) { memset(msg, 0, size); msg->header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE); msg->header.msgh_size = size; msg->header.msgh_remote_port = serverPort; msg->header.msgh_local_port = replyPort; msg->header.msgh_id = flags; msg->body.msgh_descriptor_count = 0; CFDataGetBytes(data, CFRangeMake(0, CFDataGetLength(data)), (uint8_t *)msg + sizeof(mach_msg_base_t)); //CFShow(CFStringCreateWithBytes(kCFAllocatorSystemDefault, (UInt8 *)msg + sizeof(mach_msg_base_t), CFDataGetLength(data), kCFStringEncodingUTF8, false)); retval = mach_msg((mach_msg_header_t *)msg, MACH_SEND_MSG|MACH_SEND_TIMEOUT, size, 0, MACH_PORT_NULL, MESSAGE_TIMEOUT, MACH_PORT_NULL); CFAllocatorDeallocate(kCFAllocatorSystemDefault, msg); } else { retval = unix_err(ENOMEM); } CFRelease(data); } else { retval = unix_err(ENOMEM); } CFRelease(modifiedDictionary); } else { retval = unix_err(ENOMEM); } } return retval; }
Boolean SetupMIGServer() { Boolean result = true; kern_return_t kern_result = KERN_SUCCESS; CFMachPortRef upsdMachPort = NULL; // must release mach_port_t ups_port = MACH_PORT_NULL; /*if (IOUPSMIGServerIsRunning(&bootstrap_port, NULL)) { result = false; goto finish; }*/ kern_result = task_get_bootstrap_port(mach_task_self(), &bootstrap_port); if (kern_result != KERN_SUCCESS) { result = false; goto finish; } gMainRunLoop = CFRunLoopGetCurrent(); if (!gMainRunLoop) { result = false; goto finish; } kern_result = bootstrap_check_in( bootstrap_port, kIOUPSPlugInServerName, &ups_port); if (BOOTSTRAP_SUCCESS != kern_result) { syslog(LOG_ERR, "ioupsd: bootstrap_check_in \"%s\" error = %d\n", kIOUPSPlugInServerName, kern_result); } else { upsdMachPort = CFMachPortCreateWithPort(kCFAllocatorDefault, ups_port, upsd_mach_port_callback, NULL, NULL); gClientRequestRunLoopSource = CFMachPortCreateRunLoopSource( kCFAllocatorDefault, upsdMachPort, 0); if (!gClientRequestRunLoopSource) { result = false; goto finish; } CFRunLoopAddSource(gMainRunLoop, gClientRequestRunLoopSource, kCFRunLoopDefaultMode); } finish: if (gClientRequestRunLoopSource) CFRelease(gClientRequestRunLoopSource); if (upsdMachPort) CFRelease(upsdMachPort); return result; }
CFRunLoopSourceRef CreateIPCRunLoopSource(CFStringRef aPortName, StartupContext aStartupContext) { CFRunLoopSourceRef aSource = NULL; CFMachPortRef aMachPort = NULL; CFMachPortContext aContext; kern_return_t aKernReturn = KERN_FAILURE; aContext.version = 0; aContext.info = (void*) aStartupContext; aContext.retain = 0; aContext.release = 0; aContext.copyDescription = 0; aMachPort = CFMachPortCreate(NULL, NULL, &aContext, NULL); if (aMachPort && aPortName) { CFIndex aPortNameLength = CFStringGetLength(aPortName); CFIndex aPortNameSize = CFStringGetMaximumSizeForEncoding(aPortNameLength, kCFStringEncodingUTF8) + 1; uint8_t *aBuffer = CFAllocatorAllocate(NULL, aPortNameSize, 0); if (aBuffer && CFStringGetCString(aPortName, aBuffer, aPortNameSize, kCFStringEncodingUTF8)) { mach_port_t aBootstrapPort; task_get_bootstrap_port(mach_task_self(), &aBootstrapPort); aKernReturn = bootstrap_register(aBootstrapPort, aBuffer, CFMachPortGetPort(aMachPort)); } if (aBuffer) CFAllocatorDeallocate(NULL, aBuffer); } if (aMachPort && aKernReturn == KERN_SUCCESS) { CFRunLoopSourceContext1 aSourceContext; aSourceContext.version = 1; aSourceContext.info = aMachPort; aSourceContext.retain = CFRetain; aSourceContext.release = CFRelease; aSourceContext.copyDescription = CFCopyDescription; aSourceContext.equal = CFEqual; aSourceContext.hash = CFHash; aSourceContext.getPort = getIPCPort; aSourceContext.perform = (void*)handleIPCMessage; aSource = CFRunLoopSourceCreate(NULL, 0, (CFRunLoopSourceContext*)&aSourceContext); } if (aMachPort && (!aSource || aKernReturn != KERN_SUCCESS)) { CFMachPortInvalidate(aMachPort); CFRelease(aMachPort); aMachPort = NULL; } return aSource; }
int main (int argc, char **argv) { mach_port_t bootstrap; mach_port_t control; error_t err; /* Parse our options... */ argp_parse (&argp, argc, argv, 0, 0, 0); task_get_bootstrap_port (mach_task_self (), &bootstrap); if (bootstrap == MACH_PORT_NULL) error (1, 0, "Must be started as a translator"); linktarget = argv[1]; /* Reply to our parent */ mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &control); mach_port_insert_right (mach_task_self (), control, control, MACH_MSG_TYPE_MAKE_SEND); err = fsys_startup (bootstrap, 0, control, MACH_MSG_TYPE_COPY_SEND, &realnode); mach_port_deallocate (mach_task_self (), control); mach_port_deallocate (mach_task_self (), bootstrap); if (err) error (1, err, "Starting up translator"); io_restrict_auth (realnode, &realnodenoauth, 0, 0, 0, 0); mach_port_deallocate (mach_task_self (), realnode); /* Mark us as important. */ mach_port_t proc = getproc (); if (proc == MACH_PORT_NULL) error (2, err, "cannot get a handle to our process"); err = proc_mark_important (proc); /* This might fail due to permissions or because the old proc server is still running, ignore any such errors. */ if (err && err != EPERM && err != EMIG_BAD_ID) error (2, err, "Cannot mark us as important"); mach_port_deallocate (mach_task_self (), proc); /* Launch */ while (1) { /* The timeout here is 10 minutes */ err = mach_msg_server_timeout (fsys_server, 0, control, MACH_RCV_TIMEOUT, 1000 * 60 * 10); if (err == MACH_RCV_TIMED_OUT) exit (0); } }
int main (int argc, char **argv) { error_t err; mach_port_t bootstrap; struct argp argp = { 0, 0, 0, "Hurd standard exec server." }; argp_parse (&argp, argc, argv, 0, 0, 0); save_argv = argv; #ifdef BFD /* Put the Mach kernel's idea of what flavor of machine this is into the fake BFD against which architecture compatibility checks are made. */ err = bfd_mach_host_arch_mach (mach_host_self (), &host_bfd.arch_info->arch, &host_bfd.arch_info->mach); if (err) error (1, err, "Getting host architecture from Mach"); #endif task_get_bootstrap_port (mach_task_self (), &bootstrap); if (bootstrap == MACH_PORT_NULL) error (2, 0, "Must be started as a translator"); /* Fetch our proc server port for easy use. If we are booting, it is not set yet and `getproc' returns MACH_PORT_NULL; we reset PROCSERVER in S_exec_init (below). */ procserver = getproc (); port_bucket = ports_create_bucket (); trivfs_cntl_portclasses[0] = ports_create_class (trivfs_clean_cntl, 0); trivfs_protid_portclasses[0] = ports_create_class (trivfs_clean_protid, 0); execboot_portclass = ports_create_class (deadboot, NULL); /* Reply to our parent. */ err = trivfs_startup (bootstrap, 0, trivfs_cntl_portclasses[0], port_bucket, trivfs_protid_portclasses[0], port_bucket, &fsys); mach_port_deallocate (mach_task_self (), bootstrap); if (err) error (3, err, "Contacting parent"); /* Launch. */ ports_manage_port_operations_multithread (port_bucket, exec_demuxer, 2 * 60 * 1000, 0, 0); return 0; }
pid_t sampling_fork () { kern_return_t err; mach_port_t parent_recv_port = MACH_PORT_NULL; mach_port_t child_recv_port = MACH_PORT_NULL; if (setup_recv_port (&parent_recv_port) != 0) return -1; err = task_set_bootstrap_port (mach_task_self (), parent_recv_port); CHECK_MACH_ERROR (err, "task_set_bootstrap_port failed:"); pid_t pid; switch (pid = fork ()) { case -1: err = mach_port_deallocate (mach_task_self(), parent_recv_port); CHECK_MACH_ERROR (err, "mach_port_deallocate failed:"); return pid; case 0: /* child */ err = task_get_bootstrap_port (mach_task_self (), &parent_recv_port); CHECK_MACH_ERROR (err, "task_get_bootstrap_port failed:"); if (setup_recv_port (&child_recv_port) != 0) return -1; if (send_port (parent_recv_port, mach_task_self ()) != 0) return -1; if (send_port (parent_recv_port, child_recv_port) != 0) return -1; if (recv_port (child_recv_port, &bootstrap_port) != 0) return -1; err = task_set_bootstrap_port (mach_task_self (), bootstrap_port); CHECK_MACH_ERROR (err, "task_set_bootstrap_port failed:"); break; default: /* parent */ err = task_set_bootstrap_port (mach_task_self (), bootstrap_port); CHECK_MACH_ERROR (err, "task_set_bootstrap_port failed:"); if (recv_port (parent_recv_port, &child_task) != 0) return -1; if (recv_port (parent_recv_port, &child_recv_port) != 0) return -1; if (send_port (child_recv_port, bootstrap_port) != 0) return -1; err = mach_port_deallocate (mach_task_self(), parent_recv_port); CHECK_MACH_ERROR (err, "mach_port_deallocate failed:"); break; } return pid; }
int main (int argc, char **argv) { error_t err; mach_port_t pflocal; mach_port_t bootstrap; char buf[512]; const struct argp argp = { 0, 0, 0, doc }; argp_parse (&argp, argc, argv, 0, 0, 0); control_class = ports_create_class (trivfs_clean_cntl, 0); node_class = ports_create_class (trivfs_clean_protid, 0); port_bucket = ports_create_bucket (); trivfs_protid_portclasses[0] = node_class; trivfs_cntl_portclasses[0] = control_class; task_get_bootstrap_port (mach_task_self (), &bootstrap); if (bootstrap == MACH_PORT_NULL) error(1, 0, "Must be started as a translator"); /* Reply to our parent */ err = trivfs_startup (bootstrap, 0, control_class, port_bucket, node_class, port_bucket, NULL); mach_port_deallocate (mach_task_self (), bootstrap); if (err) error(2, err, "Contacting parent"); /* Try and connect to the pflocal server */ sprintf (buf, "%s/%d", _SERVERS_SOCKET, PF_LOCAL); pflocal = file_name_lookup (buf, 0, 0); if (pflocal == MACH_PORT_NULL) address_port = MACH_PORT_NULL; else { err = socket_fabricate_address (pflocal, AF_LOCAL, &address_port); if (err) address_port = MACH_PORT_NULL; mach_port_deallocate (mach_task_self (), pflocal); } /* Launch. */ ports_manage_port_operations_one_thread (port_bucket, demuxer, 0); return 0; }
mach_port_t str2bsport(const char *s) { bool getrootbs = strcmp(s, "/") == 0; mach_port_t last_bport, bport = bootstrap_port; task_t task = mach_task_self(); kern_return_t result; if (strcmp(s, "..") == 0 || getrootbs) { do { last_bport = bport; result = bootstrap_parent(last_bport, &bport); if (result == BOOTSTRAP_NOT_PRIVILEGED) { fprintf(stderr, "Permission denied\n"); return 1; } else if (result != BOOTSTRAP_SUCCESS) { fprintf(stderr, "bootstrap_parent() %d\n", result); return 1; } } while (getrootbs && last_bport != bport); } else if( strcmp(s, "0") == 0 || strcmp(s, "NULL") == 0 ) { bport = MACH_PORT_NULL; } else { int pid = atoi(s); result = task_for_pid(mach_task_self(), pid, &task); if (result != KERN_SUCCESS) { fprintf(stderr, "task_for_pid() %s\n", mach_error_string(result)); return 1; } result = task_get_bootstrap_port(task, &bport); if (result != KERN_SUCCESS) { fprintf(stderr, "Couldn't get bootstrap port: %s\n", mach_error_string(result)); return 1; } } return bport; }
// Server side : publish the semaphore in the global namespace bool JackMachSemaphore::Allocate(const char* name, const char* server_name, int value) { BuildName(name, server_name, fName, sizeof(fName)); mach_port_t task = mach_task_self(); kern_return_t res; if (fBootPort == 0) { if ((res = task_get_bootstrap_port(task, &fBootPort)) != KERN_SUCCESS) { jack_error("Allocate: Can't find bootstrap mach port err = %s", mach_error_string(res)); return false; } } if ((res = semaphore_create(task, &fSemaphore, SYNC_POLICY_FIFO, value)) != KERN_SUCCESS) { jack_error("Allocate: can create semaphore err = %s", mach_error_string(res)); return false; } if ((res = bootstrap_register(fBootPort, fName, fSemaphore)) != KERN_SUCCESS) { jack_error("Allocate: can't check in mach semaphore name = %s err = %s", fName, mach_error_string(res)); switch (res) { case BOOTSTRAP_SUCCESS : /* service not currently registered, "a good thing" (tm) */ break; case BOOTSTRAP_NOT_PRIVILEGED : jack_log("bootstrap_register(): bootstrap not privileged"); break; case BOOTSTRAP_SERVICE_ACTIVE : jack_log("bootstrap_register(): bootstrap service active"); break; default : jack_log("bootstrap_register() err = %s", mach_error_string(res)); break; } return false; } jack_log("JackMachSemaphore::Allocate name = %s", fName); return true; }
int main (int argc, char **argv) { error_t err; mach_port_t bootstrap; struct trivfs_control *fsys; mach_port_t host_priv; argp_parse (&argp, argc, argv, 0, 0, 0); err = get_privileged_ports (&host_priv, &dev_master); if (err) error (2, err, "cannot get privileged ports"); real_defpager = MACH_PORT_NULL; err = vm_set_default_memory_manager (host_priv, &real_defpager); mach_port_deallocate (mach_task_self (), host_priv); if (err) error (3, err, "vm_set_default_memory_manager"); if (real_defpager == MACH_PORT_NULL) error (1, 0, "no default memory manager set!"); task_get_bootstrap_port (mach_task_self (), &bootstrap); if (bootstrap == MACH_PORT_NULL) error (1, 0, "Must be started as a translator"); err = trivfs_add_protid_port_class (&trivfs_protid_class); if (err) error (1, 0, "error creating protid port class"); /* Reply to our parent. */ err = trivfs_startup (bootstrap, 0, 0, 0, trivfs_protid_class, 0, &fsys); mach_port_deallocate (mach_task_self (), bootstrap); if (err) error (4, err, "Contacting parent"); /* Launch. */ ports_manage_port_operations_multithread (fsys->pi.bucket, proxy_defpager_demuxer, 2 * 60 * 1000, 0, 0); return 0; }
// Client side : get the published semaphore from server bool JackMachSemaphore::ConnectInput(const char* name, const char* server_name) { BuildName(name, server_name, fName, sizeof(fName)); kern_return_t res; if (fBootPort == 0) { if ((res = task_get_bootstrap_port(mach_task_self(), &fBootPort)) != KERN_SUCCESS) { jack_error("Connect: can't find bootstrap port err = %s", mach_error_string(res)); return false; } } if ((res = bootstrap_look_up(fBootPort, fName, &fSemaphore)) != KERN_SUCCESS) { jack_error("Connect: can't find mach semaphore name = %s err = %s", fName, mach_error_string(res)); return false; } jack_log("JackMachSemaphore::Connect name = %s ", fName); return true; }
int main(int argc, char *argv[]) { mach_port_t bootstrap; struct trivfs_control *control; error_t err; argp_parse(&kgi_argp, argc, argv, 0, NULL, NULL); init_module(); if(!display) error(3, 0, "No suitable display found... I'm bored, bye."); task_get_bootstrap_port(mach_task_self(), &bootstrap); if(bootstrap == MACH_PORT_NULL) { /* not started as translator */ printf("Init complete; press <return>.\n"); getchar(); setmode(); printf("setmode() complete; press <return>.\n"); getchar(); draw_crap(); printf("draw_crap() complete; press <return>.\n"); getchar(); unsetmode(); printf("unsetmode() complete; press <return>.\n"); getchar(); cleanup_module(); assert(!display); return 0; } err = trivfs_startup(bootstrap, 0, NULL, NULL, NULL, NULL, &control); mach_port_deallocate(mach_task_self(), bootstrap); if(err) error(2, err, "trivfs_startup"); ports_manage_port_operations_one_thread(control->pi.bucket, kgi_demuxer, 0); return 0; /* not reached */ }
void *client(void *threadarg) { struct port_args args; struct port_args *svr_args = NULL; int idx; mach_msg_header_t *req, *reply; mach_port_t bsport, servport; kern_return_t ret; int server_num = (int)(uintptr_t)threadarg; void *ints = malloc(sizeof(u_int32_t) * num_ints); if (verbose) printf("client(%d) started, server port name %s\n", server_num, server_port_name[server_num]); args.server_num = server_num; thread_setup(server_num + 1); if (stress_prepost) svr_args = &server_port_args[server_num]; /* find server port */ ret = task_get_bootstrap_port(mach_task_self(), &bsport); if (KERN_SUCCESS != ret) { mach_error("task_get_bootstrap_port(): ", ret); exit(1); } ret = bootstrap_look_up(bsport, server_port_name[server_num], &servport); if (KERN_SUCCESS != ret) { mach_error("bootstrap_look_up(): ", ret); exit(1); } setup_client_ports(&args); /* Allocate and touch memory */ if (client_pages) { unsigned i; client_memory = (long *) malloc(client_pages * PAGE_SIZE); for (i = 0; i < client_pages; i++) client_memory[i * PAGE_SIZE / sizeof(long)] = 0; } uint64_t starttm, endtm; /* start message loop */ for (idx = 0; idx < num_msgs; idx++) { req = args.req_msg; reply = args.reply_msg; req->msgh_size = args.req_size; if (stress_prepost) { req->msgh_remote_port = svr_args->port_list[idx % portcount]; } else { req->msgh_remote_port = servport; } if (oneway) { req->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0); req->msgh_local_port = MACH_PORT_NULL; } else { req->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE); req->msgh_local_port = args.port; } req->msgh_id = oneway ? 0 : 1; if (msg_type == msg_type_complex) { (req)->msgh_bits |= MACH_MSGH_BITS_COMPLEX; ((ipc_complex_message *)req)->body.msgh_descriptor_count = 1; ((ipc_complex_message *)req)->descriptor.address = ints; ((ipc_complex_message *)req)->descriptor.size = num_ints * sizeof(u_int32_t); ((ipc_complex_message *)req)->descriptor.deallocate = FALSE; ((ipc_complex_message *)req)->descriptor.copy = MACH_MSG_VIRTUAL_COPY; ((ipc_complex_message *)req)->descriptor.type = MACH_MSG_OOL_DESCRIPTOR; } if (verbose > 2) printf("client sending message %d to port %#x\n", idx, req->msgh_remote_port); starttm = mach_absolute_time(); ret = mach_msg(req, MACH_SEND_MSG, args.req_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); endtm = mach_absolute_time(); if (MACH_MSG_SUCCESS != ret) { mach_error("mach_msg (send): ", ret); fprintf(stderr, "bailing after %u iterations\n", idx); exit(1); break; } if (stress_prepost) OSAtomicAdd64(endtm - starttm, &g_client_send_time); if (!oneway) { if (verbose > 2) printf("client awaiting reply %d\n", idx); reply->msgh_bits = 0; reply->msgh_size = args.reply_size; reply->msgh_local_port = args.port; ret = mach_msg(args.reply_msg, MACH_RCV_MSG|MACH_RCV_INTERRUPT, 0, args.reply_size, args.port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (MACH_MSG_SUCCESS != ret) { mach_error("mach_msg (receive): ", ret); fprintf(stderr, "bailing after %u iterations\n", idx); exit(1); } if (verbose > 2) printf("client received reply %d\n", idx); } client_work(); } free(ints); return NULL; }
/*ARGSUSED*/ int benchmark_initbatch(void *tsd) { /* * initialize your state variables here second */ long pid; tsd_t *ts = (tsd_t *)tsd; ts->server_mode = -1; ts->verbose = opt_verbose; ts->oneway = opt_oneway; ts->overwrite = 0; ts->msg_type = opt_msg_type; ts->num_ints = opt_num_ints; ts->num_msgs = opt_num_msgs; ts->server_port_name = opt_server_port_name; ts->server_port = MACH_PORT_NULL; ts->reply_port = MACH_PORT_NULL; ts->request_msg = NULL; ts->request_msg_size = 0; ts->reply_msg = NULL; ts->reply_msg_size = 0; switch (ts->msg_type) { case msg_type_trivial: ts->request_msg_size = sizeof(ipc_trivial_message); break; case msg_type_inline: ts->request_msg_size = sizeof(ipc_inline_message) + sizeof(u_int32_t) * ts->num_ints; break; case msg_type_complex: ts->request_msg_size = sizeof(ipc_complex_message); ts->ints = malloc(sizeof(u_int32_t) * ts->num_ints); break; } ts->request_msg = malloc(ts->request_msg_size); ts->reply_msg = malloc(ts->reply_msg_size); if (ts->server_mode) { kern_return_t ret = 0; mach_port_t bsport; ts->reply_msg_size -= sizeof(mach_msg_trailer_t); ret = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &(ts->server_port)); if (KERN_SUCCESS != ret) { mach_error("mach_port_allocate(): ", ret); exit(1); } ret = mach_port_insert_right(mach_task_self(), ts->server_port, ts->server_port, MACH_MSG_TYPE_MAKE_SEND); if (KERN_SUCCESS != ret) { mach_error("mach_port_insert_right(): ", ret); exit(1); } ret = task_get_bootstrap_port(mach_task_self(), &bsport); if (KERN_SUCCESS != ret) { mach_error("task_get_bootstrap_port(): ", ret); exit(1); } ret = bootstrap_check_in(bsport, (char *)ts->server_port_name, &ts->server_port); if (KERN_SUCCESS != ret) { mach_error("bootstrap_register(): ", ret); exit(1); } } else { /* client mode */ kern_return_t ret = 0; mach_port_t bsport; ts->request_msg_size -= sizeof(mach_msg_trailer_t); ret = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &(ts->reply_port)); if (KERN_SUCCESS != ret) { mach_error("mach_port_allocate(): ", ret); exit(1); } ret = task_get_bootstrap_port(mach_task_self(), &bsport); if (KERN_SUCCESS != ret) { mach_error("task_get_bootstrap_port(): ", ret); exit(1); } ret = bootstrap_look_up(bsport, (char *)ts->server_port_name, &(ts->server_port)); if (KERN_SUCCESS != ret) { mach_error("bootstrap_look_up(): ", ret); exit(1); } } if (ts->verbose) { if (ts->server_mode) { printf("Server waiting for IPC messages from client on port '%s'.\n", ts->server_port_name); } else { printf("Client sending %d %s IPC messages to port '%s' in %s mode.\n", ts->num_msgs, (ts->msg_type == msg_type_inline) ? "inline" : ((ts->msg_type == msg_type_complex) ? "complex" : "trivial"), ts->server_port_name, (ts->oneway ? "oneway" : "rpc")); } } pid = fork(); switch (pid) { case 0: server(tsd); exit(0); break; case -1: return (-1); default: ts->pid = pid; break; } return (0); }
CFMessagePortRef CFMessagePortCreateRemote(CFAllocatorRef allocator, CFStringRef name) { CFMessagePortRef memory; CFMachPortRef native; CFMachPortContext ctx; uint8_t *utfname = NULL; CFIndex size; mach_port_t bp, port; kern_return_t ret; name = __CFMessagePortSanitizeStringName(allocator, name, &utfname, NULL); if (NULL == name) { return NULL; } __CFSpinLock(&__CFAllMessagePortsLock); if (NULL != name) { CFMessagePortRef existing; if (NULL != __CFAllRemoteMessagePorts && CFDictionaryGetValueIfPresent(__CFAllRemoteMessagePorts, name, (const void **)&existing)) { __CFSpinUnlock(&__CFAllMessagePortsLock); CFRelease(name); CFAllocatorDeallocate(allocator, utfname); return (CFMessagePortRef)CFRetain(existing); } } size = sizeof(struct __CFMessagePort) - sizeof(CFMessagePortContext) - sizeof(CFRuntimeBase); memory = (CFMessagePortRef)_CFRuntimeCreateInstance(allocator, __kCFMessagePortTypeID, size, NULL); if (NULL == memory) { __CFSpinUnlock(&__CFAllMessagePortsLock); if (NULL != name) { CFRelease(name); } CFAllocatorDeallocate(allocator, utfname); return NULL; } __CFMessagePortUnsetValid(memory); __CFMessagePortSetRemote(memory); memory->_lock = 0; memory->_name = name; memory->_port = NULL; memory->_replies = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, NULL); memory->_convCounter = 0; memory->_replyPort = NULL; memory->_source = NULL; memory->_icallout = NULL; memory->_callout = NULL; ctx.version = 0; ctx.info = memory; ctx.retain = NULL; ctx.release = NULL; ctx.copyDescription = NULL; task_get_bootstrap_port(mach_task_self(), &bp); ret = bootstrap_look_up(bp, utfname, &port); native = (KERN_SUCCESS == ret) ? CFMachPortCreateWithPort(allocator, port, __CFMessagePortDummyCallback, &ctx, NULL) : NULL; CFAllocatorDeallocate(allocator, utfname); if (NULL == native) { __CFSpinUnlock(&__CFAllMessagePortsLock); // name is released by deallocation CFRelease(memory); return NULL; } memory->_port = native; CFMachPortSetInvalidationCallBack(native, __CFMessagePortInvalidationCallBack); __CFMessagePortSetValid(memory); if (NULL != name) { if (NULL == __CFAllRemoteMessagePorts) { __CFAllRemoteMessagePorts = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeDictionaryKeyCallBacks, NULL); } CFDictionaryAddValue(__CFAllRemoteMessagePorts, name, memory); } __CFSpinUnlock(&__CFAllMessagePortsLock); return (CFMessagePortRef)memory; }
static kern_return_t k5_ipc_client_lookup_server (const char *in_service_id, boolean_t in_launch_if_necessary, boolean_t in_use_cached_port, mach_port_t *out_service_port) { kern_return_t err = 0; kern_return_t lock_err = 0; mach_port_t k5_service_port = MACH_PORT_NULL; boolean_t found_entry = 0; int i; if (!in_service_id ) { err = EINVAL; } if (!out_service_port) { err = EINVAL; } if (!err) { lock_err = k5_mutex_lock (&g_service_ports_mutex); if (lock_err) { err = lock_err; } } for (i = 0; !err && i < KIPC_SERVICE_COUNT; i++) { if (!strcmp (in_service_id, g_service_ports[i].service_id)) { found_entry = 1; if (in_use_cached_port) { k5_service_port = g_service_ports[i].service_port; } break; } } if (!err && (!MACH_PORT_VALID (k5_service_port) || !in_use_cached_port)) { mach_port_t boot_port = MACH_PORT_NULL; char *service = NULL; /* Get our bootstrap port */ err = task_get_bootstrap_port (mach_task_self (), &boot_port); if (!err && !in_launch_if_necessary) { char *lookup = NULL; mach_port_t lookup_port = MACH_PORT_NULL; int w = asprintf (&lookup, "%s%s", in_service_id, K5_MIG_LOOKUP_SUFFIX); if (w < 0) { err = ENOMEM; } if (!err) { /* Use the lookup name because the service name will return * a valid port even if the server isn't running */ err = bootstrap_look_up (boot_port, lookup, &lookup_port); } free (lookup); if (MACH_PORT_VALID (lookup_port)) { mach_port_deallocate (mach_task_self (), lookup_port); } } if (!err) { int w = asprintf (&service, "%s%s", in_service_id, K5_MIG_SERVICE_SUFFIX); if (w < 0) { err = ENOMEM; } } if (!err) { err = bootstrap_look_up (boot_port, service, &k5_service_port); if (!err && found_entry) { /* Free old port if it is valid */ if (!err && MACH_PORT_VALID (g_service_ports[i].service_port)) { mach_port_deallocate (mach_task_self (), g_service_ports[i].service_port); } g_service_ports[i].service_port = k5_service_port; } } free (service); if (MACH_PORT_VALID (boot_port)) { mach_port_deallocate (mach_task_self (), boot_port); } } if (!err) { *out_service_port = k5_service_port; } if (!lock_err) { k5_mutex_unlock (&g_service_ports_mutex); } return err; }
int32_t k5_ipc_server_listen_loop (void) { /* Run the Mach IPC listen loop. * This will call k5_ipc_server_create_client_connection for new clients * and k5_ipc_server_request for existing clients */ kern_return_t err = KERN_SUCCESS; char *service = NULL; char *lookup = NULL; mach_port_t lookup_port = MACH_PORT_NULL; mach_port_t boot_port = MACH_PORT_NULL; mach_port_t previous_notify_port = MACH_PORT_NULL; if (!err) { err = k5_ipc_server_get_lookup_and_service_names (&lookup, &service); } if (!err) { /* Get the bootstrap port */ err = task_get_bootstrap_port (mach_task_self (), &boot_port); } if (!err) { /* We are an on-demand server so our lookup port already exists. */ err = bootstrap_check_in (boot_port, lookup, &lookup_port); } if (!err) { /* We are an on-demand server so our service port already exists. */ err = bootstrap_check_in (boot_port, service, &g_service_port); } if (!err) { /* Create the port set that the server will listen on */ err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &g_notify_port); } if (!err) { /* Ask for notification when the server port has no more senders * A send-once right != a send right so our send-once right will * not interfere with the notification */ err = mach_port_request_notification (mach_task_self (), g_service_port, MACH_NOTIFY_NO_SENDERS, true, g_notify_port, MACH_MSG_TYPE_MAKE_SEND_ONCE, &previous_notify_port); } if (!err) { /* Create the port set that the server will listen on */ err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_PORT_SET, &g_listen_port_set); } if (!err) { /* Add the lookup port to the port set */ err = mach_port_move_member (mach_task_self (), lookup_port, g_listen_port_set); } if (!err) { /* Add the service port to the port set */ err = mach_port_move_member (mach_task_self (), g_service_port, g_listen_port_set); } if (!err) { /* Add the notify port to the port set */ err = mach_port_move_member (mach_task_self (), g_notify_port, g_listen_port_set); } while (!err && !g_ready_to_quit) { /* Handle one message at a time so we can check to see if * the server wants to quit */ err = mach_msg_server_once (k5_ipc_request_demux, K5_IPC_MAX_MSG_SIZE, g_listen_port_set, MACH_MSG_OPTION_NONE); } /* Clean up the ports and strings */ if (MACH_PORT_VALID (g_notify_port)) { mach_port_destroy (mach_task_self (), g_notify_port); g_notify_port = MACH_PORT_NULL; } if (MACH_PORT_VALID (g_listen_port_set)) { mach_port_destroy (mach_task_self (), g_listen_port_set); g_listen_port_set = MACH_PORT_NULL; } if (MACH_PORT_VALID (boot_port)) { mach_port_deallocate (mach_task_self (), boot_port); } free (service); free (lookup); return err; }
int main (int argc, char **argv, char **envp) { mach_port_t boot; error_t err; void *genport; process_t startup_port; mach_port_t startup; struct argp argp = { 0, 0, 0, "Hurd process server" }; argp_parse (&argp, argc, argv, 0, 0, 0); initialize_version_info (); err = task_get_bootstrap_port (mach_task_self (), &boot); assert_perror (err); if (boot == MACH_PORT_NULL) error (2, 0, "proc server can only be run by init during boot"); proc_bucket = ports_create_bucket (); proc_class = ports_create_class (0, 0); generic_port_class = ports_create_class (0, 0); exc_class = ports_create_class (exc_clean, 0); ports_create_port (generic_port_class, proc_bucket, sizeof (struct port_info), &genport); generic_port = ports_get_right (genport); /* Create the initial proc object for init (PID 1). */ init_proc = create_init_proc (); /* Create the startup proc object for /hurd/init (PID 2). */ startup_proc = allocate_proc (MACH_PORT_NULL); startup_proc->p_deadmsg = 1; complete_proc (startup_proc, HURD_PID_STARTUP); /* Create our own proc object. */ self_proc = allocate_proc (mach_task_self ()); assert (self_proc); complete_proc (self_proc, HURD_PID_PROC); startup_port = ports_get_send_right (startup_proc); err = startup_procinit (boot, startup_port, &startup_proc->p_task, &authserver, &_hurd_host_priv, &_hurd_device_master); assert_perror (err); mach_port_deallocate (mach_task_self (), startup_port); mach_port_mod_refs (mach_task_self (), authserver, MACH_PORT_RIGHT_SEND, 1); _hurd_port_set (&_hurd_ports[INIT_PORT_AUTH], authserver); mach_port_deallocate (mach_task_self (), boot); proc_death_notify (startup_proc); add_proc_to_hash (startup_proc); /* Now that we have the task port. */ /* Set our own argv and envp locations. */ self_proc->p_argv = (vm_address_t) argv; self_proc->p_envp = (vm_address_t) envp; /* Give ourselves good scheduling performance, because we are so important. */ err = increase_priority (); if (err) error (0, err, "Increasing priority failed"); #if 0 err = register_new_task_notification (_hurd_host_priv, generic_port, MACH_MSG_TYPE_MAKE_SEND); if (err) error (0, err, "Registering task notifications failed"); #endif { /* Get our stderr set up to print on the console, in case we have to panic or something. */ mach_port_t cons; error_t err; err = device_open (_hurd_device_master, D_READ|D_WRITE, "console", &cons); assert_perror (err); stdin = mach_open_devstream (cons, "r"); stdout = stderr = mach_open_devstream (cons, "w"); mach_port_deallocate (mach_task_self (), cons); } startup = file_name_lookup (_SERVERS_STARTUP, 0, 0); if (MACH_PORT_VALID (startup)) { err = startup_essential_task (startup, mach_task_self (), MACH_PORT_NULL, "proc", _hurd_host_priv); if (err) /* Due to the single-threaded nature of /hurd/startup, it can only handle requests once the core server bootstrap has completed. Therefore, it does not bind itself to /servers/startup until it is ready. */ /* Fall back to abusing the message port lookup. */ startup_fallback = 1; err = mach_port_deallocate (mach_task_self (), startup); assert_perror (err); } else /* Fall back to abusing the message port lookup. */ startup_fallback = 1; while (1) ports_manage_port_operations_multithread (proc_bucket, message_demuxer, 0, 0, 0); }
void setup_server_ports(struct port_args *ports) { kern_return_t ret = 0; mach_port_t bsport; mach_port_t port; ports->req_size = MAX(sizeof(ipc_inline_message) + sizeof(u_int32_t) * num_ints, sizeof(ipc_complex_message)); ports->reply_size = sizeof(ipc_trivial_message) - sizeof(mach_msg_trailer_t); ports->req_msg = malloc(ports->req_size); ports->reply_msg = malloc(ports->reply_size); if (setcount > 0) { ports->set = (mach_port_t *)calloc(sizeof(mach_port_t), setcount); if (!ports->set) { fprintf(stderr, "calloc(%lu, %d) failed!\n", sizeof(mach_port_t), setcount); exit(1); } } if (stress_prepost) { ports->port_list = (mach_port_t *)calloc(sizeof(mach_port_t), portcount); if (!ports->port_list) { fprintf(stderr, "calloc(%lu, %d) failed!\n", sizeof(mach_port_t), portcount); exit(1); } } if (useset) { mach_port_t set; if (setcount < 1) { fprintf(stderr, "Can't use sets with a setcount of %d\n", setcount); exit(1); } for (int ns = 0; ns < setcount; ns++) { ret = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET, &ports->set[ns]); if (KERN_SUCCESS != ret) { mach_error("mach_port_allocate(SET): ", ret); exit(1); } if (verbose > 1) printf("SVR[%d] allocated set[%d] %#x\n", ports->server_num, ns, ports->set[ns]); set = ports->set[ns]; } /* receive on a port set (always use the first in the chain) */ ports->rcv_set = ports->set[0]; } /* stuff the portset(s) with ports */ for (int i = 0; i < portcount; i++) { ret = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port); if (KERN_SUCCESS != ret) { mach_error("mach_port_allocate(PORT): ", ret); exit(1); } if (stress_prepost) ports->port_list[i] = port; if (useset) { /* insert the port into _all_ allocated lowest-level sets */ for (int ns = 0; ns < setcount; ns++) { if (verbose > 1) printf("SVR[%d] moving port %#x into set %#x...\n", ports->server_num, port, ports->set[ns]); ret = mach_port_insert_member(mach_task_self(), port, ports->set[ns]); if (KERN_SUCCESS != ret) { mach_error("mach_port_insert_member(): ", ret); exit(1); } } } } /* use the last one as the server's bootstrap port */ ports->port = port; if (stress_prepost) { /* insert a send right for _each_ port */ for (int i = 0; i < portcount; i++) { ret = mach_port_insert_right(mach_task_self(), ports->port_list[i], ports->port_list[i], MACH_MSG_TYPE_MAKE_SEND); if (KERN_SUCCESS != ret) { mach_error("mach_port_insert_right(): ", ret); exit(1); } } } else { ret = mach_port_insert_right(mach_task_self(), ports->port, ports->port, MACH_MSG_TYPE_MAKE_SEND); if (KERN_SUCCESS != ret) { mach_error("mach_port_insert_right(): ", ret); exit(1); } } ret = task_get_bootstrap_port(mach_task_self(), &bsport); if (KERN_SUCCESS != ret) { mach_error("task_get_bootstrap_port(): ", ret); exit(1); } if (verbose) { printf("server waiting for IPC messages from client on port '%s' (%#x).\n", server_port_name[ports->server_num], ports->port); } ret = bootstrap_register(bsport, server_port_name[ports->server_num], ports->port); if (KERN_SUCCESS != ret) { mach_error("bootstrap_register(): ", ret); exit(1); } }