summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--qpid/cpp/include/qpid/Options.h5
-rw-r--r--qpid/cpp/src/posix/QpiddBroker.cpp16
-rw-r--r--qpid/cpp/src/qpid/Options.cpp42
-rw-r--r--qpid/cpp/src/qpidd.cpp38
-rw-r--r--qpid/cpp/src/qpidd.h3
-rw-r--r--qpid/cpp/src/windows/QpiddBroker.cpp12
6 files changed, 89 insertions, 27 deletions
diff --git a/qpid/cpp/include/qpid/Options.h b/qpid/cpp/include/qpid/Options.h
index 0bbe7b704f..feef5d8b98 100644
--- a/qpid/cpp/include/qpid/Options.h
+++ b/qpid/cpp/include/qpid/Options.h
@@ -149,6 +149,11 @@ struct Options : public po::options_description {
const std::string& configfile=std::string(),
bool allowUnknown = false);
+ /**
+ * Tests for presence of argc/argv switch
+ */
+ QPID_COMMON_EXTERN bool findArg(int argc, char const* const* argv,
+ const std::string& theArg);
boost::program_options::options_description_easy_init addOptions() {
return add_options();
diff --git a/qpid/cpp/src/posix/QpiddBroker.cpp b/qpid/cpp/src/posix/QpiddBroker.cpp
index 76e3bb6674..f1f9009568 100644
--- a/qpid/cpp/src/posix/QpiddBroker.cpp
+++ b/qpid/cpp/src/posix/QpiddBroker.cpp
@@ -48,6 +48,10 @@ BootstrapOptions::BootstrapOptions(const char* argv0)
add(log);
}
+void BootstrapOptions::usage() const {
+ cout << "Usage: qpidd [OPTIONS]" << endl << endl << *this << endl;
+}
+
namespace {
const std::string TCP = "tcp";
}
@@ -111,17 +115,17 @@ void QpiddOptions::usage() const {
// Set the broker pointer on the signal handler, then reset at end of scope.
// This is to ensure that the signal handler doesn't keep a broker
// reference after main() has returned.
-//
+//
struct ScopedSetBroker {
ScopedSetBroker(const boost::intrusive_ptr<Broker>& broker) {
qpid::broker::SignalHandler::setBroker(broker.get());
}
~ScopedSetBroker() { qpid::broker::SignalHandler::setBroker(0); }
};
-
+
struct QpiddDaemon : public Daemon {
QpiddPosixOptions *options;
-
+
QpiddDaemon(std::string pidDir, QpiddPosixOptions *opts)
: Daemon(pidDir), options(opts) {}
@@ -129,7 +133,7 @@ struct QpiddDaemon : public Daemon {
void parent() {
uint16_t port = wait(options->daemon.wait);
if (options->parent->broker.port == 0 || options->daemon.transport != TCP)
- cout << port << endl;
+ cout << port << endl;
}
/** Code for forked child process */
@@ -162,12 +166,12 @@ int QpiddBroker::execute (QpiddOptions *options) {
QPID_LOG(notice, "Cannot stop broker: " << e.what());
return 1;
}
- if (pid < 0)
+ if (pid < 0)
return 1;
if (myOptions->daemon.check)
cout << pid << endl;
if (myOptions->daemon.quit) {
- if (kill(pid, SIGINT) < 0)
+ if (kill(pid, SIGINT) < 0)
throw Exception("Failed to stop daemon: " + qpid::sys::strError(errno));
// Wait for the process to die before returning
int retry=10000; // Try up to 10 seconds
diff --git a/qpid/cpp/src/qpid/Options.cpp b/qpid/cpp/src/qpid/Options.cpp
index 35787aa8f3..9813dda697 100644
--- a/qpid/cpp/src/qpid/Options.cpp
+++ b/qpid/cpp/src/qpid/Options.cpp
@@ -41,13 +41,13 @@ struct EnvOptMapper {
return desc->long_name().size() == env.size() &&
std::equal(env.begin(), env.end(), desc->long_name().begin(), &matchChar);
}
-
+
static bool matchCase(const string& env, boost::shared_ptr<po::option_description> desc) {
return env == desc->long_name();
}
-
+
EnvOptMapper(const Options& o) : opts(o) {}
-
+
string operator()(const string& envVar) {
static const std::string prefix("QPID_");
if (envVar.substr(0, prefix.size()) == prefix) {
@@ -75,7 +75,7 @@ struct EnvOptMapper {
string configFileLine (string& line) {
-
+
if ( isComment ( line ) )
return string();
@@ -85,7 +85,7 @@ struct EnvOptMapper {
string key = line.substr (0, pos);
#if (BOOST_VERSION >= 103300)
typedef const std::vector< boost::shared_ptr<po::option_description> > OptDescs;
- OptDescs::const_iterator i =
+ OptDescs::const_iterator i =
find_if(opts.options().begin(), opts.options().end(), boost::bind(matchCase, key, _1));
if (i != opts.options().end())
return string (line) + "\n";
@@ -109,8 +109,8 @@ std::string prettyArg(const std::string& name, const std::string& value) {
return value.empty() ? name+" " : name+" ("+value+") ";
}
-Options::Options(const string& name) :
- po::options_description(name)
+Options::Options(const string& name) :
+ po::options_description(name)
{
}
@@ -197,5 +197,33 @@ CommonOptions::CommonOptions(const string& name, const string& configfile, const
}
+
+bool Options::findArg(int argc, char const* const* argv, const std::string& theArg)
+{
+ const string parsing("command line options");
+ bool result(false);
+ try {
+ if (argc > 0 && argv != 0) {
+ po::command_line_parser clp = po::command_line_parser(argc, const_cast<char**>(argv)).
+ options(*this).allow_unregistered();
+ po::parsed_options opts = clp.run();
+
+ for (std::vector< po::basic_option<char> >::iterator
+ i = opts.options.begin(); i != opts.options.end(); i++) {
+ if (theArg.compare(i->string_key) == 0) {
+ result = true;
+ break;
+ }
+ }
+ }
+ return result;
+ }
+ catch (const std::exception& e) {
+ ostringstream msg;
+ msg << "Error in " << parsing << ": " << e.what() << endl;
+ throw Exception(msg.str());
+ }
+}
+
} // namespace qpid
diff --git a/qpid/cpp/src/qpidd.cpp b/qpid/cpp/src/qpidd.cpp
index b5686c6ab8..920009580c 100644
--- a/qpid/cpp/src/qpidd.cpp
+++ b/qpid/cpp/src/qpidd.cpp
@@ -41,6 +41,18 @@ int run_broker(int argc, char *argv[], bool hidden)
{
BootstrapOptions bootOptions(argv[0]);
string defaultPath (bootOptions.module.loadDir);
+
+ // --version causes print and exit
+ if (bootOptions.findArg(argc, argv, "version")) {
+ cout << "qpidd (" << qpid::product << ") version "
+ << qpid::version << endl;
+ return 0;
+ }
+
+ // --help sets a flag so that its presence is known despite
+ // subsequent parse problems.
+ bool helpArgSeen = bootOptions.findArg(argc, argv, "help");
+
// Parse only the common, load, and log options to see which
// modules need to be loaded. Once the modules are loaded,
// the command line will be re-parsed with all of the
@@ -51,8 +63,12 @@ int run_broker(int argc, char *argv[], bool hidden)
bootOptions.log.sinkOptions->detached();
qpid::log::Logger::instance().configure(bootOptions.log);
} catch (const std::exception& e) {
+ if (helpArgSeen) {
+ // provide help even when parsing fails
+ bootOptions.usage();
+ }
// Couldn't configure logging so write the message direct to stderr.
- cerr << "Unexpected error: " << e.what() << endl;
+ cerr << endl << "Unexpected error: " << e.what() << endl;
return 1;
}
@@ -67,16 +83,20 @@ int run_broker(int argc, char *argv[], bool hidden)
}
// Parse options
- options.reset(new QpiddOptions(argv[0]));
- options->parse(argc, argv, options->common.config);
+ try {
+ options.reset(new QpiddOptions(argv[0]));
+ options->parse(argc, argv, options->common.config);
+ } catch (const std::exception& /*e*/) {
+ if (helpArgSeen) {
+ // provide help even when parsing fails
+ options->usage();
+ }
+ throw;
+ }
// Options that just print information.
- if (options->common.help || options->common.version) {
- if (options->common.version)
- cout << "qpidd (" << qpid::product << ") version "
- << qpid::version << endl;
- else if (options->common.help)
- options->usage();
+ if (helpArgSeen) {
+ options->usage();
return 0;
}
diff --git a/qpid/cpp/src/qpidd.h b/qpid/cpp/src/qpidd.h
index f7f84d11da..08356ab29e 100644
--- a/qpid/cpp/src/qpidd.h
+++ b/qpid/cpp/src/qpidd.h
@@ -37,9 +37,10 @@ namespace broker {
struct BootstrapOptions : public qpid::Options {
qpid::CommonOptions common;
qpid::ModuleOptions module;
- qpid::log::Options log;
+ qpid::log::Options log;
BootstrapOptions(const char *argv0);
+ void usage() const;
};
// Each platform derives an options struct from QpiddOptionsPrivate, adding
diff --git a/qpid/cpp/src/windows/QpiddBroker.cpp b/qpid/cpp/src/windows/QpiddBroker.cpp
index 4ca3f3059c..de2e41dd4d 100644
--- a/qpid/cpp/src/windows/QpiddBroker.cpp
+++ b/qpid/cpp/src/windows/QpiddBroker.cpp
@@ -53,6 +53,10 @@ BootstrapOptions::BootstrapOptions(const char* argv0)
add(log);
}
+void BootstrapOptions::usage() const {
+ std::cout << "Usage: qpidd [OPTIONS]" << std::endl << std::endl << *this << std::endl;
+}
+
// Local functions to set and get the pid via a LockFile.
namespace {
@@ -225,10 +229,10 @@ VOID WINAPI SvcCtrlHandler(DWORD control)
::SetServiceStatus(svcStatusHandle, &svcStatus);
CtrlHandler(CTRL_C_EVENT);
break;
-
+
case SERVICE_CONTROL_INTERROGATE:
break;
-
+
default:
break;
}
@@ -306,7 +310,7 @@ struct ServiceOptions : public qpid::Options {
std::string password;
std::string depends;
- ServiceOptions()
+ ServiceOptions()
: qpid::Options("Service options"),
install(false),
start(false),
@@ -423,7 +427,7 @@ int QpiddBroker::execute (QpiddOptions *options) {
// Relies on port number being set via --port or QPID_PORT env variable.
NamedSharedMemory<BrokerInfo> info(brokerInfoName(options->broker.port));
int pid = info.get().pid;
- if (pid < 0)
+ if (pid < 0)
return 1;
if (myOptions->control.check)
std::cout << pid << std::endl;