I've done a fork and exec() on a process, but I'd like to run it in the background. How can I do this? I can just avoid calling waitpid on it, but then the process sits there for ever, waiting to return it's status to the parent. Is there some other way to do this?
4 Answers
I think what you are trying to do is create a daemon process. Read this link on Wikipedia for an explaination.
An example (from Steven's Advanced Programming in the Unix Environment) for making a process a daemon is:
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
int daemon_int(void)
{
pid_t pid;
if ((pid = fork()) < 0)
return (-1) ;
else if (pid != 0)
exit(0) ; /* The parent process exits */
setsid() ; /* become session leader */
chdir("/") ; /* change the working dir */
umask(0) ; /* clear out the file mode creation mask */
return(0) ;
}
Of course this does assume a Unix like OS.
So your program includes the above function and calls it as soon as it is run. It is then disassoicated from it parent process and will just keep running until it terminates or it is killed.

- 5,627
- 2
- 29
- 48
-
Hmm closer reading of the question makes me think Avi might have the answer. Or you could cause the first child to become a daemon which waits for the Grandchild to terminate. So yo break the link between Parent and Child so Parent can terminate without causing Child and Grandchild to exit. – Jackson Oct 24 '09 at 19:19
-
If you want to do this, you also want your original process to call wait() to reap it's child. Since the child process will exit quickly (right after forking the grandchild), your original process will not block long in wait(). – R Samuel Klatchko Oct 24 '09 at 19:20
Catch SIGCHLD and in the the handler, call wait().
Some flavors of Posix (I think *BSD, but don't quote me on that), if you ignore SIGCHLD, the kernel will automatically clean up zombie process (which is what you are seeing in ps). It's a nice feature but not portable.

- 74,869
- 16
- 134
- 187
-
-
For future programmers with the same question, here's what I found on page 293 of "Advanced Programming in the UNIX Environment": SIGCHLD Whenever a process terminates or stops, the SIGCHLD signal is sent to the parent. By default, this signal is ignored, so the parent must catch this signal if it wants to be notified whenever a child's status changes. The normal action in the signal-catching function is to call one of the wait functions to fetch the child's process ID and termination status. In this case, I just needed a line like liw.fi suggested: waitpid(-1,&status,WNOHANG | WUNTRACED); – Vlad the Impala Oct 24 '09 at 19:47
waitpid(-1, &status, WNOHANG)
might do what you need: it should return immediately if no child process has exited. Alternatively, you could listen for the SIGCHLD signal.
-
This is not a good strategy - unless the parent process is prepared to do that over and over again (else you still end up with zombies). – Martin v. Löwis Oct 24 '09 at 19:13
-
Unfortunately I got exactly the result Martin predicted, but it certainly sounded good till then. – Vlad the Impala Oct 24 '09 at 19:20
-
This all depends on how the parent process is structured. Sometimes it's easier to poll occasionally rather than catch SIGCHLD. – Oct 25 '09 at 06:32
Fork to create the background thread and then exec. See a dupe question on this site: Can we start a background process using exec() giving & as an argument?
-
Yes, I saw that question, but it still doesn't answer my original question. Sure I can just avoid the wait call, but then the process sits there for ever. I can see it every time I run ps -al. – Vlad the Impala Oct 24 '09 at 19:00
-
I don't think the answers to the past question actually answer this one (as aditya also complains); the correct answer was given by Avi. Furthermore, I'm skeptical that the answers to the past question actually do answer this past question (since the OP also wanted to create a background process, and nobody told him about double-fork). – Martin v. Löwis Oct 24 '09 at 19:12