raw-clone: beef up raw_clone() wrapper a bit

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.
This commit is contained in:
Lennart Poettering 2017-12-29 16:45:04 +01:00
parent 3139096321
commit 799a960d1f
3 changed files with 24 additions and 21 deletions

View 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;
}

View 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);

View file

@ -30,28 +30,27 @@
* 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;
}