fix: Replace process on reload

This commit is contained in:
Michael Carlberg 2016-12-03 15:46:48 +01:00
parent 0f91d3d8df
commit 086e498388
5 changed files with 125 additions and 122 deletions

View File

@ -37,9 +37,7 @@ class controller {
~controller(); ~controller();
void bootstrap(bool writeback = false, bool dump_wmname = false); void bootstrap(bool writeback = false, bool dump_wmname = false);
bool run();
void run();
bool completed();
protected: protected:
void install_sigmask(); void install_sigmask();

View File

@ -8,6 +8,7 @@ namespace process_util {
bool in_parent_process(pid_t pid); bool in_parent_process(pid_t pid);
bool in_forked_process(pid_t pid); bool in_forked_process(pid_t pid);
void exec(char* cmd, char** args);
void exec(const string& cmd); void exec(const string& cmd);
pid_t wait_for_completion(pid_t process_id, int* status_addr, int waitflags = 0); pid_t wait_for_completion(pid_t process_id, int* status_addr, int waitflags = 0);

View File

@ -118,6 +118,7 @@ controller::~controller() {
} }
m_connection.flush(); m_connection.flush();
m_connection.disconnect();
} }
/** /**
@ -178,7 +179,7 @@ void controller::bootstrap(bool writeback, bool dump_wmname) {
/** /**
* Launch the controller * Launch the controller
*/ */
void controller::run() { bool controller::run() {
assert(!m_connection.connection_has_error()); assert(!m_connection.connection_has_error());
m_log.info("Starting application"); m_log.info("Starting application");
@ -235,12 +236,7 @@ void controller::run() {
m_log.trace("controller: Removing config watch"); m_log.trace("controller: Removing config watch");
m_confwatch->remove(true); m_confwatch->remove(true);
} }
}
/**
* Get completion state
*/
bool controller::completed() {
return !m_running && !m_reload; return !m_running && !m_reload;
} }

View File

@ -10,6 +10,7 @@
#include "config.hpp" #include "config.hpp"
#include "utils/env.hpp" #include "utils/env.hpp"
#include "utils/inotify.hpp" #include "utils/inotify.hpp"
#include "utils/process.hpp"
#include "x11/ewmh.hpp" #include "x11/ewmh.hpp"
#include "x11/xutils.hpp" #include "x11/xutils.hpp"
@ -20,7 +21,8 @@ struct exit_failure {};
int main(int argc, char** argv) { int main(int argc, char** argv) {
uint8_t exit_code{EXIT_SUCCESS}; uint8_t exit_code{EXIT_SUCCESS};
stateflag quit{false}; bool reload{false};
int xfd;
// clang-format off // clang-format off
const command_line::options opts{ const command_line::options opts{
@ -38,6 +40,7 @@ int main(int argc, char** argv) {
logger& logger{configure_logger<decltype(logger)>(loglevel::WARNING).create<decltype(logger)>()}; logger& logger{configure_logger<decltype(logger)>(loglevel::WARNING).create<decltype(logger)>()};
try {
//================================================== //==================================================
// Connect to X server // Connect to X server
//================================================== //==================================================
@ -50,15 +53,15 @@ int main(int argc, char** argv) {
throw exit_failure{}; throw exit_failure{};
} }
int xfd{xcb_get_file_descriptor(connection)}; xfd = xcb_get_file_descriptor(connection);
while (!quit) {
try {
//================================================== //==================================================
// Parse command line arguments // Parse command line arguments
//================================================== //==================================================
string scriptname{argv[0]};
vector<string> args(argv + 1, argv + argc); vector<string> args(argv + 1, argv + argc);
cliparser cli{configure_cliparser<decltype(cli)>(argv[0], opts).create<decltype(cli)>()};
cliparser cli{configure_cliparser<decltype(cli)>(scriptname, opts).create<decltype(cli)>()};
cli.process_input(args); cli.process_input(args);
if (cli.has("quiet")) { if (cli.has("quiet")) {
@ -124,33 +127,33 @@ int main(int argc, char** argv) {
//================================================== //==================================================
// Run application // Run application
//================================================== //==================================================
ctrl->run(); if (!ctrl->run()) {
reload = true;
if (ctrl->completed()) {
throw exit_success{};
} else {
logger.info("Reloading application...");
} }
} catch (const exit_success& term) { } catch (const exit_success& term) {
exit_code = EXIT_SUCCESS; exit_code = EXIT_SUCCESS;
quit = true;
} catch (const exit_failure& term) { } catch (const exit_failure& term) {
exit_code = EXIT_FAILURE; exit_code = EXIT_FAILURE;
quit = true;
} catch (const exception& err) { } catch (const exception& err) {
logger.err(err.what()); logger.err(err.what());
exit_code = EXIT_FAILURE; exit_code = EXIT_FAILURE;
quit = true;
}
} }
logger.trace("Close connection to X server"); if (xfd != 0) {
ewmh_util::dealloc();
xcb_disconnect(connection);
close(xfd); close(xfd);
}
if (!reload) {
logger.info("Reached end of application..."); logger.info("Reached end of application...");
return exit_code; return exit_code;
}
try {
logger.info("Reload application...");
process_util::exec(argv[0], argv);
} catch (const system_error& err) {
logger.err("execlp() failed (%s)", strerror(errno));
}
return EXIT_FAILURE;
} }

View File

@ -22,6 +22,14 @@ namespace process_util {
return pid == 0; return pid == 0;
} }
/**
* Replace current process
*/
void exec(char* cmd, char** args) {
execvp(cmd, args);
throw system_error("execvp() failed");
}
/** /**
* Replace process with command * Replace process with command
*/ */
@ -38,11 +46,8 @@ namespace process_util {
for (auto&& argument : args) { for (auto&& argument : args) {
c_args.emplace_back(const_cast<char*>(argument.c_str())); c_args.emplace_back(const_cast<char*>(argument.c_str()));
} }
c_args.emplace_back(nullptr);
execvp(c_args[0], c_args.data()); exec(c_args[0], c_args.data());
throw system_error("Failed to execute command");
} }
/** /**