1 /* $NetBSD: netsnmp_daemonize.c,v 1.1.1.1 2009/12/13 16:56:32 kardel 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 DEBUGMSGT(("daemonize","deamonizing...\n")); 197 #if HAVE_FORK 198 /* 199 * Fork to return control to the invoking process and to 200 * guarantee that we aren't a process group leader. 201 */ 202 i = fork(); 203 if (i != 0) { 204 /* Parent. */ 205 DEBUGMSGT(("daemonize","first fork returned %d.\n", i)); 206 if(i == -1) { 207 snmp_log(LOG_ERR,"first fork failed (errno %d) in " 208 "netsnmp_daemonize()\n", errno); 209 return -1; 210 } 211 if (quit_immediately) { 212 DEBUGMSGT(("daemonize","parent exiting\n")); 213 exit(0); 214 } 215 } else { 216 /* Child. */ 217 #ifdef HAVE_SETSID 218 /* Become a process/session group leader. */ 219 setsid(); 220 #endif 221 /* 222 * Fork to let the process/session group leader exit. 223 */ 224 if ((i = fork()) != 0) { 225 DEBUGMSGT(("daemonize","second fork returned %d.\n", i)); 226 if(i == -1) { 227 snmp_log(LOG_ERR,"second fork failed (errno %d) in " 228 "netsnmp_daemonize()\n", errno); 229 } 230 /* Parent. */ 231 exit(0); 232 } 233 #ifndef WIN32 234 else { 235 /* Child. */ 236 237 DEBUGMSGT(("daemonize","child continuing\n")); 238 239 /* Avoid keeping any directory in use. */ 240 chdir("/"); 241 242 if (!stderr_log) { 243 /* 244 * Close inherited file descriptors to avoid 245 * keeping unnecessary references. 246 */ 247 close(0); 248 close(1); 249 close(2); 250 251 /* 252 * Redirect std{in,out,err} to /dev/null, just in 253 * case. 254 */ 255 open("/dev/null", O_RDWR); 256 dup(0); 257 dup(0); 258 } 259 } 260 #endif /* !WIN32 */ 261 } 262 #endif /* HAVE_FORK */ 263 return i; 264 } 265 266 #else /* !NEED_NETSNMP_DAEMONIZE */ 267 int netsnp_daemonize_bs; 268 #endif 269