Почему fork() перед setid()

Почему fork() до setsid() для демонтизации процесса?

В принципе, если я хочу отсоединить процесс от его управляющего терминала и сделать его лидером группы процессов: я использую setsid().

Выполнение этого без форкирования до этого не работает.

Почему?

Ответ 1

Прежде всего: setsid() сделает ваш процесс лидером группы процессов, но также сделает вас лидером нового сеанса. Если вы просто заинтересованы в получении собственной группы процессов, используйте setpgid (0,0).

Теперь для понимания фактической причины, по которой setid() возвращает EPERM, если вы уже являетесь лидером группы процессов или лидером сеанса, вам нужно понять, что группа процессов и идентификаторы сеанса инициализируются из идентификатора процесса процесса, создающего их (и, следовательно, их, то есть для лидера сеанса pid == sid и для лидера группы процессов pid == pgid). Также группы процессов не могут перемещаться между сеансами.

Это означает, что если вы являетесь лидером группы процессов и разрешите создание нового сеанса, то sid и pgid будут установлены на ваш pid, оставив другие процессы в вашей старой группе процессов в странном состоянии: их процесс лидер группы внезапно находится в другой сессии, тогда они сами могут быть. И это невозможно, поэтому EPERM ядром.

Теперь, если вы fork(), когда вы больше не являетесь ни руководителем группы, ни группой процессов, и поэтому установка sid и pgid в ваш pid безопасна, потому что в этой группе нет других процессов.

Итак, yepp, подумайте об этом, все имеет смысл.

Ответ 2

Требуется fork() и иметь дочерний вызов setsid(), чтобы гарантировать, что процесс, вызывающий setsid(), уже не является лидером группы процессов (setsid() хочет сделать вызывающий процесс лидером группы процессов новая группа процессов, поэтому в этом случае она терпит неудачу).

Ответ 3

man 2 setsid, вы получите следующее описание:

setsid() создает новый сеанс, если вызывающий процесс не является лидером группы процессов. Вызывающий процесс является лидером нового сеанса, лидером группы процессов новой группы процессов и не имеет управляющего терминала. Идентификатор группы процессов и идентификатор сеанса вызывающего процесса устанавливаются в PID вызывающего процесса. Вызывающий процесс будет единственным процессом в этой новой группе процессов и в этом новом сеансе.

Если руководителю группы процессов разрешено вызывать setsid(), создать новый сеанс и новую группу процессов (с тем же идентификатором группы процессов), это приведет к конфликту с идентификатором группы процессов.