Hi,

These are a series of patches to fix https://savannah.gnu.org/bugs/?28934

Basically the problem is that in some cases the exec server can't find the file
name of the file being executed (when it's a script), and then makes a hack
passing /dev/fd/N to the interpreter.

I tried to fix it with heuristics such as "if the file name contains no slashes,
then it's relative" and passing just a flag to the exec server to avoid needing
to create new RPCs, but that's not enough, since a call like execv("foo",{"bar",
NULL}) (i.e. filename != argv[0]) should work too. So the only option is to pass
filename to the exec server, and just use that.

So this patch adds two new RPCs: exec_exec_file_name RPC and file_exec_file_name
one. Then libc can use exec_exec_file_name in hurdexec.c.

There's a little bootstrapping problem here: you can't apply the four Hurd
patches directly and build the whole Hurd, because lib*fs will be using
exec_exec_file_name, but the dynamic linker can't find it, since libhurduser.so
should provide it but you haven't build glibc yet. So to bootstrap it (without
hacks like partially building Hurd, e.g. what we would need to do in the Debian
packages) one would need to apply all but 0004 patches to Hurd and build it,
then build glibc with the new Hurd installed, and then finally build Hurd with
the 0004 patch. I mentioned this on #hurd and antrik said that the Hurd specific
parts of libhurduser.so should maybe be moved to Hurd.

Cheers,
Emilio
>From 1ab4b589efdd9ba9a809ba6d0dd88fd0d3645b0d Mon Sep 17 00:00:00 2001
From: Emilio Pozuelo Monfort <poch...@gmail.com>
Date: Wed, 19 May 2010 23:06:13 +0200
Subject: [PATCH 1/4] Extend check_hashbang with a filename argument

If the new filename argument is not null, it's the file name
and we don't need to guess it from argv[0] and $PATH.
---
 exec/exec.c     |    2 +-
 exec/hashexec.c |    8 ++++++--
 exec/priv.h     |    1 +
 3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/exec/exec.c b/exec/exec.c
index 272b789..1ea4d92 100644
--- a/exec/exec.c
+++ b/exec/exec.c
@@ -1433,7 +1433,7 @@ do_exec (file_t file,
     {
       /* Check for a #! executable file.  */
       check_hashbang (&e,
-		      file, oldtask, flags,
+		      file, oldtask, flags, NULL,
 		      argv, argvlen, argv_copy,
 		      envp, envplen, envp_copy,
 		      dtable, dtablesize, dtable_copy,
diff --git a/exec/hashexec.c b/exec/hashexec.c
index 2aa3844..7a7b329 100644
--- a/exec/hashexec.c
+++ b/exec/hashexec.c
@@ -35,6 +35,7 @@ check_hashbang (struct execdata *e,
 		file_t file,
 		task_t oldtask,
 		int flags,
+		char *filename,
 		char *argv, u_int argvlen, boolean_t argv_copy,
 		char *envp, u_int envplen, boolean_t envp_copy,
 		mach_port_t *dtable, u_int dtablesize, boolean_t dtable_copy,
@@ -225,7 +226,8 @@ check_hashbang (struct execdata *e,
 	    file_name = NULL;
 	  else if (! (flags & EXEC_SECURE))
 	    {
-	      /* Try to figure out the file's name.  We guess that if ARGV[0]
+	      /* Try to figure out the file's name.  If FILENAME is not NULL,
+		 then it's the file's name. Otherwise we guess that if ARGV[0]
 		 contains a slash, it might be the name of the file; and that
 		 if it contains no slash, looking for files named by ARGV[0] in
 		 the `PATH' environment variable might find it.  */
@@ -278,7 +280,9 @@ check_hashbang (struct execdata *e,
 	      else
 		name = argv;
 
-	      if (strchr (name, '/') != NULL)
+	      if (filename)
+		error = lookup (name = filename, 0, &name_file);
+	      else if (strchr (name, '/') != NULL)
 		error = lookup (name, 0, &name_file);
 	      else if ((error = hurd_catch_signal
 			(sigmask (SIGBUS) | sigmask (SIGSEGV),
diff --git a/exec/priv.h b/exec/priv.h
index 7cee15e..fa41f7c 100644
--- a/exec/priv.h
+++ b/exec/priv.h
@@ -171,6 +171,7 @@ void check_hashbang (struct execdata *e,
 		     file_t file,
 		     task_t oldtask,
 		     int flags,
+		     char *filename,
 		     char *argv, u_int argvlen, boolean_t argv_copy,
 		     char *envp, u_int envplen, boolean_t envp_copy,
 		     mach_port_t *dtable, u_int dtablesize,
-- 
1.7.1

>From 80d9b08fc69f694448d5d53dea16cf14e54d1dde Mon Sep 17 00:00:00 2001
From: Emilio Pozuelo Monfort <poch...@gmail.com>
Date: Wed, 19 May 2010 23:34:12 +0200
Subject: [PATCH 2/4] Add a filename argument to do_exec

---
 exec/exec.c |    7 ++++---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/exec/exec.c b/exec/exec.c
index 1ea4d92..ea2bd5d 100644
--- a/exec/exec.c
+++ b/exec/exec.c
@@ -1338,6 +1338,7 @@ static error_t
 do_exec (file_t file,
 	 task_t oldtask,
 	 int flags,
+	 char *filename,
 	 char *argv, mach_msg_type_number_t argvlen, boolean_t argv_copy,
 	 char *envp, mach_msg_type_number_t envplen, boolean_t envp_copy,
 	 mach_port_t *dtable, mach_msg_type_number_t dtablesize,
@@ -1433,7 +1434,7 @@ do_exec (file_t file,
     {
       /* Check for a #! executable file.  */
       check_hashbang (&e,
-		      file, oldtask, flags, NULL,
+		      file, oldtask, flags, filename,
 		      argv, argvlen, argv_copy,
 		      envp, envplen, envp_copy,
 		      dtable, dtablesize, dtable_copy,
@@ -2092,7 +2093,7 @@ S_exec_exec (struct trivfs_protid *protid,
 					 trivfs_protid_portclasses[0]);
 		  if (protid)
 		    {
-		      err = do_exec (file, oldtask, 0,
+		      err = do_exec (file, oldtask, 0, NULL,
 				     argv, argvlen, argv_copy,
 				     envp, envplen, envp_copy,
 				     dtable, dtablesize, dtable_copy,
@@ -2139,7 +2140,7 @@ S_exec_exec (struct trivfs_protid *protid,
   /* There were no user-specified exec servers,
      or none of them could be found.  */
 
-  return do_exec (file, oldtask, flags,
+  return do_exec (file, oldtask, flags, NULL,
 		  argv, argvlen, argv_copy,
 		  envp, envplen, envp_copy,
 		  dtable, dtablesize, dtable_copy,
-- 
1.7.1

>From 4d42ddb105b4560a3bcefb875fb7961e526d9876 Mon Sep 17 00:00:00 2001
From: Emilio Pozuelo Monfort <poch...@gmail.com>
Date: Thu, 20 May 2010 23:53:08 +0200
Subject: [PATCH 3/4] Add a new exec_exec_file_name RPC

It's similar to exec_exec but with an additional filename
argument. This deprecates exec_exec.
---
 exec/exec.c    |   39 +++++++++++++++++++++++++++++++++++++--
 hurd/exec.defs |   16 +++++++++++++++-
 2 files changed, 52 insertions(+), 3 deletions(-)

diff --git a/exec/exec.c b/exec/exec.c
index ea2bd5d..7b51ff6 100644
--- a/exec/exec.c
+++ b/exec/exec.c
@@ -2037,6 +2037,7 @@ do_exec (file_t file,
   return e.error;
 }
 
+/* Deprecated.  */
 kern_return_t
 S_exec_exec (struct trivfs_protid *protid,
 	     file_t file,
@@ -2053,6 +2054,40 @@ S_exec_exec (struct trivfs_protid *protid,
 	     mach_port_t *deallocnames, mach_msg_type_number_t ndeallocnames,
 	     mach_port_t *destroynames, mach_msg_type_number_t ndestroynames)
 {
+  return S_exec_exec_file_name (protid,
+				file,
+				oldtask,
+				flags,
+				NULL, 0,
+				argv, argvlen, argv_copy,
+				envp, envplen, envp_copy,
+				dtable, dtablesize,
+				dtable_copy,
+				portarray, nports,
+				portarray_copy,
+				intarray, nints,
+				intarray_copy,
+				deallocnames, ndeallocnames,
+				destroynames, ndestroynames);
+}
+
+kern_return_t
+S_exec_exec_file_name (struct trivfs_protid *protid,
+		       file_t file,
+		       task_t oldtask,
+		       int flags,
+		       char *filename, mach_msg_type_number_t filenamelen,
+		       char *argv, mach_msg_type_number_t argvlen, boolean_t argv_copy,
+		       char *envp, mach_msg_type_number_t envplen, boolean_t envp_copy,
+		       mach_port_t *dtable, mach_msg_type_number_t dtablesize,
+		       boolean_t dtable_copy,
+		       mach_port_t *portarray, mach_msg_type_number_t nports,
+		       boolean_t portarray_copy,
+		       int *intarray, mach_msg_type_number_t nints,
+		       boolean_t intarray_copy,
+		       mach_port_t *deallocnames, mach_msg_type_number_t ndeallocnames,
+		       mach_port_t *destroynames, mach_msg_type_number_t ndestroynames)
+{
   if (! protid)
     return EOPNOTSUPP;
 
@@ -2093,7 +2128,7 @@ S_exec_exec (struct trivfs_protid *protid,
 					 trivfs_protid_portclasses[0]);
 		  if (protid)
 		    {
-		      err = do_exec (file, oldtask, 0, NULL,
+		      err = do_exec (file, oldtask, 0, filename,
 				     argv, argvlen, argv_copy,
 				     envp, envplen, envp_copy,
 				     dtable, dtablesize, dtable_copy,
@@ -2140,7 +2175,7 @@ S_exec_exec (struct trivfs_protid *protid,
   /* There were no user-specified exec servers,
      or none of them could be found.  */
 
-  return do_exec (file, oldtask, flags, NULL,
+  return do_exec (file, oldtask, flags, filename,
 		  argv, argvlen, argv_copy,
 		  envp, envplen, envp_copy,
 		  dtable, dtablesize, dtable_copy,
diff --git a/hurd/exec.defs b/hurd/exec.defs
index 2888fb1..ad558a2 100644
--- a/hurd/exec.defs
+++ b/hurd/exec.defs
@@ -29,6 +29,7 @@ EXEC_IMPORTS
 
 INTR_INTERFACE
 
+/*  Deprecated. Use exec_exec_file_name instead.  */
 routine exec_exec (
 	execserver: file_t;
 	file: mach_port_send_t;
@@ -42,7 +43,20 @@ routine exec_exec (
 	deallocnames: mach_port_name_array_t;
 	destroynames: mach_port_name_array_t);
 
-skip;				/* obsolete exec_startup */
+routine exec_exec_file_name (
+	execserver: file_t;
+	file: mach_port_send_t;
+	oldtask: task_t;
+	flags: int;
+	filename: data_t;
+	argv: data_t SCP;
+	envp: data_t SCP;
+	dtable: portarray_t SCP;
+	portarray: portarray_t SCP;
+	intarray: intarray_t SCP;
+	deallocnames: mach_port_name_array_t;
+	destroynames: mach_port_name_array_t);
+
 
 /* This call is made by the bootstrapping filesystem to give the
    execserver its auth handle.  */
-- 
1.7.1

>From d322e644ffb231de7ac37f4951fc9bb091b1e6d7 Mon Sep 17 00:00:00 2001
From: Emilio Pozuelo Monfort <poch...@gmail.com>
Date: Sat, 22 May 2010 17:46:56 +0200
Subject: [PATCH 4/4] Add a file_exec_file_name RPC

Make file_exec call file_exec_file_name and deprecate file_exec.
---
 hurd/fs.defs          |   21 ++++++++++++++++++-
 libdiskfs/file-exec.c |   52 +++++++++++++++++++++++++++++++++++++++++-------
 libnetfs/file-exec.c  |   51 ++++++++++++++++++++++++++++++++++++++++-------
 libtreefs/s-file.c    |   22 ++++++++++++++++++++
 libtrivfs/file-exec.c |   26 ++++++++++++++++++++++++
 trans/fakeroot.c      |   48 ++++++++++++++++++++++++++++++++++++++++----
 6 files changed, 198 insertions(+), 22 deletions(-)

diff --git a/hurd/fs.defs b/hurd/fs.defs
index 52d83bd..6f6202e 100644
--- a/hurd/fs.defs
+++ b/hurd/fs.defs
@@ -35,7 +35,8 @@ INTR_INTERFACE
 /* Overlay a task with a file.  Necessary initialization, including
    authentication changes associated with set[ug]id execution must be
    handled by the filesystem.  Filesystems normally implement this by
-   using exec_newtask or exec_loadtask as appropriate.  */
+   using exec_newtask or exec_loadtask as appropriate.
+   Deprecated. Use file_exec_file_name instead.  */
 routine file_exec (
 	exec_file: file_t;
 	RPT
@@ -352,3 +353,21 @@ routine file_reparent (
 	RPT
 	parent: mach_port_t;
 	out new_file: mach_port_send_t);
+
+/* Overlay a task with a file.  Necessary initialization, including
+   authentication changes associated with set[ug]id execution must be
+   handled by the filesystem.  Filesystems normally implement this by
+   using exec_newtask or exec_loadtask as appropriate.  */
+routine file_exec_file_name (
+	exec_file: file_t;
+	RPT
+	exec_task: task_t;
+	flags: int;
+	filename: data_t;
+	argv: data_t SCP;
+	envp: data_t SCP;
+	fdarray: portarray_t SCP;
+	portarray: portarray_t SCP;
+	intarray: intarray_t SCP;
+	deallocnames: mach_port_name_array_t SCP;
+	destroynames: mach_port_name_array_t SCP);
diff --git a/libdiskfs/file-exec.c b/libdiskfs/file-exec.c
index 452240c..511a8c2 100644
--- a/libdiskfs/file-exec.c
+++ b/libdiskfs/file-exec.c
@@ -47,6 +47,41 @@ diskfs_S_file_exec (struct protid *cred,
 		    mach_port_t *destroynames,
 		    size_t destroynameslen)
 {
+  return diskfs_S_file_exec_file_name (
+				       cred,
+				       task,
+				       flags,
+				       NULL, 0,
+				       argv, argvlen,
+				       envp, envplen,
+				       fds, fdslen,
+				       portarray, portarraylen,
+				       intarray, intarraylen,
+				       deallocnames, deallocnameslen,
+				       destroynames, destroynameslen);
+}
+
+kern_return_t
+diskfs_S_file_exec_file_name (struct protid *cred,
+			      task_t task,
+			      int flags,
+			      char *filename,
+			      size_t filenamelen,
+			      char *argv,
+			      size_t argvlen,
+			      char *envp,
+			      size_t envplen,
+			      mach_port_t *fds,
+			      size_t fdslen,
+			      mach_port_t *portarray,
+			      size_t portarraylen,
+			      int *intarray,
+			      size_t intarraylen,
+			      mach_port_t *deallocnames,
+			      size_t deallocnameslen,
+			      mach_port_t *destroynames,
+			      size_t destroynameslen)
+{
   struct node *np;
   uid_t uid;
   gid_t gid;
@@ -159,14 +194,15 @@ diskfs_S_file_exec (struct protid *cred,
       do
 	{
 	  right = ports_get_send_right (newpi);
-	  err = exec_exec (execserver,
-			   right, MACH_MSG_TYPE_COPY_SEND,
-			   task, flags, argv, argvlen, envp, envplen,
-			   fds, MACH_MSG_TYPE_COPY_SEND, fdslen,
-			   portarray, MACH_MSG_TYPE_COPY_SEND, portarraylen,
-			   intarray, intarraylen,
-			   deallocnames, deallocnameslen,
-			   destroynames, destroynameslen);
+	  err = exec_exec_file_name (execserver,
+				     right, MACH_MSG_TYPE_COPY_SEND,
+				     task, flags, filename, filenamelen,
+				     argv, argvlen, envp, envplen,
+				     fds, MACH_MSG_TYPE_COPY_SEND, fdslen,
+				     portarray, MACH_MSG_TYPE_COPY_SEND, portarraylen,
+				     intarray, intarraylen,
+				     deallocnames, deallocnameslen,
+				     destroynames, destroynameslen);
 	  mach_port_deallocate (mach_task_self (), right);
 	  if (err == MACH_SEND_INVALID_DEST)
 	    {
diff --git a/libnetfs/file-exec.c b/libnetfs/file-exec.c
index 73c125b..364344b 100644
--- a/libnetfs/file-exec.c
+++ b/libnetfs/file-exec.c
@@ -49,6 +49,40 @@ netfs_S_file_exec (struct protid *cred,
 		   mach_port_t *destroynames,
 		   size_t destroynameslen)
 {
+  return netfs_S_file_exec_file_name (cred,
+				      task,
+				      flags,
+				      NULL, 0,
+				      argv, argvlen,
+				      envp, envplen,
+				      fds, fdslen,
+				      portarray, portarraylen,
+				      intarray, intarraylen,
+				      deallocnames, deallocnameslen,
+				      destroynames, destroynameslen);
+}
+
+kern_return_t
+netfs_S_file_exec_file_name (struct protid *cred,
+			     task_t task,
+			     int flags,
+			     char *filename,
+			     size_t filenamelen,
+			     char *argv,
+			     size_t argvlen,
+			     char *envp,
+			     size_t envplen,
+			     mach_port_t *fds,
+			     size_t fdslen,
+			     mach_port_t *portarray,
+			     size_t portarraylen,
+			     int *intarray,
+			     size_t intarraylen,
+			     mach_port_t *deallocnames,
+			     size_t deallocnameslen,
+			     mach_port_t *destroynames,
+			     size_t destroynameslen)
+{
   struct node *np;
   error_t err;
   uid_t uid;
@@ -133,14 +167,15 @@ netfs_S_file_exec (struct protid *cred,
 	  if (newpi)
 	    {
 	      right = ports_get_send_right (newpi);
-	      err = exec_exec (_netfs_exec,
-			       right, MACH_MSG_TYPE_COPY_SEND,
-			       task, flags, argv, argvlen, envp, envplen,
-			       fds, MACH_MSG_TYPE_COPY_SEND, fdslen,
-			       portarray, MACH_MSG_TYPE_COPY_SEND, portarraylen,
-			       intarray, intarraylen,
-			       deallocnames, deallocnameslen,
-			       destroynames, destroynameslen);
+	      err = exec_exec_file_name (_netfs_exec,
+				         right, MACH_MSG_TYPE_COPY_SEND,
+				         task, flags, filename, filenamelen,
+				         argv, argvlen, envp, envplen,
+				         fds, MACH_MSG_TYPE_COPY_SEND, fdslen,
+				         portarray, MACH_MSG_TYPE_COPY_SEND, portarraylen,
+				         intarray, intarraylen,
+				         deallocnames, deallocnameslen,
+				         destroynames, destroynameslen);
 	      mach_port_deallocate (mach_task_self (), right);
 	      ports_port_deref (newpi);
 	    }
diff --git a/libtreefs/s-file.c b/libtreefs/s-file.c
index 73c32d7..2f6cedd 100644
--- a/libtreefs/s-file.c
+++ b/libtreefs/s-file.c
@@ -93,6 +93,28 @@ treefs_S_file_exec (struct treefs_protid *cred,
 }
 
 error_t
+treefs_S_file_exec_file_name (struct treefs_protid *cred,
+			      task_t task, int flags,
+			      char *filename, unsigned filename_len,
+			      char *argv, unsigned argv_len,
+			      char *envp, unsigned envp_len,
+			      mach_port_t *fds, unsigned fds_len,
+			      mach_port_t *ports, unsigned ports_len,
+			      int *ints, unsigned ints_len,
+			      mach_port_t *dealloc, unsigned dealloc_len,
+			      mach_port_t *destroy, unsigned destroy_len)
+{
+  if (!cred)
+    return EOPNOTSUPP;
+  /* XXX We're ignoring filename, so this is the same as if the caller would
+     have called file_exec instead of file_exec_file_name.  */
+  return treefs_s_file_exec (cred, task, flags, argv, argv_len, envp, envp_len,
+			     fds, fds_len, ports, ports_len, ints, ints_len,
+			     dealloc, dealloc_len, destroy, destroy_len);
+
+}
+
+error_t
 treefs_S_file_get_translator (struct treefs_protid *cred,
 			      char **trans, unsigned *trans_len)
 {
diff --git a/libtrivfs/file-exec.c b/libtrivfs/file-exec.c
index a3ab048..a321f05 100644
--- a/libtrivfs/file-exec.c
+++ b/libtrivfs/file-exec.c
@@ -40,3 +40,29 @@ trivfs_S_file_exec (trivfs_protid_t exec_file,
 {
   return EOPNOTSUPP;
 }
+
+kern_return_t
+trivfs_S_file_exec_file_name (trivfs_protid_t exec_file,
+			      mach_port_t reply,
+			      mach_msg_type_name_t replyPoly,
+			      mach_port_t exec_task,
+			      int flags,
+			      data_t filename,
+			      mach_msg_type_number_t filenameCnt,
+			      data_t argv,
+			      mach_msg_type_number_t argvCnt,
+			      data_t envp,
+			      mach_msg_type_number_t envpCnt,
+			      portarray_t fdarray,
+			      mach_msg_type_number_t fdarrayCnt,
+			      portarray_t portarray,
+			      mach_msg_type_number_t portarrayCnt,
+			      intarray_t intarray,
+			      mach_msg_type_number_t intarrayCnt,
+			      mach_port_array_t deallocnames,
+			      mach_msg_type_number_t deallocnamesCnt,
+			      mach_port_array_t destroynames,
+			      mach_msg_type_number_t destroynamesCnt)
+{
+  return EOPNOTSUPP;
+}
diff --git a/trans/fakeroot.c b/trans/fakeroot.c
index c110234..acb980b 100644
--- a/trans/fakeroot.c
+++ b/trans/fakeroot.c
@@ -705,6 +705,40 @@ netfs_S_file_exec (struct protid *user,
                    mach_port_t *destroynames,
                    size_t destroynameslen)
 {
+  return netfs_S_file_exec_file_name (user,
+				      task,
+				      flags,
+				      NULL, 0,
+				      argv, argvlen,
+				      envp, envplen,
+				      fds, fdslen,
+				      portarray, portarraylen,
+				      intarray, intarraylen,
+				      deallocnames, deallocnameslen,
+				      destroynames, destroynameslen);
+}
+
+kern_return_t
+netfs_S_file_exec_file_name (struct protid *user,
+			     task_t task,
+			     int flags,
+			     char *filename,
+			     size_t filenamelen,
+			     char *argv,
+			     size_t argvlen,
+			     char *envp,
+			     size_t envplen,
+			     mach_port_t *fds,
+			     size_t fdslen,
+			     mach_port_t *portarray,
+			     size_t portarraylen,
+			     int *intarray,
+			     size_t intarraylen,
+			     mach_port_t *deallocnames,
+			     size_t deallocnameslen,
+			     mach_port_t *destroynames,
+			     size_t destroynameslen)
+{
   error_t err;
   file_t file;
 
@@ -723,11 +757,15 @@ netfs_S_file_exec (struct protid *user,
     {
       /* We cannot use MACH_MSG_TYPE_MOVE_SEND because we might need to
 	 retry an interrupted call that would have consumed the rights.  */
-      err = file_exec (user->po->np->nn->file, task, flags, argv, argvlen,
-		       envp, envplen, fds, MACH_MSG_TYPE_COPY_SEND, fdslen,
-		       portarray, MACH_MSG_TYPE_COPY_SEND, portarraylen,
-		       intarray, intarraylen, deallocnames, deallocnameslen,
-		       destroynames, destroynameslen);
+      err = file_exec_file_name (user->po->np->nn->file, task, flags,
+			         filename, filenamelen,
+			         argv, argvlen,
+			         envp, envplen,
+			         fds, MACH_MSG_TYPE_COPY_SEND, fdslen,
+			         portarray, MACH_MSG_TYPE_COPY_SEND, portarraylen,
+			         intarray, intarraylen,
+			         deallocnames, deallocnameslen,
+			         destroynames, destroynameslen);
       mach_port_deallocate (mach_task_self (), file);
     }
 
-- 
1.7.1

>From 85033bc73229c2a17ff85d9003e5717e9c340aa4 Mon Sep 17 00:00:00 2001
From: Emilio Pozuelo Monfort <poch...@gmail.com>
Date: Sat, 22 May 2010 18:26:29 +0200
Subject: [PATCH] Use the new __hurd_exec_file_name RPC

This fixes problems when an script could env with /dev/fd/N
in argv[0] because the exec server didn't know the file name.
---
 hurd/Versions              |    1 +
 hurd/hurd.h                |   10 +++++++++-
 hurd/hurdexec.c            |   29 +++++++++++++++++++++--------
 sysdeps/mach/hurd/execve.c |    3 ++-
 4 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/hurd/Versions b/hurd/Versions
index 83c8ab1..81cd904 100644
--- a/hurd/Versions
+++ b/hurd/Versions
@@ -73,6 +73,7 @@ libc {
     _hurd_critical_section_unlock;
     _hurd_exception2signal;
     _hurd_exec;
+    _hurd_exec_file_name;
     _hurd_fd_get;
     _hurd_init;
     _hurd_intern_fd;
diff --git a/hurd/hurd.h b/hurd/hurd.h
index 642ea43..361fb0f 100644
--- a/hurd/hurd.h
+++ b/hurd/hurd.h
@@ -243,13 +243,21 @@ extern FILE *fopenport (io_t port, const char *mode);
 extern FILE *__fopenport (io_t port, const char *mode);
 
 
-/* Execute a file, replacing TASK's current program image.  */
+/* Deprecated, use _hurd_exec_file_name instead.  */
 
 extern error_t _hurd_exec (task_t task,
 			   file_t file,
 			   char *const argv[],
 			   char *const envp[]);
 
+/* Execute a file, replacing TASK's current program image.  */
+
+extern error_t _hurd_exec_file_name (task_t task,
+				     file_t file,
+				     const char *filename,
+				     char *const argv[],
+				     char *const envp[]);
+
 
 /* Inform the proc server we have exited with STATUS, and kill the
    task thoroughly.  This function never returns, no matter what.  */
diff --git a/hurd/hurdexec.c b/hurd/hurdexec.c
index beae869..beb41de 100644
--- a/hurd/hurdexec.c
+++ b/hurd/hurdexec.c
@@ -32,11 +32,22 @@
 
 /* Overlay TASK, executing FILE with arguments ARGV and environment ENVP.
    If TASK == mach_task_self (), some ports are dealloc'd by the exec server.
-   ARGV and ENVP are terminated by NULL pointers.  */
+   ARGV and ENVP are terminated by NULL pointers.
+   Deprecated, use _hurd_exec_file_name instead.  */
 error_t
 _hurd_exec (task_t task, file_t file,
 	    char *const argv[], char *const envp[])
 {
+  return _hurd_exec_file_name (task, file, NULL, argv, envp);
+}
+
+/* Overlay TASK, executing FILE with arguments ARGV and environment ENVP.
+   If TASK == mach_task_self (), some ports are dealloc'd by the exec server.
+   ARGV and ENVP are terminated by NULL pointers.  */
+error_t
+_hurd_exec_file_name (task_t task, file_t file, const char *filename,
+		      char *const argv[], char *const envp[])
+{
   error_t err;
   char *args, *env;
   size_t argslen, envlen;
@@ -362,13 +373,15 @@ _hurd_exec (task_t task, file_t file,
       if (__sigismember (&_hurdsig_traced, SIGKILL))
 	flags |= EXEC_SIGTRAP;
 #endif
-      err = __file_exec (file, task, flags,
-			 args, argslen, env, envlen,
-			 dtable, MACH_MSG_TYPE_COPY_SEND, dtablesize,
-			 ports, MACH_MSG_TYPE_COPY_SEND, _hurd_nports,
-			 ints, INIT_INT_MAX,
-			 please_dealloc, pdp - please_dealloc,
-			 &_hurd_msgport, task == __mach_task_self () ? 1 : 0);
+      err = __file_exec_file_name (file, task, flags,
+				   filename, filename ? strlen (filename) + 1 : 0,
+				   args, argslen, env, envlen,
+				   dtable, MACH_MSG_TYPE_COPY_SEND, dtablesize,
+				   ports, MACH_MSG_TYPE_COPY_SEND, _hurd_nports,
+				   ints, INIT_INT_MAX,
+				   please_dealloc, pdp - please_dealloc,
+				   &_hurd_msgport,
+				   task == __mach_task_self () ? 1 : 0);
     }
 
   /* Release references to the standard ports.  */
diff --git a/sysdeps/mach/hurd/execve.c b/sysdeps/mach/hurd/execve.c
index 8af8b33..f21440f 100644
--- a/sysdeps/mach/hurd/execve.c
+++ b/sysdeps/mach/hurd/execve.c
@@ -35,7 +35,8 @@ __execve (file_name, argv, envp)
     return -1;
 
   /* Hopefully this will not return.  */
-  err = _hurd_exec (__mach_task_self (), file, argv, envp);
+  err = _hurd_exec_file_name (__mach_task_self (), file,
+			      file_name, argv, envp);
 
   /* Oh well.  Might as well be tidy.  */
   __mach_port_deallocate (__mach_task_self (), file);
-- 
1.7.1

Reply via email to