12b15cb3dSCy Schubert /* 22b15cb3dSCy Schubert * system.c 32b15cb3dSCy Schubert */ 42b15cb3dSCy Schubert /* Portions of this file are subject to the following copyright(s). See 52b15cb3dSCy Schubert * the Net-SNMP's COPYING file for more details and other copyrights 62b15cb3dSCy Schubert * that may apply: 72b15cb3dSCy Schubert */ 82b15cb3dSCy Schubert /*********************************************************** 92b15cb3dSCy Schubert Copyright 1992 by Carnegie Mellon University 102b15cb3dSCy Schubert 112b15cb3dSCy Schubert All Rights Reserved 122b15cb3dSCy Schubert 132b15cb3dSCy Schubert Permission to use, copy, modify, and distribute this software and its 142b15cb3dSCy Schubert documentation for any purpose and without fee is hereby granted, 152b15cb3dSCy Schubert provided that the above copyright notice appear in all copies and that 162b15cb3dSCy Schubert both that copyright notice and this permission notice appear in 172b15cb3dSCy Schubert supporting documentation, and that the name of CMU not be 182b15cb3dSCy Schubert used in advertising or publicity pertaining to distribution of the 192b15cb3dSCy Schubert software without specific, written prior permission. 202b15cb3dSCy Schubert 212b15cb3dSCy Schubert CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 222b15cb3dSCy Schubert ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 232b15cb3dSCy Schubert CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 242b15cb3dSCy Schubert ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 252b15cb3dSCy Schubert WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 262b15cb3dSCy Schubert ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 272b15cb3dSCy Schubert SOFTWARE. 282b15cb3dSCy Schubert ******************************************************************/ 292b15cb3dSCy Schubert /* 302b15cb3dSCy Schubert * Portions of this file are copyrighted by: 312b15cb3dSCy Schubert * Copyright � 2003 Sun Microsystems, Inc. All rights reserved. 322b15cb3dSCy Schubert * Use is subject to license terms specified in the COPYING file 332b15cb3dSCy Schubert * distributed with the Net-SNMP package. 342b15cb3dSCy Schubert */ 352b15cb3dSCy Schubert /* 362b15cb3dSCy Schubert * System dependent routines go here 372b15cb3dSCy Schubert */ 382b15cb3dSCy Schubert #include <net-snmp/net-snmp-config.h> 392b15cb3dSCy Schubert #undef PACKAGE_BUGREPORT 402b15cb3dSCy Schubert #undef PACKAGE_NAME 412b15cb3dSCy Schubert #undef PACKAGE_STRING 422b15cb3dSCy Schubert #undef PACKAGE_TARNAME 432b15cb3dSCy Schubert #undef PACKAGE_URL 442b15cb3dSCy Schubert #undef PACKAGE_VERSION 452b15cb3dSCy Schubert #include <config.h> 462b15cb3dSCy Schubert 472b15cb3dSCy Schubert #ifdef NEED_NETSNMP_DAEMONIZE 482b15cb3dSCy Schubert 492b15cb3dSCy Schubert #include <stdio.h> 502b15cb3dSCy Schubert #include <ctype.h> 512b15cb3dSCy Schubert #include <errno.h> 522b15cb3dSCy Schubert 532b15cb3dSCy Schubert #if HAVE_UNISTD_H 542b15cb3dSCy Schubert #include <unistd.h> 552b15cb3dSCy Schubert #endif 562b15cb3dSCy Schubert #if HAVE_STDLIB_H 572b15cb3dSCy Schubert #include <stdlib.h> 582b15cb3dSCy Schubert #endif 592b15cb3dSCy Schubert 602b15cb3dSCy Schubert #ifdef WIN32 612b15cb3dSCy Schubert # include <sys/timeb.h> 622b15cb3dSCy Schubert #else 632b15cb3dSCy Schubert # include <sys/time.h> 642b15cb3dSCy Schubert #endif 652b15cb3dSCy Schubert #include <time.h> 662b15cb3dSCy Schubert 672b15cb3dSCy Schubert #include <sys/types.h> 682b15cb3dSCy Schubert 692b15cb3dSCy Schubert #if HAVE_NETINET_IN_H 702b15cb3dSCy Schubert #include <netinet/in.h> 712b15cb3dSCy Schubert #endif 722b15cb3dSCy Schubert 732b15cb3dSCy Schubert #if HAVE_WINSOCK_H 742b15cb3dSCy Schubert #include <winsock.h> 752b15cb3dSCy Schubert #endif 762b15cb3dSCy Schubert #if HAVE_SYS_SOCKET_H 772b15cb3dSCy Schubert #include <sys/socket.h> 782b15cb3dSCy Schubert #endif 792b15cb3dSCy Schubert #if HAVE_NET_IF_H 802b15cb3dSCy Schubert #include <net/if.h> 812b15cb3dSCy Schubert #endif 822b15cb3dSCy Schubert 832b15cb3dSCy Schubert #if HAVE_SYS_SOCKIO_H 842b15cb3dSCy Schubert #include <sys/sockio.h> 852b15cb3dSCy Schubert #endif 862b15cb3dSCy Schubert 872b15cb3dSCy Schubert #if HAVE_SYS_IOCTL_H 882b15cb3dSCy Schubert #include <sys/ioctl.h> 892b15cb3dSCy Schubert #endif 902b15cb3dSCy Schubert 912b15cb3dSCy Schubert #ifdef HAVE_NLIST_H 922b15cb3dSCy Schubert #include <nlist.h> 932b15cb3dSCy Schubert #endif 942b15cb3dSCy Schubert 952b15cb3dSCy Schubert #if HAVE_SYS_FILE_H 962b15cb3dSCy Schubert #include <sys/file.h> 972b15cb3dSCy Schubert #endif 982b15cb3dSCy Schubert 992b15cb3dSCy Schubert #if HAVE_KSTAT_H 1002b15cb3dSCy Schubert #include <kstat.h> 1012b15cb3dSCy Schubert #endif 1022b15cb3dSCy Schubert 1032b15cb3dSCy Schubert #if HAVE_SYS_PARAM_H 1042b15cb3dSCy Schubert #include <sys/param.h> 1052b15cb3dSCy Schubert #endif 1062b15cb3dSCy Schubert #if HAVE_SYS_SYSCTL_H 1072b15cb3dSCy Schubert #include <sys/sysctl.h> 1082b15cb3dSCy Schubert #endif 1092b15cb3dSCy Schubert 1102b15cb3dSCy Schubert #if HAVE_STRING_H 1112b15cb3dSCy Schubert #include <string.h> 1122b15cb3dSCy Schubert #else 1132b15cb3dSCy Schubert #include <strings.h> 1142b15cb3dSCy Schubert #endif 1152b15cb3dSCy Schubert 1162b15cb3dSCy Schubert #if HAVE_DMALLOC_H 1172b15cb3dSCy Schubert #include <dmalloc.h> 1182b15cb3dSCy Schubert #endif 1192b15cb3dSCy Schubert 1202b15cb3dSCy Schubert #ifdef HAVE_SYS_STAT_H 1212b15cb3dSCy Schubert #include <sys/stat.h> 1222b15cb3dSCy Schubert #endif 1232b15cb3dSCy Schubert #if HAVE_FCNTL_H 1242b15cb3dSCy Schubert #include <fcntl.h> 1252b15cb3dSCy Schubert #endif 1262b15cb3dSCy Schubert 1272b15cb3dSCy Schubert #if defined(hpux10) || defined(hpux11) 1282b15cb3dSCy Schubert #include <sys/pstat.h> 1292b15cb3dSCy Schubert #endif 1302b15cb3dSCy Schubert 1312b15cb3dSCy Schubert #if HAVE_SYS_UTSNAME_H 1322b15cb3dSCy Schubert #include <sys/utsname.h> 1332b15cb3dSCy Schubert #endif 1342b15cb3dSCy Schubert 1352b15cb3dSCy Schubert #if HAVE_SYS_SYSTEMCFG_H 1362b15cb3dSCy Schubert #include <sys/systemcfg.h> 1372b15cb3dSCy Schubert #endif 1382b15cb3dSCy Schubert 1392b15cb3dSCy Schubert #if HAVE_SYS_SYSTEMINFO_H 1402b15cb3dSCy Schubert #include <sys/systeminfo.h> 1412b15cb3dSCy Schubert #endif 1422b15cb3dSCy Schubert 1432b15cb3dSCy Schubert #include <net-snmp/types.h> 1442b15cb3dSCy Schubert #include <net-snmp/output_api.h> 1452b15cb3dSCy Schubert #include <net-snmp/utilities.h> 1462b15cb3dSCy Schubert #include <net-snmp/library/system.h> /* for "internal" definitions */ 1472b15cb3dSCy Schubert 1482b15cb3dSCy Schubert #include <net-snmp/library/snmp_api.h> 1492b15cb3dSCy Schubert #include <net-snmp/library/read_config.h> /* for get_temp_file_pattern() */ 1502b15cb3dSCy Schubert 1512b15cb3dSCy Schubert #ifndef IFF_LOOPBACK 1522b15cb3dSCy Schubert # define IFF_LOOPBACK 0 1532b15cb3dSCy Schubert #endif 1542b15cb3dSCy Schubert 1552b15cb3dSCy Schubert #ifdef INADDR_LOOPBACK 1562b15cb3dSCy Schubert # define LOOPBACK INADDR_LOOPBACK 1572b15cb3dSCy Schubert #else 1582b15cb3dSCy Schubert # define LOOPBACK 0x7f000001 1592b15cb3dSCy Schubert #endif 1602b15cb3dSCy Schubert 1612b15cb3dSCy Schubert /** 1622b15cb3dSCy Schubert * fork current process into the background. 1632b15cb3dSCy Schubert * 1642b15cb3dSCy Schubert * This function forks a process into the background, in order to 1652b15cb3dSCy Schubert * become a daemon process. It does a few things along the way: 1662b15cb3dSCy Schubert * 1672b15cb3dSCy Schubert * - becoming a process/session group leader, and forking a second time so 1682b15cb3dSCy Schubert * that process/session group leader can exit. 1692b15cb3dSCy Schubert * 1702b15cb3dSCy Schubert * - changing the working directory to / 1712b15cb3dSCy Schubert * 1722b15cb3dSCy Schubert * - closing stdin, stdout and stderr (unless stderr_log is set) and 1732b15cb3dSCy Schubert * redirecting them to /dev/null 1742b15cb3dSCy Schubert * 1752b15cb3dSCy Schubert * @param quit_immediately : indicates if the parent process should 1762b15cb3dSCy Schubert * exit after a successful fork. 1772b15cb3dSCy Schubert * @param stderr_log : indicates if stderr is being used for 1782b15cb3dSCy Schubert * logging and shouldn't be closed 1792b15cb3dSCy Schubert * @returns -1 : fork error 1802b15cb3dSCy Schubert * 0 : child process returning 1812b15cb3dSCy Schubert * >0 : parent process returning. returned value is the child PID. 1822b15cb3dSCy Schubert */ 1832b15cb3dSCy Schubert int 1842b15cb3dSCy Schubert netsnmp_daemonize(int quit_immediately, int stderr_log) 1852b15cb3dSCy Schubert { 1862b15cb3dSCy Schubert int i = 0; 1872b15cb3dSCy Schubert int saved_errno; 1882b15cb3dSCy Schubert 18909100258SXin LI DEBUGMSGT(("daemonize","daemonizing...\n")); 1902b15cb3dSCy Schubert #ifdef HAVE_WORKING_FORK 1912b15cb3dSCy Schubert /* 1922b15cb3dSCy Schubert * Fork to return control to the invoking process and to 1932b15cb3dSCy Schubert * guarantee that we aren't a process group leader. 1942b15cb3dSCy Schubert */ 1952b15cb3dSCy Schubert i = fork(); 1962b15cb3dSCy Schubert if (i != 0) { 1972b15cb3dSCy Schubert /* Parent. */ 1982b15cb3dSCy Schubert saved_errno = errno; 1992b15cb3dSCy Schubert DEBUGMSGT(("daemonize","first fork returned %d.\n", i)); 2002b15cb3dSCy Schubert if(i == -1) { 2012b15cb3dSCy Schubert snmp_log(LOG_ERR,"first fork failed (errno %d) in " 2022b15cb3dSCy Schubert "netsnmp_daemonize()\n", saved_errno); 2032b15cb3dSCy Schubert return -1; 2042b15cb3dSCy Schubert } 2052b15cb3dSCy Schubert if (quit_immediately) { 2062b15cb3dSCy Schubert DEBUGMSGT(("daemonize","parent exiting\n")); 2072b15cb3dSCy Schubert exit(0); 2082b15cb3dSCy Schubert } 2092b15cb3dSCy Schubert } else { 2102b15cb3dSCy Schubert /* Child. */ 2112b15cb3dSCy Schubert #ifdef HAVE_SETSID 2122b15cb3dSCy Schubert /* Become a process/session group leader. */ 2132b15cb3dSCy Schubert setsid(); 2142b15cb3dSCy Schubert #endif 2152b15cb3dSCy Schubert /* 2162b15cb3dSCy Schubert * Fork to let the process/session group leader exit. 2172b15cb3dSCy Schubert */ 2182b15cb3dSCy Schubert if ((i = fork()) != 0) { 2192b15cb3dSCy Schubert saved_errno = errno; 2202b15cb3dSCy Schubert DEBUGMSGT(("daemonize","second fork returned %d.\n", i)); 2212b15cb3dSCy Schubert if(i == -1) { 2222b15cb3dSCy Schubert snmp_log(LOG_ERR,"second fork failed (errno %d) in " 2232b15cb3dSCy Schubert "netsnmp_daemonize()\n", saved_errno); 2242b15cb3dSCy Schubert } 2252b15cb3dSCy Schubert /* Parent. */ 2262b15cb3dSCy Schubert exit(0); 2272b15cb3dSCy Schubert } 2282b15cb3dSCy Schubert #ifndef WIN32 2292b15cb3dSCy Schubert else { 2302b15cb3dSCy Schubert /* Child. */ 2312b15cb3dSCy Schubert 2322b15cb3dSCy Schubert DEBUGMSGT(("daemonize","child continuing\n")); 2332b15cb3dSCy Schubert 2342b15cb3dSCy Schubert /* Avoid keeping any directory in use. */ 2352b15cb3dSCy Schubert chdir("/"); 2362b15cb3dSCy Schubert 2372b15cb3dSCy Schubert if (!stderr_log) { 2382b15cb3dSCy Schubert /* 2392b15cb3dSCy Schubert * Close inherited file descriptors to avoid 2402b15cb3dSCy Schubert * keeping unnecessary references. 2412b15cb3dSCy Schubert */ 2422b15cb3dSCy Schubert close(0); 2432b15cb3dSCy Schubert close(1); 2442b15cb3dSCy Schubert close(2); 2452b15cb3dSCy Schubert 2462b15cb3dSCy Schubert /* 2472b15cb3dSCy Schubert * Redirect std{in,out,err} to /dev/null, just in 2482b15cb3dSCy Schubert * case. 2492b15cb3dSCy Schubert */ 2502b15cb3dSCy Schubert open("/dev/null", O_RDWR); 2512b15cb3dSCy Schubert dup(0); 2522b15cb3dSCy Schubert dup(0); 2532b15cb3dSCy Schubert } 2542b15cb3dSCy Schubert } 2552b15cb3dSCy Schubert #endif /* !WIN32 */ 2562b15cb3dSCy Schubert } 2572b15cb3dSCy Schubert #endif /* HAVE_WORKING_FORK */ 2582b15cb3dSCy Schubert return i; 2592b15cb3dSCy Schubert } 2602b15cb3dSCy Schubert 2612b15cb3dSCy Schubert #else /* !NEED_NETSNMP_DAEMONIZE */ 262*f5f40dd6SCy Schubert NONEMPTY_TRANSLATION_UNIT 2632b15cb3dSCy Schubert #endif 264