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; }
/* Create a new trivfs control port, with underlying node UNDERLYING, and return it in CONTROL. CONTROL_CLASS & CONTROL_BUCKET are passed to the ports library to create the control port, and PROTID_CLASS & PROTID_BUCKET are used when creating ports representing opens of this node. */ error_t trivfs_create_control (mach_port_t underlying, struct port_class *control_class, struct port_bucket *control_bucket, struct port_class *protid_class, struct port_bucket *protid_bucket, struct trivfs_control **control) { error_t err; /* Perhaps allocate, and perhaps add the specified port classes the ones recognized by trivfs. */ err = trivfs_add_control_port_class (&control_class); if (! err) err = trivfs_add_protid_port_class (&protid_class); else protid_class = 0; /* Perhaps allocate new port buckets. */ if (! err) err = trivfs_add_port_bucket (&control_bucket); else control_bucket = 0; if (! err) { if (! protid_bucket) /* By default, use the same port bucket for both. */ protid_bucket = control_bucket; err = trivfs_add_port_bucket (&protid_bucket); } else protid_bucket = 0; if (! err) err = ports_create_port (control_class, control_bucket, sizeof (struct trivfs_control), control); if (! err) { (*control)->underlying = underlying; (*control)->protid_class = protid_class; (*control)->protid_bucket = protid_bucket; err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &(*control)->filesys_id); if (err) { ports_port_deref (*control); goto out; } err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &(*control)->file_id); if (err) { mach_port_destroy (mach_task_self (), (*control)->filesys_id); ports_port_deref (*control); goto out; } (*control)->hook = 0; mutex_init (&(*control)->lock); } out: if (err) { trivfs_remove_control_port_class (control_class); trivfs_remove_protid_port_class (protid_class); trivfs_remove_port_bucket (control_bucket); trivfs_remove_port_bucket (protid_bucket); } return err; }