Processes

getppid#

Return the process ID of the current process’s parent.

getppid is a thin wrapper over the POSIX getppid(2) system call. It takes no arguments and returns an integer — the PID of whatever process forked (or execed into) the running program. Combined with $$ (the current process’s own PID), it is the standard way for a child to identify the process that spawned it.

Synopsis#

my $parent = getppid;

What you get back#

A positive integer — the PID of the parent process. On Linux this is 1 (init / systemd) once the original parent has exited and the child has been reparented; there is no special “orphaned” return value, the reparenting is transparent. Never returns undef or 0 on a supported platform; the underlying syscall is specified to always succeed.

Global state it touches#

None. getppid reads the kernel’s process table for the current process; it does not touch any Perl special variable. Note that $$ holds this process’s PID, not the parent’s — fetch the parent with getppid explicitly.

Examples#

Identify the parent that launched this script:

printf "my pid is %d, my parent is %d\n", $$, getppid;

Detect orphaning — a common idiom for daemons that want to exit when their controlling process goes away:

while (1) {
    last if getppid == 1;       # parent died, we've been reparented to init
    do_work();
    sleep 1;
}

Child process reports back to its parent after fork:

my $pid = fork // die "fork failed: $!";
if ($pid == 0) {
    warn "child $$ spawned by $>, parent is " . getppid . "\n";
    exit 0;
}
waitpid $pid, 0;

Compare before and after fork to confirm the relationship:

my $before = $$;
my $pid = fork // die $!;
if ($pid == 0) {
    die "parent mismatch" unless getppid == $before;
    exit;
}
waitpid $pid, 0;

Edge cases#

  • No arguments, no parentheses needed: getppid is a niladic built-in. Write getppid or getppid(); both parse identically. Do not try to pass a PID argument — unlike getpgrp, there is no “parent of another process” form.

  • Orphan reparenting is invisible: if the original parent exits, the kernel reparents the process (to init/systemd on Linux, or to the nearest ancestor with PR_SET_CHILD_SUBREAPER set). getppid silently starts returning the new parent’s PID. Code that caches the return value at startup and compares later is the standard way to detect this.

  • Race at startup: calling getppid extremely early, before the kernel has finished setting up the process, is not a concern in user Perl code — by the time the interpreter is running, the parent PID is stable.

  • PID wraparound: PIDs are recycled. A stored parent PID can, over long-running time, refer to a different process than the original parent even without reparenting. Use getppid == 1 (or the equivalent subreaper PID), not equality against a saved value, when the intent is “has my parent died?”.

  • Threads: since Perl 5.16 the Linux LinuxThreads workaround has been removed. getppid now always returns what the kernel reports for the current thread group.

Differences from upstream#

Fully compatible with upstream Perl 5.42.

See also#

  • $$ — the current process’s own PID; pair with getppid to log both ends of the parent/child relationship

  • fork — spawn a child process; the child’s getppid returns the forking process’s PID

  • waitpid — reap a specific child by PID; the mirror operation from the parent side

  • wait — reap any child; same parent-side operation, unspecified PID

  • getpgrp — process group ID rather than parent PID; related but distinct kernel concept

  • kill — send a signal to a PID, including one obtained from getppid (e.g. notifying the parent)