tags:

views:

266

answers:

4

Usually when I need to fork in C, I do something like this:

pid_t p = fork();
if(p == 0) { /* do child stuff */ }
else { /* do parent stuff and pray there wasn't an error */ }

It occured to me that I could ditch the extra variable and use:

if(fork() == 0) { /* child */ }
else { /* parent/pray */ }

Improper error handling aside, (why) does this work/not work?

+4  A: 

You lose the child process ID in the parent, which is what is returned to the parent. I think you could recover that information, but perhaps not uniquely (that is, I think you could get the PID of all of your children, but not necessarily the PID of the child you just forked). If you don't need to know the child's PID, I think the second way is fine.

Also, -1 is returned if there's an error in forking, which you aren't testing for in either case, which is usually a mistake.

jj33
+2  A: 

You should do this instead. I've never known it to not work. It's how it's done in the Stevens books.

int p;
if((p = fork()) == 0) { /* child */ }
else { /* parent/pray */ }
Charles Graham
A: 

You are free to do that in C and it will work because the parent and child will receive different return values from the fork - and it is evaluated first. The only issues are the error handling as you mentioned. Also, you won't have any other way to recover the child PID in case you wanted to operate on it, such as with a waitpid, etc.

AdamC
+14  A: 

What you are suggesting will certainly work. However, error handling is not optional in any well-behaved application. The following implementation pattern is similarly succinct and also handles errors. Furthermore, it saves the fork() return value in the pid variable, in case you want to use it later in the parent to, say, wait for the child.

switch (pid = fork()) {
case -1:       /* Failure */
  /* ... */
case 0:        /* Child */
  /* ... */
default:       /* Parent */
  /* ... */
}
Diomidis Spinellis