:: Reading this carefully, I see that the current Linux behaviour _is_
:: Posix compliant; read the first line after EPERM again. It says
:: "The calling process is already a process group leader". So what I did,
:: calling "setpgrp(0, getpgid(getppid()))" first is indeed the right thing
:: to do if you really want to setsid(). I still think it doesn't make sense,
:: but.. I'll attribute a section to the setsid() manpage about this if
:: you want ;)
Yes, you are quite right - I was too quick in thinking that the
source (as it was in 2.0.7) precisely reflected POSIX.
But in fact p->leader codes session leadership, not process group
leadership. (In particular, one might remove some confusion by
# diff fork.c~ fork.c
255c255
< p->leader = 0; /* process leadership doesn't inherit */
--- > p->leader = 0; /* session leadership doesn't inherit */.) If I am not mistaken, 2.0.8 is correct.
Michiel Boland writes:
: Included below is a warning from the setsid(2) manpage for : Solaris. Something like this should be included in the linux man : page.
: WARNINGS : A call to setsid() by a process that is a process group : leader will fail. A process can become a process group : leader by being the last member of a pipeline started by a : job control shell. Thus, a process that expects to be part : of a pipeline, and that calls setsid(), should always first : fork; the parent should exit and the child should call set- : sid(). This will ensure that the calling process will work : reliably when started by both job control shells and non-job : control shells.
I think I agree with neither of you, in the sense that if nothing is known about the present situation, two forks are required to make sure setsid() will succeed. I wrote the following in setsid.2 (part of man-pages-1.12 - obviously not released yet). Please complain if you disagree.
Andries
...
ERRORS On error, -1 will be returned. The only error which can happen is EPERM. It is returned when the process group ID of any process equals the PID of the calling process. Thus, in particular, setsid fails if the calling process is already a process group leader.
NOTES A process group leader is a process with process group ID equal to its PID. The only way to be sure that setsid will succeed, given an arbitary constellation of processes, is to fork and exit, have the child do setpgid(0,0) to make sure that it has a process group ID not occurring elsewhere, fork and exit again, and do setsid().