mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-09 23:00:07 +00:00
hurd: Add __rtld_execve
It trivially execs with the same dtable, portarray and intarray, and only has to take care of deallocating / destroying ports (file, notably).
This commit is contained in:
parent
84a9d5835a
commit
54dda2cdba
19
sysdeps/mach/hurd/dl-execve.h
Normal file
19
sysdeps/mach/hurd/dl-execve.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/* execve for the dynamic linker. Hurd version.
|
||||||
|
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, see
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
extern int __rtld_execve (const char *path, char *const *argv, char *const *envp);
|
@ -30,6 +30,7 @@
|
|||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <sysdep.h>
|
#include <sysdep.h>
|
||||||
|
#include <argz.h>
|
||||||
#include <mach/mig_support.h>
|
#include <mach/mig_support.h>
|
||||||
#include <mach/machine/vm_param.h>
|
#include <mach/machine/vm_param.h>
|
||||||
#include "hurdstartup.h"
|
#include "hurdstartup.h"
|
||||||
@ -291,7 +292,8 @@ open_file (const char *file_name, int flags,
|
|||||||
return MACH_PORT_NULL;
|
return MACH_PORT_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert (!(flags & ~(O_READ | O_CLOEXEC)));
|
assert (!(flags & ~(O_READ | O_EXEC | O_CLOEXEC)));
|
||||||
|
flags &= ~O_CLOEXEC;
|
||||||
|
|
||||||
startdir = _dl_hurd_data->portarray[file_name[0] == '/'
|
startdir = _dl_hurd_data->portarray[file_name[0] == '/'
|
||||||
? INIT_PORT_CRDIR : INIT_PORT_CWDIR];
|
? INIT_PORT_CRDIR : INIT_PORT_CWDIR];
|
||||||
@ -299,7 +301,7 @@ open_file (const char *file_name, int flags,
|
|||||||
while (file_name[0] == '/')
|
while (file_name[0] == '/')
|
||||||
file_name++;
|
file_name++;
|
||||||
|
|
||||||
err = __dir_lookup (startdir, (char *)file_name, O_RDONLY, 0,
|
err = __dir_lookup (startdir, (char *)file_name, flags, 0,
|
||||||
&doretry, retryname, port);
|
&doretry, retryname, port);
|
||||||
|
|
||||||
if (!err)
|
if (!err)
|
||||||
@ -558,6 +560,109 @@ __access_noerrno (const char *file, int type)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
__rtld_execve (const char *file_name, char *const argv[],
|
||||||
|
char *const envp[])
|
||||||
|
{
|
||||||
|
file_t file;
|
||||||
|
error_t err;
|
||||||
|
char *args, *env;
|
||||||
|
size_t argslen, envlen;
|
||||||
|
mach_port_t *ports = _dl_hurd_data->portarray;
|
||||||
|
unsigned int portarraysize = _dl_hurd_data->portarraysize;
|
||||||
|
file_t *dtable = _dl_hurd_data->dtable;
|
||||||
|
unsigned int dtablesize = _dl_hurd_data->dtablesize;
|
||||||
|
int *intarray = _dl_hurd_data->intarray;
|
||||||
|
unsigned int i, j;
|
||||||
|
mach_port_t *please_dealloc, *pdp;
|
||||||
|
mach_port_t *portnames = NULL;
|
||||||
|
mach_msg_type_number_t nportnames = 0;
|
||||||
|
mach_port_type_t *porttypes = NULL;
|
||||||
|
mach_msg_type_number_t nporttypes = 0;
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
err = open_file (file_name, O_EXEC, &file, NULL);
|
||||||
|
if (err)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (argv == NULL)
|
||||||
|
args = NULL, argslen = 0;
|
||||||
|
else if (err = __argz_create (argv, &args, &argslen))
|
||||||
|
goto outfile;
|
||||||
|
if (envp == NULL)
|
||||||
|
env = NULL, envlen = 0;
|
||||||
|
else if (err = __argz_create (envp, &env, &envlen))
|
||||||
|
goto outargs;
|
||||||
|
|
||||||
|
please_dealloc = __alloca ((portarraysize + dtablesize)
|
||||||
|
* sizeof (mach_port_t));
|
||||||
|
pdp = please_dealloc;
|
||||||
|
|
||||||
|
/* Get all ports that we may not know about and we should thus destroy. */
|
||||||
|
err = __mach_port_names (__mach_task_self (),
|
||||||
|
&portnames, &nportnames,
|
||||||
|
&porttypes, &nporttypes);
|
||||||
|
if (err)
|
||||||
|
goto outenv;
|
||||||
|
if (nportnames != nporttypes)
|
||||||
|
{
|
||||||
|
err = EGRATUITOUS;
|
||||||
|
goto outenv;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < portarraysize; ++i)
|
||||||
|
{
|
||||||
|
*pdp++ = ports[i];
|
||||||
|
for (j = 0; j < nportnames; j++)
|
||||||
|
if (portnames[j] == ports[i])
|
||||||
|
portnames[j] = MACH_PORT_NULL;
|
||||||
|
}
|
||||||
|
for (i = 0; i < dtablesize; ++i)
|
||||||
|
{
|
||||||
|
*pdp++ = dtable[i];
|
||||||
|
for (j = 0; j < nportnames; j++)
|
||||||
|
if (portnames[j] == dtable[i])
|
||||||
|
portnames[j] = MACH_PORT_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pack ports to be destroyed together. */
|
||||||
|
for (i = 0, j = 0; i < nportnames; i++)
|
||||||
|
{
|
||||||
|
if (portnames[i] == MACH_PORT_NULL)
|
||||||
|
continue;
|
||||||
|
if (j != i)
|
||||||
|
portnames[j] = portnames[i];
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
nportnames = j;
|
||||||
|
|
||||||
|
flags = 0;
|
||||||
|
#ifdef EXEC_SIGTRAP
|
||||||
|
if (__sigismember (&intarray[INIT_TRACEMASK], SIGKILL))
|
||||||
|
flags |= EXEC_SIGTRAP;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
err = __file_exec_paths (file, __mach_task_self (), flags,
|
||||||
|
file_name, file_name[0] == '/' ? file_name : "",
|
||||||
|
args, argslen,
|
||||||
|
env, envlen,
|
||||||
|
dtable, MACH_MSG_TYPE_COPY_SEND, dtablesize,
|
||||||
|
ports, MACH_MSG_TYPE_COPY_SEND, portarraysize,
|
||||||
|
intarray, INIT_INT_MAX,
|
||||||
|
please_dealloc, pdp - please_dealloc,
|
||||||
|
portnames, nportnames);
|
||||||
|
|
||||||
|
/* Oh well. Might as well be tidy. */
|
||||||
|
outenv:
|
||||||
|
free (env);
|
||||||
|
outargs:
|
||||||
|
free (args);
|
||||||
|
outfile:
|
||||||
|
__mach_port_deallocate (__mach_task_self (), file);
|
||||||
|
out:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
check_no_hidden(__getpid);
|
check_no_hidden(__getpid);
|
||||||
pid_t weak_function
|
pid_t weak_function
|
||||||
__getpid (void)
|
__getpid (void)
|
||||||
|
Loading…
Reference in New Issue
Block a user