setpgrp(2) устанавливает/получает группу процессов

Other Alias

setpgid, getpgid, getpgrp

ОБЗОР

#include <unistd.h>

int setpgid(pid_t pid, pid_t pgid);
pid_t getpgid(pid_t pid);

pid_t getpgrp(void); /* по версии POSIX.1 */
pid_t getpgrp(pid_t pid); /* по версии BSD */

int setpgrp(void); /* по версии System V */
int setpgrp(pid_t pid, pid_t pgid); /* по версии BSD */

Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):

getpgid():

_XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
|| /* начиная с glibc 2.12: */ _POSIX_C_SOURCE >= 200809L

setpgrp() (POSIX.1):


_SVID_SOURCE || _XOPEN_SOURCE >= 500 ||
_XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
|| /* начиная с glibc 2.19: */ _BSD_SOURCE

setpgrp() (BSD), getpgrp() (BSD) [до glibc 2.19]:

    _BSD_SOURCE &&
        ! (_POSIX_SOURCE || _POSIX_C_SOURCE || _XOPEN_SOURCE ||
           _XOPEN_SOURCE_EXTENDED || _GNU_SOURCE || _SVID_SOURCE)

ОПИСАНИЕ

Все перечисленные интерфейсы доступны в Linux и используются для получения и установки идентификатора группы процессов (PGID). Предпочтительней использовать версию POSIX.1: getpgrp(void) — для получения PGID вызывающего процесса; setpgid() — для установки PGID вызывающего процесса.

Вызов setpgid() устанавливает PGID у процесса с идентификатором pid равным pgid. Если значение pid равно 0, то используется идентификатор вызывающего процесса. Если значение pgid равно 0, то PGID процесса, указанного в pid, становится равным его идентификатору процесса. Если setpgid() используется для перевода процесса из одной группы в другую (это делают некоторые оболочки командной строки для объединения каналов процессов), то обе группы процессов должны быть частью одного сеанса (см. setsid(2) и credentials(7)). В этом случае в pgid указывается существующая группа процессов, в которую нужно выполнить перевод и идентификатор сеанса этой группы должен совпадать с идентификатором сеанса переводимого процесса.

В версии POSIX.1 вызов getpgrp() без аргументов возвращает PGID вызывающего процесса.

Вызов getpgid() возвращает PGID процесса с заданным pid. Если значение pid равно нулю, то используется идентификатор вызывающего процесса (получение PGID процесса, отличного от вызывающего, требуется редко, а для этой задачи хорошо подходит POSIX.1 getpgrp()).

В версии System V вызов setpgrp() без аргументов эквивалентен setpgid(0, 0).

В версии BSD вызов setpgrp() с аргументами pid и pgid является обёрточной функцией, которая вызывает


    setpgid(pid, pgid)

Начиная с glibc 2.19, BSD-функция setpgrp() была удалена из <unistd.h>; вызовы должны быть заменены на вызов setpgid(), как показано выше.

В версии BSD вызов getpgrp() с аргументом pid является обёрточной функцией, которая вызывает


    getpgid(pid)

Начиная с glibc 2.19, BSD-функция getpgrp() была удалена из <unistd.h>; вызовы должны быть заменены на вызов POSIX.1 getpgrp(), который не имеет аргументов (если нужно получить PGID вызывающего), или на вызов getpgid(), как показано выше.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

При успешном выполнении setpgid() and setpgrp() возвращают 0. В случае ошибки возвращается -1, а errno устанавливается в соответствующее значение.

Вызов getpgrp() (POSIX.1) всегда возвращает PGID вызывающего процесса.

Вызовы getpgid() и getpgrp() (BSD) при успешном выполнении возвращают группу процессов. При ошибке возвращается -1, а значение errno устанавливается соответствующим образом.

ОШИБКИ

EACCES
Попытка изменить идентификатор группы процессов у одного из потомков вызывающего процесса, но потомок уже вызвал execve(2) (setpgid(), setpgrp()).
EINVAL
Значение pgid меньше 0 (setpgid(), setpgrp()).
EPERM
Попытка переместить процесс в группу процессов из другого сеанса или изменить идентификатор группы процессов у одного из потомков вызывающего процесса, но потомок находится в другом сеансе или изменить идентификатор группы процессов лидера сеанса (setpgid(), setpgrp()).
ESRCH
Для getpgid(): нет процесса с указанным pid. Для setpgid(): значение pid не равно идентификатору вызывающего процесса или идентификатору потомка вызывающего процесса.

СООТВЕТСТВИЕ СТАНДАРТАМ

Вызов setpgid() и версия getpgrp() без аргументов соответствуют POSIX.1-2001.

В POSIX.1-2001 также определён вызов getpgid() и его версия setpgrp(), у которых нет аргументов (в POSIX.1-2008 определение setpgrp() помечено как устаревшее).

Версия getpgrp() с одним аргументом и версия setpgrp() с двумя аргументами появились из 4.2BSD и отсутствуют в POSIX.1.

ЗАМЕЧАНИЯ

Потомок, создаваемый с помощью fork(2), наследует идентификатор группы процессов своего родителя. Значение PGID сохраняется при вызове execve(2).

Каждая группа процессов является членом сеанса и каждый процесс является членом сеанса, в который входит его группа процессов.

Сеанс может иметь управляющий терминал. В любой момент одна (и только одна) группа процессов в сеансе может являться приоритетной группой процессов (foreground process group) терминала; оставшиеся группы процессов выполняются в фоновом режиме. Если от терминала приходит сигнал (например, нажата клавиша прерывания и сгенерирован SIGINT), то сигнал посылается в приоритетную группу процессов (смотрите в termios(3) описание символов, для которых генерируются сигналы). Только приоритетная группа процессов может выполнять вызов read(2) для терминала; если группа процессов в фоновом режиме пытается выполнить read(2) для терминала, то группе посылается сигнал SIGTTIN, который приостанавливает её выполнение. Функции tcgetpgrp(3) и tcsetpgrp(3) используются для получения/установки приоритетной группы процессов у управляющего терминала.

Вызовы setpgid() и getpgrp() используются программами, например bash(1), для создания группы процессов с целью реализации управления заданиями оболочки командной строки.

Если сеанс имеет управляющий терминал, у которого не установлен флаг CLOCAL и возникает зависание (hangup) терминала, то лидеру сеанса посылается SIGHUP. Если лидер сеанса существует, то сигнал SIGHUP также посылается каждому процессу в приоритетной группе процессов управляющего терминала.

Если завершение процесса лишает группу процессов главы и если любой из такой группы процессов остановлен, то каждому процессу в группе посылается сигнал SIGHUP с последующим SIGCONT. Осиротевшей считается группа процессов, у которой родитель каждого члена группы процессов сам является членом группы процессов или членом группы процессов другого сеанса (см. также credentials(7)).