Skip to content

Commit

Permalink
extend info-fd command to show exit code
Browse files Browse the repository at this point in the history
  • Loading branch information
Dominic Brown committed May 11, 2018
1 parent 56609f8 commit c189eee
Showing 1 changed file with 35 additions and 14 deletions.
49 changes: 35 additions & 14 deletions bubblewrap.c
Expand Up @@ -310,14 +310,27 @@ propagate_exit_status (int status)
return 255;
}

static void
dump_info (int fd, int child_pid, int exitc)
{
cleanup_free char *output = xasprintf ("{\n"
" \"child-pid\": %i,\n"
" \"exit-code\": %i\n}\n",
child_pid, exitc);
size_t len = strlen (output);
if (write (fd, output, len) != len)
die_with_error ("Write to info_fd");
close (fd);
}

/* This stays around for as long as the initial process in the app does
* and when that exits it exits, propagating the exit status. We do this
* by having pid 1 in the sandbox detect this exit and tell the monitor
* the exit status via a eventfd. We also track the exit of the sandbox
* pid 1 via a signalfd for SIGCHLD, and exit with an error in this case.
* This is to catch e.g. problems during setup. */
static void
monitor_child (int event_fd, pid_t child_pid)
monitor_child (int event_fd, int info_fd, pid_t child_pid)
{
int res;
uint64_t val;
Expand All @@ -327,12 +340,19 @@ monitor_child (int event_fd, pid_t child_pid)
struct pollfd fds[2];
int num_fds;
struct signalfd_siginfo fdsi;
int dont_close[] = { event_fd, -1 };
int dont_close[3];
int exitc;
pid_t died_pid;
int died_status;

/* Close all extra fds in the monitoring process.
Any passed in fds have been passed on to the child anyway. */
int j = 0;
if (event_fd != -1)
dont_close[j++] = event_fd;
if (info_fd != -1)
dont_close[j++] = info_fd;
dont_close[j++] = -1;
fdwalk (proc_fd, close_extra_fds, dont_close);

sigemptyset (&mask);
Expand Down Expand Up @@ -368,7 +388,12 @@ monitor_child (int event_fd, pid_t child_pid)
if (s == -1 && errno != EINTR && errno != EAGAIN)
die_with_error ("read eventfd");
else if (s == 8)
exit ((int) val - 1);
{
exitc = (int) val - 1;
if (info_fd != -1)
dump_info (info_fd, child_pid, exitc);
exit (exitc);
}
}

/* We need to read the signal_fd, or it will keep polling as read,
Expand All @@ -385,7 +410,12 @@ monitor_child (int event_fd, pid_t child_pid)
/* We may be getting sigchild from other children too. For instance if
someone created a child process, and then exec:ed bubblewrap. Ignore them */
if (died_pid == child_pid)
exit (propagate_exit_status (died_status));
{
exitc = propagate_exit_status (died_status);
if (info_fd != -1)
dump_info (info_fd, child_pid, exitc);
exit (exitc);
}
}
}
}
Expand Down Expand Up @@ -2187,15 +2217,6 @@ main (int argc,
/* Optionally bind our lifecycle to that of the parent */
handle_die_with_parent ();

if (opt_info_fd != -1)
{
cleanup_free char *output = xasprintf ("{\n \"child-pid\": %i\n}\n", pid);
size_t len = strlen (output);
if (write (opt_info_fd, output, len) != len)
die_with_error ("Write to info_fd");
close (opt_info_fd);
}

if (opt_userns_block_fd != -1)
{
char b[1];
Expand All @@ -2209,7 +2230,7 @@ main (int argc,
/* Ignore res, if e.g. the child died and closed child_wait_fd we don't want to error out here */
close (child_wait_fd);

monitor_child (event_fd, pid);
monitor_child (event_fd, opt_info_fd, pid);
exit (0); /* Should not be reached, but better safe... */
}

Expand Down

0 comments on commit c189eee

Please sign in to comment.