Processes

getpgrp#

Return the POSIX process-group ID that a process belongs to.

Every Unix process is a member of exactly one process group, which in turn belongs to a session. Process groups are how the kernel addresses related processes as a unit — most visibly, they are the unit that receives a signal from the controlling terminal (SIGINT on Ctrl-C, SIGTSTP on Ctrl-Z). getpgrp asks the kernel for the group ID of a given process; with no argument or a PID of 0 it answers for the current process.

Synopsis#

getpgrp
getpgrp PID
getpgrp 0

What you get back#

A non-negative integer — the process-group ID in scalar context. Process-group IDs share the PID numbering space, and the group leader’s PID equals the group ID, so the value returned by getpgrp 0 is the PID of the current process’s group leader.

On a system that does not implement getpgrp(2) at all, the call raises a fatal exception. That is vanishingly rare on modern Unix; Linux, the BSDs, macOS, and Solaris all support it.

Global state it touches#

None. getpgrp reads kernel state for the named process and sets $! only on failure (which, on a POSIX system, means “no such process” for a non-zero PID that does not exist).

Examples#

Get the current process’s own group:

my $pgid = getpgrp;
print "my group is $pgid\n";

PID of 0 means “myself” and is the portable form — some very old systems do not accept any other value:

my $pgid = getpgrp 0;                 # same as getpgrp with no args

Detect whether the current process is its own group leader — the usual test a daemon runs before calling setpgrp or POSIX::setsid to detach from its controlling terminal:

if (getpgrp(0) == $$) {
    print "already a group leader\n";
}
else {
    print "group leader is ", getpgrp(0), "\n";
}

Look up another process’s group, e.g. a child just returned by fork:

my $pid = fork // die "fork: $!";
if ($pid == 0) {
    # child
    exec @cmd;
}
print "child $pid is in group ", getpgrp($pid), "\n";

Send a signal to every member of a process group. kill with a negative PID targets the group, and getpgrp is how you discover the group ID to negate:

my $grp = getpgrp($child);
kill 'TERM', -$grp;                   # SIGTERM to the whole group

Edge cases#

  • Omitted argument equals PID of 0: getpgrp and getpgrp 0 both report the current process’s group. Prefer the explicit 0 form when portability to historical systems matters.

  • Non-existent PID: returns undef and sets $! to "No such process" (ESRCH). Check $!, not the return value’s truthiness — a legitimate group ID of 0 is falsy in Perl but is not an error condition (it is, on Linux, the idle/swapper group).

  • Not-permitted lookups: on systems that restrict cross-session lookups, querying a PID in a different session can fail with $! set to "Operation not permitted" (EPERM). This is unusual on Linux, where any process may query any PID’s group.

  • getpgrp vs. getpgrp PID: the BSD-style one-argument form was not portable to all Unixes historically; POSIX standardised both. On the platforms pperl runs on (Linux, all cranelift targets), both forms work.

  • Signed vs. unsigned: the kernel’s PID type is signed, so the returned value fits comfortably in a Perl integer. A return of -1 is not used for success on any platform pperl targets; treat -1 as the error sentinel only if you are porting code from a C codebase that checked it that way.

  • Not a shell alias for job control: the shell’s jobs and % notation operate on job tables the shell keeps, not on kernel process groups directly. getpgrp tells you the kernel truth, which can drift from a subshell’s idea of the job tree.

Differences from upstream#

Fully compatible with upstream Perl 5.42.

See also#

  • setpgrp — put a process into a new or existing group; the write counterpart to getpgrp

  • getppid — parent process ID; often wanted alongside the group ID when walking process relationships

  • getpriority — read scheduling priority, which also accepts a process-group selector (PRIO_PGRP)

  • fork — the child inherits its parent’s process group, so getpgrp on a fresh child reports the parent’s group until a setpgrp call changes it

  • killkill SIGNAL, -$pgid signals every member of the group; getpgrp is how you find $pgid

  • $$ — current PID; equal to getpgrp(0) when the process is its own group leader