summaryrefslogtreecommitdiff
path: root/cpp/src/qpidd.cpp
diff options
context:
space:
mode:
authorAlan Conway <aconway@apache.org>2007-06-11 16:05:06 +0000
committerAlan Conway <aconway@apache.org>2007-06-11 16:05:06 +0000
commitb59a0092f12a07f925bc0b1c7f8cf4949dd374e7 (patch)
treec6c188962552bac59bb96b8b7b00d791ae9e4be1 /cpp/src/qpidd.cpp
parent4c88e1be1c96cf27b8418df2a60c3cbbefd92fcc (diff)
downloadqpid-python-b59a0092f12a07f925bc0b1c7f8cf4949dd374e7.tar.gz
QPID-504: Print bound port if --port 0 is specified. Not yet used by tests.
* qpidd.cpp: - With --port 0 print the bound port number to stdout. - Removed --ppid, --check now prints pid. * Daemon.cpp/h: Move pid-file generation to caller (qpidd.cpp) * Exception.cpp: Log a debug message in exception constructors. Helps to show what exceptions were thrown even if they aren't logged at a higher level. * daemon_test: Test new daemon options. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@546180 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src/qpidd.cpp')
-rw-r--r--cpp/src/qpidd.cpp160
1 files changed, 94 insertions, 66 deletions
diff --git a/cpp/src/qpidd.cpp b/cpp/src/qpidd.cpp
index 2f4d16f0a7..3378fcdc96 100644
--- a/cpp/src/qpidd.cpp
+++ b/cpp/src/qpidd.cpp
@@ -25,23 +25,18 @@
#include "qpid/log/Options.h"
#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>
+#include <unistd.h>
using namespace qpid;
using namespace qpid::broker;
using namespace qpid::sys;
using namespace std;
-Broker::shared_ptr brokerPtr;
-
-void handle_signal(int /*signal*/){
- QPID_LOG(notice, "Shutting down...");
- brokerPtr->shutdown();
-}
-
-
/** Command line options */
struct QpiddOptions : public Broker::Options, public log::Options
{
@@ -52,39 +47,42 @@ struct QpiddOptions : public Broker::Options, public log::Options
bool quit;
bool kill;
bool check;
- bool ppid;
int wait;
string config;
po::options_description mainOpts;
po::options_description allOpts;
- po::options_description logOpts;
QpiddOptions() :
help(false), version(false), daemon(false),
- quit(false), kill(false), check(false), ppid(false), wait(10),
+ quit(false), check(false),
+ wait(10),
config("/etc/qpidd.conf"),
- mainOpts("Options"),
- logOpts("Logging Options")
+ mainOpts("Broker Options")
{
using namespace po;
- mainOpts.add_options()
- ("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;
+ // First set up the sub-option groups.
+ options_description daemonOpts("Daemon Options");
+ daemonOpts.add_options()
+ ("daemon,d", optValue(daemon), "Run as a daemon. With --port 0 print actual listening port.")
+ ("wait,w", optValue(wait, "SECONDS"), "Maximum wait for daemon response.")
+ ("check,c", optValue(check), "If a daemon is running print its pid to stdout and return 0.")
+ ("quit,q", optValue(quit), "Stop the running daemon politely.");
+
+ options_description logOpts("Logging Options");
+ log::Options::addTo(logOpts);
+
+ // Populate the main options group for --help
Broker::Options::addTo(mainOpts);
mainOpts.add_options()
("config", optValue(config, "FILE"), "Configuation file.")
("help,h", optValue(help), "Print help message.")
("long-help", optValue(longHelp), "Show complete list of options.")
("version,v", optValue(version), "Print version information.");
+ mainOpts.add(daemonOpts);
- log::Options::addTo(logOpts);
+ // Populate the all options group
allOpts.add(mainOpts).add(logOpts);
+
}
void parse(int argc, char* argv[]) {
@@ -97,19 +95,62 @@ struct QpiddOptions : public Broker::Options, public log::Options
};
};
+// Globals
+Broker::shared_ptr brokerPtr;
+QpiddOptions config;
+
+void handle_signal(int /*signal*/){
+ QPID_LOG(notice, "Shutting down...");
+ brokerPtr->shutdown();
+}
+
+/** Compute a name for the pid file */
+std::string pidFileFn() {
+ uint16_t port=brokerPtr ? brokerPtr->getPort() : config.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();
+ }
+ QPID_LOG(debug, "PID file name=" << pidPath);
+ return pidPath;
+}
+
+/** Code for forked parent */
+void parent(Daemon& demon) {
+ uint16_t realPort = demon.wait();
+ if (config.port == 0)
+ cout << realPort << endl;
+}
+
+/** Code for forked child */
+void child(Daemon& demon) {
+ brokerPtr=Broker::create(config);
+ uint16_t realPort=brokerPtr->getPort();
+ demon.ready(realPort); // Notify parent.
+ brokerPtr->run();
+}
+
+
int main(int argc, char* argv[])
{
- QpiddOptions config;
+ // Spelled 'demon' to avoid clash with daemon.h function.
+ Daemon demon(pidFileFn, config.wait);
+
try {
config.parse(argc, argv);
if (config.trace)
config.selectors.push_back("trace+");
log::Logger::instance().configure(config, argv[0]);
- string name=(boost::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.longHelp || config.version) {
@@ -123,46 +164,32 @@ int main(int argc, char* argv[])
return 0;
}
- // Options that act on an already running daemon.
- if (config.quit || config.kill || config.check) {
+ // Stop running daemon
+ if (config.quit) {
+ demon.quit();
+ return 0;
+ }
+
+ // Query running daemon
+ if (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)
+ if (pid < 0)
return 1;
- return 0;
+ else {
+ cout << pid << endl;
+ 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) {
- QPID_LOG(critical, "Broker daemon startup failed: " << e.what());
- demon.failed(); // Notify parent we failed.
- return 1;
- }
- }
- 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 {
+ if (config.daemon) { // Daemon broker
+ demon.fork(parent, child);
+ }
+ else { // Non-daemon broker.
brokerPtr = Broker::create(config);
+ if (config.port == 0)
+ cout << uint16_t(brokerPtr->getPort()) << endl;
brokerPtr->run();
}
return 0;
@@ -170,12 +197,13 @@ int main(int argc, char* argv[])
catch(const po::error& e) {
// Command line parsing error.
cerr << "Error: " << e.what() << endl
- << "Type 'qpidd --help' for usage." << endl;
+ << "Type 'qpidd --long-help' for full usage." << endl;
}
catch(const exception& e) {
- // Could be child or parent so log and print.
- QPID_LOG(error, e.what());
- cerr << "Error: " << e.what() << endl;
+ if (demon.isParent())
+ cerr << "Error: " << e.what() << endl;
+ else
+ QPID_LOG(critical, e.what());
}
return 1;
}