summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/skalibs/posixplz.h1
-rw-r--r--src/libposixplz/fork_newpid.c67
-rw-r--r--src/sysdeps/tryclonenewpid.c36
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 ;
+}