36 #include <sys/types.h>
49 using std::ostringstream;
73 static int session_id = 0;
77 static volatile sig_atomic_t sigchild = 0;
78 static volatile sig_atomic_t sigpipe = 0;
79 static volatile sig_atomic_t sigterm = 0;
80 static volatile sig_atomic_t sighup = 0;
82 static string bes_exit_message(
int cpid,
int stat)
85 oss <<
"beslistener child pid: " << cpid;
86 if (WIFEXITED(stat)) {
87 oss <<
" exited with status: " << WEXITSTATUS(stat);
89 else if (WIFSIGNALED(stat)) {
90 oss <<
" exited with signal: " << WTERMSIG(stat);
93 oss <<
" and a core dump!";
97 oss <<
" exited, but I have no clue as to why";
108 sigaddset(&set, SIGCHLD);
109 sigaddset(&set, SIGHUP);
110 sigaddset(&set, SIGTERM);
111 sigaddset(&set, SIGPIPE);
113 if (sigprocmask(SIG_BLOCK, &set, 0) < 0) {
114 throw BESInternalError(
string(
"sigprocmask error: ") + strerror(errno) +
" while trying to block signals.", __FILE__, __LINE__);
122 sigaddset(&set, SIGCHLD);
123 sigaddset(&set, SIGHUP);
124 sigaddset(&set, SIGTERM);
125 sigaddset(&set, SIGPIPE);
127 if (sigprocmask(SIG_UNBLOCK, &set, 0) < 0) {
128 throw BESInternalError(
string(
"sigprocmask error: ") + strerror(errno) +
" while trying to unblock signals.", __FILE__, __LINE__);
139 static void CatchSigChild(
int sig)
141 if (sig == SIGCHLD) {
149 static void CatchSigHup(
int sig)
156 static void CatchSigPipe(
int sig)
158 if (sig == SIGPIPE) {
166 static void CatchSigTerm(
int sig)
168 if (sig == SIGTERM) {
181 static void register_signal_handlers()
183 struct sigaction act;
184 sigemptyset(&act.sa_mask);
185 sigaddset(&act.sa_mask, SIGCHLD);
186 sigaddset(&act.sa_mask, SIGPIPE);
187 sigaddset(&act.sa_mask, SIGTERM);
188 sigaddset(&act.sa_mask, SIGHUP);
191 BESDEBUG(
"beslistener",
"beslistener: setting restart for sigchld." << endl);
192 act.sa_flags |= SA_RESTART;
195 BESDEBUG(
"beslistener",
"beslistener: Registering signal handlers ... " << endl);
197 act.sa_handler = CatchSigChild;
198 if (sigaction(SIGCHLD, &act, 0))
199 throw BESInternalFatalError(
"Could not register a handler to catch beslistener child process status.", __FILE__,
202 act.sa_handler = CatchSigPipe;
203 if (sigaction(SIGPIPE, &act, 0) < 0)
204 throw BESInternalFatalError(
"Could not register a handler to catch beslistener pipe signal.", __FILE__,
207 act.sa_handler = CatchSigTerm;
208 if (sigaction(SIGTERM, &act, 0) < 0)
209 throw BESInternalFatalError(
"Could not register a handler to catch beslistener terminate signal.", __FILE__,
212 act.sa_handler = CatchSigHup;
213 if (sigaction(SIGHUP, &act, 0) < 0)
214 throw BESInternalFatalError(
"Could not register a handler to catch beslistener hup signal.", __FILE__,
217 BESDEBUG(
"beslistener",
"beslistener: OK" << endl);
221 BESModuleApp(), _portVal(0), _gotPort(false), _unixSocket(
""), _secure(false), _mypid(0), _ts(0), _us(0), _ps(0)
236 bool needhelp =
false;
243 while ((c = getopt(argc, argv,
"hvsd:c:p:u:i:r:")) != EOF) {
254 _portVal = atoi(optarg);
258 _unixSocket = optarg;
285 if (!dashc.empty()) {
292 if (dashc.empty() && !dashi.empty()) {
293 if (dashi[dashi.length() - 1] !=
'/') {
296 string conf_file = dashi +
"etc/bes/bes.conf";
312 string port_key =
"BES.ServerPort";
319 BESDEBUG(
"beslistener",
"beslistener: FAILED" << endl);
320 string err = (string)
"FAILED: " + e.
get_message();
326 _portVal = atoi(sPort.c_str());
334 string socket_key =
"BES.ServerUnixSocket";
335 if (_unixSocket ==
"") {
340 BESDEBUG(
"server",
"beslistener: FAILED" << endl);
341 string err = (string)
"FAILED: " + e.
get_message();
348 if (!_gotPort && _unixSocket ==
"") {
349 string msg =
"Must specify a tcp port or a unix socket or both\n";
350 msg +=
"Please specify on the command line with -p <port>";
351 msg +=
" and/or -u <unix_socket>\n";
352 msg +=
"Or specify in the bes configuration file with " + port_key +
" and/or " + socket_key +
"\n";
359 if (_secure ==
false) {
360 string key =
"BES.ServerSecure";
366 BESDEBUG(
"server",
"beslistener: FAILED" << endl);
367 string err = (string)
"FAILED: " + e.
get_message();
372 if (isSecure ==
"Yes" || isSecure ==
"YES" || isSecure ==
"yes") {
377 BESDEBUG(
"beslistener",
"beslistener: initializing default module ... " << endl);
379 BESDEBUG(
"beslistener",
"beslistener: done initializing default module" << endl);
381 BESDEBUG(
"beslistener",
"beslistener: initializing default commands ... " << endl);
383 BESDEBUG(
"beslistener",
"beslistener: done initializing default commands" << endl);
386 BESDEBUG(
"beslistener",
"beslistener: initializing loaded modules ... " << endl);
388 BESDEBUG(
"beslistener",
"beslistener: done initializing loaded modules" << endl);
390 BESDEBUG(
"beslistener",
"beslistener: initialized settings:" << *
this);
399 session_id = setsid();
400 BESDEBUG(
"beslistener",
"beslistener: The master beslistener session id (group id): " << session_id << endl);
408 BESDEBUG(
"beslistener",
"beslistener: initializing memory pool ... " << endl);
410 BESDEBUG(
"beslistener",
"OK" << endl);
417 BESDEBUG(
"beslistener",
"beslistener: listening on port (" << _portVal <<
")" << endl);
419 BESDEBUG(
"beslistener",
"beslistener: about to write status (4)" << endl);
427 BESDEBUG(
"beslistener",
"beslistener: wrote status (" << res <<
")" << endl);
430 if (!_unixSocket.empty()) {
433 BESDEBUG(
"beslistener",
"beslistener: listening on unix socket (" << _unixSocket <<
")" << endl);
438 _ps =
new PPTServer(&handler, &listener, _secure);
440 register_signal_handlers();
454 if (sigterm | sighup | sigchild | sigpipe) {
457 while ((cpid = wait4(0 , &stat, WNOHANG, 0)) > 0) {
459 if (sigpipe) (*
BESLog::TheLog()) <<
"Master listener caught SISPIPE from child: " << cpid << endl;
466 BESDEBUG(
"ppt2",
"Master listener caught SIGHUP, exiting with SERVER_EXIT_RESTART" << endl);
468 (*
BESLog::TheLog()) <<
"Master listener caught SIGHUP, exiting with SERVER_EXIT_RESTART" << endl;
473 BESDEBUG(
"ppt2",
"Master listener caught SIGTERM, exiting with SERVER_NORMAL_SHUTDOWN" << endl);
475 (*
BESLog::TheLog()) <<
"Master listener caught SIGTERM, exiting with SERVER_NORMAL_SHUTDOWN" << endl;
479 sigchild = 0; sigpipe = 0;
488 BESDEBUG(
"beslistener",
"beslistener: caught BESError (" << se.
get_message() <<
")" << endl);
497 (*
BESLog::TheLog()) <<
"caught unknown exception initializing sockets" << endl;
510 pid_t apppid = getpid();
511 if (apppid == _mypid) {
531 BESDEBUG(
"beslistener",
"beslistener: terminating loaded modules ... " << endl);
533 BESDEBUG(
"beslistener",
"beslistener: done terminating loaded modules" << endl);
535 BESDEBUG(
"beslistener",
"beslistener: terminating default commands ... " << endl);
537 BESDEBUG(
"beslistener",
"beslistener: done terminating default commands ... " << endl);
539 BESDEBUG(
"beslistener",
"beslistener: terminating default module ... " << endl);
541 BESDEBUG(
"beslistener",
"beslistener: done terminating default module ... " << endl);
554 strm <<
BESIndent::LMarg <<
"ServerApp::dump - (" << (
void *)
this <<
")" << endl;
592 int main(
int argc,
char **argv)
596 return app.
main(argc, argv);
599 cerr <<
"Caught unhandled exception: " << endl;
604 cerr <<
"Caught unhandled, unknown exception" << endl;
#define SERVER_EXIT_FATAL_CANNOT_START
exception thrown if an internal error is found and is fatal to the BES
exception thrown if inernal error encountered
static void SetUp(const string &values)
Sets up debugging for the bes.
virtual void dump(std::ostream &strm) const
dumps information about this object
#define BESLISTENER_RUNNING
static int initialize(int argc, char **argv)
void unblock_signals()
See block_signals()
#define SERVER_EXIT_NORMAL_SHUTDOWN
virtual int main(int argC, char **argV)
main method of the BES application
virtual void dump(ostream &strm) const
dumps information about this object
static BESMemoryGlobalArea * initialize_memory_pool()
virtual void dump(ostream &strm) const
dumps information about this object
#define BESLISTENER_PIPE_FD
virtual int terminate(int sig=0)
clean up after the application
static int terminate(void)
Removes the default set of BES XML commands from the list of possible commands.
static void show_usage(const string &app_name)
string appName(void) const
Returns the name of the application.
virtual string get_message()
get the error message for this exception
static int initialize(int argc, char **argv)
Loads the default set of BES XML commands.
virtual void initConnection()
Using the info passed into the SocketLister, wait for an inbound request (see SocketListener::accept(...
Abstract exception class for the BES with basic string message.
virtual void closeConnection()
static int terminate(void)
static ostream & LMarg(ostream &strm)
virtual int terminate(int sig=0)
clean up after the application
virtual void dump(ostream &strm) const
dumps information about this object
virtual int initialize(int argC, char **argV)
Load and initialize any BES modules.
Base application object for all BES applications.
virtual int initialize(int argC, char **argV)
Load and initialize any BES modules.
void get_value(const string &s, string &val, bool &found)
Retrieve the value of a given key, if set.
static void show_version(const string &app_name)
int main(int argc, char **argv)
void block_signals()
For code that must use signals to stop and start the master listener, block signals being delivered t...
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
static void delete_all_catalogs()
#define SERVER_EXIT_RESTART
virtual void listen(Socket *s)
static BESKeys * TheKeys()
static void Register(const string &flagName)
register the specified debug flag
static BESApp * TheApplication(void)
Returns the BESApp application object for this application.
virtual int run()
the applications functionality is implemented in the run method
virtual void dump(ostream &strm) const
dumps information about this object