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