summaryrefslogtreecommitdiff
path: root/cpp/src/qpidd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/qpidd.cpp')
-rw-r--r--cpp/src/qpidd.cpp106
1 files changed, 83 insertions, 23 deletions
diff --git a/cpp/src/qpidd.cpp b/cpp/src/qpidd.cpp
index ec8fe570d3..e199c72683 100644
--- a/cpp/src/qpidd.cpp
+++ b/cpp/src/qpidd.cpp
@@ -19,35 +19,58 @@
*
*/
#include <Broker.h>
-#include <signal.h>
#include <iostream>
#include <memory>
#include <config.h>
-#include <unistd.h>
#include <fstream>
+#include <signal.h>
+#include <Daemon.h>
+#include <boost/format.hpp>
+using boost::format;
using namespace qpid;
using namespace qpid::broker;
using namespace qpid::sys;
using namespace std;
+Broker::shared_ptr brokerPtr;
+
+void handle_signal(int /*signal*/){
+ std::cerr << "Shutting down..." << std::endl;
+ brokerPtr->shutdown();
+}
+
+
/** Command line options */
struct QpiddOptions : public Broker::Options
{
bool help;
bool version;
bool daemon;
+ bool quit;
+ bool kill;
+ bool check;
+ bool ppid;
+ int wait;
string config;
po::options_description desc;
QpiddOptions() :
help(false), version(false), daemon(false),
+ quit(false), kill(false), check(false), ppid(false), wait(10),
config("/etc/qpidd.conf"),
desc("Options")
{
using namespace po;
desc.add_options()
- ("daemon,d", optValue(daemon), "Run as a daemon");
+ ("daemon,d", optValue(daemon), "Run as a daemon.")
+ ("quit,q", optValue(quit), "Stop the running daemon politely.")
+ ("kill,k", optValue(kill), "Kill the running daemon harshly.")
+ ("check,c", optValue(check), "If daemon is running return 0.")
+ ("wait", optValue(wait, "SECONDS"),
+ "Maximum wait for daemon response.")
+ ("ppid", optValue(ppid), "Print daemon pid to stdout" );
+ po::options_description brokerOpts;
Broker::Options::addTo(desc);
desc.add_options()
("config", optValue(config, "FILE"), "Configuation file")
@@ -87,43 +110,80 @@ ostream& operator<<(ostream& out, const QpiddOptions& config) {
config.usage(out); return out;
}
-Broker::shared_ptr brokerPtr;
-
-void handle_signal(int /*signal*/){
- if (brokerPtr) {
- cerr << "Shutting down..." << endl;
- brokerPtr->shutdown();
- }
-}
-
int main(int argc, char* argv[])
{
QpiddOptions config;
try {
config.parse(argc, argv);
+ string name=(format("%s.%d")
+ % Daemon::nameFromArgv0(argv[0])
+ % (config.port)).str();
+ // Spelled 'demon' to avoid clash with daemon.h function.
+ Daemon demon(name, config.wait);
+
+ // Options that just print information.
if(config.help) {
config.usage(cout);
+ return 0;
}
- else if (config.version) {
+ if (config.version) {
cout << "qpidd (" << PACKAGE_NAME << ") version "
<< PACKAGE_VERSION << endl;
+ return 0;
}
- else {
- brokerPtr=Broker::create(config);
- signal(SIGINT, handle_signal);
- if (config.daemon) {
- if (daemon(0, 0) < 0) // daemon(nochdir, noclose)
- throw QPID_ERROR(
- INTERNAL_ERROR,
- "Failed to detach as daemon: "+ strError(errno));
+
+ // Options that affect an already running daemon.
+ if (config.quit || config.kill || config.check) {
+ pid_t pid = demon.check();
+ if (config.ppid && pid > 0)
+ cout << pid << endl;
+ if (config.kill)
+ demon.kill();
+ else if (config.quit)
+ demon.quit();
+ if (config.check && pid <= 0)
+ return 1;
+ return 0;
+ }
+
+ // Starting the broker:
+ signal(SIGINT, handle_signal);
+ if (config.daemon) {
+ pid_t pid = demon.fork();
+ if (pid == 0) { // Child
+ try {
+ brokerPtr=Broker::create(config);
+ demon.ready(); // Notify parent we're ready.
+ brokerPtr->run();
+ } catch (const exception& e) {
+ // TODO aconway 2007-04-26: Log this, cerr is lost.
+ cerr << "Broker daemon failed: " << e.what() << endl;
+ demon.failed(); // Notify parent we failed.
+ return 1;
+ }
}
- brokerPtr->run();
+ else if (pid > 0) { // Parent
+ if (config.ppid)
+ cout << pid << endl;
+ return 0;
+ }
+ else { // pid < 0
+ throw Exception("fork failed"+strError(errno));
+ }
+ } // Non-daemon broker.
+ else {
+ brokerPtr = Broker::create(config);
+ brokerPtr->run();
}
return 0;
}
- catch(const exception& e) {
+ catch(const po::error& e) {
+ // Command line parsing error.
cerr << "Error: " << e.what() << endl
<< "Type 'qpidd --help' for usage." << endl;
}
+ catch(const exception& e) {
+ cerr << "Error: " << e.what() << endl;
+ }
return 1;
}