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. --- include/spawn.h | 67 ++++++++++++++++++++++++++ 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 ++++++ 13 files changed, 218 insertions(+) create mode 100644 include/spawn.h 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 diff --git a/include/spawn.h b/include/spawn.h new file mode 100644 index 00000000..1bcb1bbf --- /dev/null +++ b/include/spawn.h @@ -0,0 +1,67 @@ +#ifndef _SPAWN_H +#define _SPAWN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define __NEED_mode_t +#define __NEED_pid_t +#define __NEED_sigset_t + +#include + +struct sched_param; + +#define POSIX_SPAWN_RESETIDS 1 +#define POSIX_SPAWN_SETPGROUP 2 +#define POSIX_SPAWN_SETSIGDEF 4 +#define POSIX_SPAWN_SETSIGMASK 8 +#define POSIX_SPAWN_SETSCHEDPARAM 16 +#define POSIX_SPAWN_SETSCHEDULER 32 + +typedef struct { + int __flags; + pid_t __pgrp; + sigset_t __def, __mask; + int __prio, __pol, __pad[16]; +} posix_spawnattr_t; + +typedef struct { + int __pad0[2]; + void *__actions; + int __pad[16]; +} posix_spawn_file_actions_t; + +int posix_spawn(pid_t *, const char *, const posix_spawn_file_actions_t *, + const posix_spawnattr_t *, char **, char **); +int posix_spawnp(pid_t *, const char *, const posix_spawn_file_actions_t *, + const posix_spawnattr_t *, char **, char **); + +int posix_spawnattr_init(posix_spawnattr_t *); +int posix_spawnattr_destroy(posix_spawnattr_t *); + +int posix_spawnattr_setflags(posix_spawnattr_t *, short); +int posix_spawnattr_getflags(const posix_spawnattr_t *, short *); + +int posix_spawnattr_setpgroup(posix_spawnattr_t *, pid_t); +int posix_spawnattr_getpgroup(const posix_spawnattr_t *, pid_t *); + +int posix_spawnattr_setsigmask(posix_spawnattr_t *, const sigset_t *); +int posix_spawnattr_getsigmask(const posix_spawnattr_t *, sigset_t *); + +int posix_spawnattr_setsigdefault(posix_spawnattr_t *, const sigset_t *); +int posix_spawnattr_getsigdefault(const posix_spawnattr_t *, sigset_t *); + +int posix_spawn_file_actions_init(posix_spawn_file_actions_t *); +int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *); + +int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t *, int, const char *, int, mode_t); +int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *, int); +int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *, int, int); + +#ifdef __cplusplus +} +#endif + +#endif 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