diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/include/skalibs/posixplz.h | 1 | ||||
-rw-r--r-- | src/libposixplz/fork_newpid.c | 67 | ||||
-rw-r--r-- | src/sysdeps/tryclonenewpid.c | 36 |
3 files changed, 104 insertions, 0 deletions
diff --git a/src/include/skalibs/posixplz.h b/src/include/skalibs/posixplz.h index daf9cdd..c990379 100644 --- a/src/include/skalibs/posixplz.h +++ b/src/include/skalibs/posixplz.h @@ -37,6 +37,7 @@ extern void execvep_loose (char const *, char const *const *, char const *const extern void unlink_void (char const *) ; extern void munmap_void (void *, size_t) ; extern pid_t doublefork (void) ; +extern pid_t fork_newpid (void) ; extern int touch (char const *) ; extern int mkfiletemp (char *, create_func_ref, mode_t, void *) ; diff --git a/src/libposixplz/fork_newpid.c b/src/libposixplz/fork_newpid.c new file mode 100644 index 0000000..7887b53 --- /dev/null +++ b/src/libposixplz/fork_newpid.c @@ -0,0 +1,67 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> + +#ifdef SKALIBS_HASCLONENEWPID + +#include <skalibs/nonposix.h> + +#include <sys/syscall.h> +#include <stdint.h> +#include <unistd.h> +#include <signal.h> +#include <sched.h> +#include <errno.h> + +#include <skalibs/uint64.h> + +struct clone_args +{ + uint64_t flags ; + uint64_t pidfd ; + uint64_t child_tid ; + uint64_t parent_tid ; + uint64_t exit_signal ; + uint64_t stack ; + uint64_t stack_size ; + uint64_t tls ; + uint64_t set_tid ; + uint64_t set_tid_size ; + uint64_t cgroup ; +} ; + +pid_t fork_newpid (void) +{ + pid_t pid ; + pid_t settid = 1 ; + struct clone_args args = + { + .flags = CLONE_NEWPID | CLONE_PARENT_SETTID, + .pidfd = 0, + .child_tid = 0, + .parent_tid = (uint64_t)&pid, + .exit_signal = SIGCHLD, + .stack = 0, + .stack_size = 0, + .tls = 0, + .set_tid = (uint64_t)&settid, + .set_tid_size = 1, + .cgroup = 0 + } ; + long r = syscall(SYS_clone3, &args, sizeof(args)) ; + if (r < 0) return (errno = -r, -1) ; + return r ? pid : 0 ; +} + +#else + +#include <unistd.h> +#include <errno.h> + +pid_t fork_newpid (void) +{ + errno = ENOSYS ; + return -1 ; +} + +#endif diff --git a/src/sysdeps/tryclonenewpid.c b/src/sysdeps/tryclonenewpid.c new file mode 100644 index 0000000..1a1401a --- /dev/null +++ b/src/sysdeps/tryclonenewpid.c @@ -0,0 +1,36 @@ +/* ISC license. */ + +#undef _POSIX_C_SOURCE +#undef _XOPEN_SOURCE + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include <sched.h> +#include <sys/syscall.h> +#include <stdint.h> +#include <unistd.h> + +struct clone_args +{ + uint64_t flags ; + uint64_t pidfd ; + uint64_t child_tid ; + uint64_t parent_tid ; + uint64_t exit_signal ; + uint64_t stack ; + uint64_t stack_size ; + uint64_t tls ; + uint64_t set_tid ; + uint64_t set_tid_size ; + uint64_t cgroup ; +} ; + +int main (void) +{ + struct clone_args args = { 0 } ; + args.flags = CLONE_NEWPID ; + syscall(SYS_clone3, &args, sizeof(struct clone_args)) ; + return 0 ; +} |