Это поведение определяется POSIX (что означает, что оно применяется ко всему, что называет себя Unix, а не только к Linux).http://pubs.opengroup.org/onlinepubs/9699919799/functions/setpgid.html говорит:
ERRORS
[EPERM] The process indicated by the pid argument is a session leader.
В спецификации не сказано, почему существует это правило, но я считаю, что обоснование, сформулированное dbush, верно: сеанс лидер всегда должен быть лидером группы процессов;если бы он мог перейти в другую группу процессов, он перестал бы быть лидером группы процессов, нарушив инвариант.
Однако процесс, являющийся только лидером группы процессов, а не лидером сеанса, может входит в другую группу процессов (перестает быть лидером группы процессов), а затем может снова выйти из группы процессов и снова стать лидером группы процессов.Оболочки управления заданиями на самом деле имеют , чтобы сделать это при некоторых обстоятельствах: обратите внимание на бит в нижней части раздела RATIONALE спецификации
Одно неочевидное использование setpgid () - эточтобы позволить оболочке управления заданиями вернуться к своей исходной группе процессов (той, которая действовала при запуске оболочки управления заданиями).Оболочка управления заданиями делает это перед возвратом элемента управления его родителю, когда он завершает работу или приостанавливает себя, чтобы восстановить свое «состояние» управления заданиями до того уровня, которого ожидал бы его родитель.
POSIXНе объясните, почему оболочка управления заданиями в первую очередь изменила бы свою группу процессов, но раздел руководства GNU C Library по реализации управления заданиями заполняет пробел:
Когда запускается программа оболочки, которая обычно выполняет управление заданиями, она должна быть осторожна, если она была вызвана из другой оболочки, которая уже выполняет свое собственное управление заданиями.
Подоболочка, которая запускается в интерактивном режиме, должна гарантировать, чтоон был помещен на передний план его родительской оболочкой, прежде чем он сможет сам включить управление заданиями.
[...]
Как только подоболочка была помещена на передний план его родительской оболочкой,он может включить свой собственный контроль работы.Это делается путем вызова setpgid
для помещения себя в собственную группу процессов, а затем вызова tcsetpgrp
для помещения этой группы процессов на передний план.
И затем, конечно, он должен отменить это снова, если подоболочка приостановлена (например, Bash имеет встроенную suspend
, которая делает это).
Также обратите внимание, чтоОболочка управления заданиями не позиционирует себя как сессионный лидер, даже если он не является подоболочником чего-либо.Сеанс инициализируется любой программой, отвечающей за настройку управляющего терминала;эта программа, как правило, является родительской и предварительно идентифицирует внешнюю оболочку, запущенную в терминале.Например, xterm
вызывает setsid
после открытия псевдотерминала и разветвления, но перед exec
-ing программой, которая будет запускаться в этом окне терминала.