/* Return the active translator control port for NODE. If there is no translator, active or passive, MACH_PORT_NULL is returned in CONTROL_PORT. If there is a translator, it is started if necessary, and returned in CONTROL_PORT. *DIR_PORT should be a port right to use as the new translators parent directory. If it is MACH_PORT_NULL, a port is created from DIR and PARENT_PORT and stored in *DIR_PORT; otherwise DIR and PARENT_PORT are not used. Neither NODE or DIR should be locked when calling this function. */ error_t treefs_node_get_active_trans (struct treefs_node *node, struct treefs_node *dir, mach_port_t parent_port, mach_port_t *control_port, mach_port_t *dir_port) { /* Fill in dir_port */ void make_dir_port () { pthread_mutex_lock (&dir->lock); *dir_port = treefs_node_make_right (dir, 0, parent_port, 0); mach_port_insert_right (mach_task_self (), *dir_port, *dir_port, MACH_MSG_TYPE_MAKE_SEND); pthread_mutex_unlock (&dir->lock); }
/* Start the translator TRANS (of length TRANS_LEN) on NODE, which should be locked, and will be unlocked when this function returns. PARENT_PORT is a send right to use as the parent port passed to the translator. */ error_t _treefs_node_start_translator (struct treefs_node *node, char *trans, unsigned trans_len, file_t parent_port) { error_t err; int mode = O_READ | O_EXEC; struct treefs_auth *auth; file_t node_port; uid_t uid, gid; err = treefs_node_get_trans_auth (node, &auth); if (err) return err; if (!node->fsys->readonly && treefs_node_type (node) == S_IFREG) mode |= O_WRITE; /* Create the REALNODE port for the new filesystem. */ node_port = treefs_node_make_right (node, mode, parent_port, auth); mach_port_insert_right (mach_task_self (), node_port, node_port, MACH_MSG_TYPE_MAKE_SEND); mutex_unlock (&node->lock); /* XXXX Change libfshelp so that it take more than 1 uid/gid? */ uid = auth->nuids > 0 ? auth->uids[0] : -1; gid = auth->ngids > 0 ? auth->gids[0] : -1; /* XXX this should use fshelp_start_translator_long. */ err = fshelp_start_translator (&node->active_trans, NULL, trans, trans_len, parent_port, node_port, uid, gid); treefs_node_auth_unref (node, auth); return err; }