Author: aconway
Date: Wed Jul 18 19:19:17 2007
New Revision: 557455

URL: http://svn.apache.org/viewvc?view=rev&rev=557455
Log:

        * src/qpid/broker/Daemon.cpp, .h
         - Rewrote to remove libdaemon dependency.
         - PID file stored in /var/run if root, /tmp otherwise.

        * src/qpidd.cpp: Use new Daemon.cpp.

        * lib/broker/Makefile.am (libqpidbroker_la_LIBADD): 
         - Daemon.cpp now needs -lboost_iostreams
         
        * NOTICE, README, qpidc.spec.in: Removed mention of libdaemon.

        * configure.ac:
         - removed libdaemon
         - cluster off by default - no ais dependencies.

Modified:
    incubator/qpid/trunk/qpid/cpp/NOTICE
    incubator/qpid/trunk/qpid/cpp/README
    incubator/qpid/trunk/qpid/cpp/configure.ac
    incubator/qpid/trunk/qpid/cpp/qpidc.spec.in
    incubator/qpid/trunk/qpid/cpp/src/Makefile.am
    incubator/qpid/trunk/qpid/cpp/src/qpid/broker/Daemon.cpp
    incubator/qpid/trunk/qpid/cpp/src/qpid/broker/Daemon.h
    incubator/qpid/trunk/qpid/cpp/src/qpidd.cpp

Modified: incubator/qpid/trunk/qpid/cpp/NOTICE
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/NOTICE?view=diff&rev=557455&r1=557454&r2=557455
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/NOTICE (original)
+++ incubator/qpid/trunk/qpid/cpp/NOTICE Wed Jul 18 19:19:17 2007
@@ -23,13 +23,5 @@
        can be downloaded from http://www.boost.org
        - Included in most OS platfroms by defualt.
 
-Optional modules:
-       
- * libdaemon version 0.10 under LGPL and can be downloaded from 
-       http://www.stud.uni-hamburg.de/users/lennart/projects/libdaemon
-       -Optional module detected by configure scripts if present to create 
-       daemon process. 
-
-
              
 

Modified: incubator/qpid/trunk/qpid/cpp/README
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/README?view=diff&rev=557455&r1=557454&r2=557455
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/README (original)
+++ incubator/qpid/trunk/qpid/cpp/README Wed Jul 18 19:19:17 2007
@@ -38,7 +38,6 @@
  * apr     <http://apr.apache.org>          (1.2.7)
  * boost   <http://www.boost.org>           (1.33.1)
  * cppunit <http://cppunit.sourceforge.net> (1.11.4)
- * libdaemon <http://www.stud.uni-hamburg.de/users/lennart/projects/libdaemon> 
(0.10)
  * uuid    <http://e2fsprogs.sourceforge.net/> (1.39)
 
 Using tools:
@@ -74,7 +73,7 @@
 On linux most packages can be installed using your distribution's package
 management tool. For example on Fedora:
 
-  # yum install apr-devel boost-devel cppunit-devel libdaemon-devel  
e2fsprogs-devel
+  # yum install apr-devel boost-devel cppunit-devel e2fsprogs-devel
   # yum install pkgconfig doxygen graphviz help2man
 
 Follow the manual installation instruction below for any packages not

Modified: incubator/qpid/trunk/qpid/cpp/configure.ac
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/configure.ac?view=diff&rev=557455&r1=557454&r2=557455
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/configure.ac (original)
+++ incubator/qpid/trunk/qpid/cpp/configure.ac Wed Jul 18 19:19:17 2007
@@ -156,30 +156,31 @@
 AC_SUBST(DOWNLOAD_URL)
 
 # Check for headers from required devel kits.
-missing=""
-AC_CHECK_HEADERS([libdaemon/daemon.h],,[missing="$missing libdaemon"])
-AC_CHECK_HEADERS([boost/shared_ptr.hpp],,[missing="$missing boost"])
-AC_CHECK_HEADERS([uuid/uuid.h],,[missing="$missing libuuid"])
-test -z "$missing" ||
-    AC_MSG_ERROR([Missing required headers. Install the following packages or 
-devel rpms: $missing.])
+AC_CHECK_HEADERS([boost/shared_ptr.hpp uuid/uuid.h],,
+  AC_MSG_ERROR([Missing required header files.]))
 
-# Enable/disable cluster functionality based on presence of usable openais
-# and devel libs.
-# cpg_local_get is not yet in a packaged release as of 2007-06-20
-LDFLAGS_save=$LDFLAGS                          
-LDFLAGS="$LDFLAGS -L/usr/lib/openais -L/usr/lib64/openais"
-AC_CHECK_LIB([cpg], [cpg_local_get], [libcpg=yes], [libcpg=no])
-AC_CHECK_HEADER([openais/cpg.h],[cpg_h=yes],[cpg_h=no])
-if test x$libcpg = xyes -a x$cpg_h = xyes; then
-   AM_CONDITIONAL([CLUSTER], true)
-   CPPFLAGS+=" -DCLUSTER"
-else
-  AM_CONDITIONAL([CLUSTER], false)     
-  LDFLAGS=$LDFLAGS_save           
-fi
-if test x$libcpg = xno -a x$cpg_h = xyes; then
-   AC_MSG_WARN([Found cpg.h but libcpg is missing or does not contain 
cpg_local_get. Need build of openais whitetank branch head as of 2007-06-20])
+# Enable cluster functionality.
+AC_ARG_ENABLE([cluster],
+  [AS_HELP_STRING([--enable-cluster],
+    [Enable cluster functionality, requires openais (default no)])],
+  [case $enableval in
+    yes|no) enable_CLUSTER=$enableval;;
+    *) AC_MSG_ERROR([Invalid value for --enable-apr-cluster: $enableval]);;
+   esac],
+  [enable_CLUSTER=no])
+
+AM_CONDITIONAL([CLUSTER], [test x$enable_CLUSTER = xyes])
+if test x$enable_CLUSTER = xyes; then
+  CPPFLAGS+=" -DCLUSTER"
+  LDFLAGS="$LDFLAGS -L/usr/lib/openais -L/usr/lib64/openais"
+  # cpg_local_get is not yet in a packaged release as of 2007-06-20
+  AC_CHECK_LIB([cpg],[cpg_local_get],,
+    AC_MSG_ERROR([cpg_local_get not available. openais missing/too old.]))
+   AC_CHECK_HEADERS([openais/cpg.h],,
+     AC_MSG_ERROR([Required header files not found.],[]))
 fi
+
+       
 AC_CONFIG_FILES([
   qpidc.spec
   Makefile

Modified: incubator/qpid/trunk/qpid/cpp/qpidc.spec.in
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/qpidc.spec.in?view=diff&rev=557455&r1=557454&r2=557455
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/qpidc.spec.in (original)
+++ incubator/qpid/trunk/qpid/cpp/qpidc.spec.in Wed Jul 18 19:19:17 2007
@@ -20,7 +20,6 @@
 BuildRequires: e2fsprogs-devel
 BuildRequires: graphviz
 BuildRequires: help2man
-BuildRequires: libdaemon-devel
 BuildRequires: libtool
 BuildRequires: pkgconfig
 

Modified: incubator/qpid/trunk/qpid/cpp/src/Makefile.am
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/Makefile.am?view=diff&rev=557455&r1=557454&r2=557455
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/Makefile.am (original)
+++ incubator/qpid/trunk/qpid/cpp/src/Makefile.am Wed Jul 18 19:19:17 2007
@@ -183,7 +183,7 @@
   qpid/log/Statement.h \
   qpid/memory.h
 
-libqpidbroker_la_LIBADD = libqpidcommon.la -ldaemon -lboost_filesystem
+libqpidbroker_la_LIBADD = libqpidcommon.la -lboost_iostreams
 libqpidbroker_la_SOURCES = \
   qpid/broker/AccumulatedAck.cpp \
   qpid/broker/Broker.cpp \

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/broker/Daemon.cpp
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/broker/Daemon.cpp?view=diff&rev=557455&r1=557454&r2=557455
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/broker/Daemon.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/broker/Daemon.cpp Wed Jul 18 
19:19:17 2007
@@ -18,126 +18,162 @@
 #include "Daemon.h"
 #include "qpid/log/Statement.h"
 #include "qpid/QpidError.h"
-#include <libdaemon/daemon.h>
+
+#include <boost/iostreams/stream.hpp>
+#include <boost/iostreams/device/file_descriptor.hpp>
+
 #include <errno.h>
-#include <unistd.h>
-#include <sys/stat.h>
+#include <fcntl.h>
 #include <signal.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
 
 namespace qpid {
 namespace broker {
 
 using namespace std;
+typedef boost::iostreams::stream<boost::iostreams::file_descriptor> fdstream;
 
-boost::function<std::string()> qpid::broker::Daemon::pidFileFn;
-
-std::string Daemon::defaultPidFile(const std::string& identifier) {
-    daemon_pid_file_ident=identifier.c_str();
-    return daemon_pid_file_proc_default();
+namespace {
+/** Throw an exception containing msg and strerror if throwIf is true.
+ * Name is supposed to be reminiscent of perror().
+ */
+void terror(bool throwIf, const string& msg, int errNo=errno) {
+    if (throwIf)
+        throw Exception(msg + (errNo? ": "+strError(errNo) : string(".")));
 }
 
-const char* Daemon::realPidFileFn() {
-    static std::string str = pidFileFn();
-    return str.c_str();
-}
 
-Daemon::Daemon(boost::function<std::string()> fn, int secs) : pid(-1), 
timeout(secs)
-{
-    pidFileFn = fn;
-    daemon_pid_file_proc = &realPidFileFn;
-}
+struct LockFile : public fdstream {
+
+    LockFile(const std::string& path_, bool create)
+        : path(path_), fd(-1), created(create)
+    {
+        errno = 0;
+        int flags=create ? O_WRONLY|O_CREAT|O_NOFOLLOW : O_RDWR;
+        fd = ::open(path.c_str(), flags, 0644);
+        terror(fd < 0,"Cannot open "+path);
+        terror(::lockf(fd, F_TLOCK, 0) < 0, "Cannot lock "+path);
+        open(boost::iostreams::file_descriptor(fd));
+    }
 
-Daemon::~Daemon() {
-    if (isChild())
-        daemon_pid_file_remove();
-}
+    ~LockFile() {
+        if (fd >= 0) {
+            ::lockf(fd, F_ULOCK, 0);
+            close();
+        }
+    }
 
-class Daemon::Retval {
-  public:
-    Retval();
-    ~Retval();
-    int send(int s);
-    int wait(int timeout);
-  private:
-    bool completed;
+    std::string path;
+    int fd;
+    bool created;
 };
 
-pid_t Daemon::fork(Function parent, Function child) {
-    retval.reset(new Retval());
-    pid = daemon_fork();
-    if (pid < 0)
-        throw Exception("Failed to fork daemon: "+strError(errno));
-    else if (pid == 0) {
-        try {
-            child(*this);
-        } catch (const exception& e) {
-            QPID_LOG(debug, "Rethrowing: " << e.what());
-            failed();           // Notify parent
-            throw;
-        }
-    }
-    else
-        parent(*this);
-    return pid;
-}
+} // namespace
 
-int Daemon::wait() {  // parent 
-    assert(retval);
-    errno = 0;                  // Clear errno.
-    int ret = retval->wait(timeout); // wait for child.
-    if (ret == -1) {
-        if (errno)
-            throw Exception("Error waiting for daemon startup:"
-                            +strError(errno));
-        else
-            throw Exception("Error waiting for daemon startup, check logs.");
-    }
-    return ret;
+Daemon::Daemon() {
+    pid = -1;
+    pipeFds[0] = pipeFds[1] = -1;
 }
 
-void Daemon::notify(int value) { // child
-    assert(retval);
-    if (retval->send(value)) 
-        throw Exception("Failed to notify parent: "+strError(errno));
+string Daemon::dir() {
+    return (getuid() == 0 ? "/var/run" : "/tmp");
 }
 
-void Daemon::ready(int value) { // child
-    if (value==-1)
-        throw Exception("Invalid value in Dameon::notify");
-    errno = 0;
-    if (daemon_pid_file_create() != 0)
-        throw Exception(string("Failed to create PID file ") +
-                        daemon_pid_file_proc()+": "+strError(errno));
-    notify(value);
+string Daemon::pidFile(uint16_t port) {
+    ostringstream path;
+    path << dir() << "/qpidd." << port << ".pid";
+    return path.str();
 }
 
-void Daemon::failed() { notify(-1); }
+void Daemon::fork()
+{
+    terror(pipe(pipeFds) < 0, "Can't create pipe");
+    terror((pid = ::fork()) < 0, "Daemon fork failed");
+    if (pid == 0) {             // Child
+        try {
+            // File descriptors
+            terror(::close(pipeFds[0])<0, "Cannot close read pipe");
+            terror(::close(0)<0, "Cannot close stdin");
+            terror(::close(1)<0, "Cannot close stdout");
+            terror(::close(2)<0, "Cannot close stderr");
+            int fd=::open("/dev/null",O_RDWR); // stdin
+            terror(fd != 0, "Cannot re-open stdin");
+            terror(::dup(fd)<0, "Cannot re-open stdout");
+            terror(::dup(fd)<0, "Cannot re-open stderror");
+
+            // Misc
+            terror(setsid()<0, "Cannot set session ID");
+            terror(chdir(dir().c_str()) < 0, "Cannot change directory to 
"+dir());
+            umask(027);
 
-void  Daemon::quit() { 
-    if (daemon_pid_file_kill_wait(SIGINT, timeout))
-        throw Exception("Failed to stop daemon: " + strError(errno));
+            // Child behavior
+            child();
+        }
+        catch (const exception& e) {
+            QPID_LOG(critical, "Daemon startup failed: " << e.what());
+            fdstream pipe(pipeFds[1]);
+            assert(pipe.is_open());
+            pipe << "0 " << e.what() << endl;
+        }
+    }
+    else {                      // Parent
+        close(pipeFds[1]);      // Write side.
+        parent();
+    }
 }
 
-void  Daemon::kill() {
-    if (daemon_pid_file_kill_wait(SIGKILL, timeout) < 0)
-        throw Exception("Failed to stop daemon: " + strError(errno));
+Daemon::~Daemon() {
+    if (!lockFile.empty()) 
+        unlink(lockFile.c_str());
 }
 
-pid_t Daemon::check() {
-    return daemon_pid_file_is_running();
+uint16_t Daemon::wait(int timeout) {            // parent waits for child.
+    errno = 0;                  
+    struct timeval tv;
+    tv.tv_sec = timeout;
+    tv.tv_usec = 0;
+
+    fd_set fds;
+    FD_ZERO(&fds);
+    FD_SET(pipeFds[0], &fds);
+    terror(1 != select(FD_SETSIZE, &fds, 0, 0, &tv), "No response from daemon 
process");
+
+    fdstream pipe(pipeFds[0]);
+    uint16_t value = 0;
+    pipe >> value >> skipws;
+    if (value == 0) {
+        string errmsg;
+        getline(pipe, errmsg);
+        throw Exception("Daemon startup failed"+ (errmsg.empty() ? string(".") 
: ": " + errmsg));
+    }
+    return value;
 }
 
-Daemon::Retval::Retval() : completed(false) {
-    daemon_retval_init();
-}
-Daemon::Retval::~Retval() {
-    if (!completed) daemon_retval_done();
-}
-int Daemon::Retval::send(int s) {
-    return daemon_retval_send(s);
-}
-int Daemon::Retval::wait(int timeout) {
-    return daemon_retval_wait(timeout);
+void Daemon::ready(uint16_t port) { // child
+    lockFile = pidFile(port);
+    LockFile lf(lockFile, true);
+    lf << getpid() << endl;
+    if (lf.fail())
+        throw Exception("Cannot write lock file "+lockFile);
+    fdstream pipe(pipeFds[1]);
+    pipe << port << endl;;
+}
+
+pid_t Daemon::getPid(uint16_t port) {
+    string name = pidFile(port);
+    LockFile lockFile(name, false);
+    pid_t pid;
+    lockFile >> pid;
+    if (lockFile.fail())
+        throw Exception("Cannot read lock file "+name);
+    if (kill(pid, 0) < 0 && errno != EPERM) {
+        unlink(name.c_str());
+        throw Exception("Removing stale lock file "+name);
+    }
+    return pid;
 }
+
 
 }} // namespace qpid::broker

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/broker/Daemon.h
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/broker/Daemon.h?view=diff&rev=557455&r1=557454&r2=557455
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/broker/Daemon.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/broker/Daemon.h Wed Jul 18 19:19:17 
2007
@@ -22,6 +22,7 @@
 #include <string>
 #include <boost/scoped_ptr.hpp>
 #include <boost/function.hpp>
+#include <boost/noncopyable.hpp>
 
 namespace qpid {
 namespace broker {
@@ -30,72 +31,49 @@
  * Tools for forking and managing a daemon process.
  * NB: Only one Daemon instance is allowed in a process.
  */
-class Daemon
+class Daemon : private boost::noncopyable
 {
   public:
-    /** Utility function to create pid file name in a standard place
-     * (may require root acces) using identifier as the file name.
-     */
-    static std::string defaultPidFile(const std::string& identifier);
-    
-    /**
-     * Daemon control object.
-     [EMAIL PROTECTED] pidFileFn Function that will comupte a PID file name.
-     * Called when pid file is created in ready()
-     [EMAIL PROTECTED] timeout in seconds for any operations that wait.
-     */
-    Daemon(boost::function<std::string()> pidFileFn, int timeout);
+    /** Check daemon is running on port, throw exception if not */
+    static pid_t getPid(uint16_t port);
 
-    ~Daemon();
+    Daemon();
 
-    typedef boost::function<void(Daemon&)> Function;
+    virtual ~Daemon();
 
-    /** Fork the daemon.
-     [EMAIL PROTECTED] parent called in the parent process.
-     [EMAIL PROTECTED] child called in the child process.
+    /**
+     * Fork a daemon process.
+     * Call parent() in the parent process, child() in the child.
      */
-    pid_t fork(Function parent, Function child);
+    void fork();
 
-    /** Parent only: wait for child to indicate it is ready.
-     * @return value child passed to ready() */
-    int wait();
+  protected:
 
-    /** Child only. Notify the parent we are ready and write the
-     * PID file.
-     [EMAIL PROTECTED] value returned by parent call to wait(). -1 is reserved
-     * for signalling an error.
-     */
-    void ready(int value);
-    
-    /** Child only, send failed signal so parent fork() will throw. */
-    void failed();
-    
-    /** Kill the daemon with SIGINT. */
-    void quit();
-    
-    /** Kill the daemon with SIGKILL. */
-    void kill();
+    /** Called in parent process */
+    virtual void parent() = 0;
 
-    /** Check daemon is running, throw exception if not */
-    pid_t check();
+    /** Called in child process */
+    virtual void child() = 0;
 
-    bool isParent() { return pid > 0; }
+    /** Call from parent(): wait for child to indicate it is ready.
+     * @timeout in seconds to wait for response.
+     * @return port passed by child to ready().
+     */
+    uint16_t wait(int timeout);
 
-    bool isChild() { return pid == 0; }
+    /** Call from child(): Notify the parent we are ready and write the
+     * PID file.
+     [EMAIL PROTECTED] port returned by parent call to wait().
+     */
+    void ready(uint16_t port);
     
-    pid_t getPid() const {return pid; }
-
   private:
-    class Retval;
+    static std::string dir();
+    static std::string pidFile(uint16_t port);
 
-    static boost::function<std::string()> pidFileFn;
-    static const char* realPidFileFn();
-    void notify(int);
-    
-    static std::string identifier;
-    boost::scoped_ptr<Retval> retval;
     pid_t pid;
-    int timeout;
+    int pipeFds[2];
+    std::string lockFile;
 };
 
 }} // namespace qpid::broker

Modified: incubator/qpid/trunk/qpid/cpp/src/qpidd.cpp
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpidd.cpp?view=diff&rev=557455&r1=557454&r2=557455
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpidd.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpidd.cpp Wed Jul 18 19:19:17 2007
@@ -26,7 +26,6 @@
 #include "qpid/log/Logger.h"
 #include "config.h"
 #include <boost/filesystem/path.hpp>
-#include <boost/filesystem/operations.hpp>
 #include <iostream>
 #include <fstream>
 #include <signal.h>
@@ -77,53 +76,31 @@
 shared_ptr<Broker> brokerPtr;
 QpiddOptions options;
 
-void handle_signal(int /*signal*/){
-    QPID_LOG(notice, "Shutting down...");
+void shutdownHandler(int signal){
+    QPID_LOG(notice, "Shutting down on signal " << signal);
     brokerPtr->shutdown();
 }
 
-/** Compute a name for the pid file */
-std::string pidFileFn() {
-    uint16_t port=brokerPtr ? brokerPtr->getPort() : options.broker.port;
-    string file=(boost::format("qpidd.%d.pid") % port).str();
-    string pidPath;
-    if (getuid() == 0)          // Use standard pid file for root.
-        pidPath=Daemon::defaultPidFile(file);
-    else {                      // Use $HOME/.qpidd for non-root.
-        const char* home=getenv("HOME");
-        if (!home)
-            throw(Exception("$HOME is not set, cant create $HOME/.qpidd."));
-        namespace fs=boost::filesystem;
-        fs::path dir = fs::path(home,fs::native) / fs::path(".qpidd", 
fs::native);
-        fs::create_directory(dir);
-        dir /= file;
-        pidPath=dir.string();
+struct QpiddDaemon : public Daemon {
+    /** Code for parent process */
+    void parent() {
+        uint16_t port = wait(options.daemon.wait);
+        if (options.broker.port == 0)
+            cout << port << endl; 
     }
-    QPID_LOG(debug, "PID file name=" << pidPath);
-    return pidPath;
-}
-
-/** Code for forked parent */
-void parent(Daemon& demon) {
-    uint16_t realPort = demon.wait();
-    if (options.broker.port == 0)
-        cout << realPort << endl; 
-}
 
-/** Code for forked child */
-void child(Daemon& demon) {
-    brokerPtr.reset(new Broker(options.broker));
-    uint16_t realPort=brokerPtr->getPort();
-    demon.ready(realPort);   // Notify parent.
-    brokerPtr->run();
-}
+    /** Code for forked child process */
+    void child() {
+        brokerPtr.reset(new Broker(options.broker));
+        uint16_t port=brokerPtr->getPort();
+        ready(port);            // Notify parent.
+        brokerPtr->run();
+    }
+};
 
 
 int main(int argc, char* argv[])
 {
-    // Spelled 'demon' to avoid clash with daemon.h function.
-    Daemon demon(pidFileFn, options.daemon.wait);
-
     try {
         options.parse(argc, argv, options.common.config);
         qpid::log::Logger::instance().configure(options.log, argv[0]);
@@ -138,27 +115,34 @@
             return 0;
         }
 
-        // Stop running daemon
-        if (options.daemon.quit) {
-            demon.quit();
-            return 0;
-        }
-
-        // Query running daemon
-        if (options.daemon.check) {
-            pid_t pid = demon.check();
+        // Options that affect a running daemon.
+        if (options.daemon.check || options.daemon.quit) {
+            pid_t pid = Daemon::getPid(options.broker.port);
             if (pid < 0) 
                 return 1;
-            else {
+            if (options.daemon.check)
                 cout << pid << endl;
-                return 0;
-            }
+            if (options.daemon.quit && kill(pid, SIGINT) < 0)
+                throw Exception("Failed to stop daemon: " + strError(errno));
+            return 0;
         }
 
-        // Starting the broker:
-        signal(SIGINT, handle_signal);
-        if (options.daemon.daemon) {    // Daemon broker
-            demon.fork(parent, child);
+        // Starting the broker.
+
+        // Signal handling
+        signal(SIGINT,shutdownHandler); 
+        signal(SIGTERM,shutdownHandler);
+        signal(SIGHUP,SIG_IGN); // TODO aconway 2007-07-18: reload config.
+
+        signal(SIGCHLD,SIG_IGN); 
+        signal(SIGTSTP,SIG_IGN); 
+        signal(SIGTTOU,SIG_IGN);
+        signal(SIGTTIN,SIG_IGN);
+            
+        if (options.daemon.daemon) {
+            // Fork the daemon
+            QpiddDaemon d;
+            d.fork();
         } 
         else {                  // Non-daemon broker.
             brokerPtr.reset(new Broker(options.broker));
@@ -169,10 +153,7 @@
         return 0;
     }
     catch(const exception& e) {
-        if (demon.isParent())
-            cerr << e.what() << endl;
-        else
-            QPID_LOG(critical, e.what());
+        cerr << e.what() << endl;
     }
     return 1;
 }


Reply via email to