In POSIX, processes are “related” to each other through two basic hierarchies:
The hierarchy of parent and child processes.
The hierarchy of sessions and process groups.
User processes have a great deal of control over the latter, via setpgid and setsid, but they have very little control over the former—the parent process ID is set when a process is spawned and altered by the kernel when the parent exits (usually to PID 1), but otherwise it does not change. Reflecting on that, I’ve been wondering how important the parent–child relationship really is.
Here’s a summary of my understanding so far:
Parent–child relationships are clearly important from the perspective of the parent process, since various syscalls, like
waitandsetpgid, are only allowed on child processes.The session–group–process relationship is clearly important to all processes, both the session leader and other processes in the session, since syscalls like
killoperate on entire process groups,setpgidcan only be used to join a group in the same session, and all processes in a session’s foreground process group are sentSIGHUPif the session leader exits.What’s more, the two hierarchies are clearly related from the perspective of the parent, since
setsidonly affects new children andsetpgidcan only be used on children, but they seem essentially unrelated from the perspective of the child (since a parent process dying has no impact whatsoever on a process’s group or session).
Conspicuously absent, however, is any reason for a child process to care what its current parent is. Therefore, I have the following question: does the current value of getppid() have any importance whatsoever from the perspective of the child process, besides perhaps identifying whether or not its spawning process has exited?
To put the same question another way, imagine the same program is spawned twice, from the same parent, in two different ways:
The first child is spawned in the usual way, by
fork()followed shortly byexec().The second child is spawned indirectly: the parent process calls
fork(), and then the child also callsfork(), and it’s the grandchild process that callsexec(). The immediate child then exits, so the grandchild is orphaned, and its PPID is reassigned to PID 1.
In this hypothetical scenario, assuming all else is equal, do any reasonable programs have any reason to behave any differently? So far, my conclusion seems to be “no,” since the session is left unchanged, as are the process’s inherited file descriptors… but I’m not sure.
Note: I do not consider “acquiring the parent PID to communicate with it” to be a valid answer to that question, since orphaned programs cannot in general rely on their PPID to be set to 1 (some systems set orphaned processes’ PPID to some other value), so the only way to avoid a race condition is to acquire the parent process ID via a call to getpid() before forking, then to use that value in the child.