From 2948fc64a6dd7aa23757daf2c5256dfe07f4c61a Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Mon, 16 Oct 1995 02:51:06 +0000 Subject: * hurd/hurd/lookup.h: New file. * hurd/hurdlookup.c (__file_name_lookup_under): New function. (__hurd_file_name_lookup, __hurd_file_name_lookup_retry, __hurd_file_name_split): Rewritten to take callback functions for using any needed init or dtable port, instead of passing in crdir and cwdir ports. (__file_name_lookup, __file_name_split): Use new calling convention; pass _hurd_ports_use and __getdport as the callback functions. * sysdeps/mach/hurd/chroot.c: Use __file_name_lookup_under instead of __hurd_file_name_lookup. * sysdeps/mach/hurd/chdir.c: Likewise. * sysdeps/mach/hurd/fchdir.c: Likewise. * hurd/fchroot.c: Likewise. --- hurd/fchroot.c | 18 ++-- hurd/hurd/lookup.h | 101 ++++++++++++++++++++++ hurd/hurdlookup.c | 243 ++++++++++++++++++++++++++++------------------------- 3 files changed, 236 insertions(+), 126 deletions(-) create mode 100644 hurd/hurd/lookup.h (limited to 'hurd') diff --git a/hurd/fchroot.c b/hurd/fchroot.c index cccf139..37163c0 100644 --- a/hurd/fchroot.c +++ b/hurd/fchroot.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,16 +28,12 @@ DEFUN(fchroot, (fd), int fd) error_t err; file_t dir; - err = __USEPORT (CRDIR, - ({ file_t crdir = port; - HURD_DPORT_USE (fd, - __hurd_file_name_lookup (crdir, port, "", - 0, 0, &dir)); - })); + err = HURD_DPORT_USE (fd, (dir = __file_name_lookup_under (port, "", + O_EXEC, 0), + errno)); - if (err) - return __hurd_fail (err); + if (! err) + _hurd_port_set (&_hurd_ports[INIT_PORT_CRDIR], dir); - _hurd_port_set (&_hurd_ports[INIT_PORT_CRDIR], dir); - return 0; + return err ? __hurd_fail (err) : 0; } diff --git a/hurd/hurd/lookup.h b/hurd/hurd/lookup.h new file mode 100644 index 0000000..6911b8f --- /dev/null +++ b/hurd/hurd/lookup.h @@ -0,0 +1,101 @@ +/* Declarations of file name translation functions for the GNU Hurd. +Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _HURD_LOOKUP_H +#define _HURD_LOOKUP_H 1 + +/* These functions all take two callback functions as the first two arguments. + The first callback function USE_INIT_PORT is called as follows: + + error_t use_init_port (int which, error_t (*operate) (mach_port_t)); + + WHICH is nonnegative value less than INIT_PORT_MAX, indicating which + init port is required. The callback function should call *OPERATE + with a send right to the appropriate init port. No user reference + is consumed; the right will only be used after *OPERATE returns if + *OPERATE has added its own user reference. + + The second callback function GET_DTABLE_PORT should behave like `getdport'. + + All these functions return zero on success or an error code on failure. */ + + +/* Open a port to FILE with the given FLAGS and MODE (see ). If + successful, returns zero and store the port to FILE in *PORT; otherwise + returns an error code. */ + +error_t __hurd_file_name_lookup (error_t (*use_init_port) + (int which, + error_t (*operate) (mach_port_t)), + file_t (*get_dtable_port) (int fd), + const char *file_name, + int flags, mode_t mode, + file_t *result); +error_t hurd_file_name_lookup (error_t (*use_init_port) + (int which, + error_t (*operate) (mach_port_t)), + file_t (*get_dtable_port) (int fd), + const char *file_name, + int flags, mode_t mode, + file_t *result); + + +/* Split FILE into a directory and a name within the directory. Look up a + port for the directory and store it in *DIR; store in *NAME a pointer + into FILE where the name within directory begins. */ + +error_t __hurd_file_name_split (error_t (*use_init_port) + (int which, + error_t (*operate) (mach_port_t)), + file_t (*get_dtable_port) (int fd), + const char *file_name, + file_t *dir, char **name); +error_t hurd_file_name_split (error_t (*use_init_port) + (int which, + error_t (*operate) (mach_port_t)), + file_t (*get_dtable_port) (int fd), + const char *file_name, + file_t *dir, char **name); + + +/* Process the values returned by `dir_lookup' et al, and loop doing + `dir_lookup' calls until one returns FS_RETRY_NONE. The arguments + should be those just passed to and/or returned from `dir_lookup', + `fsys_getroot', or `file_invoke_translator'. This function consumes the + reference in *RESULT even if it returns an error. */ + +error_t __hurd_file_name_lookup_retry (error_t (*use_init_port) + (int which, + error_t (*operate) (mach_port_t)), + file_t (*get_dtable_port) (int fd), + enum retry_type doretry, + char retryname[1024], + int flags, mode_t mode, + file_t *result); +error_t hurd_file_name_lookup_retry (error_t (*use_init_port) + (int which, + error_t (*operate) (mach_port_t)), + file_t (*get_dtable_port) (int fd), + enum retry_type doretry, + char retryname[1024], + int flags, mode_t mode, + file_t *result); + + +#endif /* hurd/lookup.h */ diff --git a/hurd/hurdlookup.c b/hurd/hurdlookup.c index b595911..cb815ba 100644 --- a/hurd/hurdlookup.c +++ b/hurd/hurdlookup.c @@ -17,6 +17,7 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include +#include #include #include #include @@ -41,73 +42,88 @@ lookup_error (error_t error) } error_t -__hurd_file_name_lookup (file_t crdir, file_t cwdir, +__hurd_file_name_lookup (error_t (*use_init_port) + (int which, error_t (*operate) (file_t)), + file_t (*get_dtable_port) (int fd), 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! */ - file_t startdir; - startdir = file_name[0] == '/' ? crdir : cwdir; + error_t lookup (mach_port_t startdir) + { + while (file_name[0] == '/') + file_name++; - while (file_name[0] == '/') - file_name++; + return lookup_error (__dir_lookup (startdir, file_name, flags, mode, + &doretry, retryname, result)); + } - if (err = __dir_lookup (startdir, file_name, flags, mode, - &doretry, retryname, result)) - return lookup_error (err); + err = (*use_init_port) (file_name[0] == '/' + ? INIT_PORT_CRDIR : INIT_PORT_CWDIR, + &lookup); + if (! err) + err = __hurd_file_name_lookup_retry (use_init_port, get_dtable_port, + doretry, retryname, flags, mode, + result); - return __hurd_file_name_lookup_retry (crdir, doretry, retryname, flags, mode, - result); + return err; } weak_alias (__hurd_file_name_lookup, hurd_file_name_lookup) error_t -__hurd_file_name_lookup_retry (file_t crdir, +__hurd_file_name_lookup_retry (error_t (*use_init_port) + (int which, error_t (*operate) (file_t)), + file_t (*get_dtable_port) (int fd), enum retry_type doretry, char retryname[1024], int flags, mode_t mode, file_t *result) { error_t err; - file_t startdir; - file_t newpt; char *file_name; - int dealloc_dir; int nloops; - dealloc_dir = 0; + error_t lookup (file_t startdir) + { + while (file_name[0] == '/') + file_name++; + + return lookup_error (__dir_lookup (startdir, file_name, flags, mode, + &doretry, retryname, result)); + } + error_t reauthenticate (file_t unauth) + { + error_t err; + mach_port_t ref = __mach_reply_port (); + error_t reauth (auth_t auth) + { + return __auth_user_authenticate (auth, unauth, ref, + MACH_MSG_TYPE_MAKE_SEND, + result); + } + err = __io_reauthenticate (unauth, ref, MACH_MSG_TYPE_MAKE_SEND); + if (! err) + err = (*use_init_port) (INIT_PORT_AUTH, &reauth); + __mach_port_destroy (__mach_task_self (), ref); + __mach_port_deallocate (__mach_task_self (), unauth); + return err; + } + nloops = 0; err = 0; - - while (1) + do { - if (dealloc_dir) - __mach_port_deallocate (__mach_task_self (), startdir); - if (err) - return lookup_error (err); + file_t startdir = MACH_PORT_NULL; + int dirport = INIT_PORT_CWDIR; switch (doretry) { case FS_RETRY_REAUTH: - { - mach_port_t ref = __mach_reply_port (); - err = __io_reauthenticate (*result, - ref, MACH_MSG_TYPE_MAKE_SEND); - if (! err) - err = __USEPORT - (AUTH, __auth_user_authenticate (port, *result, - ref, - MACH_MSG_TYPE_MAKE_SEND, - &newpt)); - __mach_port_destroy (__mach_task_self (), ref); - } - __mach_port_deallocate (__mach_task_self (), *result); - if (err) + if (err = reauthenticate (*result)) return err; - *result = newpt; /* Fall through. */ case FS_RETRY_NORMAL: @@ -134,7 +150,6 @@ __hurd_file_name_lookup_retry (file_t crdir, } startdir = *result; - dealloc_dir = 1; file_name = retryname; break; @@ -142,8 +157,7 @@ __hurd_file_name_lookup_retry (file_t crdir, switch (retryname[0]) { case '/': - startdir = crdir; - dealloc_dir = 0; + dirport = INIT_PORT_CRDIR; if (*result != MACH_PORT_NULL) __mach_port_deallocate (__mach_task_self (), *result); file_name = &retryname[1]; @@ -166,24 +180,29 @@ __hurd_file_name_lookup_retry (file_t crdir, errno = save; return ENOENT; } - *result = __getdport (fd); - if (*result == MACH_PORT_NULL) + if (! get_dtable_port) + err = EGRATUITOUS; + else { - /* If the name was a proper number, but the file - descriptor does not exist, we return EBADF instead - of ENOENT. */ - error_t err = errno; - errno = save; - return err; + *result = (*get_dtable_port) (fd); + if (*result == MACH_PORT_NULL) + { + /* If the name was a proper number, but the file + descriptor does not exist, we return EBADF instead + of ENOENT. */ + err = errno; + errno = save; + } } errno = save; + if (err) + return err; if (*end == '\0') return 0; else { /* Do a normal retry on the remaining components. */ startdir = *result; - dealloc_dir = 1; file_name = end + 1; /* Skip the slash. */ break; } @@ -202,6 +221,7 @@ __hurd_file_name_lookup_retry (file_t crdir, struct host_basic_info hostinfo; mach_msg_type_number_t hostinfocnt = HOST_BASIC_INFO_COUNT; char *p; + /* XXX want client's host */ if (err = __host_info (__mach_host_self (), HOST_BASIC_INFO, (natural_t *) &hostinfo, &hostinfocnt)) @@ -216,7 +236,6 @@ __hurd_file_name_lookup_retry (file_t crdir, if (p > retryname) strcpy (retryname, p); startdir = *result; - dealloc_dir = 1; } else goto bad_magic; @@ -229,29 +248,15 @@ __hurd_file_name_lookup_retry (file_t crdir, error_t opentty (file_t *result) { error_t err; - file_t unauth; - err = __USEPORT (CTTYID, - __termctty_open_terminal (port, - flags, - &unauth)); - if (! err) + error_t ctty_open (file_t port) { - mach_port_t ref = __mach_reply_port (); - err = __io_reauthenticate - (unauth, - ref, - MACH_MSG_TYPE_MAKE_SEND); - if (! err) - err = __USEPORT - (AUTH, __auth_user_authenticate - (port, - unauth, - ref, MACH_MSG_TYPE_MAKE_SEND, - result)); - __mach_port_deallocate (__mach_task_self (), - unauth); - __mach_port_destroy (__mach_task_self (), ref); + return __termctty_open_terminal (port, + flags, + result); } + err = (*use_init_port) (INIT_PORT_CTTYID, &ctty_open); + if (! err) + err = reauthenticate (*result); return err; } @@ -260,7 +265,6 @@ __hurd_file_name_lookup_retry (file_t crdir, case '/': if (err = opentty (&startdir)) return err; - dealloc_dir = 1; strcpy (retryname, &retryname[4]); break; default: @@ -280,32 +284,43 @@ __hurd_file_name_lookup_retry (file_t crdir, return EGRATUITOUS; } - err = __dir_lookup (startdir, file_name, flags, mode, - &doretry, retryname, result); - } + if (startdir != MACH_PORT_NULL) + { + err = lookup (startdir); + __mach_port_deallocate (__mach_task_self (), startdir); + startdir = MACH_PORT_NULL; + } + else + err = (*use_init_port) (dirport, &lookup); + } while (! err); + + return err; } weak_alias (__hurd_file_name_lookup_retry, hurd_file_name_lookup_retry) error_t -__hurd_file_name_split (file_t crdir, file_t cwdir, +__hurd_file_name_split (error_t (*use_init_port) + (int which, error_t (*operate) (file_t)), + file_t (*get_dtable_port) (int fd), const char *file_name, file_t *dir, char **name) { - const char *lastslash; - error_t err; + error_t addref (file_t crdir) + { + *dir = crdir; + return __mach_port_mod_refs (__mach_task_self (), + crdir, MACH_PORT_RIGHT_SEND, +1); + } + + const char *lastslash = strrchr (file_name, '/'); - lastslash = strrchr (file_name, '/'); if (lastslash != NULL) { if (lastslash == file_name) { /* "/foobar" => crdir + "foobar". */ *name = (char *) file_name + 1; - if (err = __mach_port_mod_refs (__mach_task_self (), - crdir, MACH_PORT_RIGHT_SEND, +1)) - return err; - *dir = crdir; - return 0; + return (*use_init_port) (INIT_PORT_CRDIR, &addref); } else { @@ -314,18 +329,15 @@ __hurd_file_name_split (file_t crdir, file_t cwdir, memcpy (dirname, file_name, lastslash - file_name); dirname[lastslash - file_name] = '\0'; *name = (char *) lastslash + 1; - return __hurd_file_name_lookup (crdir, cwdir, dirname, 0, 0, dir); + return __hurd_file_name_lookup (use_init_port, get_dtable_port, + dirname, 0, 0, dir); } } else { /* "foobar" => cwdir + "foobar". */ *name = (char *) file_name; - if (err = __mach_port_mod_refs (__mach_task_self (), - cwdir, MACH_PORT_RIGHT_SEND, +1)) - return err; - *dir = cwdir; - return 0; + return (*use_init_port) (INIT_PORT_CWDIR, &addref); } } weak_alias (__hurd_file_name_split, hurd_file_name_split) @@ -335,22 +347,13 @@ file_t __file_name_lookup (const char *file_name, int flags, mode_t mode) { error_t err; - file_t result, crdir, cwdir; - struct hurd_userlink crdir_ulink, cwdir_ulink; - - crdir = _hurd_port_get (&_hurd_ports[INIT_PORT_CRDIR], &crdir_ulink); - cwdir = _hurd_port_get (&_hurd_ports[INIT_PORT_CWDIR], &cwdir_ulink); + file_t result; - err = __hurd_file_name_lookup (crdir, cwdir, file_name, flags, mode, + err = __hurd_file_name_lookup (&_hurd_ports_use, &__getdport, + file_name, flags, mode, &result); - _hurd_port_free (&_hurd_ports[INIT_PORT_CRDIR], &crdir_ulink, crdir); - _hurd_port_free (&_hurd_ports[INIT_PORT_CWDIR], &cwdir_ulink, cwdir); - - if (err) - return __hurd_fail (err), MACH_PORT_NULL; - else - return result; + return err ? (__hurd_fail (err), MACH_PORT_NULL) : result; } weak_alias (__file_name_lookup, file_name_lookup) @@ -359,23 +362,33 @@ file_t __file_name_split (const char *file_name, char **name) { error_t err; - file_t dir, crdir, cwdir; - struct hurd_userlink crdir_ulink, cwdir_ulink; + file_t result; + + err = __hurd_file_name_split (&_hurd_ports_use, &__getdport, + file_name, &result, name); - crdir = _hurd_port_get (&_hurd_ports[INIT_PORT_CRDIR], &crdir_ulink); - cwdir = _hurd_port_get (&_hurd_ports[INIT_PORT_CWDIR], &cwdir_ulink); + return err ? (__hurd_fail (err), MACH_PORT_NULL) : result; +} +weak_alias (__file_name_split, file_name_split) - err = __hurd_file_name_split (crdir, cwdir, file_name, &dir, name); - _hurd_port_free (&_hurd_ports[INIT_PORT_CRDIR], &crdir_ulink, crdir); - _hurd_port_free (&_hurd_ports[INIT_PORT_CWDIR], &cwdir_ulink, cwdir); +file_t +__file_name_lookup_under (file_t startdir, + const char *file_name, int flags, mode_t mode) +{ + error_t err; + file_t result; - if (err) + error_t use_init_port (int which, error_t (*operate) (mach_port_t)) { - errno = err; - return MACH_PORT_NULL; + return (which == INIT_PORT_CWDIR ? (*operate) (startdir) : + _hurd_ports_use (which, operate)); } - else - return dir; + + err = __hurd_file_name_lookup (&use_init_port, &__getdport, + file_name, flags, mode, + &result); + + return err ? (__hurd_fail (err), MACH_PORT_NULL) : result; } -weak_alias (__file_name_split, file_name_split) +weak_alias (__file_name_lookup_under, file_name_lookup_under) -- cgit v1.1