Changes: Error handling improvements.

Details: Throw std::runtime_error() instead of logErrorAndDie().

RevBy: Alexey Shilov
pull/1/head
Jussi Lind 15 years ago
parent e6456cc718
commit 6221ea763d

@ -34,6 +34,7 @@
#include <fcntl.h>
#include <cstring>
#include <sstream>
#include <stdexcept>
#ifdef Q_WS_X11
#include <X11/Xlib.h>
@ -124,9 +125,8 @@ void Booster::initialize(int initialArgc, char ** initialArgv, int newBoosterLau
// Wait and read commands from the invoker
Logger::logDebug("Booster: Wait for message from invoker");
if (!receiveDataFromInvoker(socketFd)) {
Logger::logErrorAndDie(EXIT_FAILURE, "Booster: Couldn't read command\n");
}
if (!receiveDataFromInvoker(socketFd))
throw std::runtime_error("Booster: Couldn't read command\n");
// Send parent process a message that it can create a new booster,
// send pid of invoker, booster respawn value and invoker socket connection.
@ -462,7 +462,11 @@ void Booster::setEnvironmentBeforeLaunch()
if (err < 0)
{
// Credential setup has failed, abort.
Logger::logErrorAndDie(EXIT_FAILURE, "Booster: Failed to setup credentials for launching application: %d\n", err);
std::string msg("Booster: Failed to setup credentials for launching application: ");
std::stringstream ss;
ss << err;
msg += ss.str();
throw std::runtime_error(msg);
}
#endif
@ -545,7 +549,8 @@ void* Booster::loadMain()
void * module = dlopen(m_appData->fileName().c_str(), dlopenFlags);
if (!module)
Logger::logErrorAndDie(EXIT_FAILURE, "Booster: Loading invoked application failed: '%s'\n", dlerror());
throw std::runtime_error(std::string("Booster: Loading invoked application failed: '") +
dlerror() + "'\n");
// Find out the address for symbol "main". dlerror() is first used to clear any old error conditions,
// then dlsym() is called, and then dlerror() is checked again. This procedure is documented
@ -556,7 +561,8 @@ void* Booster::loadMain()
const char * error_s = dlerror();
if (error_s != NULL)
Logger::logErrorAndDie(EXIT_FAILURE, "Booster: Loading symbol 'main' failed: '%s'\n", error_s);
throw std::runtime_error(std::string("Booster: Loading symbol 'main' failed: '") +
error_s + "'\n");
return module;
}

@ -27,6 +27,7 @@
#include <cstdlib>
#include <cerrno>
#include <unistd.h>
#include <stdexcept>
#if defined (HAVE_CREDS) && ! defined (DISABLE_VERIFICATION)
const char * Connection::m_credsStr = "applauncherd-launcher::access";
@ -57,9 +58,7 @@ Connection::Connection(int socketFd, bool testMode) :
m_io[2] = -1;
if (!m_testMode && m_curSocket == -1)
{
Logger::logErrorAndDie(EXIT_FAILURE, "Connection: Socket isn't initialized!\n");
}
throw std::runtime_error("Connection: Socket isn't initialized!\n");
#if defined (HAVE_CREDS) && ! defined (DISABLE_VERIFICATION)

@ -37,6 +37,7 @@
#include <glob.h>
#include <cstring>
#include <cstdio>
#include <stdexcept>
#include "coverage.h"
@ -57,7 +58,7 @@ Daemon::Daemon(int & argc, char * argv[]) :
}
else
{
Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: Daemon already created!\n");
throw std::runtime_error("Daemon: Daemon already created!\n");
}
// Parse arguments
@ -73,12 +74,12 @@ Daemon::Daemon(int & argc, char * argv[]) :
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, m_boosterLauncherSocket) == -1)
{
Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: Creating a socket pair for boosters failed!\n");
throw std::runtime_error("Daemon: Creating a socket pair for boosters failed!\n");
}
if (pipe(m_sigPipeFd) == -1)
{
Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: Creating a pipe for Unix signals failed!\n");
throw std::runtime_error("Daemon: Creating a pipe for Unix signals failed!\n");
}
// Daemonize if desired
@ -95,11 +96,11 @@ void Daemon::consoleQuiet()
close(2);
if (open("/dev/null", O_RDONLY) < 0)
Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: Failed to open /dev/null as read-only");
throw std::runtime_error("Daemon: Failed to open /dev/null as read-only");
int fd = open("/dev/null", O_WRONLY);
if ((fd == -1) || (dup(fd) < 0))
Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: Failed to open /dev/null as write-only");
throw std::runtime_error("Daemon: Failed to open /dev/null as write-only");
}
Daemon * Daemon::instance()
@ -400,7 +401,7 @@ void Daemon::forkBooster(char type, int sleepTime)
pid_t newPid = fork();
if (newPid == -1)
Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: Forking while invoking");
throw std::runtime_error("Daemon: Forking while invoking");
if (newPid == 0) /* Child process */
{
@ -470,7 +471,7 @@ void Daemon::forkBooster(char type, int sleepTime)
}
else
{
Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: Unknown booster type '%c'\n", type);
throw std::runtime_error(std::string("Daemon: Unknown booster type '") + type + "'");
}
}
else /* Parent process */
@ -597,10 +598,7 @@ void Daemon::daemonize()
// Fork off the parent process: first fork
pid = fork();
if (pid < 0)
{
Logger::logError("Daemon: Unable to fork daemon, code %d (%s)", errno, strerror(errno));
exit(EXIT_FAILURE);
}
throw std::runtime_error("Daemon: Unable to fork daemon");
// If we got a good PID, then we can exit the parent process.
if (pid > 0)
@ -611,10 +609,7 @@ void Daemon::daemonize()
// Fork off the parent process: second fork
pid = fork();
if (pid < 0)
{
Logger::logError("Daemon: Unable to fork daemon, code %d (%s)", errno, strerror(errno));
exit(EXIT_FAILURE);
}
throw std::runtime_error("Daemon: Unable to fork daemon");
// If we got a good PID, then we can exit the parent process.
if (pid > 0)
@ -624,9 +619,7 @@ void Daemon::daemonize()
// Check the lock
if(!Daemon::lock())
{
Logger::logErrorAndDie(EXIT_FAILURE, "%s is already running \n", PROG_NAME_LAUNCHER);
}
throw std::runtime_error(std::string(PROG_NAME_LAUNCHER) + " is already running\n");
// Change the file mode mask
umask(0);
@ -636,17 +629,11 @@ void Daemon::daemonize()
// Create a new SID for the child process
sid = setsid();
if (sid < 0)
{
Logger::logError("Daemon: Unable to create a new session, code %d (%s)", errno, strerror(errno));
exit(EXIT_FAILURE);
}
throw std::runtime_error("Daemon: Unable to setsid.");
// Change the current working directory
if ((chdir("/")) < 0)
{
Logger::logError("Daemon: Unable to change directory to %s, code %d (%s)", "/", errno, strerror(errno));
exit(EXIT_FAILURE);
}
throw std::runtime_error("Daemon: Unable to chdir to '/'");
// Open file descriptors pointing to /dev/null
// Redirect standard file descriptors to /dev/null

@ -96,17 +96,6 @@ void Logger::logError(const char * format, ...)
va_end(ap);
}
void Logger::logErrorAndDie(int code, const char * format, ...)
{
va_list(ap);
va_start(ap, format);
writeLog(LOG_ERR, format, ap);
vfprintf(stderr, format, ap);
va_end(ap);
_exit(code);
}
void Logger::setDebugMode(bool enable)
{
Logger::m_debugMode = enable;

@ -79,15 +79,6 @@ public:
*/
static void logInfo(const char * format, ...);
/*!
* \brief Log an error to the system message logger and exit
* \param format String identical to a printf format string
* \param additionalArgs Depending on the format string, the function may expect a
* sequence of additional arguments, each containing one value to be inserted
* in the format parameter, if any.
*/
static void logErrorAndDie(int code, const char * format, ...);
/*!
* \brief Forces Logger to log everything and echo to stdout if set to true.
*/

@ -28,6 +28,7 @@
#include <signal.h>
#include <fcntl.h>
#include <sys/file.h>
#include <stdexcept>
#define DECL_EXPORT extern "C" __attribute__ ((__visibility__("default")))
@ -79,28 +80,38 @@ DECL_EXPORT int main(int argc, char * argv[])
{
if(!Daemon::lock())
{
Logger::logErrorAndDie(EXIT_FAILURE, "%s is already running \n", PROG_NAME_LAUNCHER);
Logger::logError("%s is already running \n", PROG_NAME_LAUNCHER);
return EXIT_FAILURE;
}
}
// Create main daemon instance
Daemon myDaemon(argc, argv);
try
{
// Create main daemon instance
Daemon myDaemon(argc, argv);
// Get fd for signal pipe.
g_sigPipeFd = myDaemon.sigPipeFd();
// Get fd for signal pipe.
g_sigPipeFd = myDaemon.sigPipeFd();
// Install signal handlers
signal(SIGCHLD, sigChldHandler); // reap zombies
signal(SIGTERM, sigTermHandler); // exit launcher
signal(SIGUSR1, sigUsr1Handler); // enter normal mode from boot mode
signal(SIGUSR2, sigUsr2Handler); // enter boot mode (same as --boot-mode)
signal(SIGPIPE, sigPipeHandler); // broken invoker's pipe
// Install signal handlers
signal(SIGCHLD, sigChldHandler); // reap zombies
signal(SIGTERM, sigTermHandler); // exit launcher
signal(SIGUSR1, sigUsr1Handler); // enter normal mode from boot mode
signal(SIGUSR2, sigUsr2Handler); // enter boot mode (same as --boot-mode)
signal(SIGPIPE, sigPipeHandler); // broken invoker's pipe
// Run the main loop
myDaemon.run();
// Run the main loop
myDaemon.run();
// Close the log
Logger::closeLog();
// Close the log
Logger::closeLog();
}
catch (std::runtime_error & e)
{
Logger::logError(e.what());
std::cout << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

@ -22,9 +22,13 @@
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <cstdlib>
#include <cstring>
#include <stdexcept>
#include <errno.h>
#include <sstream>
void SocketManager::initSocket(const string & socketId)
{
@ -37,14 +41,23 @@ void SocketManager::initSocket(const string & socketId)
// Create a new local socket
int socketFd = socket(PF_UNIX, SOCK_STREAM, 0);
if (socketFd < 0)
Logger::logErrorAndDie(EXIT_FAILURE, "SocketManager: Failed to open socket\n");
throw std::runtime_error("SocketManager: Failed to open socket\n");
// TODO: Error if socketId >= maxLen. Also unlink() here may
// try to remove a different file than is passed to sun.sa_data.
// Remove the previous socket file
if (unlink(socketId.c_str()))
Logger::logError("SocketManager: Failed to unlink existing socket file '%s'", socketId.c_str());
struct stat sb;
stat(socketId.c_str(), &sb);
if (S_ISSOCK(sb.st_mode))
{
if (unlink(socketId.c_str()) == -1)
{
std::string msg("SocketManager: Failed to unlink existing socket file '");
msg += socketId + "': " + strerror(errno);
Logger::logWarning(msg.c_str());
}
}
// Initialize the socket struct
struct sockaddr sun;
@ -55,11 +68,23 @@ void SocketManager::initSocket(const string & socketId)
// Bind the socket
if (bind(socketFd, &sun, sizeof(sun)) < 0)
Logger::logErrorAndDie(EXIT_FAILURE, "SocketManager: Failed to bind to socket (fd=%d)\n", socketFd);
{
std::string msg("SocketManager: Failed to bind to socket (fd=");
std::stringstream ss;
ss << socketFd;
msg += ss.str() + ")";
throw std::runtime_error(msg);
}
// Listen to the socket
if (listen(socketFd, 10) < 0)
Logger::logErrorAndDie(EXIT_FAILURE, "SocketManager: Failed to listen to socket (fd=%d)\n", socketFd);
{
std::string msg("SocketManager: Failed to listen to socket (fd=");
std::stringstream ss;
ss << socketFd;
msg += ss.str() + ")";
throw std::runtime_error(msg);
}
// Set permissions
chmod(socketId.c_str(), S_IRUSR | S_IWUSR | S_IXUSR |

Loading…
Cancel
Save