summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libdiskfs/boot-start.c10
-rw-r--r--libdiskfs/diskfs.h5
-rw-r--r--libdiskfs/file-exec.c51
-rw-r--r--libdiskfs/init-init.c12
-rw-r--r--libdiskfs/priv.h4
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[];