Пример #1
0
file_t
__getdport (int fd)
{
  if (_hurd_getdport_fn)
    /* dtable.c has defined the function to fetch a port from the real file
       descriptor table.  */
    return (*_hurd_getdport_fn) (fd);

  /* getdport is the only use of file descriptors,
     so we don't bother allocating a real table.  */

  if (_hurd_init_dtable == NULL)
    {
      /* Never had a descriptor table.  */
      errno = EBADF;
      return MACH_PORT_NULL;
    }

  if (fd < 0 || (unsigned int) fd > _hurd_init_dtablesize ||
      _hurd_init_dtable[fd] == MACH_PORT_NULL)
    {
      errno = EBADF;
      return MACH_PORT_NULL;
    }
  else
    {
      __mach_port_mod_refs (__mach_task_self (), _hurd_init_dtable[fd],
			    MACH_PORT_RIGHT_SEND, 1);
      return _hurd_init_dtable[fd];
    }
}
Пример #2
0
/* Called by MiG to deallocate the reply port.  */
void
__mig_dealloc_reply_port (void)
{
  mach_port_t port = reply_port;
  reply_port = MACH_PORT_NULL;	/* So the mod_refs RPC won't use it.  */
  __mach_port_mod_refs (__mach_task_self (), port,
			MACH_PORT_RIGHT_RECEIVE, -1);
}
Пример #3
0
kern_return_t
__get_privileged_ports (mach_port_t *host_priv_ptr,
			device_t *device_master_ptr)
{
  if ((host_priv_ptr && _hurd_host_priv == MACH_PORT_NULL)
      || (device_master_ptr && _hurd_device_master == MACH_PORT_NULL))
    {
      error_t err;

      if (_hurd_ports)
	/* We have gotten some initial ports, so perhaps
	   we have a proc server to talk to.  */
	err = __USEPORT (PROC, __proc_getprivports (port,
						    &_hurd_host_priv,
						    &_hurd_device_master));
      else
	return MACH_SEND_INVALID_DEST;

      if (err)
	return err;
    }

  if (host_priv_ptr)
    {
      error_t err = _hurd_host_priv == MACH_PORT_NULL ? 0
	: __mach_port_mod_refs (mach_task_self (),
				_hurd_host_priv, MACH_PORT_RIGHT_SEND, +1);
      if (err)
	return err;
      *host_priv_ptr = _hurd_host_priv;
    }

  if (device_master_ptr)
    {
      error_t err = _hurd_device_master == MACH_PORT_NULL ? 0
	: __mach_port_mod_refs (mach_task_self (),
				_hurd_device_master, MACH_PORT_RIGHT_SEND, +1);
      if (err)
	return err;
      *device_master_ptr = _hurd_device_master;
    }

  return KERN_SUCCESS;
}
Пример #4
0
error_t
_hurd_ports_get (unsigned int which, mach_port_t *result)
{
  if (which >= _hurd_nports)
    return EINVAL;
  if (which >= INIT_PORT_MAX || _hurd_ports_getters[which] == NULL)
    return HURD_PORT_USE (&_hurd_ports[which],
			  (*result = port) == MACH_PORT_NULL ? 0
			  : __mach_port_mod_refs (__mach_task_self (),
						  port, MACH_PORT_RIGHT_SEND,
						  +1));
  return (*_hurd_ports_getters[which]) (result);
}
Пример #5
0
/* Called by MiG to deallocate the reply port.  */
void
__mig_dealloc_reply_port (mach_port_t arg)
{
  mach_port_t port;

  GETPORT;

  port = reply_port;
  reply_port = MACH_PORT_NULL;	/* So the mod_refs RPC won't use it.  */

  if (MACH_PORT_VALID (port))
    __mach_port_mod_refs (__mach_task_self (), port,
			  MACH_PORT_RIGHT_RECEIVE, -1);
}
error_t
_hurd_ports_set (unsigned int which, mach_port_t newport)
{
  error_t err;
  if (which >= _hurd_nports)
    return EINVAL;
  if (err = __mach_port_mod_refs (__mach_task_self (), newport,
				  MACH_PORT_RIGHT_SEND, 1))
    return err;
  if (which >= INIT_PORT_MAX || _hurd_ports_setters[which] == NULL)
    {
      _hurd_port_set (&_hurd_ports[which], newport);
      return 0;
    }
  return (*_hurd_ports_setters[which]) (newport);
}
Пример #7
0
  error_t addref (file_t crdir)
    {
      *dir = crdir;
      return __mach_port_mod_refs (__mach_task_self (),
				   crdir, MACH_PORT_RIGHT_SEND, +1);
    }
Пример #8
0
/* Duplicate FD to FD2, closing the old FD2 and making FD2 be
   open on the same file as FD is, and setting FD2's flags according to FLAGS.
   Return FD2 or -1.  */
int
__dup3 (int fd, int fd2, int flags)
{
  struct hurd_fd *d;

  /* Both passing flags different from O_CLOEXEC and FD2 being the same as FD
     are invalid.  */
  if ((flags & ~O_CLOEXEC
       || fd2 == fd)
      /* ... with the exception in case that dup2 behavior is requested: if FD
	 is valid and FD2 is already the same then just return it.  */
      && ! (flags == -1
	    && fd2 == fd))
    return __hurd_fail (EINVAL);

  /* Extract the ports and flags from FD.  */
  d = _hurd_fd_get (fd);
  if (d == NULL)
    return __hurd_fail (EBADF);

  HURD_CRITICAL_BEGIN;

  __spin_lock (&d->port.lock);
  if (d->port.port == MACH_PORT_NULL)
    {
      __spin_unlock (&d->port.lock);
      fd2 = __hurd_fail (EBADF);
    }
  else if (fd2 == fd)
    __spin_unlock (&d->port.lock);
  else
    {
      struct hurd_userlink ulink, ctty_ulink;
      int d_flags = d->flags;
      io_t ctty = _hurd_port_get (&d->ctty, &ctty_ulink);
      io_t port = _hurd_port_locked_get (&d->port, &ulink); /* Unlocks D.  */

      if (fd2 < 0)
	fd2 = __hurd_fail (EBADF);
      else
	{
	  /* Get a hold of the destination descriptor.  */
	  struct hurd_fd *d2;

	  __mutex_lock (&_hurd_dtable_lock);

	  if (fd2 >= _hurd_dtablesize)
	    {
	      /* The table is not large enough to hold the destination
		 descriptor.  Enlarge it as necessary to allocate this
		 descriptor.  */
	      __mutex_unlock (&_hurd_dtable_lock);
	      d2 = _hurd_alloc_fd (NULL, fd2);
	      if (d2)
		__spin_unlock (&d2->port.lock);
	      __mutex_lock (&_hurd_dtable_lock);
	    }
	  else
	    {
	      d2 = _hurd_dtable[fd2];
	      if (d2 == NULL)
		{
		  /* Must allocate a new one.  We don't initialize the port
		     cells with this call so that if it fails (out of
		     memory), we will not have already added user
		     references for the ports, which we would then have to
		     deallocate.  */
		  d2 = _hurd_dtable[fd2] = _hurd_new_fd (MACH_PORT_NULL,
							 MACH_PORT_NULL);
		}
	    }
	  __mutex_unlock (&_hurd_dtable_lock);

	  if (d2 == NULL)
	    {
	      fd2 = -1;
	      if (errno == EINVAL)
		errno = EBADF;	/* POSIX.1-1990 6.2.1.2 ll 54-55.  */
	    }
	  else
	    {
	      /* Give the ports each a user ref for the new descriptor.  */
	      __mach_port_mod_refs (__mach_task_self (), port,
				    MACH_PORT_RIGHT_SEND, 1);
	      if (ctty != MACH_PORT_NULL)
		__mach_port_mod_refs (__mach_task_self (), ctty,
				      MACH_PORT_RIGHT_SEND, 1);

	      /* Install the ports and flags in the new descriptor slot.  */
	      __spin_lock (&d2->port.lock);
	      if (flags & O_CLOEXEC)
		d2->flags = d_flags | FD_CLOEXEC;
	      else
		/* dup clears FD_CLOEXEC.  */
		d2->flags = d_flags & ~FD_CLOEXEC;
	      _hurd_port_set (&d2->ctty, ctty);
	      _hurd_port_locked_set (&d2->port, port); /* Unlocks D2.  */
	    }
	}

      _hurd_port_free (&d->port, &ulink, port);
      if (ctty != MACH_PORT_NULL)
	_hurd_port_free (&d->ctty, &ctty_ulink, port);
    }

  HURD_CRITICAL_END;

  return fd2;
}