diff options
author | Stephen D. Huston <shuston@apache.org> | 2008-10-29 19:45:18 +0000 |
---|---|---|
committer | Stephen D. Huston <shuston@apache.org> | 2008-10-29 19:45:18 +0000 |
commit | 6d26c9b2c8a19cfd23336d2498bcad561a4458f6 (patch) | |
tree | 75dcbd5c69df3accb56a5882393d6eca87eb66b1 /cpp | |
parent | 20e253844fddd084eac9b80dc9cc73efff12dd28 (diff) | |
download | qpid-python-6d26c9b2c8a19cfd23336d2498bcad561a4458f6.tar.gz |
Split platform-specific qpidd code out to posix/QpiddBroker.cpp; allows Windows port code to come in. Related to QPID-1338
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@708991 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/src/Makefile.am | 4 | ||||
-rw-r--r-- | cpp/src/posix/QpiddBroker.cpp | 164 | ||||
-rw-r--r-- | cpp/src/qpidd.cpp | 203 | ||||
-rw-r--r-- | cpp/src/qpidd.h | 70 |
4 files changed, 253 insertions, 188 deletions
diff --git a/cpp/src/Makefile.am b/cpp/src/Makefile.am index 2ac9a7e716..6af68f780b 100644 --- a/cpp/src/Makefile.am +++ b/cpp/src/Makefile.am @@ -64,8 +64,10 @@ qpidd_LDADD = \ libqpidbroker.la \ libqpidcommon.la +posix_qpidd_src = posix/QpiddBroker.cpp + sbin_PROGRAMS = qpidd -qpidd_SOURCES = qpidd.cpp +qpidd_SOURCES = qpidd.cpp $(posix_qpidd_src) posix_plat_src = \ qpid/log/posix/SinkOptions.cpp \ diff --git a/cpp/src/posix/QpiddBroker.cpp b/cpp/src/posix/QpiddBroker.cpp new file mode 100644 index 0000000000..ee98429074 --- /dev/null +++ b/cpp/src/posix/QpiddBroker.cpp @@ -0,0 +1,164 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 "qpidd.h" +#include "qpid/Exception.h" +#include "qpid/broker/Broker.h" +#include "qpid/broker/Daemon.h" +#include "qpid/broker/SignalHandler.h" +#include "qpid/log/Logger.h" + +#include <iostream> +#include <signal.h> +#include <unistd.h> +#include <sys/utsname.h> + +using namespace std; +using namespace qpid; +using qpid::broker::Broker; +using qpid::broker::Daemon; + +BootstrapOptions::BootstrapOptions(const char* argv0) + : qpid::Options("Options"), + common("", CONF_FILE), + module(MODULE_DIR), + log(argv0) +{ + add(common); + add(module); + add(log); +} + +struct DaemonOptions : public qpid::Options { + bool daemon; + bool quit; + bool check; + int wait; + std::string piddir; + std::string transport; + + DaemonOptions() : qpid::Options("Daemon options"), daemon(false), quit(false), check(false), wait(10) + { + char *home = ::getenv("HOME"); + + if (home == 0) + piddir += "/tmp"; + else + piddir += home; + piddir += "/.qpidd"; + + addOptions() + ("daemon,d", optValue(daemon), "Run as a daemon. --log-output defaults to syslog in this mode.") + ("transport", optValue(transport, "TRANSPORT"), "The transport for which to return the port") + ("pid-dir", optValue(piddir, "DIR"), "Directory where port-specific PID file is stored") + ("wait,w", optValue(wait, "SECONDS"), "Sets the maximum wait time to initialize the daemon. If the daemon fails to initialize, prints an error and returns 1") + ("check,c", optValue(check), "Prints the daemon's process ID to stdout and returns 0 if the daemon is running, otherwise returns 1") + ("quit,q", optValue(quit), "Tells the daemon to shut down"); + } +}; + +struct QpiddPosixOptions : public QpiddOptionsPrivate { + DaemonOptions daemon; + QpiddOptions *parent; + + QpiddPosixOptions(QpiddOptions *parent_) : parent(parent_) { + parent->add(daemon); + } +}; + +QpiddOptions::QpiddOptions(const char* argv0) + : qpid::Options("Options"), + common("", CONF_FILE), + module(MODULE_DIR), + log(argv0) +{ + add(common); + add(module); + add(broker); + add(log); + + platform.reset(new QpiddPosixOptions(this)); + qpid::Plugin::addOptions(*this); +} + +void QpiddOptions::usage() const { + cout << "Usage: qpidd [OPTIONS]" << endl << endl << *this << endl; +} + +struct QpiddDaemon : public Daemon { + QpiddPosixOptions *options; + + QpiddDaemon(std::string pidDir, QpiddPosixOptions *opts) + : Daemon(pidDir), options(opts) {} + + /** Code for parent process */ + void parent() { + uint16_t port = wait(options->daemon.wait); + if (options->parent->broker.port == 0 || !options->daemon.transport.empty()) + cout << port << endl; + } + + /** Code for forked child process */ + void child() { + boost::intrusive_ptr<Broker> brokerPtr(new Broker(options->parent->broker)); + qpid::broker::SignalHandler::setBroker(brokerPtr); + uint16_t port=brokerPtr->getPort(options->daemon.transport); + ready(port); // Notify parent. + brokerPtr->run(); + } +}; + +int QpiddBroker::execute (QpiddOptions *options) { + // Options that affect a running daemon. + QpiddPosixOptions *myOptions = + static_cast<QpiddPosixOptions *>(options->platform.get()); + if (myOptions == 0) + throw Exception("Internal error obtaining platform options"); + + if (myOptions->daemon.check || myOptions->daemon.quit) { + pid_t pid = Daemon::getPid(myOptions->daemon.piddir, + options->broker.port); + if (pid < 0) + return 1; + if (myOptions->daemon.check) + cout << pid << endl; + if (myOptions->daemon.quit && kill(pid, SIGINT) < 0) + throw Exception("Failed to stop daemon: " + qpid::sys::strError(errno)); + return 0; + } + + // Starting the broker. + if (myOptions->daemon.daemon) { + // For daemon mode replace default stderr with syslog. + options->log.sinkOptions->detached(); + qpid::log::Logger::instance().configure(options->log); + // Fork the daemon + QpiddDaemon d(myOptions->daemon.piddir, myOptions); + d.fork(); // Broker is stared in QpiddDaemon::child() + } + else { // Non-daemon broker. + boost::intrusive_ptr<Broker> brokerPtr(new Broker(options->broker)); + broker::SignalHandler::setBroker(brokerPtr); + if (options->broker.port == 0 || !myOptions->daemon.transport.empty()) + cout << uint16_t(brokerPtr->getPort(myOptions->daemon.transport)) << endl; + brokerPtr->run(); + } + return 0; +} diff --git a/cpp/src/qpidd.cpp b/cpp/src/qpidd.cpp index 2cc7a0b6e6..b00a3e63f6 100644 --- a/cpp/src/qpidd.cpp +++ b/cpp/src/qpidd.cpp @@ -18,166 +18,19 @@ * under the License. * */ -#include "qpid/broker/Broker.h" -#include "qpid/broker/SignalHandler.h" -#include "qpid/sys/posix/check.h" -#include "qpid/broker/Daemon.h" -#include "qpid/log/Statement.h" -#include "qpid/log/Options.h" -#include "qpid/log/Logger.h" + +#include "qpidd.h" #include "qpid/Plugin.h" #include "qpid/Version.h" +#include "qpid/log/Logger.h" #include "qpid/sys/Shlib.h" -#include "config.h" -#include <boost/filesystem/operations.hpp> -#include <boost/filesystem/path.hpp> -#include <iostream> -#include <fstream> -#include <signal.h> -#include <unistd.h> -using namespace qpid; -using namespace qpid::broker; -using namespace qpid::sys; -using namespace qpid::log; +#include <iostream> +#include <memory> using namespace std; -namespace fs=boost::filesystem; - -struct ModuleOptions : public qpid::Options { - string loadDir; - vector<string> load; - bool noLoad; - ModuleOptions() : qpid::Options("Module options"), loadDir(MODULE_DIR), noLoad(false) - { - addOptions() - ("module-dir", optValue(loadDir, "DIR"), "Load all .so modules in this directory") - ("load-module", optValue(load, "FILE"), "Specifies additional module(s) to be loaded") - ("no-module-dir", optValue(noLoad), "Don't load modules from module directory"); - } -}; - - -struct DaemonOptions : public qpid::Options { - bool daemon; - bool quit; - bool check; - int wait; - std::string piddir; - std::string transport; - - DaemonOptions() : qpid::Options("Daemon options"), daemon(false), quit(false), check(false), wait(10) - { - char *home = ::getenv("HOME"); - - if (home == 0) - piddir += "/tmp"; - else - piddir += home; - piddir += "/.qpidd"; - - addOptions() - ("daemon,d", optValue(daemon), "Run as a daemon. --log-output defaults to syslog in this mode.") - ("transport", optValue(transport, "TRANSPORT"), "The transport for which to return the port") - ("pid-dir", optValue(piddir, "DIR"), "Directory where port-specific PID file is stored") - ("wait,w", optValue(wait, "SECONDS"), "Sets the maximum wait time to initialize the daemon. If the daemon fails to initialize, prints an error and returns 1") - ("check,c", optValue(check), "Prints the daemon's process ID to stdout and returns 0 if the daemon is running, otherwise returns 1") - ("quit,q", optValue(quit), "Tells the daemon to shut down"); - } -}; - - -struct QpiddOptions : public qpid::Options { - CommonOptions common; - ModuleOptions module; - Broker::Options broker; - DaemonOptions daemon; - qpid::log::Options log; - - QpiddOptions(const char* argv0) : qpid::Options("Options"), common("", CONF_FILE), log(argv0) { - add(common); - add(module); - add(broker); - add(daemon); - add(log); - Plugin::addOptions(*this); - } - - void usage() const { - cout << "Usage: qpidd [OPTIONS]" << endl << endl << *this << endl; - }; -}; - -// BootstrapOptions is a minimal subset of options used for a pre-parse -// of the command line to discover which plugin modules need to be loaded. -// The pre-parse is necessary because plugin modules may supply their own -// set of options. CommonOptions is needed to properly support loading -// from a configuration file. -struct BootstrapOptions : public qpid::Options { - CommonOptions common; - ModuleOptions module; - qpid::log::Options log; - - BootstrapOptions(const char* argv0) : qpid::Options("Options"), common("", CONF_FILE), log(argv0) { - add(common); - add(module); - add(log); - } -}; auto_ptr<QpiddOptions> options; -struct QpiddDaemon : public Daemon { - QpiddDaemon(std::string pidDir) : Daemon(pidDir) {} - - /** Code for parent process */ - void parent() { - uint16_t port = wait(options->daemon.wait); - if (options->broker.port == 0 || !options->daemon.transport.empty()) - cout << port << endl; - } - - /** Code for forked child process */ - void child() { - boost::intrusive_ptr<Broker> brokerPtr(new Broker(options->broker)); - broker::SignalHandler::setBroker(brokerPtr); - uint16_t port=brokerPtr->getPort(options->daemon.transport); - ready(port); // Notify parent. - brokerPtr->run(); - } -}; - -void tryShlib(const char* libname, bool noThrow) { - try { - Shlib shlib(libname); - QPID_LOG (info, "Loaded Module: " << libname); - } - catch (const exception& e) { - if (!noThrow) - throw; - } -} - -void loadModuleDir (string dirname, bool isDefault) -{ - fs::path dirPath (dirname, fs::native); - - if (!fs::exists (dirPath)) - { - if (isDefault) - return; - throw Exception ("Directory not found: " + dirname); - } - - fs::directory_iterator endItr; - for (fs::directory_iterator itr (dirPath); itr != endItr; ++itr) - { - if (!fs::is_directory(*itr) && - itr->string().find (".so") == itr->string().length() - 3) - tryShlib (itr->string().data(), true); - } -} - - int main(int argc, char* argv[]) { try @@ -185,20 +38,21 @@ int main(int argc, char* argv[]) { BootstrapOptions bootOptions(argv[0]); string defaultPath (bootOptions.module.loadDir); - // 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 module-supplied options. + // 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 + // module-supplied options. bootOptions.parse (argc, argv, bootOptions.common.config, true); qpid::log::Logger::instance().configure(bootOptions.log); for (vector<string>::iterator iter = bootOptions.module.load.begin(); iter != bootOptions.module.load.end(); iter++) - tryShlib (iter->data(), false); + qpid::tryShlib (iter->data(), false); if (!bootOptions.module.noLoad) { bool isDefault = defaultPath == bootOptions.module.loadDir; - loadModuleDir (bootOptions.module.loadDir, isDefault); + qpid::loadModuleDir (bootOptions.module.loadDir, isDefault); } } @@ -207,7 +61,7 @@ int main(int argc, char* argv[]) options->parse(argc, argv, options->common.config); // Options that just print information. - if(options->common.help || options->common.version) { + if (options->common.help || options->common.version) { if (options->common.version) cout << "qpidd (" << qpid::product << ") version " << qpid::version << endl; @@ -216,35 +70,10 @@ int main(int argc, char* argv[]) return 0; } - // Options that affect a running daemon. - if (options->daemon.check || options->daemon.quit) { - pid_t pid = Daemon::getPid(options->daemon.piddir, options->broker.port); - if (pid < 0) - return 1; - if (options->daemon.check) - cout << pid << endl; - if (options->daemon.quit && kill(pid, SIGINT) < 0) - throw Exception("Failed to stop daemon: " + strError(errno)); - return 0; - } - - // Starting the broker. - if (options->daemon.daemon) { - // For daemon mode replace default stderr with syslog. - options->log.sinkOptions->detached(); - qpid::log::Logger::instance().configure(options->log); - // Fork the daemon - QpiddDaemon d(options->daemon.piddir); - d.fork(); // Broker is stared in QpiddDaemon::child() - } - else { // Non-daemon broker. - boost::intrusive_ptr<Broker> brokerPtr(new Broker(options->broker)); - broker::SignalHandler::setBroker(brokerPtr); - if (options->broker.port == 0 || !options->daemon.transport.empty()) - cout << uint16_t(brokerPtr->getPort(options->daemon.transport)) << endl; - brokerPtr->run(); - } - return 0; + // Everything else is driven by the platform-specific broker + // logic. + QpiddBroker broker; + return broker.execute(options.get()); } catch(const exception& e) { cerr << e.what() << endl; diff --git a/cpp/src/qpidd.h b/cpp/src/qpidd.h new file mode 100644 index 0000000000..c702270e80 --- /dev/null +++ b/cpp/src/qpidd.h @@ -0,0 +1,70 @@ +#ifndef QPID_H +#define QPID_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 "qpid/Modules.h" +#include "qpid/Options.h" +#include "qpid/broker/Broker.h" +#include "qpid/log/Options.h" + +#include <memory> + +// BootstrapOptions is a minimal subset of options used for a pre-parse +// of the command line to discover which plugin modules need to be loaded. +// The pre-parse is necessary because plugin modules may supply their own +// set of options. CommonOptions is needed to properly support loading +// from a configuration file. +struct BootstrapOptions : public qpid::Options { + qpid::CommonOptions common; + qpid::ModuleOptions module; + qpid::log::Options log; + + BootstrapOptions(const char *argv0); +}; + +// Each platform derives an options struct from QpiddOptionsPrivate, adding +// platform-specific option types. QpiddOptions needs to allocation one of +// these derived structs from its constructor. +struct QpiddOptions; +struct QpiddOptionsPrivate { + QpiddOptions *options; + QpiddOptionsPrivate(QpiddOptions *parent) : options(parent) {} + virtual ~QpiddOptionsPrivate() {} +protected: + QpiddOptionsPrivate() {} +}; + +struct QpiddOptions : public qpid::Options { + qpid::CommonOptions common; + qpid::ModuleOptions module; + qpid::broker::Broker::Options broker; + qpid::log::Options log; + std::auto_ptr<QpiddOptionsPrivate> platform; + + QpiddOptions(const char *argv0); + void usage() const; +}; + +class QpiddBroker { +public: + int execute (QpiddOptions *options); +}; + +#endif /*!QPID_H*/ |