[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 4/4] Make the exec filename available at exec_startup time
From: |
Jeremie Koenig |
Subject: |
[PATCH 4/4] Make the exec filename available at exec_startup time |
Date: |
Wed, 17 Aug 2011 21:25:23 +0200 |
* hurd/exec_startup.defs (exec_startup_get_info_2): Define a new version of
exec_startup_get_info to get the executable filename.
(exec_startup_get_info): Mark as deprecated.
* exec/priv.h (struct bootinfo): Add a filename field.
* exec/exec.c (do_exec): Fill it in.
(S_exec_startup_get_info): Mark as deprecated, forward to...
(S_exec_startup_get_info_2): New version, fill in the filename.
* libdiskfs/boot-start.c (diskfs_S_exec_startup_get_info_2): New function.
(diskfs_S_exec_startup_get_info): Deprecate.
---
exec/exec.c | 38 ++++++++++++++++++++++++
exec/priv.h | 1 +
hurd/exec_startup.defs | 22 ++++++++++++++
libdiskfs/boot-start.c | 74 +++++++++++++++++++++++++++++++++++------------
4 files changed, 116 insertions(+), 19 deletions(-)
diff --git a/exec/exec.c b/exec/exec.c
index 1f91d5b..947e3f0 100644
--- a/exec/exec.c
+++ b/exec/exec.c
@@ -1440,24 +1440,29 @@ do_exec (file_t file,
have no effect, and the lack of installed standard ports should
not cause an error. -mib */
if ((!std_ports || !std_ints) && (flags & (EXEC_SECURE|EXEC_DEFAULTS)))
return EIEIO;
/* Suspend the existing task before frobnicating it. */
if (oldtask != MACH_PORT_NULL && (e.error = task_suspend (oldtask)))
return e.error;
/* Prime E for executing FILE and check its validity. */
prepare_and_check (file, &e);
+ /* The user-provided FILENAME is never to be trusted in EXEC_SECURE
+ circumstances. */
+ if (flags & EXEC_SECURE)
+ filename = "";
+
if (e.error == ENOEXEC)
{
/* Check for a #! executable file. */
check_hashbang (&e,
file, oldtask, flags, filename,
argv, argvlen, argv_copy,
envp, envplen, envp_copy,
dtable, dtablesize, dtable_copy,
portarray, nports, portarray_copy,
intarray, nints, intarray_copy,
deallocnames, ndeallocnames,
destroynames, ndestroynames);
@@ -1558,24 +1563,27 @@ do_exec (file_t file,
/* These flags say the information we pass through to the new program
may need to be modified. */
secure = (flags & EXEC_SECURE);
defaults = (flags & EXEC_DEFAULTS);
/* Now record the big blocks of data we shuffle around unchanged.
Whatever arrived inline, we must allocate space for so it can
survive after this RPC returns. */
boot->flags = flags;
+ assert (filename);
+ strncpy (boot->filename, filename, sizeof (string_t));
+
argv = servercopy (argv, argvlen, argv_copy, &e.error);
if (e.error)
goto stdout;
boot->argv = argv;
boot->argvlen = argvlen;
envp = servercopy (envp, envplen, envp_copy, &e.error);
if (e.error)
goto stdout;
boot->envp = envp;
boot->envplen = envplen;
dtable = servercopy (dtable, dtablesize * sizeof (mach_port_t),
dtable_copy, &e.error);
@@ -2252,54 +2260,84 @@ S_exec_setexecdata (struct trivfs_protid *protid,
std_nints = nints;
rwlock_writer_unlock (&std_lock);
return 0;
}
#include "exec_startup_S.h"
/* RPC sent on the bootstrap port. */
+/* Deprecated. */
kern_return_t
S_exec_startup_get_info (mach_port_t port,
vm_address_t *user_entry,
vm_address_t *phdr_data, vm_size_t *phdr_size,
vm_address_t *stack_base, vm_size_t *stack_size,
int *flags,
char **argvp, mach_msg_type_number_t *argvlen,
char **envpp, mach_msg_type_number_t *envplen,
mach_port_t **dtable,
mach_msg_type_name_t *dtablepoly,
mach_msg_type_number_t *dtablesize,
mach_port_t **portarray,
mach_msg_type_name_t *portpoly,
mach_msg_type_number_t *nports,
int **intarray, mach_msg_type_number_t *nints)
{
+ return S_exec_startup_get_info_2 (port, user_entry,
+ phdr_data, phdr_size,
+ stack_base, stack_size,
+ flags, NULL,
+ argvp, argvlen, envpp, envplen,
+ dtable, dtablepoly, dtablesize,
+ portarray, portpoly, nports,
+ intarray, nints);
+}
+
+kern_return_t
+S_exec_startup_get_info_2 (mach_port_t port,
+ vm_address_t *user_entry,
+ vm_address_t *phdr_data, vm_size_t *phdr_size,
+ vm_address_t *stack_base, vm_size_t *stack_size,
+ int *flags, string_t filename,
+ char **argvp, mach_msg_type_number_t *argvlen,
+ char **envpp, mach_msg_type_number_t *envplen,
+ mach_port_t **dtable,
+ mach_msg_type_name_t *dtablepoly,
+ mach_msg_type_number_t *dtablesize,
+ mach_port_t **portarray,
+ mach_msg_type_name_t *portpoly,
+ mach_msg_type_number_t *nports,
+ int **intarray, mach_msg_type_number_t *nints)
+{
struct bootinfo *boot = ports_lookup_port (port_bucket, port,
execboot_portclass);
if (! boot)
return EOPNOTSUPP;
ports_port_deref (boot);
/* Pass back all the information we are storing. */
*user_entry = boot->user_entry;
*phdr_data = boot->phdr_addr;
*phdr_size = boot->phdr_size;
*stack_base = boot->stack_base;
*stack_size = boot->stack_size;
+ if (filename)
+ strncpy (filename, boot->filename, sizeof (string_t));
+
*argvp = boot->argv;
*argvlen = boot->argvlen;
boot->argvlen = 0;
*envpp = boot->envp;
*envplen = boot->envplen;
boot->envplen = 0;
*dtable = boot->dtable;
*dtablesize = boot->dtablesize;
*dtablepoly = MACH_MSG_TYPE_MOVE_SEND;
boot->dtablesize = 0;
diff --git a/exec/priv.h b/exec/priv.h
index 980d99f..ac48670 100644
--- a/exec/priv.h
+++ b/exec/priv.h
@@ -47,24 +47,25 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA
02139, USA. */
extern bfd_arch_info_type host_bfd_arch_info;
extern bfd host_bfd;
#endif
/* Information kept around to be given to a new task
in response to a message on the task's bootstrap port. */
struct bootinfo
{
struct port_info pi;
vm_address_t stack_base;
vm_size_t stack_size;
int flags;
+ string_t filename;
char *argv, *envp;
size_t argvlen, envplen, dtablesize, nports, nints;
mach_port_t *dtable, *portarray;
int *intarray;
vm_address_t phdr_addr, user_entry;
vm_size_t phdr_size;
};
/* Where to put the service ports. */
struct port_bucket *port_bucket;
struct port_class *execboot_portclass;
diff --git a/hurd/exec_startup.defs b/hurd/exec_startup.defs
index 9dfb79a..67a823a 100644
--- a/hurd/exec_startup.defs
+++ b/hurd/exec_startup.defs
@@ -17,30 +17,52 @@ You should have received a copy of the GNU General Public
License
along with the GNU Hurd; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Written by Roland McGrath. */
subsystem exec_startup 30500;
#include <hurd/hurd_types.defs>
/* This call is made by a new task to its bootstrap port to get its
startup ports and information. */
+/* Deprecated. */
routine exec_startup_get_info (
bootstrap: mach_port_t;
/* These describe the entry point and program header data
of the user program loaded into the task. */
out user_entry: vm_address_t;
out phdr_data: vm_address_t;
out phdr_size: vm_size_t;
/* These are the base address and size of the initial stack
allocated by the exec server. */
out stack_base: vm_address_t;
out stack_size: vm_size_t;
/* The rest of the information is that passed by exec_exec. */
out flags: int;
out argv: data_t, dealloc;
out envp: data_t, dealloc;
out dtable: portarray_t, dealloc;
out portarray: portarray_t, dealloc;
out intarray: intarray_t, dealloc);
+
+/* 2011-07: Add filename. */
+routine exec_startup_get_info_2 (
+ bootstrap: mach_port_t;
+ /* These describe the entry point and program header data
+ of the user program loaded into the task. */
+ out user_entry: vm_address_t;
+ out phdr_data: vm_address_t;
+ out phdr_size: vm_size_t;
+ /* These are the base address and size of the initial stack
+ allocated by the exec server. */
+ out stack_base: vm_address_t;
+ out stack_size: vm_size_t;
+ /* The rest of the information is that passed by exec_exec. */
+ out flags: int;
+ out filename: string_t;
+ out argv: data_t, dealloc;
+ out envp: data_t, dealloc;
+ out dtable: portarray_t, dealloc;
+ out portarray: portarray_t, dealloc;
+ out intarray: intarray_t, dealloc);
diff --git a/libdiskfs/boot-start.c b/libdiskfs/boot-start.c
index e816b0b..bac002a 100644
--- a/libdiskfs/boot-start.c
+++ b/libdiskfs/boot-start.c
@@ -276,63 +276,66 @@ diskfs_start_bootstrap ()
free (exec_argv);
free (exec_env);
mach_port_deallocate (mach_task_self (), root_pt);
mach_port_deallocate (mach_task_self (), startup_pt);
mach_port_deallocate (mach_task_self (), bootpt);
assert_perror (err);
}
/* We look like an execserver to the execserver itself; it makes this
call (as does any task) to get its state. We can't give it all of
its ports (we'll provide those with a later call to exec_init). */
kern_return_t
-diskfs_S_exec_startup_get_info (mach_port_t port,
- vm_address_t *user_entry,
- vm_address_t *phdr_data,
- vm_size_t *phdr_size,
- vm_address_t *base_addr,
- vm_size_t *stack_size,
- int *flags,
- char **argvP,
- mach_msg_type_number_t *argvlen,
- char **envpP __attribute__ ((unused)),
- mach_msg_type_number_t *envplen,
- mach_port_t **dtableP,
- mach_msg_type_name_t *dtablepoly,
- mach_msg_type_number_t *dtablelen,
- mach_port_t **portarrayP,
- mach_msg_type_name_t *portarraypoly,
- mach_msg_type_number_t *portarraylen,
- int **intarrayP,
- mach_msg_type_number_t *intarraylen)
+diskfs_S_exec_startup_get_info_2 (mach_port_t port,
+ vm_address_t *user_entry,
+ vm_address_t *phdr_data,
+ vm_size_t *phdr_size,
+ vm_address_t *base_addr,
+ vm_size_t *stack_size,
+ int *flags,
+ string_t filename,
+ char **argvP,
+ mach_msg_type_number_t *argvlen,
+ char **envpP __attribute__ ((unused)),
+ mach_msg_type_number_t *envplen,
+ mach_port_t **dtableP,
+ mach_msg_type_name_t *dtablepoly,
+ mach_msg_type_number_t *dtablelen,
+ mach_port_t **portarrayP,
+ mach_msg_type_name_t *portarraypoly,
+ mach_msg_type_number_t *portarraylen,
+ int **intarrayP,
+ mach_msg_type_number_t *intarraylen)
{
error_t err;
mach_port_t *portarray, *dtable;
mach_port_t rootport;
struct ufsport *upt;
struct protid *rootpi;
struct peropen *rootpo;
if (!(upt = ports_lookup_port (diskfs_port_bucket, port,
diskfs_execboot_class)))
return EOPNOTSUPP;
*user_entry = 0;
*phdr_data = *base_addr = 0;
*phdr_size = *stack_size = 0;
/* We have no args for it. Tell it to look on its stack
for the args placed there by the boot loader. */
*argvlen = *envplen = 0;
*flags = EXEC_STACK_ARGS;
+ if (filename)
+ memset (filename, 0, sizeof (string_t));
if (*portarraylen < INIT_PORT_MAX)
*portarrayP = mmap (0, INIT_PORT_MAX * sizeof (mach_port_t),
PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
portarray = *portarrayP;
*portarraylen = INIT_PORT_MAX;
if (*dtablelen < 3)
*dtableP = mmap (0, 3 * sizeof (mach_port_t), PROT_READ|PROT_WRITE,
MAP_ANON, 0, 0);
dtable = *dtableP;
*dtablelen = 3;
@@ -355,24 +358,57 @@ diskfs_S_exec_startup_get_info (mach_port_t port,
portarray[INIT_PORT_PROC] = MACH_PORT_NULL;
portarray[INIT_PORT_CTTYID] = MACH_PORT_NULL;
portarray[INIT_PORT_BOOTSTRAP] = port; /* use the same port */
*portarraypoly = MACH_MSG_TYPE_MAKE_SEND;
*dtablepoly = MACH_MSG_TYPE_COPY_SEND;
ports_port_deref (upt);
return 0;
}
+/* Deprecated version. */
+kern_return_t
+diskfs_S_exec_startup_get_info (mach_port_t port,
+ vm_address_t *user_entry,
+ vm_address_t *phdr_data,
+ vm_size_t *phdr_size,
+ vm_address_t *base_addr,
+ vm_size_t *stack_size,
+ int *flags,
+ char **argvP,
+ mach_msg_type_number_t *argvlen,
+ char **envpP __attribute__ ((unused)),
+ mach_msg_type_number_t *envplen,
+ mach_port_t **dtableP,
+ mach_msg_type_name_t *dtablepoly,
+ mach_msg_type_number_t *dtablelen,
+ mach_port_t **portarrayP,
+ mach_msg_type_name_t *papoly,
+ mach_msg_type_number_t *palen,
+ int **intarrayP,
+ mach_msg_type_number_t *intarraylen)
+{
+ return diskfs_S_exec_startup_get_info_2 (port, user_entry,
+ phdr_data, phdr_size,
+ base_addr, stack_size,
+ flags, NULL,
+ argvP, argvlen,
+ envpP, envplen,
+ dtableP, dtablepoly, dtablelen,
+ portarrayP, papoly, palen,
+ intarrayP, intarraylen);
+}
+
/* Called by S_fsys_startup for execserver bootstrap. The execserver
is able to function without a real node, hence this fraud. */
error_t
diskfs_execboot_fsys_startup (mach_port_t port, int flags,
mach_port_t ctl,
mach_port_t *real,
mach_msg_type_name_t *realpoly)
{
error_t err;
string_t pathbuf;
enum retry_type retry;
struct port_info *pt;
--
1.7.5.4