]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
raw-clone: beef up raw_clone() wrapper a bit
authorLennart Poettering <lennart@poettering.net>
Fri, 29 Dec 2017 15:45:04 +0000 (16:45 +0100)
committerLennart Poettering <lennart@poettering.net>
Thu, 4 Jan 2018 12:27:26 +0000 (13:27 +0100)
First of all, let's return pid_t, which appears to be the correct type
given that we return PIDs, and it#s what fork() uses too.

Most importantly though, flush out our PID cache, so that the call
becomes compatible with our getpid_cached() logic.

src/basic/process-util.c
src/basic/process-util.h
src/basic/raw-clone.h

index 7da22f4a9dba021c2011b199ee4d94672ffd327f..9a42ce34fc4119452f3f3c5f9d7afbbf577d88f7 100644 (file)
@@ -1083,7 +1083,7 @@ int ioprio_parse_priority(const char *s, int *ret) {
 
 static pid_t cached_pid = CACHED_PID_UNSET;
 
-static void reset_cached_pid(void) {
+void reset_cached_pid(void) {
         /* Invoked in the child after a fork(), i.e. at the first moment the PID changed */
         cached_pid = CACHED_PID_UNSET;
 }
index b20e527af77a3acbb5b2b8354472e2179a95ae57..fa58c69464d880561c3e6499bbc4e6690c4642dd 100644 (file)
@@ -147,6 +147,7 @@ static inline int sched_policy_to_string_alloc_with_check(int n, char **s) {
 int ioprio_parse_priority(const char *s, int *ret);
 
 pid_t getpid_cached(void);
+void reset_cached_pid(void);
 
 int must_be_root(void);
 
index f01b73a8feb0bc54637cebacecaff9977d3739d9..8c95380305cd502dbc847130c66e08a03b1dad4e 100644 (file)
  * raw_clone() - uses clone to create a new process with clone flags
  * @flags: Flags to pass to the clone system call
  *
- * Uses the clone system call to create a new process with the cloning
- * flags and termination signal passed in the flags parameter. Opposed
- * to glibc's clone funtion, using this function does not set up a
- * separate stack for the child, but relies on copy-on-write semantics
- * on the one stack at a common virtual address, just as fork does.
+ * Uses the clone system call to create a new process with the cloning flags and termination signal passed in the flags
+ * parameter. Opposed to glibc's clone funtion, using this function does not set up a separate stack for the child, but
+ * relies on copy-on-write semantics on the one stack at a common virtual address, just as fork does.
  *
- * To obtain copy-on-write semantics, flags must not contain CLONE_VM,
- * and thus CLONE_THREAD and CLONE_SIGHAND (which require CLONE_VM) are
- * not usabale.
- * Additionally, as this function does not pass the ptid, newtls and ctid
- * parameters to the kernel, flags must not contain CLONE_PARENT_SETTID,
- * CLONE_CHILD_SETTID, CLONE_CHILD_CLEARTID or CLONE_SETTLS.
+ * To obtain copy-on-write semantics, flags must not contain CLONE_VM, and thus CLONE_THREAD and CLONE_SIGHAND (which
+ * require CLONE_VM) are not usable.
+ *
+ * Additionally, as this function does not pass the ptid, newtls and ctid parameters to the kernel, flags must not
+ * contain CLONE_PARENT_SETTID, CLONE_CHILD_SETTID, CLONE_CHILD_CLEARTID or CLONE_SETTLS.
  *
  * Returns: 0 in the child process and the child process id in the parent.
  */
-static inline int raw_clone(unsigned long flags) {
+static inline pid_t raw_clone(unsigned long flags) {
+        pid_t ret;
+
         assert((flags & (CLONE_VM|CLONE_PARENT_SETTID|CLONE_CHILD_SETTID|
                          CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0);
 #if defined(__s390x__) || defined(__s390__) || defined(__CRIS__)
         /* On s390/s390x and cris the order of the first and second arguments
          * of the raw clone() system call is reversed. */
-        return (int) syscall(__NR_clone, NULL, flags);
+        ret = (pid_t) syscall(__NR_clone, NULL, flags);
 #elif defined(__sparc__) && defined(__arch64__)
         {
                 /**
@@ -60,8 +59,8 @@ static inline int raw_clone(unsigned long flags) {
                  * %o1. Inline assembly is needed to get the flag returned
                  * in %o1.
                  */
-                int in_child;
-                int child_pid;
+                int in_child, child_pid;
+
                 asm volatile("mov %2, %%g1\n\t"
                              "mov %3, %%o0\n\t"
                              "mov 0 , %%o1\n\t"
@@ -71,12 +70,15 @@ static inline int raw_clone(unsigned long flags) {
                              "=r"(in_child), "=r"(child_pid) :
                              "i"(__NR_clone), "r"(flags) :
                              "%o1", "%o0", "%g1" );
-                if (in_child)
-                        return 0;
-                else
-                        return child_pid;
+
+                ret = in_child ? 0 : child_pid;
         }
 #else
-        return (int) syscall(__NR_clone, flags, NULL);
+        ret = (pid_t) syscall(__NR_clone, flags, NULL);
 #endif
+
+        if (ret == 0)
+                reset_cached_pid();
+
+        return ret;
 }