diff options
author | Lennart Poettering <lennart@poettering.net> | 2018-02-26 20:50:57 +0100 |
---|---|---|
committer | Sven Eden <yamakuzure@gmx.net> | 2018-05-30 07:59:08 +0200 |
commit | d177b5ffe6a5a5273d8e075dca1716cc926839c4 (patch) | |
tree | a4f95ca5a362aff548c038c6f908c721560c78b4 /src | |
parent | ecc6cb9a01b132b88cdf20272573c142eeb84e8b (diff) |
process-util: don't install atfork() handler more than once
Diffstat (limited to 'src')
-rw-r--r-- | src/basic/process-util.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/src/basic/process-util.c b/src/basic/process-util.c index 03d42c07d..1ebfb0c72 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -1180,6 +1180,7 @@ extern void* __dso_handle __attribute__ ((__weak__)); #endif // ifdef __GLIBC__ pid_t getpid_cached(void) { + static bool installed = false; pid_t current_value; /* getpid_cached() is much like getpid(), but caches the value in local memory, to avoid having to invoke a @@ -1200,10 +1201,18 @@ pid_t getpid_cached(void) { new_pid = raw_getpid(); - if (__register_atfork(NULL, NULL, reset_cached_pid, __dso_handle) != 0) { - /* OOM? Let's try again later */ - cached_pid = CACHED_PID_UNSET; - return new_pid; + if (!installed) { + /* __register_atfork() either returns 0 or -ENOMEM, in its glibc implementation. Since it's + * only half-documented (glibc doesn't document it but LSB does — though only superficially) + * we'll check for errors only in the most generic fashion possible. */ + + if (__register_atfork(NULL, NULL, reset_cached_pid, __dso_handle) != 0) { + /* OOM? Let's try again later */ + cached_pid = CACHED_PID_UNSET; + return new_pid; + } + + installed = true; } cached_pid = new_pid; |