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; }
error_t __hurd_invoke_translator (file_t file, int flags, file_t *newport) { error_t err; enum retry_type doretry; char retryname[1024]; /* XXX string_t LOSES! */ err = __file_invoke_translator (file, flags, &doretry, retryname, newport); if (! err) err = __USEPORT (CRDIR, __hurd_file_name_lookup_retry (port, doretry, retryname, flags, 0, newport)); return err; }
error_t __hurd_file_name_lookup (error_t (*use_init_port) (int which, error_t (*operate) (file_t)), file_t (*get_dtable_port) (int fd), error_t (*lookup) (file_t dir, char *name, int flags, mode_t mode, retry_type *do_retry, string_t retry_name, mach_port_t *result), const char *file_name, int flags, mode_t mode, file_t *result) { error_t err; enum retry_type doretry; char retryname[1024]; /* XXX string_t LOSES! */ int startport; error_t lookup_op (mach_port_t startdir) { return lookup_error ((*lookup) (startdir, file_name, flags, mode, &doretry, retryname, result)); } if (! lookup) lookup = __dir_lookup; if (file_name[0] == '\0') return ENOENT; startport = (file_name[0] == '/') ? INIT_PORT_CRDIR : INIT_PORT_CWDIR; while (file_name[0] == '/') file_name++; if (flags & O_NOFOLLOW) /* See lookup-retry.c about O_NOFOLLOW. */ flags |= O_NOTRANS; if (flags & O_DIRECTORY) { /* The caller wants to require that the file we look up is a directory. We can do this without an extra RPC by appending a trailing slash to the file name we look up. */ size_t len = strlen (file_name); if (len == 0) file_name = "/"; else if (file_name[len - 1] != '/') { char *n = alloca (len + 2); memcpy (n, file_name, len); n[len] = '/'; n[len + 1] = '\0'; file_name = n; } } err = (*use_init_port) (startport, &lookup_op); if (! err) err = __hurd_file_name_lookup_retry (use_init_port, get_dtable_port, lookup, doretry, retryname, flags, mode, result); return err; }