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