summaryrefslogtreecommitdiff
path: root/cpp/lib
diff options
context:
space:
mode:
authorAlan Conway <aconway@apache.org>2007-04-30 18:08:17 +0000
committerAlan Conway <aconway@apache.org>2007-04-30 18:08:17 +0000
commitb16914a34d89e4b99eceb0a3f5b277d454c4e39f (patch)
tree669e6c913361f3fb1ce27e5159534f1290238720 /cpp/lib
parent80b492223507dbb4a64a3e1c5e6e3f65ac53afa1 (diff)
downloadqpid-python-b16914a34d89e4b99eceb0a3f5b277d454c4e39f.tar.gz
* README: added new dependency, libdaemon.
* qpidc.spec.in: libdaemon dependencies. * broker/Daemon.h|cpp: Daemon and pid file management, wrapper for libdaemon. * qpidd.cpp modifid flags -d [ --daemon ] - waits till deamon is listening before returning. * qpidd.cpp: new flags -q [ --quit ] Stop the running daemon politely. -k [ --kill ] Kill the running daemon harshly. -c [ --check ] If daemon is running return 0. --wait SECONDS (=10) Maximum wait for daemon response. --ppid Print daemon pid to stdout * tests/dameon_test: Test daemon startup, shutdown. * deleted tests/broker: obsolete script. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/branches/M2@533819 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/lib')
-rw-r--r--cpp/lib/broker/Daemon.cpp144
-rw-r--r--cpp/lib/broker/Daemon.h91
-rw-r--r--cpp/lib/broker/Makefile.am8
3 files changed, 242 insertions, 1 deletions
diff --git a/cpp/lib/broker/Daemon.cpp b/cpp/lib/broker/Daemon.cpp
new file mode 100644
index 0000000000..d54882a274
--- /dev/null
+++ b/cpp/lib/broker/Daemon.cpp
@@ -0,0 +1,144 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include "QpidError.h"
+#include "Daemon.h"
+#include <libdaemon/daemon.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <signal.h>
+#include <boost/filesystem/path.hpp>
+#include <boost/filesystem/operations.hpp>
+
+namespace qpid {
+namespace broker {
+
+using namespace std;
+
+string Daemon::pidFile;
+string Daemon::name;
+
+string Daemon::nameFromArgv0(const char* argv0) {
+ return string(daemon_ident_from_argv0(const_cast<char*>(argv0)));
+}
+
+const char* Daemon::getPidFile() {
+ if (pidFile.empty()) {
+ const char* home=getenv("HOME");
+ if (!home)
+ throw(Exception("$HOME is not set, cant create $HOME/.qpidd."));
+ using namespace boost::filesystem;
+ path dir = path(home,native) / path(".qpidd", native);
+ create_directory(dir);
+ dir /= name;
+ pidFile = dir.string();
+ }
+ return pidFile.c_str();
+}
+
+Daemon::Daemon(const string& name_, int secs) : timeout(secs)
+{
+ name = name_;
+ daemon_pid_file_ident = daemon_log_ident = name.c_str();
+ if (getuid() != 0) {
+ // For normal users put pid file under $HOME/.qpid
+ daemon_pid_file_proc = getPidFile;
+ }
+ // For root use the libdaemon default: /var/run.
+}
+
+Daemon::~Daemon() {
+ if (isChild())
+ daemon_pid_file_remove();
+}
+
+class Daemon::Retval {
+ public:
+ Retval();
+ ~Retval();
+ int send(int s);
+ int wait(int timeout);
+ private:
+ bool completed;
+};
+
+pid_t Daemon::fork() {
+ retval.reset(new Retval());
+ pid = daemon_fork();
+ if (pid < 0)
+ throw Exception("Failed to fork daemon: "+strError(errno));
+ else if (pid > 0) {
+ int ret = retval->wait(timeout); // parent, wait for child.
+ if (ret != 0) {
+ string err;
+ if (ret > 0)
+ err = strError(ret);
+ else if (ret == -1)
+ err= strError(errno);
+ else
+ err= "unknown error";
+ throw Exception("Deamon startup failed: "+err);
+ }
+ }
+ else if (pid == 0) { // child.
+ // TODO aconway 2007-04-26: Should log failures.
+ if (daemon_pid_file_create())
+ failed();
+ }
+ return pid;
+}
+
+void Daemon::notify(int i) {
+ assert(retval);
+ if (retval->send(i))
+ throw Exception("Failed to notify parent: "+strError(errno));
+}
+
+void Daemon::ready() { notify(0); }
+
+// NB: Not -1, confused with failure of fork() on the parent side.
+void Daemon::failed() { notify(errno? errno:-2); }
+
+void Daemon::quit() {
+ if (daemon_pid_file_kill_wait(SIGINT, timeout))
+ throw Exception("Failed to stop daemon: " + strError(errno));
+}
+
+void Daemon::kill() {
+ if (daemon_pid_file_kill_wait(SIGKILL, timeout) < 0)
+ throw Exception("Failed to stop daemon: " + strError(errno));
+}
+
+pid_t Daemon::check() {
+ return daemon_pid_file_is_running();
+}
+
+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);
+}
+
+}} // namespace qpid::broker
diff --git a/cpp/lib/broker/Daemon.h b/cpp/lib/broker/Daemon.h
new file mode 100644
index 0000000000..cf9bf13764
--- /dev/null
+++ b/cpp/lib/broker/Daemon.h
@@ -0,0 +1,91 @@
+#ifndef _broker_Daemon_h
+#define _broker_Daemon_h
+
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <string>
+#include <boost/scoped_ptr.hpp>
+
+namespace qpid {
+namespace broker {
+
+/**
+ * Tools for forking and managing a daemon process.
+ * NB: Only one Daemon instance is allowed in a process.
+ */
+class Daemon
+{
+ public:
+
+ /** Extract the daemon's name from argv[0] */
+ static std::string nameFromArgv0(const char* argv0);
+
+ /**
+ * Creating a Daemon instance forks a daemon process.
+ *@param name used to create pid files etc.
+ *@param timeout in seconds for all operations that wait.
+ */
+ Daemon(const std::string& name, int timeout);
+
+ ~Daemon();
+
+ /** Fork the daemon, wait till it signals readiness */
+ pid_t fork();
+
+ /** Child only, send ready signal so parent fork() will return. */
+ void ready();
+
+ /** 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();
+
+ /** Check daemon is running, throw exception if not */
+ pid_t check();
+
+ bool isParent() { return pid > 0; }
+
+ bool isChild() { return pid == 0; }
+
+ std::string getName() const { return name; }
+
+ pid_t getPid() const {return pid; }
+
+ private:
+ class Retval;
+
+ void notify(int);
+
+ static std::string name;
+ static std::string pidFile;
+ static const char* getPidFile();
+ boost::scoped_ptr<Retval> retval;
+ pid_t pid;
+ int timeout;
+};
+
+}} // namespace qpid::broker
+
+
+
+#endif /*!_broker_Daemon_h*/
diff --git a/cpp/lib/broker/Makefile.am b/cpp/lib/broker/Makefile.am
index dfc0315902..5da38adc33 100644
--- a/cpp/lib/broker/Makefile.am
+++ b/cpp/lib/broker/Makefile.am
@@ -7,7 +7,11 @@ INCLUDES = \
$(APR_CXXFLAGS)
lib_LTLIBRARIES = libqpidbroker.la
-libqpidbroker_la_LIBADD = ../common/libqpidcommon.la
+libqpidbroker_la_LIBADD = \
+ ../common/libqpidcommon.la \
+ -ldaemon \
+ -lboost_filesystem
+
libqpidbroker_la_LDFLAGS = -version-info $(LIBTOOL_VERSION_INFO_ARG)
libqpidbroker_la_SOURCES = \
AccumulatedAck.cpp \
@@ -27,6 +31,8 @@ libqpidbroker_la_SOURCES = \
ConnectionToken.h \
Consumer.h \
Content.h \
+ Daemon.cpp \
+ Daemon.h \
DeletingTxOp.cpp \
DeletingTxOp.h \
Deliverable.h \