diff options
Diffstat (limited to 'libdiskfs')
-rw-r--r-- | libdiskfs/boot-start.c | 10 | ||||
-rw-r--r-- | libdiskfs/diskfs.h | 5 | ||||
-rw-r--r-- | libdiskfs/file-exec.c | 51 | ||||
-rw-r--r-- | libdiskfs/init-init.c | 12 | ||||
-rw-r--r-- | libdiskfs/priv.h | 4 |
5 files changed, 60 insertions, 22 deletions
diff --git a/libdiskfs/boot-start.c b/libdiskfs/boot-start.c index 21fc9656..c968cf31 100644 --- a/libdiskfs/boot-start.c +++ b/libdiskfs/boot-start.c @@ -36,7 +36,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "fsys_reply_U.h" static mach_port_t diskfs_exec_ctl; -mach_port_t diskfs_exec = MACH_PORT_NULL; extern task_t diskfs_exec_server_task; static task_t parent_task = MACH_PORT_NULL; @@ -101,6 +100,7 @@ diskfs_start_bootstrap () size_t exec_argvlen; struct port_info *bootinfo; struct protid *rootpi; + mach_port_t diskfs_exec; /* Create the port for current and root directory. */ err = diskfs_create_protid (diskfs_make_peropen (diskfs_root_node, @@ -295,6 +295,9 @@ diskfs_start_bootstrap () mach_port_deallocate (mach_task_self (), startup_pt); mach_port_deallocate (mach_task_self (), bootpt); assert_perror (err); + + /* Cache the exec server port for file_exec to use. */ + _hurd_port_set (&_diskfs_exec_portcell, diskfs_exec); } /* We look like an execserver to the execserver itself; it makes this @@ -503,8 +506,9 @@ diskfs_S_fsys_init (mach_port_t port, /* Don't start this until now so that exec is fully authenticated with proc. */ - exec_init (diskfs_exec, authhandle, - execprocess, MACH_MSG_TYPE_COPY_SEND); + HURD_PORT_USE (&_diskfs_exec_portcell, + exec_init (port, authhandle, + execprocess, MACH_MSG_TYPE_COPY_SEND)); mach_port_deallocate (mach_task_self (), execprocess); /* We don't need this anymore. */ diff --git a/libdiskfs/diskfs.h b/libdiskfs/diskfs.h index e99676ef..aabbf6fb 100644 --- a/libdiskfs/diskfs.h +++ b/libdiskfs/diskfs.h @@ -132,12 +132,13 @@ struct modreq #define SPEC_DOTDOT 0x10000000 struct argp; /* opaque in this file */ +struct argp_child; /* opaque in this file */ +struct store; /* opaque in this file */ +struct store_parsed; /* opaque in this file */ /* Declarations of variables the library sets. */ extern mach_port_t diskfs_default_pager; /* send right */ -extern mach_port_t diskfs_exec_ctl; /* send right */ -extern mach_port_t diskfs_exec; /* send right */ extern auth_t diskfs_auth_server_port; /* send right */ /* The io_identity identity port for the filesystem. */ diff --git a/libdiskfs/file-exec.c b/libdiskfs/file-exec.c index 2933a7d4..521f3528 100644 --- a/libdiskfs/file-exec.c +++ b/libdiskfs/file-exec.c @@ -54,16 +54,31 @@ diskfs_S_file_exec (struct protid *cred, int suid, sgid; struct protid *newpi; error_t err = 0; + mach_port_t execserver; int cached_exec; + struct hurd_userlink ulink; +#define RETURN(code) do { err = (code); goto out; } while (0) if (!cred) return EOPNOTSUPP; - cached_exec = (diskfs_exec != MACH_PORT_NULL); - if (diskfs_exec == MACH_PORT_NULL) - diskfs_exec = file_name_lookup (_SERVERS_EXEC, 0, 0); /* XXX unlocked */ - if (diskfs_exec == MACH_PORT_NULL) - return EOPNOTSUPP; + /* Get a light reference to the cached exec server port. */ + execserver = _hurd_port_get (&_diskfs_exec_portcell, &ulink); + cached_exec = (execserver != MACH_PORT_NULL); + if (execserver == MACH_PORT_NULL) + { + /* No cached port. Look up the canonical naming point. */ + execserver = file_name_lookup (_SERVERS_EXEC, 0, 0); + if (execserver == MACH_PORT_NULL) + return EOPNOTSUPP; /* No exec server, no exec. */ + else + { + /* Install the newly-gotten exec server port for other + threads to use, then get a light reference for this call. */ + _hurd_port_set (&_diskfs_exec_portcell, execserver); + execserver = _hurd_port_get (&_diskfs_exec_portcell, &ulink); + } + } np = cred->po->np; @@ -74,17 +89,17 @@ diskfs_S_file_exec (struct protid *cred, mutex_unlock (&np->lock); if (_diskfs_noexec) - return EACCES; + RETURN (EACCES); if ((cred->po->openstat & O_EXEC) == 0) - return EBADF; + RETURN (EBADF); if (!((mode & (S_IXUSR|S_IXGRP|S_IXOTH)) || ((mode & S_IUSEUNK) && (mode & (S_IEXEC << S_IUNKSHIFT))))) - return EACCES; + RETURN (EACCES); if ((mode & S_IFMT) == S_IFDIR) - return EACCES; + RETURN (EACCES); suid = mode & S_ISUID; sgid = mode & S_ISGID; @@ -124,7 +139,7 @@ diskfs_S_file_exec (struct protid *cred, { do { - err = exec_exec (diskfs_exec, + err = exec_exec (execserver, ports_get_right (newpi), MACH_MSG_TYPE_MAKE_SEND, task, flags, argv, argvlen, envp, envplen, @@ -140,10 +155,17 @@ diskfs_S_file_exec (struct protid *cred, /* We were using a previously looked-up exec server port. Try looking up a new one before giving an error. */ cached_exec = 0; - mach_port_deallocate (mach_task_self (), diskfs_exec); - diskfs_exec = file_name_lookup (_SERVERS_EXEC, 0, 0); - if (diskfs_exec == MACH_PORT_NULL) + _hurd_port_free (&_diskfs_exec_portcell, &ulink, execserver); + + execserver = file_name_lookup (_SERVERS_EXEC, 0, 0); + if (execserver == MACH_PORT_NULL) err = EOPNOTSUPP; + else + { + _hurd_port_set (&_diskfs_exec_portcell, execserver); + execserver = _hurd_port_get (&_diskfs_exec_portcell, + &ulink); + } } else err = EOPNOTSUPP; @@ -163,5 +185,8 @@ diskfs_S_file_exec (struct protid *cred, mach_port_deallocate (mach_task_self (), portarray[i]); } + out: + _hurd_port_free (&_diskfs_exec_portcell, &ulink, execserver); + return err; } diff --git a/libdiskfs/init-init.c b/libdiskfs/init-init.c index f60b53b6..7853be26 100644 --- a/libdiskfs/init-init.c +++ b/libdiskfs/init-init.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation + Copyright (C) 1994, 95, 96, 97, 98 Free Software Foundation, Inc. This file is part of the GNU Hurd. @@ -8,7 +8,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. -The GNU Hurd is distributed in the hope that it will be useful, +The GNU Hurd 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 General Public License for more details. @@ -32,6 +32,8 @@ mach_port_t diskfs_fsys_identity; int _diskfs_nosuid = 0, _diskfs_noexec = 0; +struct hurd_port _diskfs_exec_portcell; + spin_lock_t diskfs_node_refcnt_lock = SPIN_LOCK_INITIALIZER; spin_lock_t _diskfs_control_lock = SPIN_LOCK_INITIALIZER; @@ -46,12 +48,12 @@ struct port_class *diskfs_shutdown_notification_class; struct port_bucket *diskfs_port_bucket; /* Call this after arguments have been parsed to initialize the - library. */ + library. */ error_t diskfs_init_diskfs (void) { error_t err; - + if (diskfs_boot_flags) /* This is a boot filesystem, we have to do some things specially. */ { @@ -88,6 +90,8 @@ diskfs_init_diskfs (void) diskfs_port_bucket = ports_create_bucket (); + _hurd_port_init (&_diskfs_exec_portcell, MACH_PORT_NULL); + return 0; } diff --git a/libdiskfs/priv.h b/libdiskfs/priv.h index 11cbe534..d45b3f22 100644 --- a/libdiskfs/priv.h +++ b/libdiskfs/priv.h @@ -23,6 +23,7 @@ #include <hurd/ports.h> #include <hurd/fshelp.h> #include <hurd/iohelp.h> +#include <hurd/port.h> #include <assert.h> #include "diskfs.h" @@ -36,6 +37,9 @@ extern const char *_diskfs_chroot_directory; /* If --boot-command is given, this points to the program and args. */ extern char **_diskfs_boot_command; +/* Port cell holding a cached port to the exec server. */ +extern struct hurd_port _diskfs_exec_portcell; + volatile struct mapped_time_value *_diskfs_mtime; extern struct argp_option diskfs_common_options[]; |