diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-03-19 13:05:27 +0100 |
---|---|---|
committer | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-03-19 13:05:27 +0100 |
commit | dfcc3ffcccc66117fea88bc7a9bb9d0b7a8c0e3b (patch) | |
tree | 33f60d21f59020070b9ea80f398b69ab66717d82 /debian/patches/libpager-deadlock.patch | |
parent | 6f015b01235c0f779a6961b1fbeb1cf514fe0b45 (diff) |
add libpager-deadlock.patch
Diffstat (limited to 'debian/patches/libpager-deadlock.patch')
-rw-r--r-- | debian/patches/libpager-deadlock.patch | 1688 |
1 files changed, 1688 insertions, 0 deletions
diff --git a/debian/patches/libpager-deadlock.patch b/debian/patches/libpager-deadlock.patch new file mode 100644 index 00000000..b4a1e015 --- /dev/null +++ b/debian/patches/libpager-deadlock.patch @@ -0,0 +1,1688 @@ +diff --git a/TODO b/TODO +index d2500dc..297ac98 100644 +--- a/TODO ++++ b/TODO +@@ -135,7 +135,7 @@ See `tasks', the exported task list. + + ** libtrivfs + *** Allow for read/write/exec to be passed down. +-*** Implement file_exec when appropriate. !! ++*** Implement file_exec_file_name when appropriate. !! + *** Provide for the visible owner, etc., to be held in command-line args + instead of the underlying node, when it's important. !! + +diff --git a/configure.ac b/configure.ac +index b6f777e..a03b666 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -160,8 +160,8 @@ else + fi + AC_SUBST(VERSIONING) + +-# Check if libc contains getgrouplist and/or uselocale. +-AC_CHECK_FUNCS(getgrouplist uselocale) ++# Check if libc contains these functions. ++AC_CHECK_FUNCS(getgrouplist uselocale file_exec_file_name exec_exec_file_name _hurd_exec_file_name) + + + # From glibc HEAD, 2007-11-07. +diff --git a/doc/hurd.texi b/doc/hurd.texi +index 07ddfb4..32a8194 100644 +--- a/doc/hurd.texi ++++ b/doc/hurd.texi +@@ -102,7 +102,7 @@ This file documents the GNU Hurd kernel component. This edition of the + documentation was last updated for version @value{VERSION} of the Hurd. + + Copyright @copyright{} 1994, 1996, 1998, 1999, 2000, 2001, 2002, 2003, +-2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. ++2004, 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + @quotation + Permission is granted to make and distribute verbatim copies of +@@ -2737,10 +2737,10 @@ write the file. + @node Program Execution + @subsection Program Execution + +-@findex file_exec ++@findex file_exec_file_name + Execution of programs on the Hurd is done through fileservers with the +-@code{file_exec} RPC. The fileserver is expected to verify that the +-user is allowed to execute the file, make whatever modifications to the ++@code{file_exec_file_name} RPC. The fileserver is expected to verify that ++the user is allowed to execute the file, make whatever modifications to the + ports are necessary for setuid execution, and then invoke the standard + execserver found on @file{/servers/exec}. + +@@ -2752,13 +2752,13 @@ The file must be opened for execution; if it is not, @code{EBADF} should + be returned. In addition, at least one of the execute bits must be on. A + failure of this check should result in @code{EACCES}---not + @code{ENOEXEC}. It is not proper for the fileserver ever to respond to +-the @code{file_exec} RPC with @code{ENOEXEC}. ++the @code{file_exec_file_name} RPC with @code{ENOEXEC}. + + If either the setuid or setgid bits are set, the server needs to + construct a new authentication handle with the additional new ID's. +-Then all the ports passed to @code{file_exec} need to be reauthenticated +-with the new handle. If the fileserver is unable to make the new +-authentication handle (for example, because it is not running as root) ++Then all the ports passed to @code{file_exec_file_name} need to be ++reauthenticated with the new handle. If the fileserver is unable to make the ++new authentication handle (for example, because it is not running as root) + it is not acceptable to return an error; in such a case the server + should simply silently fail to implement the setuid/setgid semantics. + +@@ -2766,14 +2766,14 @@ If the setuid/setgid transformation adds a new uid or gid to the user's + authentication handle that was not previously present (as opposed to + merely reordering them), then the @code{EXEC_SECURE} and + @code{EXEC_NEWTASK} flags should both be added in the call to +-@code{exec_exec}. ++@code{exec_exec_file_name}. + + The server then needs to open a new port onto the executed file which + will not share any file pointers with the port the user passed in, + opened with @code{O_READ}. Finally, all the information (mutated + appropriately for setuid/setgid) should be sent to the execserver with +-@code{exec_exec}. Whatever error code @code{exec_exec} returns should +-returned to the caller of @code{file_exec}. ++@code{exec_exec_file_name}. Whatever error code @code{exec_exec_file_name} ++returns should be returned to the caller of @code{file_exec_file_name}. + + @node File Locking + @subsection File Locking +diff --git a/exec/Makefile b/exec/Makefile +index 3ef742d..a285c13 100644 +--- a/exec/Makefile ++++ b/exec/Makefile +@@ -22,7 +22,7 @@ makemode := server + + SRCS = exec.c main.c hashexec.c hostarch.c + OBJS = main.o hostarch.o exec.o hashexec.o \ +- execServer.o exec_startupServer.o ++ execServer.o exec_startupServer.o exec_experimentalServer.o + + target = exec + #targets = exec exec.static +@@ -30,6 +30,7 @@ HURDLIBS = trivfs fshelp iohelp ports ihash shouldbeinlibc + OTHERLIBS = -lpthread + + exec-MIGSFLAGS = -imacros $(srcdir)/execmutations.h ++exec_experimental-MIGSFLAGS = -imacros $(srcdir)/execmutations.h + + include ../Makeconf + +diff --git a/exec/exec.c b/exec/exec.c +index e693f63..09e7df1 100644 +--- a/exec/exec.c ++++ b/exec/exec.c +@@ -1,6 +1,6 @@ + /* GNU Hurd standard exec server. +- Copyright (C) 1992,93,94,95,96,98,99,2000,01,02,04 +- Free Software Foundation, Inc. ++ Copyright (C) 1992 ,1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, ++ 2002, 2004, 2010 Free Software Foundation, Inc. + Written by Roland McGrath. + + Can exec ELF format directly. +@@ -738,6 +738,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, +@@ -796,7 +797,7 @@ do_exec (file_t file, + { + /* Check for a #! executable file. */ + check_hashbang (&e, +- file, oldtask, flags, ++ file, oldtask, flags, filename, + argv, argvlen, argv_copy, + envp, envplen, envp_copy, + dtable, dtablesize, dtable_copy, +@@ -1371,6 +1372,7 @@ do_exec (file_t file, + return e.error; + } + ++/* Deprecated. */ + kern_return_t + S_exec_exec (struct trivfs_protid *protid, + file_t file, +@@ -1387,13 +1389,51 @@ 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, ++ "", ++ 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, ++ 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; + + /* 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, filename, + argv, argvlen, argv_copy, + envp, envplen, envp_copy, + dtable, dtablesize, dtable_copy, +diff --git a/exec/hashexec.c b/exec/hashexec.c +index 5641218..91dc9a6 100644 +--- a/exec/hashexec.c ++++ b/exec/hashexec.c +@@ -1,5 +1,6 @@ + /* GNU Hurd standard exec server, #! script execution support. +- Copyright (C) 1995,96,97,98,99,2000,02 Free Software Foundation, Inc. ++ Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2010 ++ Free Software Foundation, Inc. + Written by Roland McGrath. + + This file is part of the GNU Hurd. +@@ -23,6 +24,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + #include <unistd.h> + #include <envz.h> + #include <sys/param.h> ++#ifdef HAVE_FILE_EXEC_FILE_NAME ++#include <hurd/fs_experimental.h> ++#endif + + /* This is called to check E for a #! interpreter specification. E has + already been prepared (successfully) and checked (unsuccessfully). If +@@ -35,6 +39,7 @@ check_hashbang (struct execdata *e, + file_t file, + task_t oldtask, + int flags, ++ char *file_name_exec, + 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,10 +230,13 @@ 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] +- 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. */ ++ /* Try to figure out the file's name. If FILE_NAME_EXEC ++ is not NULL and not the empty string, 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. */ + + error_t error; + char *name; +@@ -264,49 +272,59 @@ check_hashbang (struct execdata *e, + return err; + } + +- error = io_identity (file, &fileid, &filefsid, &fileno); +- if (error) +- goto out; +- mach_port_deallocate (mach_task_self (), filefsid); +- +- if (memchr (argv, '\0', argvlen) == NULL) +- { +- name = alloca (argvlen + 1); +- bcopy (argv, name, argvlen); +- name[argvlen] = '\0'; +- } ++ if (file_name_exec && file_name_exec[0] != '\0') ++ name = file_name_exec; + else +- name = argv; +- +- if (strchr (name, '/') != NULL) +- error = lookup (name, 0, &name_file); +- else if ((error = hurd_catch_signal +- (sigmask (SIGBUS) | sigmask (SIGSEGV), +- (vm_address_t) envp, (vm_address_t) envp + envplen, +- &search_path, SIG_ERR))) +- name_file = MACH_PORT_NULL; +- +- if (!error && name_file != MACH_PORT_NULL) + { +- mach_port_t id, fsid; +- ino_t ino; +- error = io_identity (name_file, &id, &fsid, &ino); +- mach_port_deallocate (mach_task_self (), name_file); +- if (!error) ++ /* Try to locate the file. */ ++ error = io_identity (file, &fileid, &filefsid, &fileno); ++ if (error) ++ goto out; ++ mach_port_deallocate (mach_task_self (), filefsid); ++ ++ if (memchr (argv, '\0', argvlen) == NULL) + { +- mach_port_deallocate (mach_task_self (), fsid); +- mach_port_deallocate (mach_task_self (), id); ++ name = alloca (argvlen + 1); ++ bcopy (argv, name, argvlen); ++ name[argvlen] = '\0'; + } +- if (!error && id == fileid) ++ else ++ name = argv; ++ ++ if (strchr (name, '/') != NULL) ++ error = lookup (name, 0, &name_file); ++ else if ((error = hurd_catch_signal ++ (sigmask (SIGBUS) | sigmask (SIGSEGV), ++ (vm_address_t) envp, (vm_address_t) envp + envplen, ++ &search_path, SIG_ERR))) ++ name_file = MACH_PORT_NULL; ++ ++ /* See whether we found the right file. */ ++ if (!error && name_file != MACH_PORT_NULL) + { +- file_name = name; +- free_file_name = free_name; ++ mach_port_t id, fsid; ++ ino_t ino; ++ error = io_identity (name_file, &id, &fsid, &ino); ++ mach_port_deallocate (mach_task_self (), name_file); ++ if (!error) ++ { ++ mach_port_deallocate (mach_task_self (), fsid); ++ mach_port_deallocate (mach_task_self (), id); ++ if (id != fileid) ++ error = 1; ++ } + } +- else if (free_name) +- free (name); ++ ++ mach_port_deallocate (mach_task_self (), fileid); + } + +- mach_port_deallocate (mach_task_self (), fileid); ++ if (!error) ++ { ++ file_name = name; ++ free_file_name = free_name; ++ } ++ else if (free_name) ++ free (name); + } + + if (file_name == NULL) +@@ -415,16 +433,32 @@ check_hashbang (struct execdata *e, + /* We cannot open the interpreter file to execute it. Lose! */ + return; + ++#ifdef HAVE_FILE_EXEC_FILE_NAME + /* Execute the interpreter program. */ +- e->error = file_exec (interp_file, +- oldtask, flags, +- new_argv, new_argvlen, envp, envplen, +- new_dtable ?: dtable, MACH_MSG_TYPE_COPY_SEND, +- new_dtable ? new_dtablesize : dtablesize, +- portarray, MACH_MSG_TYPE_COPY_SEND, nports, +- intarray, nints, +- deallocnames, ndeallocnames, +- destroynames, ndestroynames); ++ e->error = file_exec_file_name (interp_file, ++ oldtask, flags, interp, ++ new_argv, new_argvlen, envp, envplen, ++ new_dtable ?: dtable, ++ MACH_MSG_TYPE_COPY_SEND, ++ new_dtable ? new_dtablesize : dtablesize, ++ portarray, MACH_MSG_TYPE_COPY_SEND, nports, ++ intarray, nints, ++ deallocnames, ndeallocnames, ++ destroynames, ndestroynames); ++ /* For backwards compatibility. Just drop it when we kill file_exec. */ ++ if (e->error == MIG_BAD_ID) ++#endif ++ e->error = file_exec (interp_file, ++ oldtask, flags, ++ new_argv, new_argvlen, envp, envplen, ++ new_dtable ?: dtable, MACH_MSG_TYPE_COPY_SEND, ++ new_dtable ? new_dtablesize : dtablesize, ++ portarray, MACH_MSG_TYPE_COPY_SEND, nports, ++ intarray, nints, ++ deallocnames, ndeallocnames, ++ destroynames, ndestroynames); ++ ++ + mach_port_deallocate (mach_task_self (), interp_file); + munmap (new_argv, new_argvlen); + +diff --git a/exec/main.c b/exec/main.c +index 27f33b1..2987e2d 100644 +--- a/exec/main.c ++++ b/exec/main.c +@@ -47,6 +47,7 @@ char **save_argv; + + + #include "exec_S.h" ++#include "exec_experimental_S.h" + #include "exec_startup_S.h" + + static int +@@ -54,6 +55,7 @@ exec_demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp) + { + mig_routine_t routine; + if ((routine = exec_server_routine (inp)) || ++ (routine = exec_experimental_server_routine (inp)) || + (routine = NULL, trivfs_demuxer (inp, outp)) || + (routine = exec_startup_server_routine (inp))) + { +diff --git a/exec/priv.h b/exec/priv.h +index 85e03ae..cfd73be 100644 +--- a/exec/priv.h ++++ b/exec/priv.h +@@ -1,5 +1,6 @@ + /* GNU Hurd standard exec server, private declarations. +- Copyright (C) 1992,93,94,95,96,99,2000,02, 04 Free Software Foundation, Inc. ++ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2002, 2004, ++ 2010 Free Software Foundation, Inc. + Written by Roland McGrath. + + This file is part of the GNU Hurd. +@@ -32,6 +33,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + #include <link.h> /* This gives us the ElfW macro. */ + #include <fcntl.h> + #include "exec_S.h" ++#include "exec_experimental_S.h" + + + #ifndef exec_priv_h +@@ -134,6 +136,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, +diff --git a/hurd/exec.defs b/hurd/exec.defs +index 2888fb1..7433cc2 100644 +--- a/hurd/exec.defs ++++ b/hurd/exec.defs +@@ -1,5 +1,6 @@ + /* Interface definitions for the exec servers. +- Copyright (C) 1991,92,93,94,95,2001 Free Software Foundation, Inc. ++ Copyright (C) 1991, 1992, 1993, 1994, 1995, 2001, 2010 ++ Free Software Foundation, Inc. + + This file is part of the GNU Hurd. + +@@ -29,6 +30,7 @@ EXEC_IMPORTS + + INTR_INTERFACE + ++/* Deprecated: use exec_exec_file_name instead. */ + routine exec_exec ( + execserver: file_t; + file: mach_port_send_t; +diff --git a/hurd/fs.defs b/hurd/fs.defs +index 2452682..0f0b140 100644 +--- a/hurd/fs.defs ++++ b/hurd/fs.defs +@@ -1,5 +1,6 @@ + /* Definitions for the filesystem interface. +- Copyright (C) 1994,95,96,97,98,99,2002 Free Software Foundation, Inc. ++ Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2002, 2010 ++ Free Software Foundation, Inc. + + This file is part of the GNU Hurd. + +@@ -35,7 +36,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 +@@ -129,8 +131,8 @@ routine file_lock_stat ( + (regardless of the current open modes for this port). ALLOWED is a + bitwise OR of O_READ, O_WRITE, and O_EXEC. This is not necessarily the + same as what an open or exec would allow; O_EXEC is set for root even if +- no executable bits are on (in which case file_exec should fail) and +- O_WRITE is set a directory can be modified, even though it can't be ++ no executable bits are on (in which case file_exec_file_name should fail) ++ and O_WRITE is set a directory can be modified, even though it can't be + written directly. */ + routine file_check_access ( + file: file_t; +diff --git a/hurd/hurd_types.h b/hurd/hurd_types.h +index 7d1bb73..5e470eb 100644 +--- a/hurd/hurd_types.h ++++ b/hurd/hurd_types.h +@@ -1,5 +1,6 @@ + /* C declarations for Hurd server interfaces +- Copyright (C) 1993,94,95,96,98,99,2001,02 Free Software Foundation, Inc. ++ Copyright (C) 1993, 1994, 1995, 1996, 1998, 1999, 2001, 2002, ++ 2010 Free Software Foundation, Inc. + + This file is part of the GNU Hurd. + +@@ -78,7 +79,7 @@ typedef struct timespec timespec_t; + /* Many such parameters and flags are also defined in various libc + headers. */ + +-/* Bits for flags in fs.defs:file_exec and exec.defs:exec_* calls: */ ++/* Bits for flags in fs.defs:file_exec_file_name and exec.defs:exec_* calls: */ + #define EXEC_NEWTASK 0x00000001 /* Create new task; kill old one. */ + #define EXEC_SECURE 0x00000002 /* Use secure values of portarray, etc. */ + #define EXEC_DEFAULTS 0x00000004 /* Use defaults for unspecified ports. */ +@@ -344,7 +345,7 @@ typedef int *procinfo_t; + #define FSTYPE_MEMFS 0x00000019 /* In-core filesystem */ + #define FSTYPE_ISO9660 0x0000001a /* ISO9660 */ + +-/* Standard port assignments for file_exec and exec_* */ ++/* Standard port assignments for file_exec_file_name and exec_* */ + enum + { + INIT_PORT_CWDIR, +@@ -358,7 +359,7 @@ enum + INIT_PORT_MAX + }; + +-/* Standard ints for file_exec and exec_* */ ++/* Standard ints for file_exec_file_name and exec_* */ + enum + { + INIT_UMASK, +diff --git a/hurd/process.defs b/hurd/process.defs +index bf90556..8c17666 100644 +--- a/hurd/process.defs ++++ b/hurd/process.defs +@@ -373,7 +373,11 @@ routine proc_getnports ( + + /*** Routines related to early server bootstrapping ***/ + +-skip; /* Reserved for proc_set_init_task */ ++/* Set the task of process HURD_PID_INIT. Only the startup process ++ HURD_PID_STARTUP may use this interface. */ ++routine proc_set_init_task ( ++ process: process_t; ++ task: task_t); + + /* Inform the process server that the process is important. */ + routine proc_mark_important ( +diff --git a/hurd/process_request.defs b/hurd/process_request.defs +index 38e7146..cb8f083 100644 +--- a/hurd/process_request.defs ++++ b/hurd/process_request.defs +@@ -374,7 +374,10 @@ simpleroutine proc_getnports_request ( + + /*** Routines related to early server bootstrapping ***/ + +-skip; /* Reserved for proc_set_init_task */ ++simpleroutine proc_set_init_task_request ( ++ process: process_t; ++ ureplyport reply: reply_port_t; ++ task: task_t); + + /* Inform the process server that the process is important. */ + simpleroutine proc_mark_important_request ( +diff --git a/include/pids.h b/include/pids.h +index 22415f4..dff7635 100644 +--- a/include/pids.h ++++ b/include/pids.h +@@ -22,8 +22,9 @@ + #ifndef _HURD_PROCESSES_H + #define _HURD_PROCESSES_H + +-#define HURD_PID_STARTUP 1 +-#define HURD_PID_KERNEL 2 +-#define HURD_PID_PROC 3 ++#define HURD_PID_INIT 1 ++#define HURD_PID_STARTUP 2 ++#define HURD_PID_KERNEL 3 ++#define HURD_PID_PROC 4 + + #endif /* _HURD_PROCESSES_H */ +diff --git a/init/init.c b/init/init.c +index b7b40bd..e86be61 100644 +--- a/init/init.c ++++ b/init/init.c +@@ -1,7 +1,7 @@ + /* Start and maintain hurd core servers and system run state + + Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +- 2005, 2008, 2013 Free Software Foundation, Inc. ++ 2005, 2008, 2010, 2013 Free Software Foundation, Inc. + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or modify +@@ -24,6 +24,9 @@ + one file. */ + #include <hurd.h> + #include <hurd/fs.h> ++#ifdef HAVE_FILE_EXEC_FILE_NAME ++#include <hurd/fs_experimental.h> ++#endif + #include <hurd/fsys.h> + #include <device/device.h> + #include <stdio.h> +@@ -376,13 +379,28 @@ run (const char *server, mach_port_t *ports, task_t *task) + printf ("Pausing for %s\n", prog); + getchar (); + } +- err = file_exec (file, *task, 0, +- (char *)prog, strlen (prog) + 1, /* Args. */ +- startup_envz, startup_envz_len, +- default_dtable, MACH_MSG_TYPE_COPY_SEND, 3, +- ports, MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX, +- default_ints, INIT_INT_MAX, +- NULL, 0, NULL, 0); ++#ifdef HAVE_FILE_EXEC_FILE_NAME ++ err = file_exec_file_name (file, *task, 0, (char *)prog, ++ (char *)prog, ++ strlen (prog) + 1, /* Args. */ ++ startup_envz, startup_envz_len, ++ default_dtable, ++ MACH_MSG_TYPE_COPY_SEND, 3, ++ ports, MACH_MSG_TYPE_COPY_SEND, ++ INIT_PORT_MAX, ++ default_ints, INIT_INT_MAX, ++ NULL, 0, NULL, 0); ++ /* For backwards compatibility. Just drop it when we kill ++ file_exec. */ ++ if (err == MIG_BAD_ID) ++#endif ++ err = file_exec (file, *task, 0, ++ (char *)prog, strlen (prog) + 1, /* Args. */ ++ startup_envz, startup_envz_len, ++ default_dtable, MACH_MSG_TYPE_COPY_SEND, 3, ++ ports, MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX, ++ default_ints, INIT_INT_MAX, ++ NULL, 0, NULL, 0); + if (!err) + break; + +@@ -469,14 +487,27 @@ run_for_real (char *filename, char *args, int arglen, mach_port_t ctty, + ++progname; + else + progname = filename; +- err = file_exec (file, task, 0, +- args, arglen, +- startup_envz, startup_envz_len, +- default_dtable, MACH_MSG_TYPE_COPY_SEND, 3, +- default_ports, MACH_MSG_TYPE_COPY_SEND, +- INIT_PORT_MAX, +- default_ints, INIT_INT_MAX, +- NULL, 0, NULL, 0); ++#ifdef HAVE_FILE_EXEC_FILE_NAME ++ err = file_exec_file_name (file, task, 0, filename, ++ args, arglen, ++ startup_envz, startup_envz_len, ++ default_dtable, MACH_MSG_TYPE_COPY_SEND, 3, ++ default_ports, MACH_MSG_TYPE_COPY_SEND, ++ INIT_PORT_MAX, ++ default_ints, INIT_INT_MAX, ++ NULL, 0, NULL, 0); ++ /* For backwards compatibility. Just drop it when we kill file_exec. */ ++ if (err == MIG_BAD_ID) ++#endif ++ err = file_exec (file, task, 0, ++ args, arglen, ++ startup_envz, startup_envz_len, ++ default_dtable, MACH_MSG_TYPE_COPY_SEND, 3, ++ default_ports, MACH_MSG_TYPE_COPY_SEND, ++ INIT_PORT_MAX, ++ default_ints, INIT_INT_MAX, ++ NULL, 0, NULL, 0); ++ + mach_port_deallocate (mach_task_self (), default_ports[INIT_PORT_PROC]); + mach_port_deallocate (mach_task_self (), task); + if (ctty != MACH_PORT_NULL) +@@ -1058,7 +1089,7 @@ start_child (const char *prog, char **progargs) + NULL, 0, /* OSF Mach */ + #endif + 0, &child_task); +- proc_child (procserver, child_task); ++ proc_set_init_task (procserver, child_task); + proc_task2pid (procserver, child_task, &child_pid); + proc_task2proc (procserver, child_task, &default_ports[INIT_PORT_PROC]); + +@@ -1068,13 +1099,26 @@ start_child (const char *prog, char **progargs) + getchar (); + } + +- err = file_exec (file, child_task, 0, +- args, arglen, +- startup_envz, startup_envz_len, +- NULL, MACH_MSG_TYPE_COPY_SEND, 0, /* No fds. */ +- default_ports, MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX, +- default_ints, INIT_INT_MAX, +- NULL, 0, NULL, 0); ++#ifdef HAVE_FILE_EXEC_FILE_NAME ++ err = file_exec_file_name (file, child_task, 0, args, ++ args, arglen, ++ startup_envz, startup_envz_len, ++ NULL, MACH_MSG_TYPE_COPY_SEND, 0, /* No fds. */ ++ default_ports, MACH_MSG_TYPE_COPY_SEND, ++ INIT_PORT_MAX, ++ default_ints, INIT_INT_MAX, ++ NULL, 0, NULL, 0); ++ /* For backwards compatibility. Just drop it when we kill file_exec. */ ++ if (err == MIG_BAD_ID) ++#endif ++ err = file_exec (file, child_task, 0, ++ args, arglen, ++ startup_envz, startup_envz_len, ++ NULL, MACH_MSG_TYPE_COPY_SEND, 0, /* No fds. */ ++ default_ports, MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX, ++ default_ints, INIT_INT_MAX, ++ NULL, 0, NULL, 0); ++ + proc_mark_important (default_ports[INIT_PORT_PROC]); + mach_port_deallocate (mach_task_self (), default_ports[INIT_PORT_PROC]); + mach_port_deallocate (mach_task_self (), file); +diff --git a/libdiskfs/Makefile b/libdiskfs/Makefile +index aeebe4e..636a83e 100644 +--- a/libdiskfs/Makefile ++++ b/libdiskfs/Makefile +@@ -56,7 +56,7 @@ OTHERSRCS = conch-fetch.c conch-set.c dir-clear.c dir-init.c dir-renamed.c \ + SRCS = $(OTHERSRCS) $(FSSRCS) $(IOSRCS) $(FSYSSRCS) $(IFSOCKSRCS) + installhdrs = diskfs.h diskfs-pager.h + +-MIGSTUBS = fsServer.o ioServer.o fsysServer.o exec_startupServer.o \ ++MIGSTUBS = fsServer.o fs_experimentalServer.o ioServer.o fsysServer.o exec_startupServer.o \ + fsys_replyUser.o fs_notifyUser.o ifsockServer.o \ + startup_notifyServer.o + OBJS = $(sort $(SRCS:.c=.o) $(MIGSTUBS)) +@@ -66,6 +66,7 @@ LDLIBS += -lpthread + + fsys-MIGSFLAGS = -imacros $(srcdir)/fsmutations.h -DREPLY_PORTS + fs-MIGSFLAGS = -imacros $(srcdir)/fsmutations.h ++fs_experimental-MIGSFLAGS = -imacros $(srcdir)/fsmutations.h + io-MIGSFLAGS = -imacros $(srcdir)/fsmutations.h + ifsock-MIGSFLAGS = -imacros $(srcdir)/fsmutations.h + MIGCOMSFLAGS = -prefix diskfs_ +diff --git a/libdiskfs/boot-start.c b/libdiskfs/boot-start.c +index 7b8a84f..9dd7ec8 100644 +--- a/libdiskfs/boot-start.c ++++ b/libdiskfs/boot-start.c +@@ -196,7 +196,7 @@ diskfs_start_bootstrap () + diskfs_exec_ctl = MACH_PORT_NULL; /* Not used after this. */ + } + +- /* Cache the exec server port for file_exec to use. */ ++ /* Cache the exec server port for file_exec_file_name to use. */ + _hurd_port_set (&_diskfs_exec_portcell, diskfs_exec); + + if (_diskfs_boot_command) +diff --git a/libdiskfs/demuxer.c b/libdiskfs/demuxer.c +index 4a1c4fb..ff33b1b 100644 +--- a/libdiskfs/demuxer.c ++++ b/libdiskfs/demuxer.c +@@ -19,6 +19,7 @@ + + #include "io_S.h" + #include "fs_S.h" ++#include "fs_experimental_S.h" + #include "../libports/notify_S.h" + #include "fsys_S.h" + #include "../libports/interrupt_S.h" +@@ -33,6 +34,7 @@ diskfs_demuxer (mach_msg_header_t *inp, + mig_routine_t routine; + if ((routine = diskfs_io_server_routine (inp)) || + (routine = diskfs_fs_server_routine (inp)) || ++ (routine = diskfs_fs_experimental_server_routine (inp)) || + (routine = ports_notify_server_routine (inp)) || + (routine = diskfs_fsys_server_routine (inp)) || + (routine = ports_interrupt_server_routine (inp)) || +diff --git a/libdiskfs/file-exec.c b/libdiskfs/file-exec.c +index 9572dbe..3fe4059 100644 +--- a/libdiskfs/file-exec.c ++++ b/libdiskfs/file-exec.c +@@ -1,5 +1,6 @@ +-/* File execution (file_exec RPC) for diskfs servers, using exec server. +- Copyright (C) 1993,94,95,96,97,98,2000,02 Free Software Foundation, Inc. ++/* File execution (file_exec_file_name RPC) for diskfs servers, using exec server. ++ Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2002, ++ 2010 Free Software Foundation, Inc. + + This file is part of the GNU Hurd. + +@@ -21,10 +22,14 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + #include "priv.h" + #include "fs_S.h" ++#include "fs_experimental_S.h" + #include <sys/stat.h> + #include <fcntl.h> + #include <hurd/exec.h> + #include <hurd/paths.h> ++#ifdef HAVE_EXEC_EXEC_FILE_NAME ++#include <hurd/exec_experimental.h> ++#endif + #include <string.h> + #include <idvec.h> + +@@ -47,6 +52,39 @@ diskfs_S_file_exec (struct protid *cred, + mach_port_t *destroynames, + size_t destroynameslen) + { ++ return diskfs_S_file_exec_file_name (cred, ++ task, ++ flags, ++ "", ++ 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, ++ 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; +@@ -136,9 +174,9 @@ diskfs_S_file_exec (struct protid *cred, + + if (! err) + /* Make a new peropen for the exec server to access the file, since any +- seeking the exec server might want to do should not affect the +- original peropen on which file_exec was called. (The new protid for +- this peropen clones the caller's iouser to preserve the caller's ++ seeking the exec server might want to do should not affect the original ++ peropen on which file_exec_file_name was called. (The new protid ++ for this peropen clones the caller's iouser to preserve the caller's + authentication credentials.) The new peropen's openmodes must have + O_READ even if the caller had only O_EXEC privilege, so the exec + server can read the executable file. We also include O_EXEC so that +@@ -159,14 +197,31 @@ 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); ++#ifdef HAVE_EXEC_EXEC_FILE_NAME ++ err = exec_exec_file_name (execserver, ++ right, MACH_MSG_TYPE_COPY_SEND, ++ task, flags, filename, ++ argv, argvlen, envp, envplen, ++ fds, MACH_MSG_TYPE_COPY_SEND, fdslen, ++ portarray, MACH_MSG_TYPE_COPY_SEND, ++ portarraylen, ++ intarray, intarraylen, ++ deallocnames, deallocnameslen, ++ destroynames, destroynameslen); ++ /* For backwards compatibility. Just drop it when we kill ++ exec_exec. */ ++ if (err == MIG_BAD_ID) ++#endif ++ 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); ++ ++ + mach_port_deallocate (mach_task_self (), right); + if (err == MACH_SEND_INVALID_DEST) + { +diff --git a/libfshelp/start-translator-long.c b/libfshelp/start-translator-long.c +index 64a20be..8927c0d 100644 +--- a/libfshelp/start-translator-long.c ++++ b/libfshelp/start-translator-long.c +@@ -1,5 +1,6 @@ + /* +- Copyright (C) 1995,96,99,2000,02, 04 Free Software Foundation, Inc. ++ Copyright (C) 1995, 1996, 1999, 2000, 2002, 2004, 2010 ++ Free Software Foundation, Inc. + Written by Miles Bader and Michael I. Bushnell. + + This file is part of the GNU Hurd. +@@ -27,6 +28,9 @@ + #include <string.h> + #include <assert.h> + #include "fshelp.h" ++#ifdef HAVE_FILE_EXEC_FILE_NAME ++#include <hurd/fs_experimental.h> ++#endif + + + /* The data passed in the various messages we're interested in. */ +@@ -272,12 +276,22 @@ fshelp_start_translator_long (fshelp_open_fn_t underlying_open_fn, + saveport = ports[INIT_PORT_BOOTSTRAP]; + ports[INIT_PORT_BOOTSTRAP] = bootstrap; + ++#ifdef HAVE_FILE_EXEC_FILE_NAME + /* Try and exec the translator in TASK... */ +- err = file_exec (executable, task, EXEC_DEFAULTS, +- argz, argz_len, 0, 0, +- fds, fds_type, fds_len, +- ports, ports_type, ports_len, +- ints, ints_len, 0, 0, 0, 0); ++ err = file_exec_file_name (executable, task, EXEC_DEFAULTS, name, ++ argz, argz_len, 0, 0, ++ fds, fds_type, fds_len, ++ ports, ports_type, ports_len, ++ ints, ints_len, 0, 0, 0, 0); ++ /* For backwards compatibility. Just drop it when we kill file_exec. */ ++ if (err == MIG_BAD_ID) ++#endif ++ err = file_exec (executable, task, EXEC_DEFAULTS, ++ argz, argz_len, 0, 0, ++ fds, fds_type, fds_len, ++ ports, ports_type, ports_len, ++ ints, ints_len, 0, 0, 0, 0); ++ + ports_moved = 1; + + if (ports_type == MACH_MSG_TYPE_COPY_SEND) +diff --git a/libnetfs/Makefile b/libnetfs/Makefile +index c3830c0..4aade5a 100644 +--- a/libnetfs/Makefile ++++ b/libnetfs/Makefile +@@ -59,12 +59,13 @@ SRCS= $(OTHERSRCS) $(FSSRCS) $(IOSRCS) $(FSYSSRCS) $(IFSOCKSRCS) + + installhdrs=netfs.h + +-MIGSTUBS= ioServer.o fsServer.o fsysServer.o fsys_replyUser.o ifsockServer.o ++MIGSTUBS= ioServer.o fsServer.o fs_experimentalServer.o fsysServer.o fsys_replyUser.o ifsockServer.o + + OBJS=$(sort $(SRCS:.c=.o) $(MIGSTUBS)) + + fsys-MIGSFLAGS = -imacros $(srcdir)/mutations.h -DREPLY_PORTS + fs-MIGSFLAGS = -imacros $(srcdir)/mutations.h ++fs_experimental-MIGSFLAGS = -imacros $(srcdir)/mutations.h + io-MIGSFLAGS = -imacros $(srcdir)/mutations.h + ifsock-MIGSFLAGS = -imacros $(srcdir)/mutations.h + MIGCOMSFLAGS = -prefix netfs_ +diff --git a/libnetfs/demuxer.c b/libnetfs/demuxer.c +index 4c20ab6..bf78812 100644 +--- a/libnetfs/demuxer.c ++++ b/libnetfs/demuxer.c +@@ -22,6 +22,7 @@ + + #include "io_S.h" + #include "fs_S.h" ++#include "fs_experimental_S.h" + #include "../libports/notify_S.h" + #include "fsys_S.h" + #include "../libports/interrupt_S.h" +@@ -34,6 +35,7 @@ netfs_demuxer (mach_msg_header_t *inp, + mig_routine_t routine; + if ((routine = netfs_io_server_routine (inp)) || + (routine = netfs_fs_server_routine (inp)) || ++ (routine = netfs_fs_experimental_server_routine (inp)) || + (routine = ports_notify_server_routine (inp)) || + (routine = netfs_fsys_server_routine (inp)) || + (routine = ports_interrupt_server_routine (inp)) || +diff --git a/libnetfs/file-exec.c b/libnetfs/file-exec.c +index 638f0ae..ffaf598 100644 +--- a/libnetfs/file-exec.c ++++ b/libnetfs/file-exec.c +@@ -1,5 +1,6 @@ + /* +- Copyright (C) 1996,97,2000,01,02 Free Software Foundation, Inc. ++ Copyright (C) 1996, 1997, 2000, 2001, 2002, 2010 ++ Free Software Foundation, Inc. + Written by Michael I. Bushnell, p/BSG. + + This file is part of the GNU Hurd. +@@ -23,10 +24,14 @@ + #include "netfs.h" + #include "execserver.h" + #include "fs_S.h" ++#include "fs_experimental_S.h" + #include <sys/stat.h> + #include <fcntl.h> + #include <hurd/exec.h> + #include <hurd/paths.h> ++#ifdef HAVE_EXEC_EXEC_FILE_NAME ++#include <hurd/exec_experimental.h> ++#endif + #include <string.h> + #include <idvec.h> + +@@ -49,6 +54,39 @@ netfs_S_file_exec (struct protid *cred, + mach_port_t *destroynames, + size_t destroynameslen) + { ++ return netfs_S_file_exec_file_name (cred, ++ task, ++ flags, ++ "", ++ 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, ++ 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 +171,31 @@ 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); ++#ifdef HAVE_EXEC_EXEC_FILE_NAME ++ err = exec_exec_file_name (_netfs_exec, ++ right, MACH_MSG_TYPE_COPY_SEND, ++ task, flags, filename, ++ argv, argvlen, envp, envplen, ++ fds, MACH_MSG_TYPE_COPY_SEND, fdslen, ++ portarray, MACH_MSG_TYPE_COPY_SEND, ++ portarraylen, ++ intarray, intarraylen, ++ deallocnames, deallocnameslen, ++ destroynames, destroynameslen); ++ /* For backwards compatibility. Just drop it when we kill ++ exec_exec. */ ++ if (err == MIG_BAD_ID) ++#endif ++ 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); ++ + mach_port_deallocate (mach_task_self (), right); + ports_port_deref (newpi); + } +diff --git a/libpager/pager-attr.c b/libpager/pager-attr.c +index 7629f1d..ad1560e 100644 +--- a/libpager/pager-attr.c ++++ b/libpager/pager-attr.c +@@ -19,9 +19,9 @@ + #include <assert.h> + + /* Change the attributes of the memory object underlying pager P. +- Args MAY_CACHE and COPY_STRATEGY are as for +- memory_object_change_atributes. Wait for the kernel to report completion +- off WAIT is set.*/ ++ Arguments MAY_CACHE and COPY_STRATEGY are as for ++ memory_object_change_atributes. Wait for the kernel to report ++ completion if WAIT is set. */ + void + pager_change_attributes (struct pager *p, + boolean_t may_cache, +@@ -77,11 +77,14 @@ pager_change_attributes (struct pager *p, + } + } + ++ pthread_mutex_unlock (&p->interlock); + memory_object_change_attributes (p->memobjcntl, may_cache, copy_strategy, + wait ? p->port.port_right : MACH_PORT_NULL); + + if (wait) + { ++ pthread_mutex_lock (&p->interlock); ++ + while (ar->attrs_pending) + pthread_cond_wait (&p->wakeup, &p->interlock); + +@@ -92,7 +95,7 @@ pager_change_attributes (struct pager *p, + ar->next->prevp = ar->prevp; + free (ar); + } ++ ++ pthread_mutex_unlock (&p->interlock); + } +- +- pthread_mutex_unlock (&p->interlock); + } +diff --git a/libpager/pager.h b/libpager/pager.h +index 75ff108..d0572af 100644 +--- a/libpager/pager.h ++++ b/libpager/pager.h +@@ -111,9 +111,9 @@ pager_offer_page (struct pager *pager, + vm_address_t buf); + + /* Change the attributes of the memory object underlying pager PAGER. +- Args MAY_CACHE and COPY_STRATEGY are as for +- memory_object_change_atributes. Wait for the kernel to report completion +- off WAIT is set.*/ ++ Arguments MAY_CACHE and COPY_STRATEGY are as for ++ memory_object_change_atributes. Wait for the kernel to report ++ completion if WAIT is set. */ + void + pager_change_attributes (struct pager *pager, + boolean_t may_cache, +diff --git a/libtrivfs/Makefile b/libtrivfs/Makefile +index 921acbe..f68aa7b 100644 +--- a/libtrivfs/Makefile ++++ b/libtrivfs/Makefile +@@ -44,7 +44,7 @@ OTHERSRCS=demuxer.c protid-clean.c protid-dup.c cntl-create.c \ + + SRCS=$(FSSRCS) $(IOSRCS) $(FSYSSRCS) $(OTHERSRCS) + +-MIGSTUBS=fsServer.o ioServer.o fsysServer.o fsys_replyUser.o ++MIGSTUBS=fsServer.o fs_experimentalServer.o ioServer.o fsysServer.o fsys_replyUser.o + + libname = libtrivfs + HURDLIBS = fshelp iohelp ports shouldbeinlibc +@@ -54,7 +54,7 @@ MIGCOMSFLAGS = -prefix trivfs_ + installhdrs := trivfs.h + mig-sheader-prefix = trivfs_ + ifndef no_deps +-installhdrs += $(patsubst %,trivfs_%_S.h,fs io fsys) ++installhdrs += $(patsubst %,trivfs_%_S.h,fs fs_experimental io fsys) + endif + + include ../Makeconf +diff --git a/libtrivfs/demuxer.c b/libtrivfs/demuxer.c +index 306cd11..221d218 100644 +--- a/libtrivfs/demuxer.c ++++ b/libtrivfs/demuxer.c +@@ -23,6 +23,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + #include "trivfs_io_S.h" + #include "trivfs_fs_S.h" ++#include "trivfs_fs_experimental_S.h" + #include "../libports/notify_S.h" + #include "trivfs_fsys_S.h" + #include "../libports/interrupt_S.h" +@@ -34,6 +35,7 @@ trivfs_demuxer (mach_msg_header_t *inp, + mig_routine_t routine; + if ((routine = trivfs_io_server_routine (inp)) || + (routine = trivfs_fs_server_routine (inp)) || ++ (routine = trivfs_fs_experimental_server_routine (inp)) || + (routine = ports_notify_server_routine (inp)) || + (routine = trivfs_fsys_server_routine (inp)) || + (routine = ports_interrupt_server_routine (inp))) +diff --git a/libtrivfs/file-exec.c b/libtrivfs/file-exec.c +index a3ab048..f626955 100644 +--- a/libtrivfs/file-exec.c ++++ b/libtrivfs/file-exec.c +@@ -1,5 +1,5 @@ + /* +- Copyright (C) 1994,2002 Free Software Foundation, Inc. ++ Copyright (C) 1994, 2002, 2010 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as +@@ -40,3 +40,28 @@ 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, ++ string_t filename, ++ 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/proc/main.c b/proc/main.c +index 73742ed..f1f4e1b 100644 +--- a/proc/main.c ++++ b/proc/main.c +@@ -1,5 +1,5 @@ + /* Initialization of the proc server +- Copyright (C) 1993,94,95,96,97,99,2000,01 Free Software Foundation, Inc. ++ Copyright (C) 1993,94,95,96,97,99,2000,01,13 Free Software Foundation, Inc. + + This file is part of the GNU Hurd. + +@@ -88,7 +88,12 @@ main (int argc, char **argv, char **envp) + generic_port = ports_get_right (genport); + + /* Create the initial proc object for init (PID 1). */ +- startup_proc = create_startup_proc (); ++ init_proc = create_init_proc (); ++ ++ /* Create the startup proc object for /hurd/init (PID 2). */ ++ startup_proc = allocate_proc (MACH_PORT_NULL); ++ startup_proc->p_deadmsg = 1; ++ complete_proc (startup_proc, HURD_PID_STARTUP); + + /* Create our own proc object. */ + self_proc = allocate_proc (mach_task_self ()); +diff --git a/proc/mgt.c b/proc/mgt.c +index 5e0accd..3ab7d8d 100644 +--- a/proc/mgt.c ++++ b/proc/mgt.c +@@ -1,5 +1,6 @@ + /* Process management +- Copyright (C) 1992,93,94,95,96,99,2000,01,02 Free Software Foundation, Inc. ++ Copyright (C) 1992,93,94,95,96,99,2000,01,02,13 ++ Free Software Foundation, Inc. + + This file is part of the GNU Hurd. + +@@ -184,7 +185,7 @@ S_proc_child (struct proc *parentp, + /* Process hierarchy. Remove from our current location + and place us under our new parent. Sanity check to make sure + parent is currently init. */ +- assert (childp->p_parent == startup_proc); ++ assert (childp->p_parent == init_proc); + if (childp->p_sib) + childp->p_sib->p_prevsib = childp->p_prevsib; + *childp->p_prevsib = childp->p_sib; +@@ -587,7 +588,7 @@ allocate_proc (task_t task) + /* Allocate and initialize the proc structure for init (PID 1), + the original parent of all other procs. */ + struct proc * +-create_startup_proc (void) ++create_init_proc (void) + { + static const uid_t zero; + struct proc *p; +@@ -596,7 +597,7 @@ create_startup_proc (void) + p = allocate_proc (MACH_PORT_NULL); + assert (p); + +- p->p_pid = HURD_PID_STARTUP; ++ p->p_pid = HURD_PID_INIT; + + p->p_parent = p; + p->p_sib = 0; +@@ -644,7 +645,7 @@ proc_death_notify (struct proc *p) + } + + /* Complete a new process that has been allocated but not entirely initialized. +- This gets called for every process except startup_proc (PID 1). */ ++ This gets called for every process except init_proc (PID 1). */ + void + complete_proc (struct proc *p, pid_t pid) + { +@@ -663,30 +664,47 @@ complete_proc (struct proc *p, pid_t pid) + + p->p_pid = pid; + +- ids_ref (&nullids); +- p->p_id = &nullids; ++ if (pid == HURD_PID_STARTUP) ++ { ++ /* Equip HURD_PID_STARTUP with the same credentials as ++ HURD_PID_INIT. */ ++ static const uid_t zero; ++ p->p_id = make_ids (&zero, 1); ++ assert (p->p_id); ++ } ++ else ++ { ++ ids_ref (&nullids); ++ p->p_id = &nullids; ++ } + + p->p_login = nulllogin; + p->p_login->l_refcnt++; + + /* Our parent is init for now. */ +- p->p_parent = startup_proc; ++ p->p_parent = init_proc; + +- p->p_sib = startup_proc->p_ochild; +- p->p_prevsib = &startup_proc->p_ochild; ++ p->p_sib = init_proc->p_ochild; ++ p->p_prevsib = &init_proc->p_ochild; + if (p->p_sib) + p->p_sib->p_prevsib = &p->p_sib; +- startup_proc->p_ochild = p; ++ init_proc->p_ochild = p; + p->p_loginleader = 0; + p->p_ochild = 0; + p->p_parentset = 0; + + p->p_noowner = 1; + +- p->p_pgrp = startup_proc->p_pgrp; ++ p->p_pgrp = init_proc->p_pgrp; + +- proc_death_notify (p); +- add_proc_to_hash (p); ++ /* At this point, we do not know the task of the startup process, ++ defer registering death notifications and adding it to the hash ++ tables. */ ++ if (pid != HURD_PID_STARTUP) ++ { ++ proc_death_notify (p); ++ add_proc_to_hash (p); ++ } + join_pgrp (p); + } + +@@ -748,7 +766,7 @@ process_has_exited (struct proc *p) + nowait_msg_proc_newids (tp->p_msgport, tp->p_task, + 1, tp->p_pgrp->pg_pgid, + !tp->p_pgrp->pg_orphcnt); +- tp->p_parent = startup_proc; ++ tp->p_parent = init_proc; + if (tp->p_dead) + isdead = 1; + } +@@ -756,17 +774,17 @@ process_has_exited (struct proc *p) + nowait_msg_proc_newids (tp->p_msgport, tp->p_task, + 1, tp->p_pgrp->pg_pgid, + !tp->p_pgrp->pg_orphcnt); +- tp->p_parent = startup_proc; ++ tp->p_parent = init_proc; + + /* And now append the lists. */ +- tp->p_sib = startup_proc->p_ochild; ++ tp->p_sib = init_proc->p_ochild; + if (tp->p_sib) + tp->p_sib->p_prevsib = &tp->p_sib; +- startup_proc->p_ochild = p->p_ochild; +- p->p_ochild->p_prevsib = &startup_proc->p_ochild; ++ init_proc->p_ochild = p->p_ochild; ++ p->p_ochild->p_prevsib = &init_proc->p_ochild; + + if (isdead) +- alert_parent (startup_proc); ++ alert_parent (init_proc); + } + + /* If an operation is in progress for this process, cause it +@@ -946,3 +964,21 @@ S_proc_get_code (struct proc *callerp, + + return 0; + } ++ ++/* Implement proc_set_init_task as described in <hurd/process.defs>. */ ++error_t ++S_proc_set_init_task(struct proc *callerp, ++ task_t task) ++{ ++ if (! callerp) ++ return EOPNOTSUPP; ++ ++ if (callerp != startup_proc) ++ return EPERM; ++ ++ init_proc->p_task = task; ++ proc_death_notify (init_proc); ++ add_proc_to_hash (init_proc); ++ ++ return 0; ++} +diff --git a/proc/proc.h b/proc/proc.h +index 12f56da..8c8de08 100644 +--- a/proc/proc.h ++++ b/proc/proc.h +@@ -1,5 +1,6 @@ + /* Process server definitions +- Copyright (C) 1992,93,94,95,96,99,2000,01 Free Software Foundation, Inc. ++ Copyright (C) 1992,93,94,95,96,99,2000,01,13 ++ Free Software Foundation, Inc. + + This file is part of the GNU Hurd. + +@@ -134,7 +135,8 @@ struct exc + + mach_port_t authserver; + struct proc *self_proc; /* process HURD_PID_PROC (us) */ +-struct proc *startup_proc; /* process 1 (init) */ ++struct proc *init_proc; /* process 1 (sysvinit) */ ++struct proc *startup_proc; /* process 2 (hurd/init) */ + + struct port_bucket *proc_bucket; + struct port_class *proc_class; +@@ -190,7 +192,7 @@ void exc_clean (void *); + struct proc *add_tasks (task_t); + int pidfree (pid_t); + +-struct proc *create_startup_proc (void); ++struct proc *create_init_proc (void); + struct proc *allocate_proc (task_t); + void proc_death_notify (struct proc *); + void complete_proc (struct proc *, pid_t); +diff --git a/trans/fakeroot.c b/trans/fakeroot.c +index c519180..07d9462 100644 +--- a/trans/fakeroot.c ++++ b/trans/fakeroot.c +@@ -1,5 +1,5 @@ + /* fakeroot -- a translator for faking actions that aren't really permitted +- Copyright (C) 2002, 2003, 2008, 2013 Free Software Foundation, Inc. ++ Copyright (C) 2002, 2003, 2008, 2010, 2013 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as +@@ -28,6 +28,9 @@ + #include <pthread.h> + #include <hurd/ihash.h> + #include <hurd/paths.h> ++#ifdef HAVE_FILE_EXEC_FILE_NAME ++#include <hurd/fs_experimental.h> ++#endif + + #include <version.h> + +@@ -784,6 +787,39 @@ netfs_S_file_exec (struct protid *user, + mach_port_t *destroynames, + size_t destroynameslen) + { ++ return netfs_S_file_exec_file_name (user, ++ task, ++ flags, ++ "", ++ 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, ++ 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; + +@@ -800,13 +836,29 @@ netfs_S_file_exec (struct protid *user, + + if (!err) + { ++#ifdef HAVE_FILE_EXEC_FILE_NAME + /* 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, ++ argv, argvlen, ++ envp, envplen, ++ fds, MACH_MSG_TYPE_COPY_SEND, fdslen, ++ portarray, MACH_MSG_TYPE_COPY_SEND, ++ portarraylen, ++ intarray, intarraylen, ++ deallocnames, deallocnameslen, ++ destroynames, destroynameslen); ++ /* For backwards compatibility. Just drop it when we kill ++ file_exec. */ ++ if (err == MIG_BAD_ID) ++#endif ++ 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); ++ + mach_port_deallocate (mach_task_self (), file); + } + +@@ -936,6 +988,7 @@ netfs_demuxer (mach_msg_header_t *inp, + { + mig_routine_t netfs_io_server_routine (mach_msg_header_t *); + mig_routine_t netfs_fs_server_routine (mach_msg_header_t *); ++ mig_routine_t netfs_fs_experimental_server_routine (mach_msg_header_t *); + mig_routine_t ports_notify_server_routine (mach_msg_header_t *); + mig_routine_t netfs_fsys_server_routine (mach_msg_header_t *); + mig_routine_t ports_interrupt_server_routine (mach_msg_header_t *); +@@ -943,6 +996,7 @@ netfs_demuxer (mach_msg_header_t *inp, + mig_routine_t routine; + if ((routine = netfs_io_server_routine (inp)) || + (routine = netfs_fs_server_routine (inp)) || ++ (routine = netfs_fs_experimental_server_routine (inp)) || + (routine = ports_notify_server_routine (inp)) || + (routine = netfs_fsys_server_routine (inp)) || + /* XXX we should intercept interrupt_operation and do +diff --git a/utils/fakeauth.c b/utils/fakeauth.c +index 590a421..851772c 100644 +--- a/utils/fakeauth.c ++++ b/utils/fakeauth.c +@@ -1,5 +1,5 @@ + /* fakeauth -- proxy auth server to lie to users about what their IDs are +- Copyright (C) 2002 Free Software Foundation, Inc. ++ Copyright (C) 2002, 2010 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as +@@ -397,7 +397,7 @@ believe it has restricted them to different identities or no identity at all.\ + /* We cannot use fork because it doesn't do the right thing with our send + rights that point to our own receive rights, i.e. the new auth port. + Since posix_spawn might be implemented with fork (prior to glibc 2.3), +- we cannot use that simple interface either. We use _hurd_exec ++ we cannot use that simple interface either. We use _hurd_exec_file_name + directly to effect what posix_spawn does in the simple case. */ + { + task_t newtask; +@@ -422,7 +422,12 @@ believe it has restricted them to different identities or no identity at all.\ + if (err) + error (3, err, "proc_child"); + ++#ifdef HAVE__HURD_EXEC_FILE_NAME ++ err = _hurd_exec_file_name (newtask, execfile, argv[argi], ++ &argv[argi], environ); ++#else + err = _hurd_exec (newtask, execfile, &argv[argi], environ); ++#endif + mach_port_deallocate (mach_task_self (), newtask); + mach_port_deallocate (mach_task_self (), execfile); + if (err) +diff --git a/utils/login.c b/utils/login.c +index cad3b1e..808a244 100644 +--- a/utils/login.c ++++ b/utils/login.c +@@ -1,6 +1,7 @@ + /* Hurdish login + +- Copyright (C) 1995,96,97,98,99,2002 Free Software Foundation, Inc. ++ Copyright (C) 1995, 1996, 1997, 1998, 1999, 2002, 2010 ++ Free Software Foundation, Inc. + + Written by Miles Bader <miles@gnu.org> + +@@ -46,6 +47,9 @@ + #include <error.h> + #include <timefmt.h> + #include <hurd/lookup.h> ++#ifdef HAVE_FILE_EXEC_FILE_NAME ++#include <hurd/fs_experimental.h> ++#endif + #include <ugids.h> + + const char *argp_program_version = STANDARD_HURD_VERSION (login); +@@ -882,12 +886,22 @@ main(int argc, char *argv[]) + } + } + +- err = file_exec (exec, mach_task_self (), EXEC_DEFAULTS, +- sh_args, sh_args_len, env, env_len, +- fds, MACH_MSG_TYPE_COPY_SEND, 3, +- ports, MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX, +- ints, INIT_INT_MAX, +- 0, 0, 0, 0); ++#ifdef HAVE_FILE_EXEC_FILE_NAME ++ err = file_exec_file_name (exec, mach_task_self (), EXEC_DEFAULTS, shell, ++ sh_args, sh_args_len, env, env_len, ++ fds, MACH_MSG_TYPE_COPY_SEND, 3, ++ ports, MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX, ++ ints, INIT_INT_MAX, ++ 0, 0, 0, 0); ++ /* Fallback in case the file server hasn't been restarted. */ ++ if (err == MIG_BAD_ID) ++#endif ++ err = file_exec (exec, mach_task_self (), EXEC_DEFAULTS, ++ sh_args, sh_args_len, env, env_len, ++ fds, MACH_MSG_TYPE_COPY_SEND, 3, ++ ports, MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX, ++ ints, INIT_INT_MAX, ++ 0, 0, 0, 0); + if (err) + error(5, err, "%s", shell); + +diff --git a/utils/rpctrace.c b/utils/rpctrace.c +index d7ee203..e9b634a 100644 +--- a/utils/rpctrace.c ++++ b/utils/rpctrace.c +@@ -1734,7 +1734,11 @@ traced_spawn (char **argv, char **envp) + /* Now actually run the command they told us to trace. We do the exec on + the actual task, so the RPCs to map in the program itself do not get + traced. Could have an option to use TASK_WRAPPER here instead. */ ++#ifdef HAVE__HURD_EXEC_FILE_NAME ++ err = _hurd_exec_file_name (traced_task, file, *argv, argv, envp); ++#else + err = _hurd_exec (traced_task, file, argv, envp); ++#endif + if (err) + error (2, err, "cannot exec `%s'", argv[0]); + +diff --git a/utils/shd.c b/utils/shd.c +index a1a4b26..855284f 100644 +--- a/utils/shd.c ++++ b/utils/shd.c +@@ -1,5 +1,5 @@ + /* +- Copyright (C) 1994,95,99,2002 Free Software Foundation ++ Copyright (C) 1994, 1995, 1999, 2002, 2010 Free Software Foundation + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as +@@ -159,15 +159,18 @@ run (char **argv, int fd0, int fd1) + movefd (fd1, 1, &save1)) + return -1; + ++#ifdef HAVE__HURD_EXEC_FILE_NAME ++ err = _hurd_exec_file_name (task, file, program, argv, environ); ++#else + err = _hurd_exec (task, file, argv, environ); +- ++#endif + if (restorefd (fd0, 0, &save0) || + restorefd (fd1, 1, &save1)) + return -1; + + if (err) + { +- error (0, err, "_hurd_exec"); ++ error (0, err, "_hurd_exec_file_name"); + err = task_terminate (task); + if (err) + error (0, err, "task_terminate"); |