diff --git a/src/comm/comm_client.cpp b/src/comm/comm_client.cpp index 3dde5341..827486fd 100644 --- a/src/comm/comm_client.cpp +++ b/src/comm/comm_client.cpp @@ -62,7 +62,7 @@ namespace comm else if (pid == 0) { // Websocat process. - util::unmask_signal(); + util::fork_detach(); close(write_pipe[1]); //parent write close(read_pipe[0]); //parent read diff --git a/src/comm/comm_server.cpp b/src/comm/comm_server.cpp index 5726dfaa..c3d2b185 100644 --- a/src/comm/comm_server.cpp +++ b/src/comm/comm_server.cpp @@ -295,7 +295,7 @@ namespace comm else if (pid == 0) { // Websocketd process. - util::unmask_signal(); + util::fork_detach(); // We are using websocketd forked repo: https://github.com/codetsunami/websocketd diff --git a/src/cons/cons.cpp b/src/cons/cons.cpp index 5da62c5e..5d16009c 100644 --- a/src/cons/cons.cpp +++ b/src/cons/cons.cpp @@ -519,7 +519,7 @@ namespace cons if (pid == 0) { // appbill process. - util::unmask_signal(); + util::fork_detach(); // before execution chdir into a valid the latest state data directory that contains an appbill.table chdir(conf::ctx.state_rw_dir.c_str()); diff --git a/src/hpfs/hpfs.cpp b/src/hpfs/hpfs.cpp index 3e3b61af..0fbccab3 100644 --- a/src/hpfs/hpfs.cpp +++ b/src/hpfs/hpfs.cpp @@ -56,7 +56,7 @@ namespace hpfs else if (pid == 0) { // hpfs process. - util::unmask_signal(); + util::fork_detach(); // Fill process args. char *execv_args[] = { @@ -145,7 +145,7 @@ namespace hpfs else if (pid == 0) { // hpfs process. - util::unmask_signal(); + util::fork_detach(); // If the mount dir is not specified, assign a mount dir based on hpfs process id. const pid_t self_pid = getpid(); diff --git a/src/main.cpp b/src/main.cpp index 856faaf2..0af79615 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -67,12 +67,12 @@ int parse_cmd(int argc, char **argv) */ void deinit() { + usr::deinit(); + p2p::deinit(); cons::deinit(); state_sync::deinit(); state_serve::deinit(); read_req::deinit(); - usr::deinit(); - p2p::deinit(); hpfs::deinit(); } @@ -190,8 +190,9 @@ int main(int argc, char **argv) << (conf::cfg.startup_mode == conf::OPERATING_MODE::OBSERVER ? "Observer" : "Proposer"); LOG_INFO << "Public key: " << conf::cfg.pubkeyhex.substr(2); // Public key without 'ed' prefix. - if (hpfs::init() != 0 || p2p::init() != 0 || usr::init() != 0 || read_req::init() != 0 || - state_serve::init() != 0 || state_sync::init() != 0 || cons::init() != 0) + if (hpfs::init() != 0 || read_req::init() != 0 || + state_serve::init() != 0 || state_sync::init() != 0 || cons::init() != 0 || + p2p::init() != 0 || usr::init() != 0) { deinit(); return -1; @@ -203,7 +204,7 @@ int main(int argc, char **argv) // Wait until consensus thread finishes. cons::wait(); - // deinit() here only gets called when there is an error in consensus. + // deinit() here only gets called when there is an error in consensus. // If not deinit in the sigint handler is called when a SIGINT is received. deinit(); } diff --git a/src/sc.cpp b/src/sc.cpp index 0c26c5f3..06728b80 100644 --- a/src/sc.cpp +++ b/src/sc.cpp @@ -67,7 +67,7 @@ namespace sc else if (pid == 0) { // Contract process. - util::unmask_signal(); + util::fork_detach(); // Set up the process environment and overlay the contract binary program with execv(). @@ -112,7 +112,9 @@ namespace sc ret = -1; success: - stop_hpfs_rw_session(ctx); + if (stop_hpfs_rw_session(ctx) == -1) + ret = -1; + cleanup_fdmap(ctx.userfds); if (!ctx.args.readonly) { @@ -131,7 +133,7 @@ namespace sc { if (pid > 0) { - int scstatus; + int scstatus = 0; waitpid(pid, &scstatus, 0); if (!WIFEXITED(scstatus)) return WEXITSTATUS(scstatus); @@ -156,17 +158,18 @@ namespace sc */ int stop_hpfs_rw_session(execution_context &ctx) { + int result = 0; // Read the root hash if not in readonly mode. if (!ctx.args.readonly && hpfs::get_hash(ctx.args.post_execution_state_hash, ctx.args.state_dir, "/") < 1) - return -1; + result = -1; LOG_DEBUG << "Stopping hpfs session... pid:" << ctx.hpfs_pid << (ctx.args.readonly ? " (rdonly)" : ""); if (util::kill_process(ctx.hpfs_pid, true) == -1) - return -1; + result = -1; ctx.hpfs_pid = 0; - return 0; + return result; } /** @@ -711,9 +714,6 @@ namespace sc if (ctx.contract_pid > 0) util::kill_process(ctx.contract_pid, true); - if (ctx.hpfs_pid > 0) - util::kill_process(ctx.hpfs_pid, true); - if (ctx.output_fetcher_thread.joinable()) ctx.output_fetcher_thread.join(); } diff --git a/src/util.cpp b/src/util.cpp index 591b4185..4de6b0fa 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -206,13 +206,25 @@ namespace util pthread_sigmask(SIG_BLOCK, &mask, NULL); } - // Clears signal mask from the calling thread. - // Used for other processes forked from hpcore threads. - void unmask_signal() + /** + * Clears signal mask and signal handlers from the caller. + * Called by other processes forked from hpcore threads so they get detatched from + * the hpcore signal setup. + */ + void fork_detach() { + // Restore signal handlers to defaults. + signal(SIGINT, SIG_DFL); + signal(SIGSEGV, SIG_DFL); + signal(SIGABRT, SIG_DFL); + + // Remove any signal masks applied by hpcore. sigset_t mask; sigemptyset(&mask); pthread_sigmask(SIG_SETMASK, &mask, NULL); + + // Set process group id (so the terminal doesn't send kill signals to forked children). + setpgrp(); } // Kill a process with a signal and if specified, wait until it stops running. diff --git a/src/util.hpp b/src/util.hpp index 00ee11bb..f2ba1339 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -90,7 +90,7 @@ namespace util void mask_signal(); - void unmask_signal(); + void fork_detach(); int kill_process(const pid_t pid, const bool wait, const int signal = SIGINT); diff --git a/test/bin/hpfs b/test/bin/hpfs index 763575b7..415e9f44 100755 Binary files a/test/bin/hpfs and b/test/bin/hpfs differ