diff options
Diffstat (limited to 'web/apache/service.cxx')
-rw-r--r-- | web/apache/service.cxx | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/web/apache/service.cxx b/web/apache/service.cxx new file mode 100644 index 0000000..6b73e02 --- /dev/null +++ b/web/apache/service.cxx @@ -0,0 +1,109 @@ +// file : web/apache/service.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#include <web/apache/service> + +#include <unistd.h> // getppid() +#include <signal.h> // kill() + +#include <httpd/httpd.h> +#include <httpd/http_config.h> + +#include <memory> // unique_ptr +#include <string> +#include <exception> + +using namespace std; + +namespace web +{ + namespace apache + { + void service:: + init_directives() + { + assert(cmds == nullptr); + + // Fill apache module directive definitions. Directives share + // common name space in apache configuration file, so to prevent name + // clash have to form directive name as a combination of module and + // option names: <module name>-<option name>. This why for option + // bar of module foo the corresponding directive will appear in apache + // configuration file as foo-bar. + // + unique_ptr<command_rec[]> directives ( + new command_rec[option_names_.size () + 1]); + + command_rec* d (directives.get ()); + + for (auto& o: option_names_) + { + o = name_ + "-" + o; + + *d++ = + { + o.c_str (), + reinterpret_cast<cmd_func> (add_option), + this, + RSRC_CONF, + TAKE1, + nullptr + }; + } + + *d = {}; + + cmds = directives.release (); + } + + const char* service:: + add_option (cmd_parms *parms, void *mconfig, const char *value) noexcept + { + service& srv (*reinterpret_cast<service*> (parms->cmd->cmd_data)); + string name (parms->cmd->name + srv.name_.length () + 1); + + for (auto& v: srv.options_) + if (v.name == name) + { + v.value = value; + return 0; + } + + srv.options_.emplace_back (name, value); + return 0; + } + + void service:: + init_worker(log& l) noexcept + { + static const string func_name ( + "web::apache::service<" + name_ + ">::init_worker"); + + try + { + exemplar_.init (options_, l); + } + catch (const exception& e) + { + l.write (nullptr, 0, func_name.c_str (), APLOG_EMERG, e.what ()); + + // Terminate the root apache process. + // + ::kill (::getppid (), SIGTERM); + } + catch (...) + { + l.write (nullptr, + 0, + func_name.c_str (), + APLOG_EMERG, + "unknown error"); + + // Terminate the root apache process. + // + ::kill (::getppid (), SIGTERM); + } + } + } +} |