コード例 #1
0
error_t
_hurd_fd_close (struct hurd_fd *fd)
{
  error_t err;

  HURD_CRITICAL_BEGIN;

  __spin_lock (&fd->port.lock);
  if (fd->port.port == MACH_PORT_NULL)
    {
      __spin_unlock (&fd->port.lock);
      err = EBADF;
    }
  else
    {
      /* Clear the descriptor's port cells.
	 This deallocates the ports if noone else is still using them.  */
      _hurd_port_set (&fd->ctty, MACH_PORT_NULL);
      _hurd_port_locked_set (&fd->port, MACH_PORT_NULL);
      err = 0;
    }

  HURD_CRITICAL_END;

  return err;
}
コード例 #2
0
ファイル: port2fd.c プロジェクト: angelhunt/SNP
void
_hurd_port2fd (struct hurd_fd *d, io_t port, int flags)
{
  io_t ctty;
  mach_port_t cttyid;
  int is_ctty = !(flags & O_IGNORE_CTTY) && ! __term_getctty (port, &cttyid);

  if (is_ctty)
    {
      /* This port is capable of being a controlling tty.
	 Is it ours?  */
      struct hurd_port *const id = &_hurd_ports[INIT_PORT_CTTYID];
      __spin_lock (&id->lock);
      if (id->port == MACH_PORT_NULL)
	/* We have no controlling tty, so make this one it.  */
	_hurd_port_locked_set (id, cttyid);
      else
	{
	  if (cttyid != id->port)
	    /* We have a controlling tty and this is not it.  */
	    is_ctty = 0;
	  /* Either we don't want CTTYID, or ID->port already is it.
	     So we don't need to change ID->port, and we can release
	     the reference to CTTYID.  */
	  __spin_unlock (&id->lock);
	  __mach_port_deallocate (__mach_task_self (), cttyid);
	}
    }

  if (!is_ctty || __term_open_ctty (port, _hurd_pid, _hurd_pgrp, &ctty) != 0)
    /* XXX if IS_CTTY, then this port is our ctty, but we are
       not doing ctty style i/o because term_become_ctty barfed.
       What to do?  */
    /* No ctty magic happening here.  */
    ctty = MACH_PORT_NULL;

  /* Install PORT in the descriptor cell, leaving it locked.  */
  {
    mach_port_t old
      = _hurd_userlink_clear (&d->port.users) ? d->port.port : MACH_PORT_NULL;
    d->port.port = port;
    if (old != MACH_PORT_NULL)
      __mach_port_deallocate (__mach_task_self (), old);
  }

  _hurd_port_set (&d->ctty, ctty);
}
コード例 #3
0
ファイル: dup3.c プロジェクト: Drakey83/steamlink-sdk
/* 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;
}