1 /* Copyright 1993-95 by Carl Harris, Jr.
4 * Distribute freely, except: don't remove my name from the source or
5 * documentation (don't take credit for my work), mark your changes (don't
6 * get me blamed for your possible bugs), don't alter or remove this
7 * notice. May be sold if buildable source is provided to buyer. No
8 * warrantee of any kind, express or implied, is included with this
9 * software; use at your own risk, responsibility for damages (if any) to
10 * anyone resulting from the use of this software rests entirely with the
13 * Send bug reports, bug fixes, enhancements, requests, flames, etc., and
14 * I'll try to keep a version up to date. I can be reached as follows:
15 * Carl Harris <ceharris@mal.com>
19 /***********************************************************************
22 programmer: Carl Harris, ceharris@mal.com
23 description: This module contains all of the code needed to
24 turn a process into a daemon for POSIX, SysV, and
28 Revision 1.2 1996/06/26 19:08:57 esr
29 This is what I sent Harris.
31 Revision 1.1 1996/06/25 14:32:01 esr
34 Revision 1.1 1995/08/14 18:36:38 ceharris
35 Patches to support POP3's LAST command.
36 Final revisions for beta3 release.
38 ***********************************************************************/
44 #include <sys/types.h>
49 #if defined(HAVE_SYS_WAIT_H)
50 # include <sys/wait.h>
53 #if defined(HAVE_UNISTD_H)
58 #include "popclient.h"
61 /******************************************************************
62 function: sigchld_handler
63 description: Process the SIGCHLD (a.k.a SIGCLD) signal by calling
64 a wait() variant to obtain the exit code of the
67 ret. value: none (or undefined if REGSIGTYPE is int).
70 *****************************************************************/
77 #if defined(HAVE_UNION_WAIT)
83 #if defined(HAVE_WAIT3)
84 while ((pid = wait3(&status, WNOHANG, (struct rusage *) 0)) > 0)
85 ; /* swallow 'em up. */
86 #elif defined(HAVE_WAITPID)
87 while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
88 ; /* swallow 'em up. */
89 #else /* Zooks! Nothing to do but wait(), and hope we don't block... */
97 /******************************************************************
99 description: become a daemon process; i.e. detach from the
100 control terminal, don't reacquire a control terminal,
101 become process group leader of our own process group,
102 and set up to catch child process termination signals.
104 logfile file to direct stdout and stderr to, if non-NULL.
107 globals: refers to the address of sigchld_handler().
109 *****************************************************************/
117 RETSIGTYPE sigchld_handler();
119 /* if we are started by init (process 1) via /etc/inittab we needn't
120 bother to detach from our process group context */
125 /* Ignore BSD terminal stop signals */
127 signal(SIGTTOU, SIG_IGN);
130 signal(SIGTTIN, SIG_IGN);
133 signal(SIGTSTP, SIG_IGN);
136 /* In case we were not started in the background, fork and let
137 the parent exit. Guarantees that the child is not a process
140 if ((childpid = fork()) < 0) {
144 else if (childpid > 0)
145 exit(0); /* parent */
148 /* Make ourselves the leader of a new process group with no
149 controlling terminal */
151 #if defined(HAVE_SETSID) /* POSIX */
152 /* POSIX makes this soooo easy to do */
157 #elif defined(SIGTSTP) /* BSD */
158 /* change process group */
159 setpgrp(0, getpid());
161 /* lose controlling tty */
162 if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
163 ioctl(fd, TIOCNOTTY, (char *) 0);
166 #else /* SVR3 and older */
167 /* change process group */
170 /* lose controlling tty */
171 signal(SIGHUP, SIG_IGN);
172 if ((childpid = fork) < 0) {
176 else if (childpid > 0) {
177 exit(0); /* parent */
183 /* Close any/all open file descriptors */
184 #if defined(HAVE_GETDTABLESIZE)
185 for (fd = getdtablesize()-1; fd >= 0; fd--)
186 #elif defined(NOFILE)
187 for (fd = NOFILE-1; fd >= 0; fd--)
188 #else /* make an educated guess */
189 for (fd = 19; fd >= 0; fd--)
195 /* Reopen stdin descriptor on /dev/null */
196 if ((fd = open("/dev/null", O_RDWR)) < 0) { /* stdin */
197 perror("open: /dev/null");
202 open(logfile, O_CREAT|O_WRONLY, 0777); /* stdout */
204 if (dup(fd) < 0) { /* stdout */
208 if (dup(fd) < 0) { /* stderr */
213 /* move to root directory, so we don't prevent filesystem unmounts */
216 /* set our umask to something reasonable (we hope) */
217 #if defined(DEF_UMASK)
223 /* set up to catch child process termination signals */
224 signal(SIGCLD, sigchld_handler);