How to check if the calling process is a fork

Is there a way or C api on Linux / POSIX to determine if the current process is a fork? That is, if it was created by a call fork()without a subsequent call to the family execve()?

I do not control the code leading to this point (it runs in a high-level language binding). I just need to know if the top-level program is working in the current process or in its plug.

The best I came up with is testing if the process has the same gid as the parent:

int is_fork = getpgid(0) == getpgid(getppid());

However, this only works if the parent called setpgid(), which apparently execve()does not execute by default. This leads to many false positives.

+4
source share
4 answers

On Linux, one rather inaccurate check is to see if the process executable ( /proc/$pid/exe) is the same as its parent. However, this will not work if the process exechas its own executable file, which can be distributed in some environments (for example, shells).

+1
source

Perhaps you can use tms_utime, tms_stime, tms_cutimeor tms_cstime(see. Http://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html ). These variables are set to 0in the child process.

untested

0
source

, LD_PRELOAD , pthread_atfork, , . , , exec.

0
/* ppid.c
cc -Wall ppid.c -o ppid
 */

#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv)
{
int pid, ppid, pgid;

pid = getpid();
ppid = getppid();
pgid = getpgid(0);

printf("[%s] Pid=%d Ppid=%d Pgid=%d\n"
        , argv[0], pid, ppid, pgid);

return 0;
}

/* testppid.c
cc -Wall testppid.c -c testppid
*/

#include <stdio.h>
#include <unistd.h>

int main(void)
{
int pid, pid2; 

pid = fork();
if (pid == -1) return 1;

if (pid) { /* parent */
        char *args[] = { "Parent", NULL};
        sleep(3);
        execve("./ppid", args, NULL);
} else { /* child */

        pid = getpid();
        setpgid(pid,pid);
        pid2 = fork();
        if (pid2 == -1) return 1;

        if (pid2) { /* child1 */
                char *args[] = { "Child1", NULL};
                sleep(2);
                execve("./ppid", args, NULL);

        } else { /* grandchild */
                char *args[] = { "Child2", NULL};
                sleep(1);
                execve("./ppid", args, NULL);
                }
        }

return 0;
}

:


$ ./testppid
[Child2] Pid=6220 Ppid=6219 Pgid=6219
[Child1] Pid=6219 Ppid=6218 Pgid=6219
[Parent] Pid=6218 Ppid=27410 Pgid=6218
$

, (pid = 27410) , Child1, Child2: {fork, setpgid, exec}. Child1 Child2 ()

-1

Source: https://habr.com/ru/post/1669459/


All Articles