*[Processes](../perlfunc-by-category.md)* # 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.md) / `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.md). ## Synopsis ```perl setpgrp PID, PGRP setpgrp # same as setpgrp(0, 0) ``` ## What you get back `1` on success, [`undef`](undef.md) on failure with [`$!`](../perlvar.md) 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.md) — 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.md) 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.md): ```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.md): ```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.md) — wrap in [`eval`](eval.md) 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.md). Catch [`$!`](../perlvar.md) `== 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.md), 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.md) — read the current process group id; the obvious companion for verifying a `setpgrp` call took effect - [`POSIX::setpgid`](../../POSIX/setpgid.md) — 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.md) — 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.md) — how you actually use a process group once you’ve built one: `kill SIG, -$pgid` signals every member