From c97f0d998cae23472ea30564663a8612dcfb6f83 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sat, 28 May 2011 18:36:30 -0400 Subject: initial implementation of posix_spawn file actions are not yet implemented, but everything else should be mostly complete and roughly correct. --- src/process/posix_spawn.c | 65 ++++++++++++++++++++++++++ src/process/posix_spawn_file_actions_destroy.c | 9 ++++ src/process/posix_spawn_file_actions_init.c | 7 +++ src/process/posix_spawnattr_getflags.c | 7 +++ src/process/posix_spawnattr_getpgroup.c | 7 +++ src/process/posix_spawnattr_getsigdefault.c | 7 +++ src/process/posix_spawnattr_getsigmask.c | 7 +++ src/process/posix_spawnattr_setflags.c | 7 +++ src/process/posix_spawnattr_setpgroup.c | 7 +++ src/process/posix_spawnattr_setsigdefault.c | 7 +++ src/process/posix_spawnattr_setsigmask.c | 7 +++ src/process/posix_spawnp.c | 14 ++++++ 12 files changed, 151 insertions(+) create mode 100644 src/process/posix_spawn.c create mode 100644 src/process/posix_spawn_file_actions_destroy.c create mode 100644 src/process/posix_spawn_file_actions_init.c create mode 100644 src/process/posix_spawnattr_getflags.c create mode 100644 src/process/posix_spawnattr_getpgroup.c create mode 100644 src/process/posix_spawnattr_getsigdefault.c create mode 100644 src/process/posix_spawnattr_getsigmask.c create mode 100644 src/process/posix_spawnattr_setflags.c create mode 100644 src/process/posix_spawnattr_setpgroup.c create mode 100644 src/process/posix_spawnattr_setsigdefault.c create mode 100644 src/process/posix_spawnattr_setsigmask.c create mode 100644 src/process/posix_spawnp.c (limited to 'src') diff --git a/src/process/posix_spawn.c b/src/process/posix_spawn.c new file mode 100644 index 00000000..e718cee3 --- /dev/null +++ b/src/process/posix_spawn.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include "syscall.h" + +extern char **environ; + +int __posix_spawnx(pid_t *res, const char *path, + int (*exec)(const char *, char *const *), + const posix_spawn_file_actions_t *fa, + const posix_spawnattr_t *attr, char **argv, char **envp) +{ + pid_t pid; + sigset_t oldmask; + int i; + posix_spawnattr_t dummy_attr = { 0 }; + + if (!attr) attr = &dummy_attr; + + sigprocmask(SIG_BLOCK, (void *)(uint64_t []){-1}, &oldmask); + pid = __syscall(SYS_fork); + + if (pid) { + sigprocmask(SIG_SETMASK, &oldmask, 0); + if (pid < 0) return -pid; + *res = pid; + return 0; + } + + for (i=1; i<=64; i++) { + struct sigaction sa; + sigaction(i, 0, &sa); + if (sa.sa_handler!=SIG_IGN || sigismember(&attr->__def, i)) { + sa.sa_handler = SIG_DFL; + sigaction(i, &sa, 0); + } + } + + if ((attr->__flags&POSIX_SPAWN_SETPGROUP) && setpgid(0, attr->__pgrp)) + _exit(127); + + /* Use syscalls directly because pthread state is not consistent + * for making calls to the library wrappers... */ + if ((attr->__flags&POSIX_SPAWN_RESETIDS) && ( + __syscall(SYS_setgid, __syscall(SYS_getgid)) || + __syscall(SYS_setuid, __syscall(SYS_getuid)) )) + _exit(127); + + sigprocmask(SIG_SETMASK, (attr->__flags & POSIX_SPAWN_SETSIGMASK) + ? &attr->__mask : &oldmask, 0); + + if (envp) environ = envp; + exec(path, argv); + _exit(127); + + return 0; +} + +int posix_spawn(pid_t *res, const char *path, + const posix_spawn_file_actions_t *fa, + const posix_spawnattr_t *attr, char **argv, char **envp) +{ + return __posix_spawnx(res, path, execv, fa, attr, argv, envp); +} diff --git a/src/process/posix_spawn_file_actions_destroy.c b/src/process/posix_spawn_file_actions_destroy.c new file mode 100644 index 00000000..c2501ddf --- /dev/null +++ b/src/process/posix_spawn_file_actions_destroy.c @@ -0,0 +1,9 @@ +#include +#include + +int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *fa) +{ + // FIXME + free(fa->__actions); + return 0; +} diff --git a/src/process/posix_spawn_file_actions_init.c b/src/process/posix_spawn_file_actions_init.c new file mode 100644 index 00000000..89d5e127 --- /dev/null +++ b/src/process/posix_spawn_file_actions_init.c @@ -0,0 +1,7 @@ +#include + +int posix_spawn_file_actions_init(posix_spawn_file_actions_t *fa) +{ + fa->__actions = 0; + return 0; +} diff --git a/src/process/posix_spawnattr_getflags.c b/src/process/posix_spawnattr_getflags.c new file mode 100644 index 00000000..7353d24a --- /dev/null +++ b/src/process/posix_spawnattr_getflags.c @@ -0,0 +1,7 @@ +#include + +int posix_spawnattr_getflags(const posix_spawnattr_t *attr, short *flags) +{ + *flags = attr->__flags; + return 0; +} diff --git a/src/process/posix_spawnattr_getpgroup.c b/src/process/posix_spawnattr_getpgroup.c new file mode 100644 index 00000000..2c72e985 --- /dev/null +++ b/src/process/posix_spawnattr_getpgroup.c @@ -0,0 +1,7 @@ +#include + +int posix_spawnattr_getpgroup(const posix_spawnattr_t *attr, pid_t *pgrp) +{ + *pgrp = attr->__pgrp; + return 0; +} diff --git a/src/process/posix_spawnattr_getsigdefault.c b/src/process/posix_spawnattr_getsigdefault.c new file mode 100644 index 00000000..5f0dfb58 --- /dev/null +++ b/src/process/posix_spawnattr_getsigdefault.c @@ -0,0 +1,7 @@ +#include + +int posix_spawnattr_getsigdefault(const posix_spawnattr_t *attr, sigset_t *def) +{ + *def = attr->__def; + return 0; +} diff --git a/src/process/posix_spawnattr_getsigmask.c b/src/process/posix_spawnattr_getsigmask.c new file mode 100644 index 00000000..b4490756 --- /dev/null +++ b/src/process/posix_spawnattr_getsigmask.c @@ -0,0 +1,7 @@ +#include + +int posix_spawnattr_getsigmask(const posix_spawnattr_t *attr, sigset_t *mask) +{ + *mask = attr->__mask; + return 0; +} diff --git a/src/process/posix_spawnattr_setflags.c b/src/process/posix_spawnattr_setflags.c new file mode 100644 index 00000000..f750c040 --- /dev/null +++ b/src/process/posix_spawnattr_setflags.c @@ -0,0 +1,7 @@ +#include + +int posix_spawnattr_setflags(posix_spawnattr_t *attr, short flags) +{ + attr->__flags = flags; + return 0; +} diff --git a/src/process/posix_spawnattr_setpgroup.c b/src/process/posix_spawnattr_setpgroup.c new file mode 100644 index 00000000..f39596a6 --- /dev/null +++ b/src/process/posix_spawnattr_setpgroup.c @@ -0,0 +1,7 @@ +#include + +int posix_spawnattr_setpgroup(posix_spawnattr_t *attr, pid_t pgrp) +{ + attr->__pgrp = pgrp; + return 0; +} diff --git a/src/process/posix_spawnattr_setsigdefault.c b/src/process/posix_spawnattr_setsigdefault.c new file mode 100644 index 00000000..a6ddd4d8 --- /dev/null +++ b/src/process/posix_spawnattr_setsigdefault.c @@ -0,0 +1,7 @@ +#include + +int posix_spawnattr_setsigdefault(posix_spawnattr_t *attr, const sigset_t *def) +{ + attr->__def = *def; + return 0; +} diff --git a/src/process/posix_spawnattr_setsigmask.c b/src/process/posix_spawnattr_setsigmask.c new file mode 100644 index 00000000..6afbf876 --- /dev/null +++ b/src/process/posix_spawnattr_setsigmask.c @@ -0,0 +1,7 @@ +#include + +int posix_spawnattr_setsigmask(posix_spawnattr_t *attr, const sigset_t *mask) +{ + attr->__mask = *mask; + return 0; +} diff --git a/src/process/posix_spawnp.c b/src/process/posix_spawnp.c new file mode 100644 index 00000000..7434bb69 --- /dev/null +++ b/src/process/posix_spawnp.c @@ -0,0 +1,14 @@ +#include +#include + +int __posix_spawnx(pid_t *, const char *, + int (*)(const char *, char *const *), + const posix_spawn_file_actions_t *, + const posix_spawnattr_t *, char **, char **); + +int posix_spawnp(pid_t *res, const char *file, + const posix_spawn_file_actions_t *fa, + const posix_spawnattr_t *attr, char **argv, char **envp) +{ + return __posix_spawnx(res, file, execvp, fa, attr, argv, envp); +} -- cgit v1.2.1