mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-23 09:43:32 +08:00
hurd: Use the new file_exec_paths RPC
From: Emilio Pozuelo Monfort <pochu27@gmail.com> From: Svante Signell <svante.signell@gmail.com> Pass the file paths of executable to the exec server, both relative and absolute, which exec needs to properly execute and avertise #!-scripts. Previously, the exec server tried to guess the name from argv[0] but argv[0] only contains the executable name by convention. * hurd/hurdexec.c (_hurd_exec): Deprecate function. (_hurd_exec_paths): New function. * hurd/hurd.h (_hurd_exec): Deprecate function. (_hurd_exec_paths): Declare function. * hurd/Versions: Export _hurd_exec_paths. * sysdeps/mach/hurd/execve.c: Include <stdlib.h> and <stdio.h> (__execve): Use __getcwd to build absolute path, and use _hurd_exec_paths instead of _hurd_exec. * sysdeps/mach/hurd/spawni.c: Likewise. * sysdeps/mach/hurd/fexecve.c: Use _hurd_exec_paths instead of _hurd_exec.
This commit is contained in:
parent
d7ff3f11b6
commit
311ba8dc44
15
ChangeLog
15
ChangeLog
@ -1,3 +1,18 @@
|
||||
2010-08-04 Emilio Pozuelo Monfort <pochu27@gmail.com>
|
||||
2017-09-26 Svante Signell <svante.signell@gmail.com>
|
||||
|
||||
* hurd/hurdexec.c (_hurd_exec): Deprecate function.
|
||||
(_hurd_exec_paths): New function.
|
||||
* hurd/hurd.h (_hurd_exec): Deprecate function.
|
||||
(_hurd_exec_paths): Declare function.
|
||||
* hurd/Versions: Export _hurd_exec_paths.
|
||||
* sysdeps/mach/hurd/execve.c: Include <stdlib.h> and <stdio.h>
|
||||
(__execve): Use __getcwd to build absolute path, and use
|
||||
_hurd_exec_paths instead of _hurd_exec.
|
||||
* sysdeps/mach/hurd/spawni.c: Likewise.
|
||||
* sysdeps/mach/hurd/fexecve.c: Use _hurd_exec_paths instead of
|
||||
_hurd_exec.
|
||||
|
||||
2018-01-08 Dmitry V. Levin <ldv@altlinux.org>
|
||||
|
||||
* sysdeps/unix/sysv/linux/tst-ttyname.c (do_in_chroot_1): Skip the
|
||||
|
@ -129,6 +129,10 @@ libc {
|
||||
# functions used in macros & inline functions
|
||||
__errno_location;
|
||||
}
|
||||
GLIBC_2.27 {
|
||||
# "quasi-internal" functions
|
||||
_hurd_exec_paths;
|
||||
}
|
||||
|
||||
HURD_CTHREADS_0.3 {
|
||||
# weak refs to libthreads functions that libc calls iff libthreads in use
|
||||
|
13
hurd/hurd.h
13
hurd/hurd.h
@ -240,12 +240,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_paths instead. */
|
||||
|
||||
extern error_t _hurd_exec (task_t task,
|
||||
file_t file,
|
||||
char *const argv[],
|
||||
char *const envp[]);
|
||||
char *const envp[]) __attribute_deprecated__;
|
||||
|
||||
/* Execute a file, replacing TASK's current program image. */
|
||||
|
||||
extern error_t _hurd_exec_paths (task_t task,
|
||||
file_t file,
|
||||
const char *path,
|
||||
const char *abspath,
|
||||
char *const argv[],
|
||||
char *const envp[]);
|
||||
|
||||
|
||||
/* Inform the proc server we have exited with STATUS, and kill the
|
||||
|
@ -30,10 +30,29 @@
|
||||
|
||||
/* 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_paths instead. */
|
||||
error_t
|
||||
_hurd_exec (task_t task, file_t file,
|
||||
char *const argv[], char *const envp[])
|
||||
{
|
||||
return _hurd_exec_paths (task, file, NULL, NULL, argv, envp);
|
||||
}
|
||||
|
||||
link_warning (_hurd_exec,
|
||||
"_hurd_exec is deprecated, use _hurd_exec_paths instead");
|
||||
|
||||
/* 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. PATH is the relative path to
|
||||
FILE and ABSPATH is the absolute path to FILE. Passing NULL, though possible,
|
||||
should be avoided, since then the exec server may not know the path to
|
||||
FILE if FILE is a script, and will then pass /dev/fd/N to the
|
||||
interpreter. */
|
||||
error_t
|
||||
_hurd_exec_paths (task_t task, file_t file,
|
||||
const char *path, const char *abspath,
|
||||
char *const argv[], char *const envp[])
|
||||
{
|
||||
error_t err;
|
||||
char *args, *env;
|
||||
@ -216,7 +235,7 @@ _hurd_exec (task_t task, file_t file,
|
||||
/* We have euid != svuid or egid != svgid. POSIX.1 says that exec
|
||||
sets svuid = euid and svgid = egid. So we must get a new auth
|
||||
port and reauthenticate everything with it. We'll pass the new
|
||||
ports in file_exec instead of our own ports. */
|
||||
ports in file_exec_paths instead of our own ports. */
|
||||
|
||||
auth_t newauth;
|
||||
|
||||
@ -360,13 +379,28 @@ _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_paths (file, task, flags,
|
||||
path ? path : "",
|
||||
abspath ? abspath : "",
|
||||
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);
|
||||
/* Fall back for backwards compatibility. This can just be removed
|
||||
when __file_exec goes away. */
|
||||
if (err == MIG_BAD_ID)
|
||||
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);
|
||||
}
|
||||
|
||||
/* Release references to the standard ports. */
|
||||
|
@ -18,6 +18,8 @@
|
||||
#include <unistd.h>
|
||||
#include <hurd.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* Replace the current process, executing FILE_NAME with arguments ARGV and
|
||||
environment ENVP. ARGV and ENVP are terminated by NULL pointers. */
|
||||
@ -25,16 +27,46 @@ int
|
||||
__execve (const char *file_name, char *const argv[], char *const envp[])
|
||||
{
|
||||
error_t err;
|
||||
file_t file = __file_name_lookup (file_name, O_EXEC, 0);
|
||||
char *concat_name = NULL;
|
||||
const char *abs_path;
|
||||
|
||||
file_t file = __file_name_lookup (file_name, O_EXEC, 0);
|
||||
if (file == MACH_PORT_NULL)
|
||||
return -1;
|
||||
|
||||
if (file_name[0] == '/')
|
||||
{
|
||||
/* Already an absolute path */
|
||||
abs_path = file_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Relative path */
|
||||
char *cwd = __getcwd (NULL, 0);
|
||||
if (cwd == NULL)
|
||||
{
|
||||
__mach_port_deallocate (__mach_task_self (), file);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int res = __asprintf (&concat_name, "%s/%s", cwd, file_name);
|
||||
free (cwd);
|
||||
if (res == -1)
|
||||
{
|
||||
__mach_port_deallocate (__mach_task_self (), file);
|
||||
return -1;
|
||||
}
|
||||
|
||||
abs_path = concat_name;
|
||||
}
|
||||
|
||||
/* Hopefully this will not return. */
|
||||
err = _hurd_exec (__mach_task_self (), file, argv, envp);
|
||||
err = _hurd_exec_paths (__mach_task_self (), file,
|
||||
file_name, abs_path, argv, envp);
|
||||
|
||||
/* Oh well. Might as well be tidy. */
|
||||
__mach_port_deallocate (__mach_task_self (), file);
|
||||
free (concat_name);
|
||||
|
||||
return __hurd_fail (err);
|
||||
}
|
||||
|
@ -25,8 +25,9 @@
|
||||
int
|
||||
fexecve (int fd, char *const argv[], char *const envp[])
|
||||
{
|
||||
error_t err = HURD_DPORT_USE (fd, _hurd_exec (__mach_task_self (), port,
|
||||
argv, envp));
|
||||
error_t err = HURD_DPORT_USE (fd, _hurd_exec_paths (__mach_task_self (),
|
||||
port, NULL, NULL,
|
||||
argv, envp));
|
||||
if (! err)
|
||||
err = EGRATUITOUS;
|
||||
return __hurd_fail (err);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <spawn.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <hurd.h>
|
||||
#include <hurd/signal.h>
|
||||
@ -44,6 +45,8 @@ __spawni (pid_t *pid, const char *file,
|
||||
{
|
||||
pid_t new_pid;
|
||||
char *path, *p, *name;
|
||||
char *concat_name = NULL, *relpath, *abspath;
|
||||
int res;
|
||||
size_t len;
|
||||
size_t pathlen;
|
||||
short int flags;
|
||||
@ -59,14 +62,14 @@ __spawni (pid_t *pid, const char *file,
|
||||
that remains visible after an exec is registration with the proc
|
||||
server, and the inheritance of various values and ports. All those
|
||||
inherited values and ports are what get collected up and passed in the
|
||||
file_exec RPC by an exec call. So we do the proc server registration
|
||||
here, following the model of fork (see fork.c). We then collect up
|
||||
the inherited values and ports from this (parent) process following
|
||||
the model of exec (see hurd/hurdexec.c), modify or replace each value
|
||||
that fork would (plus the specific changes demanded by ATTRP and
|
||||
FILE_ACTIONS), and make the file_exec RPC on the requested executable
|
||||
file with the child process's task port rather than our own. This
|
||||
should be indistinguishable from the fork + exec implementation,
|
||||
file_exec_paths RPC by an exec call. So we do the proc server
|
||||
registration here, following the model of fork (see fork.c). We then
|
||||
collect up the inherited values and ports from this (parent) process
|
||||
following the model of exec (see hurd/hurdexec.c), modify or replace each
|
||||
value that fork would (plus the specific changes demanded by ATTRP and
|
||||
FILE_ACTIONS), and make the file_exec_paths RPC on the requested
|
||||
executable file with the child process's task port rather than our own.
|
||||
This should be indistinguishable from the fork + exec implementation,
|
||||
except that all errors will be detected here (in the parent process)
|
||||
and return proper errno codes rather than the child dying with 127.
|
||||
|
||||
@ -547,7 +550,7 @@ __spawni (pid_t *pid, const char *file,
|
||||
|
||||
if ((xflags & SPAWN_XFLAGS_USE_PATH) == 0 || strchr (file, '/') != NULL)
|
||||
/* The FILE parameter is actually a path. */
|
||||
err = child_lookup (file, O_EXEC, 0, &execfile);
|
||||
err = child_lookup (relpath = file, O_EXEC, 0, &execfile);
|
||||
else
|
||||
{
|
||||
/* We have to search for FILE on the path. */
|
||||
@ -608,6 +611,7 @@ __spawni (pid_t *pid, const char *file,
|
||||
}
|
||||
|
||||
// We only get here when we are done looking for the file.
|
||||
relpath = startp;
|
||||
break;
|
||||
}
|
||||
while (*p++ != '\0');
|
||||
@ -615,6 +619,26 @@ __spawni (pid_t *pid, const char *file,
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
if (relpath[0] == '/')
|
||||
{
|
||||
/* Already an absolute path */
|
||||
abspath = relpath;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Relative path */
|
||||
char *cwd = __getcwd (NULL, 0);
|
||||
if (cwd == NULL)
|
||||
goto out;
|
||||
|
||||
res = __asprintf (&concat_name, "%s/%s", cwd, relpath);
|
||||
free (cwd);
|
||||
if (res == -1)
|
||||
goto out;
|
||||
|
||||
abspath = concat_name;
|
||||
}
|
||||
|
||||
/* Almost there! */
|
||||
{
|
||||
mach_port_t ports[_hurd_nports];
|
||||
@ -624,14 +648,28 @@ __spawni (pid_t *pid, const char *file,
|
||||
|
||||
inline error_t exec (file_t file)
|
||||
{
|
||||
return __file_exec (file, task,
|
||||
(__sigismember (&_hurdsig_traced, SIGKILL)
|
||||
? EXEC_SIGTRAP : 0),
|
||||
args, argslen, env, envlen,
|
||||
dtable, MACH_MSG_TYPE_COPY_SEND, dtablesize,
|
||||
ports, MACH_MSG_TYPE_COPY_SEND, _hurd_nports,
|
||||
ints, INIT_INT_MAX,
|
||||
NULL, 0, NULL, 0);
|
||||
error_t err = __file_exec_paths
|
||||
(file, task,
|
||||
__sigismember (&_hurdsig_traced, SIGKILL) ? EXEC_SIGTRAP : 0,
|
||||
relpath, abspath, args, argslen, env, envlen,
|
||||
dtable, MACH_MSG_TYPE_COPY_SEND, dtablesize,
|
||||
ports, MACH_MSG_TYPE_COPY_SEND, _hurd_nports,
|
||||
ints, INIT_INT_MAX,
|
||||
NULL, 0, NULL, 0);
|
||||
|
||||
/* Fallback for backwards compatibility. This can just be removed
|
||||
when __file_exec goes away. */
|
||||
if (err == MIG_BAD_ID)
|
||||
return __file_exec (file, task,
|
||||
(__sigismember (&_hurdsig_traced, SIGKILL)
|
||||
? EXEC_SIGTRAP : 0),
|
||||
args, argslen, env, envlen,
|
||||
dtable, MACH_MSG_TYPE_COPY_SEND, dtablesize,
|
||||
ports, MACH_MSG_TYPE_COPY_SEND, _hurd_nports,
|
||||
ints, INIT_INT_MAX,
|
||||
NULL, 0, NULL, 0);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Now we are out of things that can fail before the file_exec RPC,
|
||||
@ -750,6 +788,8 @@ __spawni (pid_t *pid, const char *file,
|
||||
_hurd_port_free (dtable_cells[i], &ulink_dtable[i], dtable[i]);
|
||||
}
|
||||
|
||||
free (concat_name);
|
||||
|
||||
if (err)
|
||||
/* This hack canonicalizes the error code that we return. */
|
||||
err = (__hurd_fail (err), errno);
|
||||
|
Loading…
Reference in New Issue
Block a user