From c66c13dd12c72e1f6fa1fb7d9383b9c181b9d817 Mon Sep 17 00:00:00 2001 From: Davin McCall Date: Mon, 5 Nov 2018 22:01:26 +0000 Subject: [PATCH] shutdown: clean up error handling. --- src/shutdown.cc | 73 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 55 insertions(+), 18 deletions(-) diff --git a/src/shutdown.cc b/src/shutdown.cc index 947896b..d669d6b 100644 --- a/src/shutdown.cc +++ b/src/shutdown.cc @@ -1,10 +1,10 @@ #include #include #include -#include #include #include #include +#include #include #include @@ -12,6 +12,7 @@ #include #include #include +#include #include #include "cpbuffer.h" @@ -536,46 +537,82 @@ static void run_process(const char * prog_args[], loop_t &loop, subproc_buffer & sp_watcher_t sp_watcher; // Create output pipe + bool have_pipe = true; int pipefds[2]; if (dasynq::pipe2(pipefds, O_NONBLOCK) == -1) { - // TODO - std::cout << "*** pipe2 failed ***" << std::endl; + sub_buf.append("Warning: "); + sub_buf.append(prog_args[0]); + sub_buf.append(": could not create pipe for subprocess output\n"); + have_pipe = false; + // Note, we proceed and let the sub-process run with our stdout/stderr. } + subproc_out_watch owatch {sub_buf}; + + if (have_pipe) { + close(pipefds[1]); + try { + owatch.add_watch(loop, pipefds[0], dasynq::IN_EVENTS); + } + catch (...) { + // failed to create the watcher for the subprocess output; again, let it run with + // our stdout/stderr + sub_buf.append("Warning: could not create output watch for subprocess\n"); + close(pipefds[0]); + have_pipe = false; + } + } + + // If we've buffered any messages/output, give them a chance to go out now: + loop.poll(); + pid_t ch_pid = sp_watcher.fork(loop); if (ch_pid == 0) { // child // Dup output pipe to stdout, stderr - dup2(pipefds[1], STDOUT_FILENO); - dup2(pipefds[1], STDERR_FILENO); - close(pipefds[0]); - close(pipefds[1]); + if (have_pipe) { + dup2(pipefds[1], STDOUT_FILENO); + dup2(pipefds[1], STDERR_FILENO); + close(pipefds[0]); + close(pipefds[1]); + } execv(prog_args[0], const_cast(prog_args)); - puts("Failed to execute subprocess:\n"); + puts("Failed to execute subprocess: "); perror(prog_args[0]); _exit(1); } - close(pipefds[1]); - - subproc_out_watch owatch {sub_buf}; - owatch.add_watch(loop, pipefds[0], dasynq::IN_EVENTS); - do { loop.run(); } while (! sp_watcher.terminated); - owatch.deregister(loop); + if (have_pipe) { + owatch.deregister(loop); + } } static void unmount_disks(loop_t &loop, subproc_buffer &sub_buf) { - const char * unmount_args[] = { "/bin/umount", "-a", "-r", nullptr }; - run_process(unmount_args, loop, sub_buf); + try { + const char * unmount_args[] = { "/bin/umount", "-a", "-r", nullptr }; + run_process(unmount_args, loop, sub_buf); + } + catch (std::exception &e) { + sub_buf.append("Couldn't fork for umount: "); + sub_buf.append(e.what()); + sub_buf.append("\n"); + } } static void swap_off(loop_t &loop, subproc_buffer &sub_buf) { - const char * swapoff_args[] = { "/sbin/swapoff", "-a", nullptr }; - run_process(swapoff_args, loop, sub_buf); + try { + const char * swapoff_args[] = { "/sbin/swapoff", "-a", nullptr }; + run_process(swapoff_args, loop, sub_buf); + } + catch (std::exception &e) { + sub_buf.append("Couldn't fork for swapoff: "); + sub_buf.append(e.what()); + sub_buf.append("\n"); + } } -- 2.25.1