xref: /netbsd-src/external/bsd/ntp/dist/ntpsnmpd/netsnmp_daemonize.c (revision 82d56013d7b633d116a93943de88e08335357a7c)
1 /*	$NetBSD: netsnmp_daemonize.c,v 1.7 2020/05/25 20:47:26 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_URL
46 #undef PACKAGE_VERSION
47 #include <config.h>
48 
49 #ifdef NEED_NETSNMP_DAEMONIZE
50 
51 #include <stdio.h>
52 #include <ctype.h>
53 #include <errno.h>
54 
55 #if HAVE_UNISTD_H
56 #include <unistd.h>
57 #endif
58 #if HAVE_STDLIB_H
59 #include <stdlib.h>
60 #endif
61 
62 #if TIME_WITH_SYS_TIME
63 # ifdef WIN32
64 #  include <sys/timeb.h>
65 # else
66 #  include <sys/time.h>
67 # endif
68 # include <time.h>
69 #else
70 # if HAVE_SYS_TIME_H
71 #  include <sys/time.h>
72 # else
73 #  include <time.h>
74 # endif
75 #endif
76 
77 #include <sys/types.h>
78 
79 #if HAVE_NETINET_IN_H
80 #include <netinet/in.h>
81 #endif
82 
83 #if HAVE_WINSOCK_H
84 #include <winsock.h>
85 #endif
86 #if HAVE_SYS_SOCKET_H
87 #include <sys/socket.h>
88 #endif
89 #if HAVE_NET_IF_H
90 #include <net/if.h>
91 #endif
92 
93 #if HAVE_SYS_SOCKIO_H
94 #include <sys/sockio.h>
95 #endif
96 
97 #if HAVE_SYS_IOCTL_H
98 #include <sys/ioctl.h>
99 #endif
100 
101 #ifdef HAVE_NLIST_H
102 #include <nlist.h>
103 #endif
104 
105 #if HAVE_SYS_FILE_H
106 #include <sys/file.h>
107 #endif
108 
109 #if HAVE_KSTAT_H
110 #include <kstat.h>
111 #endif
112 
113 #if HAVE_SYS_PARAM_H
114 #include <sys/param.h>
115 #endif
116 #if HAVE_SYS_SYSCTL_H
117 #include <sys/sysctl.h>
118 #endif
119 
120 #if HAVE_STRING_H
121 #include <string.h>
122 #else
123 #include <strings.h>
124 #endif
125 
126 #if HAVE_DMALLOC_H
127 #include <dmalloc.h>
128 #endif
129 
130 #ifdef HAVE_SYS_STAT_H
131 #include <sys/stat.h>
132 #endif
133 #if HAVE_FCNTL_H
134 #include <fcntl.h>
135 #endif
136 
137 #if defined(hpux10) || defined(hpux11)
138 #include <sys/pstat.h>
139 #endif
140 
141 #if HAVE_SYS_UTSNAME_H
142 #include <sys/utsname.h>
143 #endif
144 
145 #if HAVE_SYS_SYSTEMCFG_H
146 #include <sys/systemcfg.h>
147 #endif
148 
149 #if HAVE_SYS_SYSTEMINFO_H
150 #include <sys/systeminfo.h>
151 #endif
152 
153 #include <net-snmp/types.h>
154 #include <net-snmp/output_api.h>
155 #include <net-snmp/utilities.h>
156 #include <net-snmp/library/system.h>    /* for "internal" definitions */
157 
158 #include <net-snmp/library/snmp_api.h>
159 #include <net-snmp/library/read_config.h> /* for get_temp_file_pattern() */
160 
161 #ifndef IFF_LOOPBACK
162 #	define IFF_LOOPBACK 0
163 #endif
164 
165 #ifdef  INADDR_LOOPBACK
166 # define LOOPBACK    INADDR_LOOPBACK
167 #else
168 # define LOOPBACK    0x7f000001
169 #endif
170 
171 /**
172  * fork current process into the background.
173  *
174  * This function forks a process into the background, in order to
175  * become a daemon process. It does a few things along the way:
176  *
177  * - becoming a process/session group leader, and  forking a second time so
178  *   that process/session group leader can exit.
179  *
180  * - changing the working directory to /
181  *
182  * - closing stdin, stdout and stderr (unless stderr_log is set) and
183  *   redirecting them to /dev/null
184  *
185  * @param quit_immediately : indicates if the parent process should
186  *                           exit after a successful fork.
187  * @param stderr_log       : indicates if stderr is being used for
188  *                           logging and shouldn't be closed
189  * @returns -1 : fork error
190  *           0 : child process returning
191  *          >0 : parent process returning. returned value is the child PID.
192  */
193 int
194 netsnmp_daemonize(int quit_immediately, int stderr_log)
195 {
196     int i = 0;
197     int saved_errno;
198 
199     DEBUGMSGT(("daemonize","daemonizing...\n"));
200 #ifdef HAVE_WORKING_FORK
201     /*
202      * Fork to return control to the invoking process and to
203      * guarantee that we aren't a process group leader.
204      */
205     i = fork();
206     if (i != 0) {
207         /* Parent. */
208 	saved_errno = errno;
209         DEBUGMSGT(("daemonize","first fork returned %d.\n", i));
210         if(i == -1) {
211             snmp_log(LOG_ERR,"first fork failed (errno %d) in "
212                      "netsnmp_daemonize()\n", saved_errno);
213             return -1;
214         }
215         if (quit_immediately) {
216             DEBUGMSGT(("daemonize","parent exiting\n"));
217             exit(0);
218         }
219     } else {
220         /* Child. */
221 #ifdef HAVE_SETSID
222         /* Become a process/session group leader. */
223         setsid();
224 #endif
225         /*
226          * Fork to let the process/session group leader exit.
227          */
228         if ((i = fork()) != 0) {
229 	    saved_errno = errno;
230             DEBUGMSGT(("daemonize","second fork returned %d.\n", i));
231             if(i == -1) {
232                 snmp_log(LOG_ERR,"second fork failed (errno %d) in "
233                          "netsnmp_daemonize()\n", saved_errno);
234             }
235             /* Parent. */
236             exit(0);
237         }
238 #ifndef WIN32
239         else {
240             /* Child. */
241 
242             DEBUGMSGT(("daemonize","child continuing\n"));
243 
244             /* Avoid keeping any directory in use. */
245             chdir("/");
246 
247             if (!stderr_log) {
248                 /*
249                  * Close inherited file descriptors to avoid
250                  * keeping unnecessary references.
251                  */
252                 close(0);
253                 close(1);
254                 close(2);
255 
256                 /*
257                  * Redirect std{in,out,err} to /dev/null, just in
258                  * case.
259                  */
260                 open("/dev/null", O_RDWR);
261                 dup(0);
262                 dup(0);
263             }
264         }
265 #endif /* !WIN32 */
266     }
267 #endif /* HAVE_WORKING_FORK */
268     return i;
269 }
270 
271 #else /* !NEED_NETSNMP_DAEMONIZE */
272 int netsnp_daemonize_bs;
273 #endif
274