Esempio n. 1
0
file_t
__file_name_lookup_at (int fd, int at_flags,
		       const char *file_name, int flags, mode_t mode)
{
  error_t err;
  file_t result;
  int empty = at_flags & AT_EMPTY_PATH;

  at_flags &= ~AT_EMPTY_PATH;

  err = __hurd_at_flags (&at_flags, &flags);
  if (err)
    return (__hurd_fail (err), MACH_PORT_NULL);

  if (fd == AT_FDCWD || file_name[0] == '/')
    return __file_name_lookup (file_name, flags, mode);

  if (empty != 0 && file_name[0] == '\0')
    {
      enum retry_type doretry;
      char retryname[1024];	/* XXX string_t LOSES! */

      err = HURD_DPORT_USE (fd, __dir_lookup (port, "", flags, mode,
					      &doretry, retryname,
					      &result));

      if (! err)
	err = __hurd_file_name_lookup_retry (&_hurd_ports_use, &__getdport,
					     NULL, doretry, retryname,
					     flags, mode, &result);

      return err ? (__hurd_dfail (fd, err), MACH_PORT_NULL) : result;
    }

  file_t startdir;
  error_t use_init_port (int which, error_t (*operate) (mach_port_t))
    {
      return (which == INIT_PORT_CWDIR ? (*operate) (startdir) :
	      _hurd_ports_use (which, operate));
    }

  err = HURD_DPORT_USE (fd, (startdir = port,
			     __hurd_file_name_lookup (&use_init_port,
						      &__getdport, NULL,
						      file_name,
						      flags,
						      mode & ~_hurd_umask,
						      &result)));

  return err ? (__hurd_dfail (fd, err), MACH_PORT_NULL) : result;
}
Esempio n. 2
0
/* Give the socket FD the local address ADDR (which is LEN bytes long).  */
int
__bind  (int fd, __CONST_SOCKADDR_ARG addrarg, socklen_t len)
{
    addr_port_t aport;
    error_t err;
    const struct sockaddr_un *addr = addrarg.__sockaddr_un__;

    if (addr->sun_family == AF_LOCAL)
    {
        /* For the local domain, we must create a node in the filesystem
        using the ifsock translator and then fetch the address from it.  */
        file_t dir, node, ifsock;
        char name[len - offsetof (struct sockaddr_un, sun_path) + 1], *n;

        strncpy (name, addr->sun_path, sizeof name - 1);
        name[sizeof name - 1] = '\0'; /* Make sure */

        dir = __file_name_split (name, &n);
        if (dir == MACH_PORT_NULL)
            return -1;

        /* Create a new, unlinked node in the target directory.  */
        err = __dir_mkfile (dir, O_CREAT, 0666 & ~_hurd_umask, &node);

        if (! err)
        {
            /* Set the node's translator to make it a local-domain socket.  */
            err = __file_set_translator (node,
                                         FS_TRANS_EXCL | FS_TRANS_SET,
                                         FS_TRANS_EXCL | FS_TRANS_SET, 0,
                                         _HURD_IFSOCK, sizeof _HURD_IFSOCK,
                                         MACH_PORT_NULL,
                                         MACH_MSG_TYPE_COPY_SEND);
            if (! err)
            {
                enum retry_type doretry;
                char retryname[1024];
                /* Get a port to the ifsock translator.  */
                err = __dir_lookup (node, "", 0, 0, &doretry, retryname, &ifsock);
                if (! err && (doretry != FS_RETRY_NORMAL || retryname[0] != '\0'))
                    err = EADDRINUSE;
            }
            if (! err)
            {
                /* Get the address port.  */
                err = __ifsock_getsockaddr (ifsock, &aport);
                if (err == MIG_BAD_ID || err == EOPNOTSUPP)
                    err = EGRATUITOUS;
                if (! err)
                {
                    /* Link the node, now a socket with proper mode, into the
                       target directory.  */
                    err = __dir_link (dir, node, n, 1);
                    if (err == EEXIST)
                        err = EADDRINUSE;
                    if (err)
                        __mach_port_deallocate (__mach_task_self (), aport);
                }
                __mach_port_deallocate (__mach_task_self (), ifsock);
            }
            __mach_port_deallocate (__mach_task_self (), node);
        }
        __mach_port_deallocate (__mach_task_self (), dir);

        if (err)
            return __hurd_fail (err);
    }