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:
parent
3139096321
commit
799a960d1f
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue