From 2c5b51d8c7e51f384c2db7b22fa3a3e398a73695 Mon Sep 17 00:00:00 2001 From: wierenga <sdos@astron.nl> Date: Fri, 28 Oct 2005 14:56:35 +0000 Subject: [PATCH] bugid:419 Start RSPDriver, CalServer and BeamServer in background (detached from terminal) when they are passed a "-d" option ('d' for daemon). All file-descriptors are closed to LofarLogger must be set up correctly with .log_prop files to output logging to a file. rspdriver.in, calserver.in and beamserver.in init scripts now use 'daemon' function to start the server in the background. --- MAC/APL/PAC/BeamServer/src/BeamServer.cc | 11 ++ .../PAC/BeamServer/src/BeamServer.log_prop.in | 32 ++++- MAC/APL/PAC/BeamServer/src/beamserver.in | 48 +++++-- MAC/APL/PAC/CalServer/src/CalServer.cc | 11 ++ .../PAC/CalServer/src/CalServer.log_prop.in | 32 ++++- MAC/APL/PAC/CalServer/src/calserver.in | 37 +++-- MAC/APL/PIC/RSPDriver/src/Makefile.am | 6 +- MAC/APL/PIC/RSPDriver/src/RSPDriver.cc | 20 ++- MAC/APL/PIC/RSPDriver/src/rspdriver.in | 44 +++--- MAC/APL/RTCCommon/configure.in | 2 +- .../include/APL/RTCCommon/Makefile.am | 3 +- .../include/APL/RTCCommon/daemonize.h | 49 +++++++ MAC/APL/RTCCommon/src/Makefile.am | 3 +- MAC/APL/RTCCommon/src/daemonize.c | 131 ++++++++++++++++++ 14 files changed, 373 insertions(+), 56 deletions(-) create mode 100644 MAC/APL/RTCCommon/include/APL/RTCCommon/daemonize.h create mode 100644 MAC/APL/RTCCommon/src/daemonize.c diff --git a/MAC/APL/PAC/BeamServer/src/BeamServer.cc b/MAC/APL/PAC/BeamServer/src/BeamServer.cc index 82d8ca4f91b..93722890281 100644 --- a/MAC/APL/PAC/BeamServer/src/BeamServer.cc +++ b/MAC/APL/PAC/BeamServer/src/BeamServer.cc @@ -24,6 +24,7 @@ #include <lofar_config.h> #include <Common/LofarLogger.h> +#include <APL/RTCCommon/daemonize.h> #include <APL/BS_Protocol/BS_Protocol.ph> #include <APL/RSP_Protocol/RSP_Protocol.ph> #include <APL/CAL_Protocol/CAL_Protocol.ph> @@ -812,6 +813,16 @@ GCFEvent::TResult BeamServer::recall(GCFPortInterface& p) int main(int argc, char** argv) { + /* daemonize if required */ + if (argc >= 2) { + if (!strcmp(argv[1], "-d")) { + if (0 != daemonize(false)) { + cerr << "Failed to background this process: " << strerror(errno) << endl; + exit(EXIT_FAILURE); + } + } + } + GCFTask::init(argc, argv); LOG_INFO(formatString("Program %s has started", argv[0])); diff --git a/MAC/APL/PAC/BeamServer/src/BeamServer.log_prop.in b/MAC/APL/PAC/BeamServer/src/BeamServer.log_prop.in index ae240a58f83..ce9f7643fe5 100644 --- a/MAC/APL/PAC/BeamServer/src/BeamServer.log_prop.in +++ b/MAC/APL/PAC/BeamServer/src/BeamServer.log_prop.in @@ -1,11 +1,37 @@ -log4cplus.rootLogger=INFO, STDOUT + +log4cplus.rootLogger=INFO, MACSTDERR log4cplus.additivity.ASTRON=FALSE log4cplus.appender.STDOUT=log4cplus::ConsoleAppender log4cplus.appender.STDOUT.layout=log4cplus::PatternLayout log4cplus.appender.STDOUT.layout.ConversionPattern=%D{%d-%m-%y %H:%M:%S} %-5p %c{3} - %m [%.25l]%n +log4cplus.appender.MACSTDERR=log4cplus::ConsoleAppender +log4cplus.appender.MACSTDERR.layout=log4cplus::PatternLayout +log4cplus.appender.MACSTDERR.layout.ConversionPattern=%x %D{%d-%m %H:%M:%S.%q} %-5p %c{4} - %m [%.25l]%n +log4cplus.appender.MACSTDERR.logToStdErr=true + +log4cplus.appender.MACCLP=log4cplus::SocketAppender +log4cplus.appender.MACCLP.port=25003 +log4cplus.appender.MACCLP.host=lofar30 +log4cplus.appender.MACCLP.Threshold=INFO + +log4cplus.appender.FILE=log4cplus::RollingFileAppender +log4cplus.appender.FILE.File=BeamServer.log +log4cplus.appender.FILE.MaxFileSize=10MB +log4cplus.appender.FILE.MaxBackupIndex=10 +log4cplus.appender.FILE.layout=log4cplus::PatternLayout +log4cplus.appender.FILE.layout.ConversionPattern=%x %D{%d-%m-%y %H:%M:%S} %-5p %c{3} - %m [%.25l]%n +log4cplus.appender.FILE.logToStdErr=true + +log4cplus.appender.DUMP=log4cplus::NullAppender + +#log4cplus.logger.TRC=DUMP +#log4cplus.additivity.TRC=FALSE + log4cplus.additivity.MAC=FALSE -log4cplus.logger.MAC=DEBUG, STDOUT -log4cplus.logger.TRC=TRACE8 \ No newline at end of file +log4cplus.logger.MAC=DEBUG, FILE + +log4cplus.additivity.TRC=FALSE +log4cplus.logger.TRC=TRACE, FILE diff --git a/MAC/APL/PAC/BeamServer/src/beamserver.in b/MAC/APL/PAC/BeamServer/src/beamserver.in index 6ff452fe8d2..192a9182fbb 100644 --- a/MAC/APL/PAC/BeamServer/src/beamserver.in +++ b/MAC/APL/PAC/BeamServer/src/beamserver.in @@ -16,39 +16,57 @@ if [ -f $PREFIX/etc/sysconfig/beamserver ];then . $PREFIX/etc/sysconfig/beamserver fi -# Check preconditions -# These files must exist -[ -x $PREFIX/bin/BeamServer ] || exit 0 -[ -e $PREFIX/etc/BeamServer.conf ] || exit 0 - +# intialize variables RETVAL=0 prog="BeamServer" +# Check preconditions +# These files must exist +[ -x $PREFIX/bin/$prog ] || exit 0 +[ -e $PREFIX/etc/$prog.conf ] || exit 0 + start() { + # + # Check if running as root + # + if [ "$USER" != "root" ]; then + echo Must run as root. + return 1 + fi + + # check if it is already running + if [ -f /var/lock/subsys/$prog ]; then + status $prog + return 1 + fi # set OPTIONS - OPTIONS= + OPTIONS="-d" # Start BeamServer echo -n $"Starting $prog: " - mkdir -p $PREFIX/var/run/ - touch $PREFIX/var/run/$prog.pid - mkdir -p $PREFIX/var/log/ - nohup $PREFIX/bin/$prog $OPTIONS > $PREFIX/var/log/BeamServer.log & + + daemon $PREFIX/bin/$prog $OPTIONS RETVAL=$? - mkdir -p $PREFIX/var/lock/subsys - [ $RETVAL -eq 0 ] && touch $PREFIX/var/lock/subsys/$prog && success $"$prog startup" + [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog echo return $RETVAL } stop() { + # + # Check if running as root + # + if [ "$USER" != "root" ]; then + echo Must run as root. + return 1 + fi # Stop BeamServer echo -n $"Shutting down $prog: " killproc $prog RETVAL=$? - [ $RETVAL -eq 0 ] && rm -f $PREFIX/var/lock/subsys/$prog + [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$prog echo return $RETVAL } @@ -57,9 +75,11 @@ stop() { case "$1" in start) start + RETVAL=$? ;; stop) stop + RETVAL=$? ;; status) status $prog @@ -71,7 +91,7 @@ case "$1" in RETVAL=$? ;; condrestart) - if [ -f $PREFIX/var/lock/subsys/$prog ]; then + if [ -f /var/lock/subsys/$prog ]; then stop start RETVAL=$? diff --git a/MAC/APL/PAC/CalServer/src/CalServer.cc b/MAC/APL/PAC/CalServer/src/CalServer.cc index 39861a836c4..5b4337725dc 100644 --- a/MAC/APL/PAC/CalServer/src/CalServer.cc +++ b/MAC/APL/PAC/CalServer/src/CalServer.cc @@ -24,6 +24,7 @@ #include <lofar_config.h> #include <Common/LofarLogger.h> +#include <APL/RTCCommon/daemonize.h> #include <APL/CAL_Protocol/CAL_Protocol.ph> #include "CalServer.h" @@ -686,6 +687,16 @@ void CalServer::write_acc() int main(int argc, char** argv) { + /* daemonize if required */ + if (argc >= 2) { + if (!strcmp(argv[1], "-d")) { + if (0 != daemonize(false)) { + cerr << "Failed to background this process: " << strerror(errno) << endl; + exit(EXIT_FAILURE); + } + } + } + GCFTask::init(argc, argv); LOG_INFO(formatString("Program %s has started", argv[0])); diff --git a/MAC/APL/PAC/CalServer/src/CalServer.log_prop.in b/MAC/APL/PAC/CalServer/src/CalServer.log_prop.in index ae240a58f83..3cdc20b1ddb 100644 --- a/MAC/APL/PAC/CalServer/src/CalServer.log_prop.in +++ b/MAC/APL/PAC/CalServer/src/CalServer.log_prop.in @@ -1,11 +1,37 @@ -log4cplus.rootLogger=INFO, STDOUT + +log4cplus.rootLogger=INFO, MACSTDERR log4cplus.additivity.ASTRON=FALSE log4cplus.appender.STDOUT=log4cplus::ConsoleAppender log4cplus.appender.STDOUT.layout=log4cplus::PatternLayout log4cplus.appender.STDOUT.layout.ConversionPattern=%D{%d-%m-%y %H:%M:%S} %-5p %c{3} - %m [%.25l]%n +log4cplus.appender.MACSTDERR=log4cplus::ConsoleAppender +log4cplus.appender.MACSTDERR.layout=log4cplus::PatternLayout +log4cplus.appender.MACSTDERR.layout.ConversionPattern=%x %D{%d-%m %H:%M:%S.%q} %-5p %c{4} - %m [%.25l]%n +log4cplus.appender.MACSTDERR.logToStdErr=true + +log4cplus.appender.MACCLP=log4cplus::SocketAppender +log4cplus.appender.MACCLP.port=25003 +log4cplus.appender.MACCLP.host=lofar30 +log4cplus.appender.MACCLP.Threshold=INFO + +log4cplus.appender.FILE=log4cplus::RollingFileAppender +log4cplus.appender.FILE.File=CalServer.log +log4cplus.appender.FILE.MaxFileSize=10MB +log4cplus.appender.FILE.MaxBackupIndex=10 +log4cplus.appender.FILE.layout=log4cplus::PatternLayout +log4cplus.appender.FILE.layout.ConversionPattern=%x %D{%d-%m-%y %H:%M:%S} %-5p %c{3} - %m [%.25l]%n +log4cplus.appender.FILE.logToStdErr=true + +log4cplus.appender.DUMP=log4cplus::NullAppender + +#log4cplus.logger.TRC=DUMP +#log4cplus.additivity.TRC=FALSE + log4cplus.additivity.MAC=FALSE -log4cplus.logger.MAC=DEBUG, STDOUT -log4cplus.logger.TRC=TRACE8 \ No newline at end of file +log4cplus.logger.MAC=DEBUG, FILE + +log4cplus.additivity.TRC=FALSE +log4cplus.logger.TRC=TRACE, FILE diff --git a/MAC/APL/PAC/CalServer/src/calserver.in b/MAC/APL/PAC/CalServer/src/calserver.in index 299669202a6..fd119649574 100644 --- a/MAC/APL/PAC/CalServer/src/calserver.in +++ b/MAC/APL/PAC/CalServer/src/calserver.in @@ -25,30 +25,47 @@ RETVAL=0 prog="CalServer" start() { + # + # Check if running as root + # + if [ "$USER" != "root" ]; then + echo Must run as root. + return 1 + fi + + # check if it is already running + if [ -f /var/lock/subsys/$prog ]; then + status $prog + return 1 + fi # set OPTIONS - OPTIONS= + OPTIONS="-d" # Start CalServer echo -n $"Starting $prog: " - mkdir -p $PREFIX/var/run - touch $PREFIX/var/run/$prog.pid - mkdir -p $PREFIX/var/log/ - nohup $PREFIX/bin/$prog $OPTIONS > $PREFIX/var/log/CalServer.log & + + daemon $PREFIX/bin/$prog $OPTIONS RETVAL=$? - mkdir -p $PREFIX/var/lock/subsys - [ $RETVAL -eq 0 ] && touch $PREFIX/var/lock/subsys/$prog && success $"$prog startup" + [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog echo return $RETVAL } stop() { + # + # Check if running as root + # + if [ "$USER" != "root" ]; then + echo Must run as root. + return 1 + fi # Stop CalServer echo -n $"Shutting down $prog: " killproc $prog RETVAL=$? - [ $RETVAL -eq 0 ] && rm -f $PREFIX/var/lock/subsys/$prog + [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$prog echo return $RETVAL } @@ -57,9 +74,11 @@ stop() { case "$1" in start) start + RETVAL=$? ;; stop) stop + RETVAL=$? ;; status) status $prog @@ -71,7 +90,7 @@ case "$1" in RETVAL=$? ;; condrestart) - if [ -f $PREFIX/var/lock/subsys/$prog ]; then + if [ -f /var/lock/subsys/$prog ]; then stop start RETVAL=$? diff --git a/MAC/APL/PIC/RSPDriver/src/Makefile.am b/MAC/APL/PIC/RSPDriver/src/Makefile.am index b0cd5636149..4b98d7409b9 100644 --- a/MAC/APL/PIC/RSPDriver/src/Makefile.am +++ b/MAC/APL/PIC/RSPDriver/src/Makefile.am @@ -20,7 +20,8 @@ BUILT_SOURCES = \ RSPDriver.conf \ Tuner.conf \ SetWG.conf \ - rspctl.conf + rspctl.conf \ + RSPDriver.log_prop clean-local: rm -f *.ph @@ -34,7 +35,8 @@ sysconf_DATA = \ RSPDriver.conf \ Tuner.conf \ SetWG.conf \ - rspctl.conf + rspctl.conf \ + RSPDriver.log_prop %.properties: $(MAC_CONFIG)/%.properties cp $< $@ diff --git a/MAC/APL/PIC/RSPDriver/src/RSPDriver.cc b/MAC/APL/PIC/RSPDriver/src/RSPDriver.cc index a1ced4abdc7..1ba425c9522 100644 --- a/MAC/APL/PIC/RSPDriver/src/RSPDriver.cc +++ b/MAC/APL/PIC/RSPDriver/src/RSPDriver.cc @@ -24,18 +24,20 @@ #include <lofar_config.h> #include <Common/LofarLogger.h> +#include <APL/RTCCommon/PSAccess.h> +#include <APL/RTCCommon/daemonize.h> +#include <GCF/ParameterSet.h> + #include <APL/RSP_Protocol/RSP_Protocol.ph> #include <APL/RSP_Protocol/EPA_Protocol.ph> #include <APL/RSP_Protocol/MEPHeader.h> -#include <APL/RTCCommon/PSAccess.h> -#include <GCF/ParameterSet.h> - #include <blitz/array.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> +#include <string.h> #include "RSPDriver.h" #include "Command.h" @@ -1519,10 +1521,20 @@ void RSPDriver::rsp_unsubclocks(GCFEvent& event, GCFPortInterface& port) int main(int argc, char** argv) { + /* daemonize if required */ + if (argc >= 2) { + if (!strcmp(argv[1], "-d")) { + if (0 != daemonize(false)) { + cerr << "Failed to background this process: " << strerror(errno) << endl; + exit(EXIT_FAILURE); + } + } + } + GCFTask::init(argc, argv); LOG_INFO(formatString("Program %s has started", argv[0])); - + try { GCF::ParameterSet::instance()->adoptFile("RSPDriverPorts.conf"); diff --git a/MAC/APL/PIC/RSPDriver/src/rspdriver.in b/MAC/APL/PIC/RSPDriver/src/rspdriver.in index dbc77f4ae23..dd6567222bb 100644 --- a/MAC/APL/PIC/RSPDriver/src/rspdriver.in +++ b/MAC/APL/PIC/RSPDriver/src/rspdriver.in @@ -16,37 +16,43 @@ if [ -f $PREFIX/etc/sysconfig/rspdriver ];then . $PREFIX/etc/sysconfig/rspdriver fi +# +# initialize variables, set program name +# +RETVAL=0 +prog="RSPDriver" + # Check preconditions # These files must exist -[ -x $PREFIX/bin/RSPDriver ] || exit 0 -[ -e $PREFIX/etc/RSPDriver.conf ] || exit 0 -[ -e $PREFIX/etc/RSPDriverPorts.conf ] || exit 0 +[ -x $PREFIX/bin/$prog ] || exit 0 +[ -e $PREFIX/etc/$prog.conf ] || exit 0 +[ -e $PREFIX/etc/$prog""Ports.conf ] || exit 0 [ -e $PREFIX/etc/RemoteStation.conf ] || exit 0 -RETVAL=0 -prog="RSPDriver" - start() { # # Check if running as root # if [ "$USER" != "root" ]; then echo Must run as root. - exit 0 + return 1 + fi + + # check if it is already running + if [ -f /var/lock/subsys/$prog ]; then + status $prog + return 1 fi - # set OPTIONS - OPTIONS=--root + # -d means start in the background as daemon + OPTIONS="-d" # Start RSPDriver echo -n $"Starting $prog: " - mkdir -p $PREFIX/var/run - touch $PREFIX/var/run/$prog.pid - mkdir -p $PREFIX/var/log/ - nohup $PREFIX/bin/$prog $OPTIONS > $PREFIX/var/log/RSPDriver.log & + + daemon $PREFIX/bin/$prog $OPTIONS RETVAL=$? - mkdir -p $PREFIX/var/lock/subsys - [ $RETVAL -eq 0 ] && touch $PREFIX/var/lock/subsys/$prog && success $"$prog startup" + [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog echo return $RETVAL } @@ -57,14 +63,14 @@ stop() { # if [ "$USER" != "root" ]; then echo Must run as root. - exit 0 + return 1 fi # Stop RSPDriver echo -n $"Shutting down $prog: " killproc $prog RETVAL=$? - [ $RETVAL -eq 0 ] && rm -f $PREFIX/var/lock/subsys/$prog + [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$prog echo return $RETVAL } @@ -73,9 +79,11 @@ stop() { case "$1" in start) start + RETVAL=$? ;; stop) stop + RETVAL=$? ;; status) status $prog @@ -87,7 +95,7 @@ case "$1" in RETVAL=$? ;; condrestart) - if [ -f $PREFIX/var/lock/subsys/$prog ]; then + if [ -f /var/lock/subsys/$prog ]; then stop start RETVAL=$? diff --git a/MAC/APL/RTCCommon/configure.in b/MAC/APL/RTCCommon/configure.in index 7e41d443b73..9ebc0e66337 100644 --- a/MAC/APL/RTCCommon/configure.in +++ b/MAC/APL/RTCCommon/configure.in @@ -36,7 +36,7 @@ dnl AC_CHECK_LIB(vport_r, main) dnl Checks for header files. AC_HEADER_STDC -AC_CHECK_HEADERS(unistd.h) +AC_CHECK_HEADERS([string.h sys/time.h unistd.h sys/types.h sys/stat.h sys/resource.h signal.h]) dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST diff --git a/MAC/APL/RTCCommon/include/APL/RTCCommon/Makefile.am b/MAC/APL/RTCCommon/include/APL/RTCCommon/Makefile.am index 9cb2bb1fa61..8f54411de8b 100644 --- a/MAC/APL/RTCCommon/include/APL/RTCCommon/Makefile.am +++ b/MAC/APL/RTCCommon/include/APL/RTCCommon/Makefile.am @@ -9,7 +9,8 @@ INSTHDRS = \ PSAccess.h \ Subject.h \ TestSuite.h \ - Timestamp.h + Timestamp.h \ + daemonize.h NOINSTHDRS = diff --git a/MAC/APL/RTCCommon/include/APL/RTCCommon/daemonize.h b/MAC/APL/RTCCommon/include/APL/RTCCommon/daemonize.h new file mode 100644 index 00000000000..6b78640a559 --- /dev/null +++ b/MAC/APL/RTCCommon/include/APL/RTCCommon/daemonize.h @@ -0,0 +1,49 @@ +//# -*- mode: c++ -*- +//# +//# daemonize.h: function to put a daemon process in the background +//# +//# Copyright (C) 2002-2004 +//# ASTRON (Netherlands Foundation for Research in Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl +//# +//# This program is free software; you can redistribute it and/or modify +//# it under the terms of the GNU General Public License as published by +//# the Free Software Foundation; either version 2 of the License, or +//# (at your option) any later version. +//# +//# This program is distributed in the hope that it will be useful, +//# but WITHOUT ANY WARRANTY; without even the implied warranty of +//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//# GNU General Public License for more details. +//# +//# You should have received a copy of the GNU General Public License +//# along with this program; if not, write to the Free Software +//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//# +//# $Id$ + +#ifndef DAEMONIZE_H_ +#define DAEMONIZE_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * Function to put a daemon process in the background. + * + * Call this function to safely make the current process a daemon + * detects whether we were started from init - NOTE: this test is + * unreliable, if the parent dies VERY quickly then we will mistakenly + * think we started from init + * @param nofork if != 0 then do not try to fork at all + * @returns 0 on success, -1 or errno on failure + */ +int daemonize(int nofork); + +#ifdef __cplusplus +} +#endif + +#endif /* DAEMONIZE_H_ */ diff --git a/MAC/APL/RTCCommon/src/Makefile.am b/MAC/APL/RTCCommon/src/Makefile.am index 9669dc89c65..d4490ba808e 100644 --- a/MAC/APL/RTCCommon/src/Makefile.am +++ b/MAC/APL/RTCCommon/src/Makefile.am @@ -25,7 +25,8 @@ lib_LTLIBRARIES = librtccommon.la libgnuplot_i.la librtccommon_la_SOURCES = \ Timestamp.cc \ - Subject.cc + Subject.cc \ + daemonize.c libgnuplot_i_la_SOURCES = \ gnuplot_i.cc diff --git a/MAC/APL/RTCCommon/src/daemonize.c b/MAC/APL/RTCCommon/src/daemonize.c new file mode 100644 index 00000000000..f47eb93401d --- /dev/null +++ b/MAC/APL/RTCCommon/src/daemonize.c @@ -0,0 +1,131 @@ +/* daemonize.c + $Id$ + Glen Wiley, <gwiley@gwiley.com> + + TODO: some implementations may call setpgrp with args (UNPv1) + TODO: BSD may want us to call wait3() on child signals (UNPv1) + TODO: regression tests +*/ + +#if HAVE_CONFIG_H +//# include "config.h" +#include <lofar_config.h> +#endif + +#include <errno.h> +#if HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#if HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#if HAVE_UNISTD_H +# include <unistd.h> +#endif +#if HAVE_SYS_RESOURCE_H +# include <sys/resource.h> +#endif +#if HAVE_SIGNAL_H +# include <signal.h> +#endif + +/* the umask gets set to this */ +static const mode_t NEWUMASK= S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH + | S_IXOTH; + +/*---------------------------------------- daemonize + call this function to safely make the current process a daemon + detects whether we were started from init - NOTE: this test is + unreliable, if the parent dies VERY quickly then we will mistakenly + think we started from init + if nofork != 0 then do not try to fork at all + returns 0 on success, -1 or errno on failure +*/ +int daemonize(int nofork) +{ + pid_t pid; + int i; + struct rlimit rlim; +#if HAVE_SIGACTION + struct sigaction sact; + sigset_t sset; +#endif + + /* get into the background if not started by init */ + if(nofork != 0 || getppid() != 1) + { + pid = fork(); + if(pid == -1) + return errno; + if(pid != 0) + exit(0); + + /* dissociate from process group and control terminal */ +#if HAVE_SETSID + setsid(); +#else +# if HAVE_SETPGRP + setpgrp(); +# endif +#endif + +#if HAVE_SIGACTION + sigemptyset(&sset); + sact.sa_mask = sset; + sact.sa_handler = SIG_IGN; + if(sigaction(SIGHUP, &sact, NULL) != 0) + return errno; +#else + if(signal(SIGHUP, SIG_IGN) != 0) + return errno; +#endif + + pid = fork(); + if(pid == -1) + return errno; + if(pid != 0) + exit(0); + + /* ignore terminal io signals */ +#if HAVE_SIGACTION + if(sigaction(SIGTTIN, &sact, NULL) != 0) + return errno; + if(sigaction(SIGTTOU, &sact, NULL) != 0) + return errno; + if(sigaction(SIGTSTP, &sact, NULL) != 0) + return errno; + if(sigaction(SIGCLD, &sact, NULL) != 0) + return errno; +#else + if(signal(SIGTTIN, SIG_IGN) != 0) + return errno; + if(signal(SIGTTOU, SIG_IGN) != 0) + return errno; + if(signal(SIGTSTP, SIG_IGN) != 0) + return errno; + if(signal(SIGCLD, SIG_IGN) != 0) + return errno; +#endif + } /* if(getppid() == 1) */ + + /* close all file descriptors */ + if(getrlimit(RLIMIT_NOFILE, &rlim) != 0) + return errno; + for(i=0; i<rlim.rlim_cur; i++) + close(i); + errno = 0; + +/* Don't change dir. It bites LOFAR appliations. */ +#if 0 + /* change to root directory to free up mounts */ + if(chdir("/") != 0) + return errno; +#endif + + /* reset file creation mask to rather restrictive */ + (void)umask(NEWUMASK); + + return 0; +} /* daemonize */ + +/* daemonize.c */ -- GitLab