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