Ejemplo n.º 1
0
int
ethernet_open (struct device *dev)
{
  error_t err;
  device_t master_device;
  struct ether_device *edev = (struct ether_device *) dev->priv;

  assert (edev->ether_port == MACH_PORT_NULL);

  err = ports_create_port (etherreadclass, etherport_bucket,
			   sizeof (struct port_info), &edev->readpt);
  assert_perror (err);
  edev->readptname = ports_get_right (edev->readpt);
  mach_port_insert_right (mach_task_self (), edev->readptname, edev->readptname,
			  MACH_MSG_TYPE_MAKE_SEND);

  mach_port_set_qlimit (mach_task_self (), edev->readptname, MACH_PORT_QLIMIT_MAX);

  master_device = file_name_lookup (dev->name, O_READ | O_WRITE, 0);
  if (master_device != MACH_PORT_NULL)
    {
      /* The device name here is the path of a device file.  */
      err = device_open (master_device, D_WRITE | D_READ, "eth", &edev->ether_port);
      mach_port_deallocate (mach_task_self (), master_device);
      if (err)
	error (2, err, "device_open on %s", dev->name);

      err = device_set_filter (edev->ether_port, ports_get_right (edev->readpt),
			       MACH_MSG_TYPE_MAKE_SEND, 0,
			       bpf_ether_filter, bpf_ether_filter_len);
      if (err)
	error (2, err, "device_set_filter on %s", dev->name);
    }
  else
    {
      /* No, perhaps a Mach device?  */
      int file_errno = errno;
      err = get_privileged_ports (0, &master_device);
      if (err)
	{
	  error (0, file_errno, "file_name_lookup %s", dev->name);
	  error (2, err, "and cannot get device master port");
	}
      err = device_open (master_device, D_WRITE | D_READ, dev->name, &edev->ether_port);
      mach_port_deallocate (mach_task_self (), master_device);
      if (err)
	{
	  error (0, file_errno, "file_name_lookup %s", dev->name);
	  error (2, err, "device_open(%s)", dev->name);
	}

      err = device_set_filter (edev->ether_port, ports_get_right (edev->readpt),
			       MACH_MSG_TYPE_MAKE_SEND, 0,
			       ether_filter, ether_filter_len);
      if (err)
	error (2, err, "device_set_filter on %s", dev->name);
    }

  return 0;
}
Ejemplo n.º 2
0
int ethernet_open (char *dev_name, device_t master_device, 
		   struct port_bucket *etherport_bucket,
		   struct port_class *etherreadclass)
{
  error_t err;

  assert (ether_port == MACH_PORT_NULL);

  err = ports_create_port (etherreadclass, etherport_bucket,
			   sizeof (struct port_info), &readpt);
  if (err)
    error (2, err, "ports_create_port");
  readptname = ports_get_right (readpt);
  mach_port_insert_right (mach_task_self (), readptname, readptname,
			  MACH_MSG_TYPE_MAKE_SEND);

  mach_port_set_qlimit (mach_task_self (), readptname, MACH_PORT_QLIMIT_MAX);

  err = device_open (master_device, D_WRITE | D_READ, "eth", &ether_port);
  mach_port_deallocate (mach_task_self (), master_device);
  if (err)
    error (2, err, "device_open: %s", dev_name);

  err = device_set_filter (ether_port, ports_get_right (readpt),
			   MACH_MSG_TYPE_MAKE_SEND, 0,
			   (unsigned short *)ether_filter, ether_filter_len);
  if (err)
    error (2, err, "device_set_filter: %s", dev_name);

  set_promisc (dev_name, ether_port, 1);
  return 0;
}
Ejemplo n.º 3
0
/* Callback function needed for calls to fshelp_fetch_root.  See
   <hurd/fshelp.h> for the interface description.  */
static error_t
_netfs_translator_callback2_fn (void *cookie1, void *cookie2, int flags,
				mach_port_t *underlying,
				mach_msg_type_name_t *underlying_type)
{
  error_t err;
  struct protid *cred;
  struct node *node = cookie1;
  struct iouser *user;

  err = iohelp_create_simple_iouser (&user, node->nn_stat.st_uid,
				   node->nn_stat.st_gid);
  if (err)
    return err;

  cred = netfs_make_protid (netfs_make_peropen (node, flags, cookie2),
			    user);
  if (cred)
    {
      *underlying = ports_get_right (cred);
      *underlying_type = MACH_MSG_TYPE_MAKE_SEND;
      ports_port_deref (cred);
      return 0;
    }
  else
    {
      iohelp_free_iouser (user);
      return errno;
    }
}
Ejemplo n.º 4
0
/* Implement io_duplicate as described in <hurd/io.defs>. */
kern_return_t
diskfs_S_io_duplicate (struct protid *cred,
		       mach_port_t *port,
		       mach_msg_type_name_t *portpoly)
{
  error_t err;
  struct protid *newpi;

  if (!cred)
    return EOPNOTSUPP;
  
  mutex_lock (&cred->po->np->lock);

  err = diskfs_create_protid (cred->po, cred->user, &newpi);
  if (! err)
    {
      *port = ports_get_right (newpi);
      *portpoly = MACH_MSG_TYPE_MAKE_SEND;
      ports_port_deref (newpi);
    }

  mutex_unlock (&cred->po->np->lock);

  return err;
}
Ejemplo n.º 5
0
error_t
fshelp_get_identity (struct port_bucket *bucket,
		     ino_t fileno,
		     mach_port_t *pt)
{
  struct idspec *i;
  error_t err = 0;

  error_t check_port (void *arg)
    {
      struct idspec *i = arg;
      if (i->fileno == fileno)
	{
	  *pt = ports_get_right (i);
	  return 1;
	}
      else
	return 0;
    }

  mutex_lock (&idlock);
  if (!idclass)
    id_initialize ();

  *pt = MACH_PORT_NULL;

  ports_class_iterate (idclass, check_port);

  if (*pt != MACH_PORT_NULL)
    {
      mutex_unlock (&idlock);
      return 0;
    }

  err = ports_create_port (idclass, bucket, sizeof (struct idspec), &i);
  if (err)
    {
      mutex_unlock (&idlock);
      return err;
    }
  i->fileno = fileno;

  *pt = ports_get_right (i);
  ports_port_deref (i);
  mutex_unlock (&idlock);
  return 0;
}
Ejemplo n.º 6
0
/* Return a new connection from a socket previously listened.  */
error_t
S_socket_accept (struct sock_user *user,
                 mach_port_t *port, mach_msg_type_name_t *port_type,
                 mach_port_t *peer_addr_port,
                 mach_msg_type_name_t *peer_addr_port_type)
{
    error_t err;
    struct sock *sock;

    if (!user)
        return EOPNOTSUPP;

    sock = user->sock;

    err = ensure_connq (sock);
    if (!err)
    {
        struct timespec noblock = {0, 0};
        struct sock *peer_sock;

        err = connq_listen (sock->listen_queue,
                            (sock->flags & PFLOCAL_SOCK_NONBLOCK) ? &noblock : NULL,
                            &peer_sock);
        if (!err)
        {
            struct addr *peer_addr;
            *port_type = MACH_MSG_TYPE_MAKE_SEND;
            err = sock_create_port (peer_sock, port);
            if (!err)
                err = sock_get_addr (peer_sock, &peer_addr);
            if (!err)
            {
                *peer_addr_port = ports_get_right (peer_addr);
                *peer_addr_port_type = MACH_MSG_TYPE_MAKE_SEND;
                ports_port_deref (peer_addr);
            }
            else
            {
                /* TEAR DOWN THE CONNECTION XXX */
            }
        }
    }

    return err;
}
Ejemplo n.º 7
0
/* Find out the name of a socket.  */
error_t
S_socket_name (struct sock_user *user,
               mach_port_t *addr_port, mach_msg_type_name_t *addr_port_type)
{
    error_t err;
    struct addr *addr;

    if (!user)
        return EOPNOTSUPP;

    err = sock_get_addr (user->sock, &addr);
    if (err)
        return err;

    *addr_port = ports_get_right (addr);
    *addr_port_type = MACH_MSG_TYPE_MAKE_SEND;
    ports_port_deref (addr);

    return 0;
}
Ejemplo n.º 8
0
error_t
netfs_S_dir_mkfile (struct protid *diruser, int flags, mode_t mode, 
		    mach_port_t *newfile, mach_msg_type_name_t *newfiletype)
{
  error_t err;
  struct node *np;
  struct iouser *user;
  struct protid *newpi;

  pthread_mutex_lock (&diruser->po->np->lock);
  err = netfs_attempt_mkfile (diruser->user, diruser->po->np, mode, &np);

  if (!err)
    {
      /* the dir is now unlocked and NP is locked */
      flags &= OPENONLY_STATE_MODES;
      err = iohelp_dup_iouser (&user, diruser->user);
      if (! err)
        {
          newpi = netfs_make_protid (netfs_make_peropen (np, flags,
							 diruser->po),
				     user);
	  if (newpi)
	    {
	      *newfile = ports_get_right (newpi);
	      *newfiletype = MACH_MSG_TYPE_MAKE_SEND;
	      ports_port_deref (newpi);
	    }
	  else
	    {
	      err = errno;
	      iohelp_free_iouser (user);
	    }
	}
      netfs_nput (np);
    }

  return err;
}
Ejemplo n.º 9
0
error_t
netfs_S_io_restrict_auth (struct protid *user,
			  mach_port_t *newport,
			  mach_msg_type_name_t *newporttype,
			  uid_t *uids,
			  mach_msg_type_number_t nuids,
			  gid_t *gids,
			  mach_msg_type_number_t ngids)
{
  error_t err;
  struct protid *newpi;
  struct iouser *new_user;

  if (!user)
    return EOPNOTSUPP;

  err = iohelp_restrict_iouser (&new_user, user->user,
				uids, nuids, gids, ngids);
  if (err)
    return err;

  refcount_ref (&user->po->refcnt);
  newpi = netfs_make_protid (user->po, new_user);
  if (newpi)
    {
      *newport = ports_get_right (newpi);
      *newporttype = MACH_MSG_TYPE_MAKE_SEND;
    }
  else
    {
      refcount_deref (&user->po->refcnt);
      iohelp_free_iouser (new_user);
      err = ENOMEM;
    }

  ports_port_deref (newpi);
  return err;
}
Ejemplo n.º 10
0
kern_return_t
trivfs_S_io_restrict_auth (struct trivfs_protid *cred,
			   mach_port_t reply,
			   mach_msg_type_name_t replytype,
			   mach_port_t *newport,
			   mach_msg_type_name_t *newporttype,
			   uid_t *uids, size_t nuids,
			   uid_t *gids, size_t ngids)
{
  int i;
  error_t err;
  struct trivfs_protid *newcred;
  struct idvec *uvec, *gvec;
  struct iouser *user;

  if (!cred)
    return EOPNOTSUPP;

  if (cred->isroot)
    /* CRED has root access, and so may use any ids.  */
    {
      err = iohelp_create_complex_iouser (&user, uids, nuids, gids, ngids);
      if (err)
        return err;
    }
  else
    {
      uvec = make_idvec ();
      if (! uvec)
        return ENOMEM;

      gvec = make_idvec ();
      if (! gvec)
        {
	  idvec_free (uvec);
	  return ENOMEM;
	}

      /* Otherwise, use any of the requested ids that CRED already has.  */
      for (i = 0; i < cred->user->uids->num; i++)
	if (listmember (uids, cred->user->uids->ids[i], nuids))
	  {
	    err = idvec_add (uvec, cred->user->uids->ids[i]);
	    if (err)
	      goto out;
	  }

      for (i = 0; i < cred->user->gids->num; i++)
	if (listmember (gids, cred->user->gids->ids[i], ngids))
	  {
	    err = idvec_add (gvec, cred->user->gids->ids[i]);
	    if (err)
	      goto out;
	  }

      err = iohelp_create_iouser (&user, uvec, gvec);
      if (err)
        {
	out:
	  idvec_free (uvec);
	  idvec_free (gvec);
	  return err;
	}
    }

  err = ports_create_port (cred->po->cntl->protid_class,
			   cred->po->cntl->protid_bucket,
			   sizeof (struct trivfs_protid),
			   &newcred);
  if (err)
    {
      iohelp_free_iouser (user);
      return err;
    }

  newcred->isroot = 0;
  mutex_lock (&cred->po->cntl->lock);
  newcred->po = cred->po;
  newcred->po->refcnt++;
  mutex_unlock (&cred->po->cntl->lock);
  if (cred->isroot && idvec_contains (user->uids, 0))
    newcred->isroot = 1;
  newcred->user = user;
  newcred->hook = cred->hook;

  err = io_restrict_auth (cred->realnode, &newcred->realnode,
			  user->uids->ids, user->uids->num,
			  user->gids->ids, user->gids->num);
  if (!err && trivfs_protid_create_hook)
    {
      err = (*trivfs_protid_create_hook) (newcred);
      if (err)
	mach_port_deallocate (mach_task_self (), newcred->realnode);
    }

  if (err)
    /* Signal that the user destroy hook shouldn't be called on NEWCRED.  */
    newcred->realnode = MACH_PORT_NULL;
  else
    {
      *newport = ports_get_right (newcred);
      *newporttype = MACH_MSG_TYPE_MAKE_SEND;
    }

  /* This will destroy NEWCRED if we got an error and didn't do the
     ports_get_right above.  */
  ports_port_deref (newcred);

  return 0;
}
Ejemplo n.º 11
0
/* Return in FILE & FILE_TYPE the file in FSYS corresponding to the NFS file
   handle HANDLE & HANDLE_LEN.  */
error_t
diskfs_S_fsys_getfile (mach_port_t fsys,
		       mach_port_t reply, mach_msg_type_name_t reply_type,
		       uid_t *uids, mach_msg_type_number_t nuids,
		       gid_t *gids, mach_msg_type_number_t ngids,
		       char *handle, mach_msg_type_number_t handle_len,
		       mach_port_t *file, mach_msg_type_name_t *file_type)
{
  int flags;
  error_t err;
  struct node *node;
  const union diskfs_fhandle *f;
  struct protid *new_cred;
  struct peropen *new_po;
  struct iouser *user;
  struct port_info *pt =
    ports_lookup_port (diskfs_port_bucket, fsys, diskfs_control_class);

  if (!pt)
    return EOPNOTSUPP;

  if (handle_len != sizeof *f)
    {
      ports_port_deref (pt);
      return EINVAL;
    }

  f = (const union diskfs_fhandle *) handle;

  err = diskfs_cached_lookup (f->data.cache_id, &node);
  if (err)
    {
      ports_port_deref (pt);
      return err;
    }

  if (node->dn_stat.st_gen != f->data.gen)
    {
      diskfs_nput (node);
      ports_port_deref (pt);
      return ESTALE;
    }

  err = iohelp_create_complex_iouser (&user, uids, nuids, gids, ngids);
  if (err)
    {
      diskfs_nput (node);
      ports_port_deref (pt);
      return err;
    }

  flags = 0;
  if (! fshelp_access (&node->dn_stat, S_IREAD, user))
    flags |= O_READ;
  if (! fshelp_access (&node->dn_stat, S_IEXEC, user))
    flags |= O_EXEC;
  if (! fshelp_access (&node->dn_stat, S_IWRITE, user)
      && ! S_ISDIR (node->dn_stat.st_mode)
      && ! diskfs_check_readonly ())
    flags |= O_WRITE;

  err = diskfs_make_peropen (node, flags, 0, &new_po);
  if (! err)
    {
      err = diskfs_create_protid (new_po, user, &new_cred);
      if (err)
	diskfs_release_peropen (new_po);
    }

  iohelp_free_iouser (user);

  diskfs_nput (node);
  ports_port_deref (pt);

  if (! err)
    {
      *file = ports_get_right (new_cred);
      *file_type = MACH_MSG_TYPE_MAKE_SEND;
    }

  return err;
}
Ejemplo n.º 12
0
Archivo: main.c Proyecto: Larhard/hurd
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);
}
Ejemplo n.º 13
0
kern_return_t
trivfs_S_fsys_getroot (struct trivfs_control *cntl,
		       mach_port_t reply_port,
		       mach_msg_type_name_t reply_port_type,
		       mach_port_t dotdot,
		       uid_t *uids, size_t nuids,
		       uid_t *gids, size_t ngids,
		       int flags,
		       retry_type *do_retry,
		       char *retry_name,
		       mach_port_t *newpt,
		       mach_msg_type_name_t *newpttype)
{
  int perms;
  error_t err = 0;
  mach_port_t new_realnode;
  struct trivfs_protid *cred;
  struct iouser *user;

  if (!cntl)
    return EOPNOTSUPP;

  if (trivfs_getroot_hook)
    {
      err = (*trivfs_getroot_hook) (cntl, reply_port, reply_port_type, dotdot,
				    uids, nuids, gids, ngids, flags,
				    do_retry, retry_name, newpt, newpttype);
      if (err != EAGAIN)
	return err;
    }

  if ((flags & O_WRITE & trivfs_allow_open) != (flags & O_WRITE))
    return EROFS;
  if ((flags & (O_READ|O_WRITE|O_EXEC) & trivfs_allow_open)
      != (flags & (O_READ|O_WRITE|O_EXEC)))
    return EACCES;

  /* O_CREAT and O_EXCL are not meaningful here; O_NOLINK and O_NOTRANS
     will only be useful when trivfs supports translators (which it doesn't
     now). */
  flags &= O_HURD;
  flags &= ~(O_CREAT|O_EXCL|O_NOLINK|O_NOTRANS);

  struct idvec idvec = {
    .ids = uids,
    .num = nuids,
    .alloced = nuids,
  };

  if (_is_privileged (&idvec))
    /* Privileged users should be given all our rights.  */
    err = io_duplicate (cntl->underlying, &new_realnode);
  else
    /* Non-privileged, restrict rights.  */
    err = io_restrict_auth (cntl->underlying,
			    &new_realnode, uids, nuids, gids, ngids);

  if (err)
    return err;

  err = iohelp_create_complex_iouser (&user, uids, nuids, gids, ngids);
  if (err)
    return err;

  /* Validate permissions.  */
  if (! trivfs_check_access_hook)
    file_check_access (new_realnode, &perms);
  else
    (*trivfs_check_access_hook) (cntl, user, new_realnode, &perms);
  if ((flags & (O_READ|O_WRITE|O_EXEC) & perms)
      != (flags & (O_READ|O_WRITE|O_EXEC)))
    err = EACCES;

  if (!err && trivfs_check_open_hook)
    err = (*trivfs_check_open_hook) (cntl, user, flags);
  if (!err)
    {
      if (! trivfs_open_hook)
	{
	  err = trivfs_open (cntl, user, flags, new_realnode, &cred);
	  if (!err)
	    mach_port_deallocate (mach_task_self (), dotdot);
	}
      else
	err = (*trivfs_open_hook) (cntl, user, dotdot, flags, new_realnode,
				   &cred);
    }

  if (err)
    {
      mach_port_deallocate (mach_task_self (), new_realnode);
      iohelp_free_iouser (user);
    }
  else
    {
      *do_retry = FS_RETRY_NORMAL;
      *retry_name = '\0';
      *newpt = ports_get_right (cred);
      *newpttype = MACH_MSG_TYPE_MAKE_SEND;
      ports_port_deref (cred);
    }

  return err;
}
Ejemplo n.º 14
0
int
main (int argc, char **argv, char **envp)
{
  mach_port_t boot;
  error_t err;
  mach_port_t pset, psetcntl;
  void *genport;
  process_t startup_port;
  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).  */
  startup_proc = create_startup_proc ();

  /* Create our own proc object (we are PID 0).  */
  self_proc = allocate_proc (mach_task_self ());
  assert (self_proc);

  complete_proc (self_proc, 0);

  startup_port = ports_get_send_right (startup_proc);
  err = startup_procinit (boot, startup_port, &startup_proc->p_task,
			  &authserver, &master_host_port, &master_device_port);
  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 = thread_get_assignment (mach_thread_self (), &pset);
  assert_perror (err);
  err = host_processor_set_priv (master_host_port, pset, &psetcntl);
  assert_perror (err);
  thread_max_priority (mach_thread_self (), psetcntl, 0);
  assert_perror (err);
  err = task_priority (mach_task_self (), 2, 1);
  assert_perror (err);

  mach_port_deallocate (mach_task_self (), pset);
  mach_port_deallocate (mach_task_self (), psetcntl);

  {
    /* 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 (master_device_port, 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);
  }

  while (1)
    ports_manage_port_operations_multithread (proc_bucket,
					      message_demuxer,
					      0, 0, 0);
}
Ejemplo n.º 15
0
/* Receive data from a socket, possibly including Mach ports.  */
error_t
S_socket_recv (struct sock_user *user,
               mach_port_t *addr, mach_msg_type_name_t *addr_type,
               int in_flags,
               char **data, size_t *data_len,
               mach_port_t **ports, mach_msg_type_name_t *ports_type,
               size_t *num_ports,
               char **control, size_t *control_len,
               int *out_flags, size_t amount)
{
    error_t err;
    unsigned flags;
    struct pipe *pipe;
    void *source_addr = NULL;

    if (!user)
        return EOPNOTSUPP;

    if (in_flags & MSG_OOB)
        /* BSD local sockets don't support OOB data.  */
        return EINVAL;		/* XXX */

    /* Fill in the pipe FLAGS from any corresponding ones in IN_FLAGS.  */
    flags = in_flags & MSG_PEEK;

    err = sock_acquire_read_pipe (user->sock, &pipe);
    if (err == EPIPE)
        /* EOF */
    {
        *data_len = 0;
        if (num_ports)
            *num_ports = 0;
        if (control_len)
            *control_len = 0;
    }
    else if (!err)
    {
        err =
            pipe_recv (pipe, user->sock->flags & PFLOCAL_SOCK_NONBLOCK, &flags,
                       &source_addr, data, data_len, amount,
                       control, control_len, ports, num_ports);
        pipe_release_reader (pipe);
    }

    if (!err)
        /* Setup mach ports for return.  */
    {
        *addr_type = MACH_MSG_TYPE_MAKE_SEND;
        *ports_type = MACH_MSG_TYPE_MOVE_SEND;
        if (source_addr)
        {
            *addr = ports_get_right (source_addr);
            ports_port_deref (source_addr); /* since get_right has one too.  */
        }
        else
            *addr = MACH_PORT_NULL;
    }

    *out_flags = 0;

    return err;
}
Ejemplo n.º 16
0
kern_return_t
trivfs_S_dir_lookup (struct trivfs_protid *cred,
		     mach_port_t reply, mach_msg_type_name_t reply_type,
		     char *filename,
		     int flags,
		     mode_t mode,
		     retry_type *retry_type,
		     char *retry_name,
		     mach_port_t *retrypt,
		     mach_msg_type_name_t *retrypt_type)
{
  int perms;
  error_t err;
  struct trivfs_protid *newcred;

  if (!cred)
    return EOPNOTSUPP;

  if (filename[0])
    return ENOTDIR;

  /* This is a null-pathname "reopen" call; do the right thing. */

  /* Burn off flags we don't actually implement */
  flags &= O_HURD;
  flags &= ~(O_CREAT|O_EXCL|O_NOLINK|O_NOTRANS);

  /* Validate permissions */
  if (! trivfs_check_access_hook)
    file_check_access (cred->realnode, &perms);
  else
    (*trivfs_check_access_hook) (cred->po->cntl, cred->user,
				 cred->realnode, &perms);
  if ((flags & (O_READ|O_WRITE|O_EXEC) & perms)
      != (flags & (O_READ|O_WRITE|O_EXEC)))
    return EACCES;

  /* Execute the open */
  err = 0;
  if (trivfs_check_open_hook)
    err = (*trivfs_check_open_hook) (cred->po->cntl, cred->user, flags);
  if (!err)
    {
      struct iouser *user;

      err = iohelp_dup_iouser (&user, cred->user);
      if (err)
	return err;

      err = trivfs_open (cred->po->cntl, user, flags,
			 cred->realnode, &newcred);
      if (err)
	iohelp_free_iouser (user);
      else
	mach_port_mod_refs (mach_task_self (), cred->realnode,
			    MACH_PORT_RIGHT_SEND, +1);
    }
  if (err)
    return err;

  *retry_type = FS_RETRY_NORMAL;
  *retry_name = '\0';
  *retrypt = ports_get_right (newcred);
  *retrypt_type = MACH_MSG_TYPE_MAKE_SEND;
  ports_port_deref (newcred);
  return 0;
}