Esempio n. 1
0
/* Create a new socket of type TYPE in domain DOMAIN, using
   protocol PROTOCOL.  If PROTOCOL is zero, one is chosen automatically.
   Returns a file descriptor for the new socket, or -1 for errors.  */
int
__socket (int domain, int type, int protocol)
{
  error_t err;
  socket_t sock, server;

  /* Find the socket server for DOMAIN.  */
  server = _hurd_socket_server (domain, 0);
  if (server == MACH_PORT_NULL)
    return -1;

  err = __socket_create (server, type, protocol, &sock);
  if (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED
      || err == MIG_BAD_ID || err == EOPNOTSUPP)
    {
      /* On the first use of the socket server during the operation,
	 allow for the old server port dying.  */
      server = _hurd_socket_server (domain, 1);
      if (server == MACH_PORT_NULL)
	return -1;
      err = __socket_create (server, type, protocol, &sock);
    }

  /* These errors all mean that the server node doesn't support the
     socket.defs protocol, which we'll take to mean that the protocol
     isn't supported.  */
  if (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED
      || err == MIG_BAD_ID || err == EOPNOTSUPP)
    err = EAFNOSUPPORT;

  if (err)
    return __hurd_fail (err);

  return _hurd_intern_fd (sock, O_IGNORE_CTTY, 1);
}
Esempio n. 2
0
/* This returns a new stream opened on a temporary file (generated
   by tmpnam).  The file is opened with mode "w+b" (binary read/write).
   If we couldn't generate a unique filename or the file couldn't
   be opened, NULL is returned.  */
FILE *
__tmpfile (void)
{
  error_t err;
  file_t file;
  int fd;
  FILE *f;

  /* Get a port to the directory that will contain the file.  */
  const char *dirname = __libc_secure_getenv ("TMPDIR") ?: P_tmpdir;
  file_t dir = __file_name_lookup (dirname, 0, 0);
  if (dir == MACH_PORT_NULL)
    return NULL;

  /* Create an unnamed file in the temporary directory.  */
  err = __dir_mkfile (dir, O_RDWR, S_IRUSR | S_IWUSR, &file);
  __mach_port_deallocate (__mach_task_self (), dir);
  if (err)
    return __hurd_fail (err), NULL;

  /* Get a file descriptor for that port.  POSIX.1 requires that streams
     returned by tmpfile allocate file descriptors as fopen would.  */
  fd = _hurd_intern_fd (file, O_RDWR, 1); /* dealloc on error */
  if (fd < 0)
    return NULL;

  /* Open a stream on the unnamed file.
     It will cease to exist when this stream is closed.  */
  if ((f = _IO_fdopen (fd, "w+b")) == NULL)
    __close (fd);

  return f;
}
Esempio n. 3
0
/* Open FILE with access OFLAG.  If O_CREAT or O_TMPFILE is in OFLAG,
   a third argument is the file protection.  */
int
__libc_open (const char *file, int oflag, ...)
{
  mode_t mode;
  io_t port;

  if (__OPEN_NEEDS_MODE (oflag))
    {
      va_list arg;
      va_start (arg, oflag);
      mode = va_arg (arg, mode_t);
      va_end (arg);
    }
  else
    mode = 0;

  port = __file_name_lookup (file, oflag, mode);
  if (port == MACH_PORT_NULL)
    return -1;

  return _hurd_intern_fd (port, oflag, 1);
}
Esempio n. 4
0
/* Open the shared memory segment *R_KEY and return a file descriptor
   to it in R_FD.  If KEY is IPC_PRIVATE, use a private key and return
   it in R_KEY.  */
static error_t
get_exclusive (int shmflags, size_t size, key_t *r_key, int *r_fd)
{
  error_t err;
  file_t dir;
  file_t file;
  char filename[SHM_NAMEMAX];
  key_t key = *r_key;
  bool is_private;

  /* Create the shared memory segment.  */
  err = create_shm_file (size, shmflags, &dir, &file);
  if (err)
    return err;

  if (key == IPC_PRIVATE)
    {
      is_private = true;
      key = SHM_PRIV_KEY_START;

      /* Try to link the shared memory segment into the filesystem
	 (exclusively).  Private segments have negative keys.  */
      do
	{
	  sprintf (filename, SHM_NAMEPRI, key);
	  err = __dir_link (dir, file, filename, 1);
	  if (!err)
	    {
	      /* We are done.  */
	      *r_key = key;
	      break;
	    }
	  else if (err == EEXIST)
	    {
	      /* Check if we ran out of keys.  If not, try again with new
		 key.  */
	      if (key == SHM_PRIV_KEY_END)
		err = ENOSPC;
	      else
		err = 0;

	      key--;
	    }
	}
      while (!err);
    }
  else
    {
      /* Try to link the shared memory segment into the filesystem
	 (exclusively) under the given key.  */
      sprintf (filename, SHM_NAMEPRI, key);
      err = __dir_link (dir, file, filename, 1);
    }

  __mach_port_deallocate (__mach_task_self (), dir);

  if (!err)
    {
      int fd;

      /* Get a file descriptor for that port.  */
      fd = _hurd_intern_fd (file, O_RDWR, 1); /* dealloc on error */
      if (fd < 0)
	err = errno;
      else
	*r_fd = fd;
    }

  return err;
}
Esempio n. 5
0
int
openport (io_t port, int flags)
{
  return _hurd_intern_fd (port, flags, 0);
}
Esempio n. 6
0
/* Create two new sockets, of type TYPE in domain DOMAIN and using
   protocol PROTOCOL, which are connected to each other, and put file
   descriptors for them in FDS[0] and FDS[1].  If PROTOCOL is zero,
   one will be chosen automatically.  Returns 0 on success, -1 for errors.  */
int
__socketpair (int domain, int type, int protocol, int fds[2])
{
  error_t err;
  socket_t server, sock1, sock2;
  int d1, d2;

  if (fds == NULL)
    return __hurd_fail (EINVAL);

  /* Find the domain's socket server.  */
  server = _hurd_socket_server (domain, 0);
  if (server == MACH_PORT_NULL)
    return -1;

  /* Create two sockets and connect them together.  */

  err = __socket_create (server, type, protocol, &sock1);
  if (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED
      || err == MIG_BAD_ID || err == EOPNOTSUPP)
    {
      /* On the first use of the socket server during the operation,
	 allow for the old server port dying.  */
      server = _hurd_socket_server (domain, 1);
      if (server == MACH_PORT_NULL)
	return -1;
      err = __socket_create (server, type, protocol, &sock1);
    }
  if (err)
    return __hurd_fail (err);
  if (err = __socket_create (server, type, protocol, &sock2))
    {
      __mach_port_deallocate (__mach_task_self (), sock1);
      return __hurd_fail (err);
    }
  if (err = __socket_connect2 (sock1, sock2))
    {
      __mach_port_deallocate (__mach_task_self (), sock1);
      __mach_port_deallocate (__mach_task_self (), sock2);
      return __hurd_fail (err);
    }

  /* Put the sockets into file descriptors.  */

  d1 = _hurd_intern_fd (sock1, O_IGNORE_CTTY, 1);
  if (d1 < 0)
    {
      __mach_port_deallocate (__mach_task_self (), sock2);
      return -1;
    }
  d2 = _hurd_intern_fd (sock2, O_IGNORE_CTTY, 1);
  if (d2 < 0)
    {
      err = errno;
      (void) close (d1);
      return __hurd_fail (err);
    }

  fds[0] = d1;
  fds[1] = d2;
  return 0;
}