xref: /netbsd-src/external/bsd/ntp/dist/ntpsnmpd/netsnmp_daemonize.c (revision 413d532bcc3f62d122e56d92e13ac64825a40baf)
1 /*	$NetBSD: netsnmp_daemonize.c,v 1.1.1.3 2013/12/27 23:31:07 christos Exp $	*/
2 
3 /*
4  * system.c
5  */
6 /* Portions of this file are subject to the following copyright(s).  See
7  * the Net-SNMP's COPYING file for more details and other copyrights
8  * that may apply:
9  */
10 /***********************************************************
11         Copyright 1992 by Carnegie Mellon University
12 
13                       All Rights Reserved
14 
15 Permission to use, copy, modify, and distribute this software and its
16 documentation for any purpose and without fee is hereby granted,
17 provided that the above copyright notice appear in all copies and that
18 both that copyright notice and this permission notice appear in
19 supporting documentation, and that the name of CMU not be
20 used in advertising or publicity pertaining to distribution of the
21 software without specific, written prior permission.
22 
23 CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
24 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
25 CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
26 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
27 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
28 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
29 SOFTWARE.
30 ******************************************************************/
31 /*
32  * Portions of this file are copyrighted by:
33  * Copyright � 2003 Sun Microsystems, Inc. All rights reserved.
34  * Use is subject to license terms specified in the COPYING file
35  * distributed with the Net-SNMP package.
36  */
37 /*
38  * System dependent routines go here
39  */
40 #include <net-snmp/net-snmp-config.h>
41 #undef PACKAGE_BUGREPORT
42 #undef PACKAGE_NAME
43 #undef PACKAGE_STRING
44 #undef PACKAGE_TARNAME
45 #undef PACKAGE_VERSION
46 #include <config.h>
47 
48 #ifdef NEED_NETSNMP_DAEMONIZE
49 
50 #include <stdio.h>
51 #include <ctype.h>
52 #include <errno.h>
53 
54 #if HAVE_UNISTD_H
55 #include <unistd.h>
56 #endif
57 #if HAVE_STDLIB_H
58 #include <stdlib.h>
59 #endif
60 
61 #if TIME_WITH_SYS_TIME
62 # ifdef WIN32
63 #  include <sys/timeb.h>
64 # else
65 #  include <sys/time.h>
66 # endif
67 # include <time.h>
68 #else
69 # if HAVE_SYS_TIME_H
70 #  include <sys/time.h>
71 # else
72 #  include <time.h>
73 # endif
74 #endif
75 
76 #include <sys/types.h>
77 
78 #if HAVE_NETINET_IN_H
79 #include <netinet/in.h>
80 #endif
81 
82 #if HAVE_WINSOCK_H
83 #include <winsock.h>
84 #endif
85 #if HAVE_SYS_SOCKET_H
86 #include <sys/socket.h>
87 #endif
88 #if HAVE_NET_IF_H
89 #include <net/if.h>
90 #endif
91 
92 #if HAVE_SYS_SOCKIO_H
93 #include <sys/sockio.h>
94 #endif
95 
96 #if HAVE_SYS_IOCTL_H
97 #include <sys/ioctl.h>
98 #endif
99 
100 #ifdef HAVE_NLIST_H
101 #include <nlist.h>
102 #endif
103 
104 #if HAVE_SYS_FILE_H
105 #include <sys/file.h>
106 #endif
107 
108 #if HAVE_KSTAT_H
109 #include <kstat.h>
110 #endif
111 
112 #if HAVE_SYS_PARAM_H
113 #include <sys/param.h>
114 #endif
115 #if HAVE_SYS_SYSCTL_H
116 #include <sys/sysctl.h>
117 #endif
118 
119 #if HAVE_STRING_H
120 #include <string.h>
121 #else
122 #include <strings.h>
123 #endif
124 
125 #if HAVE_DMALLOC_H
126 #include <dmalloc.h>
127 #endif
128 
129 #ifdef HAVE_SYS_STAT_H
130 #include <sys/stat.h>
131 #endif
132 #if HAVE_FCNTL_H
133 #include <fcntl.h>
134 #endif
135 
136 #if defined(hpux10) || defined(hpux11)
137 #include <sys/pstat.h>
138 #endif
139 
140 #if HAVE_SYS_UTSNAME_H
141 #include <sys/utsname.h>
142 #endif
143 
144 #if HAVE_SYS_SYSTEMCFG_H
145 #include <sys/systemcfg.h>
146 #endif
147 
148 #if HAVE_SYS_SYSTEMINFO_H
149 #include <sys/systeminfo.h>
150 #endif
151 
152 #include <net-snmp/types.h>
153 #include <net-snmp/output_api.h>
154 #include <net-snmp/utilities.h>
155 #include <net-snmp/library/system.h>    /* for "internal" definitions */
156 
157 #include <net-snmp/library/snmp_api.h>
158 #include <net-snmp/library/read_config.h> /* for get_temp_file_pattern() */
159 
160 #ifndef IFF_LOOPBACK
161 #	define IFF_LOOPBACK 0
162 #endif
163 
164 #ifdef  INADDR_LOOPBACK
165 # define LOOPBACK    INADDR_LOOPBACK
166 #else
167 # define LOOPBACK    0x7f000001
168 #endif
169 
170 /**
171  * fork current process into the background.
172  *
173  * This function forks a process into the background, in order to
174  * become a daemon process. It does a few things along the way:
175  *
176  * - becoming a process/session group leader, and  forking a second time so
177  *   that process/session group leader can exit.
178  *
179  * - changing the working directory to /
180  *
181  * - closing stdin, stdout and stderr (unless stderr_log is set) and
182  *   redirecting them to /dev/null
183  *
184  * @param quit_immediately : indicates if the parent process should
185  *                           exit after a successful fork.
186  * @param stderr_log       : indicates if stderr is being used for
187  *                           logging and shouldn't be closed
188  * @returns -1 : fork error
189  *           0 : child process returning
190  *          >0 : parent process returning. returned value is the child PID.
191  */
192 int
193 netsnmp_daemonize(int quit_immediately, int stderr_log)
194 {
195     int i = 0;
196     int saved_errno;
197 
198     DEBUGMSGT(("daemonize","deamonizing...\n"));
199 #ifdef HAVE_WORKING_FORK
200     /*
201      * Fork to return control to the invoking process and to
202      * guarantee that we aren't a process group leader.
203      */
204     i = fork();
205     if (i != 0) {
206         /* Parent. */
207 	saved_errno = errno;
208         DEBUGMSGT(("daemonize","first fork returned %d.\n", i));
209         if(i == -1) {
210             snmp_log(LOG_ERR,"first fork failed (errno %d) in "
211                      "netsnmp_daemonize()\n", saved_errno);
212             return -1;
213         }
214         if (quit_immediately) {
215             DEBUGMSGT(("daemonize","parent exiting\n"));
216             exit(0);
217         }
218     } else {
219         /* Child. */
220 #ifdef HAVE_SETSID
221         /* Become a process/session group leader. */
222         setsid();
223 #endif
224         /*
225          * Fork to let the process/session group leader exit.
226          */
227         if ((i = fork()) != 0) {
228 	    saved_errno = errno;
229             DEBUGMSGT(("daemonize","second fork returned %d.\n", i));
230             if(i == -1) {
231                 snmp_log(LOG_ERR,"second fork failed (errno %d) in "
232                          "netsnmp_daemonize()\n", saved_errno);
233             }
234             /* Parent. */
235             exit(0);
236         }
237 #ifndef WIN32
238         else {
239             /* Child. */
240 
241             DEBUGMSGT(("daemonize","child continuing\n"));
242 
243             /* Avoid keeping any directory in use. */
244             chdir("/");
245 
246             if (!stderr_log) {
247                 /*
248                  * Close inherited file descriptors to avoid
249                  * keeping unnecessary references.
250                  */
251                 close(0);
252                 close(1);
253                 close(2);
254 
255                 /*
256                  * Redirect std{in,out,err} to /dev/null, just in
257                  * case.
258                  */
259                 open("/dev/null", O_RDWR);
260                 dup(0);
261                 dup(0);
262             }
263         }
264 #endif /* !WIN32 */
265     }
266 #endif /* HAVE_WORKING_FORK */
267     return i;
268 }
269 
270 #else /* !NEED_NETSNMP_DAEMONIZE */
271 int netsnp_daemonize_bs;
272 #endif
273