PDA

View Full Version : Set process group


tmw
November 23rd, 2009, 22:30
Hello,

I have a code shown bellow:


#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
int status;
pid_t foo;
pid_t gpid,pid, gpid2, pid2;

pid = getpid();
gpid = getpgid(pid);
foo = fork();
if(foo == 0) {
pid2 = getpid();
gpid2 = getpgid(pid2);
if( setpgid(0,0) < 0) { printf("error\n"); }

exit(0);
}
wait(&status);
return 0;
}



I think this should change the child process group but the child process is still in parent process group. Can anyone know what im doing wrong? :)

Best regards

expl
November 24th, 2009, 01:30
...
if( setpgid(0,0) < 0) { printf("error\n"); }
...


Second value in setpgid() need to point to existing PGID in the session or must be equal to the target process ID. 0 will never be a valid PGID.

tmw
November 24th, 2009, 07:48
Thanks ! :)

anemos
November 24th, 2009, 09:54
int setpgid(pid_t pid, pid_t pgid); (http://www.opengroup.org/onlinepubs/000095399/functions/setpgid.html)

Setting 0 as pgid is absolutely valid. It means that the process ID of the calling process should be used as the process group ID. If pid is 0 then the PID of the caller is used. If pid and pgid are equal, then the calling process becomes a process group leader.

See http://www.amazon.com/Programming-Environment-Addison-Wesley-Professional-Computing/dp/0321525949/ref=sr_1_1?ie=UTF8&s=books&qid=1259049648&sr=8-1

I think that the problem is a race condition.
According to http://www.opengroup.org/onlinepubs/000095399/functions/setpgid.html, setpgid() should be used by the parent process as well in order for this race condition to be avoided. E.g.

...
foo = fork();

if(foo == 0) {
pid2 = getpid();
gpid2 = getpgid(pid2);
if (setpgid(0,0) < 0) {
perror("error\n");
exit(0);
}
} else {
if (setpgid(foo, foo) < 0) {
perror("error\n");
exit(0);
}
}

exit(0);
...

expl
November 24th, 2009, 14:24
Setting 0 as pgid is absolutely valid. It means that the process ID of the calling process should be used as the process group ID. If pid is 0 then the PID of the caller is used. If pid and pgid are equal, then the calling process becomes a process group leader.


The FreeBSD implementation of the setpgid or at least its man page does not say that pgid being 0 is a valid value.

http://www.gsp.com/cgi-bin/man.cgi?section=2&topic=setpgid

anemos
November 24th, 2009, 21:04
The FreeBSD implementation of the setpgid or at least its man page does not say that pgid being 0 is a valid value.

http://www.gsp.com/cgi-bin/man.cgi?section=2&topic=setpgid

Yes! You're right! It should be documented though.


int
setpgid(struct thread *td, register struct setpgid_args *uap)
{
...

if (uap->pgid == 0)
uap->pgid = targp->p_pid;

...


I will raise the question to a mailing list.