c - Writing data to stderr makes the program to exit after the program becomes a daemon -
please @ code. runs in centos6 64bit.
#include<stdio.h> int main(int argc, char **argv) { fprintf(stderr, "output 1\n"); printf("output 2\n"); fflush(stdout); system("echo abc"); fprintf(stderr, "output 3\n "); printf("output 4\n"); fflush(stdout); daemon(0, 1); fprintf(stderr, "output 5\n"); printf("output 6\n"); fflush(stdout); system("echo abc"); fprintf(stderr, "output 7\n"); printf("output 8\n"); fflush(stdout); }
if run it, see these messages:
output 1 output 2 abc output 3 output 4 output 5 output 6 abc output 7 output 8
if use ssh login , run it, see same results.
however, if use binary name parameter of ssh , run it, program exit when writing data stderr after calling daemon(0, 1). suppose binary name myapp. run
ssh localhost myapp
and see these messages:
output 1 output 2 abc output 3 output 4 output 5 output 6 abc
does know why? according debugging, program exits after doing 3 things:
- call daemon(0, 1).
- call system run application or bash command.
- write stderr.
thanks lot!
if run command shell, you're seeing new shell prompt between output 4 , output 5 (this more noticeable if there sleeps in between output lines).
that's because daemon()
system call causes program split 2 independent processes. called "fork", , can controlled little more closely using fork()
system call. after fork, both processes keep pointers open file descriptors: stdin, stdout , stderr. according "man 3 daemon", parent process calls exit()
after fork.
when call executable ssh, ssh session run 1 process. forks off child, , main process exits. ssh sees command issued has finished, , closes ssh connection. closes stdout , stderr. unfortunately, child process still has work do, can't write shared stderr because file descriptor has been closed. if printed more debug info, return values printf()
, fprintf()
calls, you'd see not able write closed file descriptors.
if, instead of printing stderr, printed log file (which daemons do), you'll see child process continue run in background , write expected.
if had chosen use fork()
instead of daemon()
, have parent wait until child finishes. pid_t waitpid(pid_t pid, int *stat_loc, int options);
.
you might want take @ signals sent between parent , child. when child process dies, send sigchild parent. if you'd reverse notification, can set 1 (on linux only) using prctl(pr_set_pdeathsig, sighup);
, parent sends sighup child.
Comments
Post a Comment