setpgrp#
Set the process group of a process.
setpgrp moves the process identified by PID into the process group
identified by PGRP. A PID of 0 means the current process; a
PGRP of 0 means “use PID as the new group id” — that is, make
the process a group leader. With no arguments it defaults to
setpgrp(0, 0), which makes the current process the leader of a new
process group whose id equals its own pid.
This is the Perl interface to the underlying
setpgid(2) / setpgrp(2) system call. It is
the building block for detaching a process from its controlling
terminal and for job-control schemes that want to send signals to a
whole group at once with kill.
Synopsis#
setpgrp PID, PGRP
setpgrp # same as setpgrp(0, 0)
What you get back#
1 on success, undef on failure with $!
set to the reason (commonly EPERM when the target process is not
the caller or a child of the caller, or ESRCH when no such process
exists). Check the return value — silently proceeding with a process
still in the old group is almost never what you want.
setpgrp(0, 0)
or die "setpgrp failed: $!";
Global state it touches#
$!— set to theerrnovalue on failure. Not touched on success.
Examples#
Detach the current process into a new process group of its own. This
is the classic first step of a daemonisation sequence, run after
fork and before closing the standard handles:
setpgrp(0, 0)
or die "setpgrp failed: $!";
Move a just-spawned child into its own group so that a SIGTERM sent
to the group kills the child and any grandchildren it spawns, without
touching the parent:
my $pid = fork // die "fork: $!";
if ($pid == 0) {
setpgrp(0, 0) or die "setpgrp: $!";
exec @cmd or die "exec: $!";
}
# parent: signal the whole group with a negative pid
kill 'TERM', -$pid;
Read the group id back after setting it, using getpgrp:
setpgrp(0, 0) or die $!;
my $pgid = getpgrp(0);
print "now leader of group $pgid\n";
Handle the portability failure mode — on a platform without the
underlying system call the function raises an exception rather than
returning undef:
eval { setpgrp(0, 0) };
if ($@) {
warn "no process-group support on this platform: $@";
}
Edge cases#
No arguments defaults to
(0, 0). Writingsetpgrp;is the same assetpgrp(0, 0)— make the current process a new group leader. The no-argument form is the portable form (see below).BSD 4.2 compatibility. The historical BSD 4.2
setpgrptook no arguments. Scripts that must run on such systems can only rely on thesetpgrp(0, 0)/setpgrp()forms; any other argument combination is non-portable.Raises, not returns
undef, on unsupported platforms. On a machine that implements neither POSIXsetpgid(2)nor BSDsetpgrp(2),setpgrpraises an exception. This is the one failure mode that does not go through$!— wrap inevalif you need to degrade gracefully.EPERMon cross-session moves. The kernel rejects attempts to move a process into a group in a different session, or to move a process that has already calledexec. Catch$!== EPERMand fall back rather than retrying.Signalling the whole group. Once a group is established,
kill SIG, -$pgiddeliversSIGto every process in the group. The negative-pid convention is a property ofkill, not ofsetpgrp— but it’s the reason you usually callsetpgrpin the first place.Not a session leader.
setpgrpchanges process group, not session. To detach from the controlling terminal entirely you needPOSIX::setsid, which creates a new session and a new group in one step.
Differences from upstream#
Fully compatible with upstream Perl 5.42.
See also#
getpgrp— read the current process group id; the obvious companion for verifying asetpgrpcall took effectPOSIX::setpgid— the POSIX-named wrapper around the same system call, preferred in new code because its argument order and semantics are unambiguous across platformsPOSIX::setsid— create a new session and a new process group in one call; use this, notsetpgrp, for full terminal detachmentfork— the call that almost always precedessetpgrp; a child that wants its own group callssetpgrp(0, 0)right afterforkreturns0kill— how you actually use a process group once you’ve built one:kill SIG, -$pgidsignals every member