Reputation: 4487
I'm trying to start another process (daemon) from my own:
pid_t pid=fork();
if (pid==0) { /* child */
static char *argv[]={NULL};
execv("/sbin/daemon", argv);
exit(127); /* only if execv fails */
}
/* parent */
sleep(5); /* ugly way to wait for /sbin/daemon */
/* THIS_POINT */
How can I get rid of this sleep? I have to be sure that after THIS_POINT the /sbin/daemon
is already started.
What kind of approach would you suggest?
Upvotes: 1
Views: 70
Reputation: 753890
If you have control over the daemon (so you can modify it if necessary), consider creating a pipe, and have the daemon write "OK" on its standard output (the write end of the pipe) when it is running (and then close it). Your parent process reads from the pipe and knows the daemon is running if it gets "OK". It would be sensible to include a newline after the OK; it is important to remember that the data read won't be null terminated.
int fd[2];
if (pipe(fd) != 0) { …report error… }
pid_t pid=fork();
if (pid < 0) { …report error… }
if (pid == 0)
{
static char *argv[] = { "/sbin/daemon", NULL };
dup2(fd[1], FILENO_STDOUT);
close(fd[0]);
close(fd[1]);
execv(argv[0], argv);
exit(127);
}
close(fd[1]);
char buffer[16];
if (read(fd[0], buffer, sizeof(buffer)) >= 2 && memcmp(buffer, "OK", 2) == 0)
…daemon started successfully…
else
…daemon failed…
close(fd[0]);
If you don't have control over the daemon, you can still create the pipe, but you have to rely on the daemon daemonizing itself properly by closing its standard output. In that case, the parent process will simply get zero bytes to read (EOF) from the pipe, and you then check with waitpid(pid, &status, WNOHANG)
whether the child died (which would also give you EOF).
Upvotes: 2