--- name: setpgrp signature: 'setpgrp PID,PGRP' since: 5.0 status: documented categories: ["Processes"] --- ```{index} single: setpgrp; Perl built-in ``` *[Processes](../perlfunc-by-category)* # 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)`](../../POSIX/setpgid) / `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`](kill). ## Synopsis ```perl setpgrp PID, PGRP setpgrp # same as setpgrp(0, 0) ``` ## What you get back `1` on success, [`undef`](undef) on failure with [`$!`](../perlvar) 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. ```perl setpgrp(0, 0) or die "setpgrp failed: $!"; ``` ## Global state it touches - [`$!`](../perlvar) — set to the `errno` value 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`](fork) and before closing the standard handles: ```perl 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: ```perl 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`](getpgrp): ```perl 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`](undef): ```perl eval { setpgrp(0, 0) }; if ($@) { warn "no process-group support on this platform: $@"; } ``` ## Edge cases - **No arguments defaults to `(0, 0)`**. Writing `setpgrp;` is the same as `setpgrp(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 `setpgrp` took no arguments. Scripts that must run on such systems can only rely on the `setpgrp(0, 0)` / `setpgrp()` forms; any other argument combination is non-portable. - **Raises, not returns `undef`, on unsupported platforms**. On a machine that implements neither POSIX `setpgid(2)` nor BSD `setpgrp(2)`, `setpgrp` raises an exception. This is the one failure mode that does **not** go through [`$!`](../perlvar) — wrap in [`eval`](eval) if you need to degrade gracefully. - **`EPERM` on 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 called [`exec`](exec). Catch [`$!`](../perlvar) `== EPERM` and fall back rather than retrying. - **Signalling the whole group**. Once a group is established, `kill SIG, -$pgid` delivers `SIG` to every process in the group. The negative-pid convention is a property of [`kill`](kill), not of `setpgrp` — but it's the reason you usually call `setpgrp` in the first place. - **Not a session leader**. `setpgrp` changes process group, not session. To detach from the controlling terminal entirely you need `POSIX::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`](getpgrp) — read the current process group id; the obvious companion for verifying a `setpgrp` call took effect - [`POSIX::setpgid`](../../POSIX/setpgid) — the POSIX-named wrapper around the same system call, preferred in new code because its argument order and semantics are unambiguous across platforms - `POSIX::setsid` — create a new session *and* a new process group in one call; use this, not `setpgrp`, for full terminal detachment - [`fork`](fork) — the call that almost always precedes `setpgrp`; a child that wants its own group calls `setpgrp(0, 0)` right after `fork` returns `0` - [`kill`](kill) — how you actually use a process group once you've built one: `kill SIG, -$pgid` signals every member