1258945Sroberto/* 2258945Sroberto * system.c 3258945Sroberto */ 4258945Sroberto/* Portions of this file are subject to the following copyright(s). See 5258945Sroberto * the Net-SNMP's COPYING file for more details and other copyrights 6258945Sroberto * that may apply: 7258945Sroberto */ 8258945Sroberto/*********************************************************** 9258945Sroberto Copyright 1992 by Carnegie Mellon University 10258945Sroberto 11258945Sroberto All Rights Reserved 12258945Sroberto 13258945SrobertoPermission to use, copy, modify, and distribute this software and its 14258945Srobertodocumentation for any purpose and without fee is hereby granted, 15258945Srobertoprovided that the above copyright notice appear in all copies and that 16258945Srobertoboth that copyright notice and this permission notice appear in 17258945Srobertosupporting documentation, and that the name of CMU not be 18258945Srobertoused in advertising or publicity pertaining to distribution of the 19258945Srobertosoftware without specific, written prior permission. 20258945Sroberto 21258945SrobertoCMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 22258945SrobertoALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 23258945SrobertoCMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 24258945SrobertoANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 25258945SrobertoWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 26258945SrobertoARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 27258945SrobertoSOFTWARE. 28258945Sroberto******************************************************************/ 29258945Sroberto/* 30258945Sroberto * Portions of this file are copyrighted by: 31258945Sroberto * Copyright � 2003 Sun Microsystems, Inc. All rights reserved. 32258945Sroberto * Use is subject to license terms specified in the COPYING file 33258945Sroberto * distributed with the Net-SNMP package. 34258945Sroberto */ 35258945Sroberto/* 36258945Sroberto * System dependent routines go here 37258945Sroberto */ 38258945Sroberto#include <net-snmp/net-snmp-config.h> 39258945Sroberto#undef PACKAGE_BUGREPORT 40258945Sroberto#undef PACKAGE_NAME 41258945Sroberto#undef PACKAGE_STRING 42258945Sroberto#undef PACKAGE_TARNAME 43280849Scy#undef PACKAGE_URL 44258945Sroberto#undef PACKAGE_VERSION 45258945Sroberto#include <config.h> 46258945Sroberto 47258945Sroberto#ifdef NEED_NETSNMP_DAEMONIZE 48258945Sroberto 49258945Sroberto#include <stdio.h> 50258945Sroberto#include <ctype.h> 51258945Sroberto#include <errno.h> 52258945Sroberto 53258945Sroberto#if HAVE_UNISTD_H 54258945Sroberto#include <unistd.h> 55258945Sroberto#endif 56258945Sroberto#if HAVE_STDLIB_H 57258945Sroberto#include <stdlib.h> 58258945Sroberto#endif 59258945Sroberto 60258945Sroberto#if TIME_WITH_SYS_TIME 61258945Sroberto# ifdef WIN32 62258945Sroberto# include <sys/timeb.h> 63258945Sroberto# else 64258945Sroberto# include <sys/time.h> 65258945Sroberto# endif 66258945Sroberto# include <time.h> 67258945Sroberto#else 68258945Sroberto# if HAVE_SYS_TIME_H 69258945Sroberto# include <sys/time.h> 70258945Sroberto# else 71258945Sroberto# include <time.h> 72258945Sroberto# endif 73258945Sroberto#endif 74258945Sroberto 75258945Sroberto#include <sys/types.h> 76258945Sroberto 77258945Sroberto#if HAVE_NETINET_IN_H 78258945Sroberto#include <netinet/in.h> 79258945Sroberto#endif 80258945Sroberto 81258945Sroberto#if HAVE_WINSOCK_H 82258945Sroberto#include <winsock.h> 83258945Sroberto#endif 84258945Sroberto#if HAVE_SYS_SOCKET_H 85258945Sroberto#include <sys/socket.h> 86258945Sroberto#endif 87258945Sroberto#if HAVE_NET_IF_H 88258945Sroberto#include <net/if.h> 89258945Sroberto#endif 90258945Sroberto 91258945Sroberto#if HAVE_SYS_SOCKIO_H 92258945Sroberto#include <sys/sockio.h> 93258945Sroberto#endif 94258945Sroberto 95258945Sroberto#if HAVE_SYS_IOCTL_H 96258945Sroberto#include <sys/ioctl.h> 97258945Sroberto#endif 98258945Sroberto 99258945Sroberto#ifdef HAVE_NLIST_H 100258945Sroberto#include <nlist.h> 101258945Sroberto#endif 102258945Sroberto 103258945Sroberto#if HAVE_SYS_FILE_H 104258945Sroberto#include <sys/file.h> 105258945Sroberto#endif 106258945Sroberto 107258945Sroberto#if HAVE_KSTAT_H 108258945Sroberto#include <kstat.h> 109258945Sroberto#endif 110258945Sroberto 111258945Sroberto#if HAVE_SYS_PARAM_H 112258945Sroberto#include <sys/param.h> 113258945Sroberto#endif 114258945Sroberto#if HAVE_SYS_SYSCTL_H 115258945Sroberto#include <sys/sysctl.h> 116258945Sroberto#endif 117258945Sroberto 118258945Sroberto#if HAVE_STRING_H 119258945Sroberto#include <string.h> 120258945Sroberto#else 121258945Sroberto#include <strings.h> 122258945Sroberto#endif 123258945Sroberto 124258945Sroberto#if HAVE_DMALLOC_H 125258945Sroberto#include <dmalloc.h> 126258945Sroberto#endif 127258945Sroberto 128258945Sroberto#ifdef HAVE_SYS_STAT_H 129258945Sroberto#include <sys/stat.h> 130258945Sroberto#endif 131258945Sroberto#if HAVE_FCNTL_H 132258945Sroberto#include <fcntl.h> 133258945Sroberto#endif 134258945Sroberto 135258945Sroberto#if defined(hpux10) || defined(hpux11) 136258945Sroberto#include <sys/pstat.h> 137258945Sroberto#endif 138258945Sroberto 139258945Sroberto#if HAVE_SYS_UTSNAME_H 140258945Sroberto#include <sys/utsname.h> 141258945Sroberto#endif 142258945Sroberto 143258945Sroberto#if HAVE_SYS_SYSTEMCFG_H 144258945Sroberto#include <sys/systemcfg.h> 145258945Sroberto#endif 146258945Sroberto 147258945Sroberto#if HAVE_SYS_SYSTEMINFO_H 148258945Sroberto#include <sys/systeminfo.h> 149258945Sroberto#endif 150258945Sroberto 151258945Sroberto#include <net-snmp/types.h> 152258945Sroberto#include <net-snmp/output_api.h> 153258945Sroberto#include <net-snmp/utilities.h> 154258945Sroberto#include <net-snmp/library/system.h> /* for "internal" definitions */ 155258945Sroberto 156258945Sroberto#include <net-snmp/library/snmp_api.h> 157258945Sroberto#include <net-snmp/library/read_config.h> /* for get_temp_file_pattern() */ 158258945Sroberto 159258945Sroberto#ifndef IFF_LOOPBACK 160258945Sroberto# define IFF_LOOPBACK 0 161258945Sroberto#endif 162258945Sroberto 163258945Sroberto#ifdef INADDR_LOOPBACK 164258945Sroberto# define LOOPBACK INADDR_LOOPBACK 165258945Sroberto#else 166258945Sroberto# define LOOPBACK 0x7f000001 167258945Sroberto#endif 168258945Sroberto 169258945Sroberto/** 170258945Sroberto * fork current process into the background. 171258945Sroberto * 172258945Sroberto * This function forks a process into the background, in order to 173258945Sroberto * become a daemon process. It does a few things along the way: 174258945Sroberto * 175258945Sroberto * - becoming a process/session group leader, and forking a second time so 176258945Sroberto * that process/session group leader can exit. 177258945Sroberto * 178258945Sroberto * - changing the working directory to / 179258945Sroberto * 180258945Sroberto * - closing stdin, stdout and stderr (unless stderr_log is set) and 181258945Sroberto * redirecting them to /dev/null 182258945Sroberto * 183258945Sroberto * @param quit_immediately : indicates if the parent process should 184258945Sroberto * exit after a successful fork. 185258945Sroberto * @param stderr_log : indicates if stderr is being used for 186258945Sroberto * logging and shouldn't be closed 187258945Sroberto * @returns -1 : fork error 188258945Sroberto * 0 : child process returning 189258945Sroberto * >0 : parent process returning. returned value is the child PID. 190258945Sroberto */ 191258945Srobertoint 192258945Srobertonetsnmp_daemonize(int quit_immediately, int stderr_log) 193258945Sroberto{ 194258945Sroberto int i = 0; 195280849Scy int saved_errno; 196280849Scy 197330106Sdelphij DEBUGMSGT(("daemonize","daemonizing...\n")); 198280849Scy#ifdef HAVE_WORKING_FORK 199258945Sroberto /* 200258945Sroberto * Fork to return control to the invoking process and to 201258945Sroberto * guarantee that we aren't a process group leader. 202258945Sroberto */ 203258945Sroberto i = fork(); 204258945Sroberto if (i != 0) { 205258945Sroberto /* Parent. */ 206280849Scy saved_errno = errno; 207258945Sroberto DEBUGMSGT(("daemonize","first fork returned %d.\n", i)); 208258945Sroberto if(i == -1) { 209258945Sroberto snmp_log(LOG_ERR,"first fork failed (errno %d) in " 210280849Scy "netsnmp_daemonize()\n", saved_errno); 211258945Sroberto return -1; 212258945Sroberto } 213258945Sroberto if (quit_immediately) { 214258945Sroberto DEBUGMSGT(("daemonize","parent exiting\n")); 215258945Sroberto exit(0); 216258945Sroberto } 217258945Sroberto } else { 218258945Sroberto /* Child. */ 219258945Sroberto#ifdef HAVE_SETSID 220258945Sroberto /* Become a process/session group leader. */ 221258945Sroberto setsid(); 222258945Sroberto#endif 223258945Sroberto /* 224258945Sroberto * Fork to let the process/session group leader exit. 225258945Sroberto */ 226258945Sroberto if ((i = fork()) != 0) { 227280849Scy saved_errno = errno; 228258945Sroberto DEBUGMSGT(("daemonize","second fork returned %d.\n", i)); 229258945Sroberto if(i == -1) { 230258945Sroberto snmp_log(LOG_ERR,"second fork failed (errno %d) in " 231280849Scy "netsnmp_daemonize()\n", saved_errno); 232258945Sroberto } 233258945Sroberto /* Parent. */ 234258945Sroberto exit(0); 235258945Sroberto } 236258945Sroberto#ifndef WIN32 237258945Sroberto else { 238258945Sroberto /* Child. */ 239258945Sroberto 240258945Sroberto DEBUGMSGT(("daemonize","child continuing\n")); 241258945Sroberto 242258945Sroberto /* Avoid keeping any directory in use. */ 243258945Sroberto chdir("/"); 244258945Sroberto 245258945Sroberto if (!stderr_log) { 246258945Sroberto /* 247258945Sroberto * Close inherited file descriptors to avoid 248258945Sroberto * keeping unnecessary references. 249258945Sroberto */ 250258945Sroberto close(0); 251258945Sroberto close(1); 252258945Sroberto close(2); 253258945Sroberto 254258945Sroberto /* 255258945Sroberto * Redirect std{in,out,err} to /dev/null, just in 256258945Sroberto * case. 257258945Sroberto */ 258258945Sroberto open("/dev/null", O_RDWR); 259258945Sroberto dup(0); 260258945Sroberto dup(0); 261258945Sroberto } 262258945Sroberto } 263258945Sroberto#endif /* !WIN32 */ 264258945Sroberto } 265258945Sroberto#endif /* HAVE_WORKING_FORK */ 266258945Sroberto return i; 267258945Sroberto} 268258945Sroberto 269258945Sroberto#else /* !NEED_NETSNMP_DAEMONIZE */ 270258945Srobertoint netsnp_daemonize_bs; 271258945Sroberto#endif 272