xref: /freebsd/contrib/ntp/ntpsnmpd/netsnmp_daemonize.c (revision f5f40dd63bc7acbb5312b26ac1ea1103c12352a6)
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