#include #include #include #include #include #include #define CLONE_NEWPID 0x20000000 #ifndef __NR_gettid #ifdef __x86__ #define __NR_gettid 224 #elif __s390__ #define __NR_gettid 236 #else #error __NR_gettid undefined #endif #endif #ifndef __NR_clone_with_pids #ifdef __x86__ #define __NR_clone_with_pids 335 #elif __s390__ #define __NR_clone_with_pids 332 #else #error __NR_clone_with_pids undefined #endif #endif /* * TODO: getpid() in child returns pid of parent for some reason gettid() * returns correct pid (i.e 1 if CLONE_NEWPID or 19799 otherwise) */ int gettid() { int rc; rc = syscall(__NR_gettid, 0, 0, 0); if (rc < 0) { printf("rc %d, errno %d\n", rc, errno); fflush(stdout); } return rc; } struct target_pid_set { int num_pids; pid_t *target_pids; unsigned long flags; }; main() { int rc; int clone_flags; struct target_pid_set pid_set; int stacksize = 4 * getpagesize(); void *childsp, *topstack; int pids[1] = { 19799 }; childsp = malloc(stacksize); if (!childsp) return -1; topstack = childsp + stacksize; pid_set.num_pids = 1; pid_set.target_pids = &pids[0]; pid_set.flags = 0; //clone_flags = (CLONE_NEWPID| CLONE_FS | CLONE_FILES | SIGCHLD); clone_flags = ( CLONE_FS | CLONE_FILES | SIGCHLD); printf("Parent: Call clone_with_pids() for &pid_set %p\n", &pid_set); rc = syscall(__NR_clone_with_pids, topstack, clone_flags, NULL, NULL, &pid_set); //NULL, NULL); if (rc == 0) { printf("Child: tid %d\n", gettid()); _exit(0); } else if (rc > 0) { printf("Parent: child pid %d\n", rc); _exit(0); } else { printf("myclone() failed, rc %d, errno %d\n", rc, errno); } }