#include <cstddef>
#include <cstdio>
#include <csignal>
-#include <unistd.h>
#include <cstring>
#include <string>
#include <iostream>
+#include <exception>
#include <sys/reboot.h>
#include <sys/types.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <sys/stat.h>
+#include <unistd.h>
#include <fcntl.h>
#include "cpbuffer.h"
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<char **>(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");
+ }
}