Beispiel #1
0
/* 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;
}