/**************************************************************** function: daemonize description: detach the server process from the current context, creating a pristine, predictable environment in which it will execute. arguments: servfd file descriptor in use by server. return value: none. calls: none. globals: none. ****************************************************************/ void daemonize (servfd) int servfd; { int childpid, fd, fdtablesize; /* ignore terminal I/O, stop signals */ signal(SIGTTOU,SIG_IGN); signal(SIGTTIN,SIG_IGN); signal(SIGTSTP,SIG_IGN); /* fork to put us in the background (whether or not the user specified '&' on the command line */ if ((childpid = fork()) < 0) { fputs("failed to fork first childrn",stderr); exit(1); } else if (childpid > 0) exit(0); /* terminate parent, continue in child */ /* dissociate from process group */ if (setpgrp(0,getpid())<0) { fputs("failed to become process group leaderrn",stderr); exit(1); } /* lose controlling terminal */ if ((fd = open("/dev/tty",O_RDWR)) >= 0) { ioctl(fd,TIOCNOTTY,NULL); close(fd); } /* close any open file descriptors */ for (fd = 0, fdtablesize = getdtablesize(); fd < fdtablesize; fd++) if (fd != servfd) close(fd); /* set working directory to allow filesystems to be unmounted */ chdir("/"); /* clear the inherited umask */ umask(0); /* setup zombie prevention */ signal(SIGCLD,(Sigfunc *)reap_status); }
/**************************************************************** function: reap_status description: handle a SIGCLD signal by reaping the exit status of the perished child, and discarding it. arguments: none. return value: none. calls: none. globals: none. ****************************************************************/ void reap_status() { int pid; union wait status; while ((pid = wait3(&status,WNOHANG,NULL)) > 0) ; /* loop while there are more dead children */ }