# Set process group



## tmw (Nov 23, 2009)

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 (Nov 24, 2009)

```
...
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 (Nov 24, 2009)

Thanks !


----------



## anemos (Nov 24, 2009)

```
[url=http://www.opengroup.org/onlinepubs/000095399/functions/setpgid.html]int setpgid(pid_t pid, pid_t pgid);[/URL]
```

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-E...=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 (Nov 24, 2009)

anemos said:
			
		

> 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 (Nov 24, 2009)

expl said:
			
		

> 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.


----------

