diff options
| -rw-r--r-- | include/spawn.h | 67 | ||||
| -rw-r--r-- | src/process/posix_spawn.c | 65 | ||||
| -rw-r--r-- | src/process/posix_spawn_file_actions_destroy.c | 9 | ||||
| -rw-r--r-- | src/process/posix_spawn_file_actions_init.c | 7 | ||||
| -rw-r--r-- | src/process/posix_spawnattr_getflags.c | 7 | ||||
| -rw-r--r-- | src/process/posix_spawnattr_getpgroup.c | 7 | ||||
| -rw-r--r-- | src/process/posix_spawnattr_getsigdefault.c | 7 | ||||
| -rw-r--r-- | src/process/posix_spawnattr_getsigmask.c | 7 | ||||
| -rw-r--r-- | src/process/posix_spawnattr_setflags.c | 7 | ||||
| -rw-r--r-- | src/process/posix_spawnattr_setpgroup.c | 7 | ||||
| -rw-r--r-- | src/process/posix_spawnattr_setsigdefault.c | 7 | ||||
| -rw-r--r-- | src/process/posix_spawnattr_setsigmask.c | 7 | ||||
| -rw-r--r-- | src/process/posix_spawnp.c | 14 | 
13 files changed, 218 insertions, 0 deletions
| 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 <bits/alltypes.h> + +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 <spawn.h> +#include <unistd.h> +#include <signal.h> +#include <stdint.h> +#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 <spawn.h> +#include <stdlib.h> + +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 <spawn.h> + +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 <spawn.h> + +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 <spawn.h> + +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 <spawn.h> + +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 <spawn.h> + +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 <spawn.h> + +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 <spawn.h> + +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 <spawn.h> + +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 <spawn.h> + +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 <spawn.h> +#include <unistd.h> + +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); +} | 
