aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxl/libxl_exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/libxl/libxl_exec.c')
-rw-r--r--tools/libxl/libxl_exec.c61
1 files changed, 57 insertions, 4 deletions
diff --git a/tools/libxl/libxl_exec.c b/tools/libxl/libxl_exec.c
index ce6e93f4f0..27fd6cd600 100644
--- a/tools/libxl/libxl_exec.c
+++ b/tools/libxl/libxl_exec.c
@@ -36,20 +36,72 @@ static int call_waitpid(pid_t (*waitpid_cb)(pid_t, int *, int), pid_t pid, int *
return (waitpid_cb) ? waitpid_cb(pid, status, options) : waitpid(pid, status, options);
}
+static void check_open_fds(const char *what)
+{
+ const char *env_debug;
+ int debug;
+ int i, flags, badness = 0;
+ char path[PATH_MAX];
+ char link[PATH_MAX+1];
+
+ env_debug = getenv("_LIBXL_DEBUG_EXEC_FDS");
+ if (!env_debug) return;
+
+ debug = strtol(env_debug, (char **) NULL, 10);atoi(env_debug);
+ if (debug <= 0) return;
+
+ for (i = 4; i < 256; i++) {
+#ifdef __linux__
+ size_t len;
+#endif
+ flags = fcntl(i, F_GETFD);
+ if ( flags == -1 ) {
+ if ( errno != EBADF )
+ fprintf(stderr, "libxl: execing %s: fd %d flags returned %s (%d)\n",
+ what, i, strerror(errno), errno);
+ continue;
+ }
+
+ if ( flags & FD_CLOEXEC )
+ continue;
+
+ badness++;
+
+#ifdef __linux__
+ snprintf(path, PATH_MAX, "/proc/%d/fd/%d", getpid(), i);
+ len = readlink(path, link, PATH_MAX);
+ if (len > 0) {
+ link[len] = '\0';
+ fprintf(stderr, "libxl: execing %s: fd %d is open to %s with flags %#x\n",
+ what, i, link, flags);
+ } else
+#endif
+ fprintf(stderr, "libxl: execing %s: fd %d is open with flags %#x\n",
+ what, i, flags);
+ }
+ if (debug < 2) return;
+ if (badness) abort();
+}
+
void libxl__exec(int stdinfd, int stdoutfd, int stderrfd, const char *arg0,
char **args)
/* call this in the child */
{
- int i;
-
if (stdinfd != -1)
dup2(stdinfd, STDIN_FILENO);
if (stdoutfd != -1)
dup2(stdoutfd, STDOUT_FILENO);
if (stderrfd != -1)
dup2(stderrfd, STDERR_FILENO);
- for (i = 4; i < 256; i++)
- close(i);
+
+ if (stdinfd != -1)
+ close(stdinfd);
+ if (stdoutfd != -1 && stdoutfd != stdinfd)
+ close(stdoutfd);
+ if (stderrfd != -1 && stderrfd != stdinfd && stderrfd != stdoutfd)
+ close(stderrfd);
+
+ check_open_fds(arg0);
signal(SIGPIPE, SIG_DFL);
/* in case our caller set it to IGN. subprocesses are entitled
@@ -148,6 +200,7 @@ int libxl__spawn_spawn(libxl__gc *gc,
}
/* we are now the intermediate process */
+ if (for_spawn) close(pipes[0]);
child = fork();
if (child == -1)