fluxbox/src/main.cc

301 lines
8.5 KiB
C++
Raw Normal View History

2003-04-27 01:51:04 +00:00
// main.cc for Fluxbox Window manager
2006-02-16 06:53:05 +00:00
// Copyright (c) 2001 - 2006 Henrik Kinnunen (fluxgen at fluxbox dot org)
2005-01-18 19:06:04 +00:00
// and 2003-2005 Simon Bowden (rathnor at users.sourceforge.net)
2001-12-11 20:47:02 +00:00
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
2001-12-11 20:47:02 +00:00
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#include "fluxbox.hh"
#include "version.h"
#include "defaults.hh"
#include "cli.hh"
2004-01-11 13:12:02 +00:00
2004-06-07 11:46:05 +00:00
#include "FbTk/I18n.hh"
#include "FbTk/StringUtil.hh"
2001-12-11 20:47:02 +00:00
2002-08-13 23:56:02 +00:00
//use GNU extensions
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif // _GNU_SOURCE
2004-08-31 15:26:40 +00:00
#ifdef HAVE_CSTDLIB
#include <cstdlib>
#else
#include <stdlib.h>
#endif
2007-12-14 22:21:39 +00:00
#ifdef HAVE_CSTRING
#include <cstring>
#else
#include <string.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif // HAVE_SYS_WAIT_H
2015-01-03 13:07:34 +00:00
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
#include <iostream>
2002-10-13 21:48:28 +00:00
#include <stdexcept>
2003-01-09 18:28:48 +00:00
#include <typeinfo>
2002-10-13 21:48:28 +00:00
using std::cout;
using std::cerr;
using std::endl;
using std::string;
using std::ostream;
using std::ofstream;
using std::streambuf;
using std::auto_ptr;
using std::out_of_range;
using std::runtime_error;
using std::bad_cast;
using std::bad_alloc;
using std::exception;
namespace {
auto_ptr<Fluxbox> fluxbox;
void handleSignal(int signum) {
_FB_USES_NLS;
static int re_enter = 0;
switch (signum) {
#ifndef _WIN32
case SIGCHLD: // we don't want the child process to kill us
// more than one process may have terminated
while (waitpid(-1, 0, WNOHANG | WUNTRACED) > 0);
break;
case SIGHUP:
// xinit sends HUP when it wants to go down. there is no point in
// restoring anything in the screens / workspaces, the connection
// to the xserver might drop any moment
if (fluxbox.get()) { fluxbox->shutdown(1); }
break;
case SIGUSR1:
if (fluxbox.get()) { fluxbox->restart(); }
break;
case SIGUSR2:
if (fluxbox.get()) { fluxbox->reconfigure(); }
break;
#endif
case SIGSEGV:
abort();
break;
case SIGALRM:
// last resort for shutting down fluxbox. the alarm() is set in
// Fluxbox::shutdown()
if (fluxbox.get() && fluxbox->isShuttingDown()) {
cerr << "fluxbox took longer than expected to shutdown\n";
exit(13);
}
break;
case SIGFPE:
case SIGINT:
#ifndef _WIN32
case SIGPIPE:
#endif
case SIGTERM:
if (fluxbox.get()) { fluxbox->shutdown(); }
break;
default:
fprintf(stderr,
_FB_CONSOLETEXT(BaseDisplay, SignalCaught,
"%s: signal %d caught\n",
"signal catch debug message. Include %s for Command<void> and %d for signal number").c_str(),
"TODO: m_arg[0]", signum);
if (! fluxbox->isStartup() && ! re_enter) {
re_enter = 1;
cerr<<_FB_CONSOLETEXT(BaseDisplay, ShuttingDown,
"Shutting Down\n",
"Quitting because of signal, end with newline");
if (fluxbox.get()) { fluxbox->shutdown(); }
}
cerr << _FB_CONSOLETEXT(BaseDisplay, Aborting,
"Aborting... dumping core\n",
"Aboring and dumping core, end with newline");
abort();
break;
2002-12-01 13:42:15 +00:00
}
}
void setupSignalHandling() {
signal(SIGSEGV, handleSignal);
signal(SIGSEGV, handleSignal);
signal(SIGFPE, handleSignal);
signal(SIGTERM, handleSignal);
signal(SIGINT, handleSignal);
#ifdef HAVE_ALARM
signal(SIGALRM, handleSignal);
#endif
#ifndef _WIN32
signal(SIGPIPE, handleSignal); // e.g. output sent to grep
signal(SIGCHLD, handleSignal);
signal(SIGHUP, handleSignal);
signal(SIGUSR1, handleSignal);
signal(SIGUSR2, handleSignal);
2011-10-28 17:15:48 +00:00
#endif
}
}
int main(int argc, char **argv) {
FbTk::NLSInit("fluxbox.cat");
FluxboxCli::Options opts;
int exitcode = opts.parse(argc, argv);
if (exitcode != -1) {
exit(exitcode);
}
exitcode = EXIT_FAILURE;
2001-12-11 20:47:02 +00:00
2003-05-07 22:19:59 +00:00
#ifdef __EMX__
2002-12-01 13:42:15 +00:00
_chdir2(getenv("X11ROOT"));
2001-12-11 20:47:02 +00:00
#endif // __EMX__
streambuf *outbuf = 0;
streambuf *errbuf = 0;
ofstream log_file(opts.log_filename.c_str());
_FB_USES_NLS;
// setup log file
if (log_file.is_open()) {
2010-09-18 15:27:28 +00:00
cerr << _FB_CONSOLETEXT(main, LoggingTo, "Logging to", "Logging to a file")
<< ": "
<< opts.log_filename << endl;
log_file <<"------------------------------------------" << endl;
log_file << _FB_CONSOLETEXT(main, LogFile, "Log File", "")
<< ": "
<< opts.log_filename <<endl;
FluxboxCli::showInfo(log_file);
2010-09-18 15:27:28 +00:00
log_file << "------------------------------------------" << endl;
// setup log to use cout and cerr stream
outbuf = cout.rdbuf(log_file.rdbuf());
errbuf = cerr.rdbuf(log_file.rdbuf());
}
FluxboxCli::setupConfigFiles(opts.rc_path, opts.rc_file);
FluxboxCli::updateConfigFilesIfNeeded(opts.rc_file);
2002-12-01 13:42:15 +00:00
try {
fluxbox.reset(new Fluxbox(argc, argv,
opts.session_display,
opts.rc_path,
opts.rc_file,
opts.xsync));
setupSignalHandling();
2002-12-01 13:42:15 +00:00
fluxbox->eventLoop();
exitcode = EXIT_SUCCESS;
} catch (out_of_range &oor) {
2010-09-18 15:27:28 +00:00
cerr <<"Fluxbox: "
<< _FB_CONSOLETEXT(main, ErrorOutOfRange, "Out of range", "Error message")
<< ": "
<< oor.what() << endl;
} catch (runtime_error &re) {
2010-09-18 15:27:28 +00:00
cerr << "Fluxbox: "
<< _FB_CONSOLETEXT(main, ErrorRuntime, "Runtime error", "Error message")
<< ": "
<< re.what() << endl;
} catch (bad_cast &bc) {
2010-09-18 15:27:28 +00:00
cerr << "Fluxbox: "
<< _FB_CONSOLETEXT(main, ErrorBadCast, "Bad cast", "Error message")
<< ": "
<< bc.what() << endl;
} catch (bad_alloc &ba) {
2010-09-18 15:27:28 +00:00
cerr << "Fluxbox: "
<< _FB_CONSOLETEXT(main, ErrorBadAlloc, "Bad Alloc", "Error message")
<< ": "
<< ba.what() << endl;
} catch (exception &e) {
2010-09-18 15:27:28 +00:00
cerr << "Fluxbox: "
<< _FB_CONSOLETEXT(main, ErrorStandardException, "Standard Exception", "Error message")
<< ": "
<< e.what() << endl;
} catch (string & error_str) {
2010-09-18 15:27:28 +00:00
cerr << _FB_CONSOLETEXT(Common, Error, "Error", "Error message header")
<< ": "
<< error_str << endl;
2002-12-01 13:42:15 +00:00
} catch (...) {
2010-09-18 15:27:28 +00:00
cerr << "Fluxbox: "
<< _FB_CONSOLETEXT(main, ErrorUnknown, "Unknown error", "Error message")
<< "." << endl;
2002-12-02 22:02:35 +00:00
abort();
2002-12-01 13:42:15 +00:00
}
bool restarting = false;
string restart_argument;
if (fluxbox.get()) {
restarting = fluxbox->isRestarting();
restart_argument = fluxbox->getRestartArgument();
}
2004-01-11 13:12:02 +00:00
// destroy fluxbox
fluxbox.reset(0);
// restore cout and cin streams
if (outbuf != 0)
cout.rdbuf(outbuf);
if (errbuf != 0)
cerr.rdbuf(errbuf);
FbTk::FbStringUtil::shutdown();
if (restarting) {
if (!restart_argument.empty()) {
const char *shell = getenv("SHELL");
if (!shell)
shell = "/bin/sh";
2008-01-25 07:21:35 +00:00
execlp(shell, shell, "-c", restart_argument.c_str(), (const char *) NULL);
perror(restart_argument.c_str());
}
// fall back in case the above execlp doesn't work
execvp(argv[0], argv);
perror(argv[0]);
const char *basename = FbTk::StringUtil::basename(argv[0]).c_str();
execvp(basename, argv);
perror(basename);
}
2002-12-03 01:46:28 +00:00
return exitcode;
2001-12-11 20:47:02 +00:00
}