diff options
author | Richard W.M. Jones <rjones@redhat.com> | 2012-06-26 14:39:16 +0100 |
---|---|---|
committer | Richard W.M. Jones <rjones@redhat.com> | 2012-06-26 14:53:33 +0100 |
commit | c87956837e962072fff61edef5b18e55ad42d730 (patch) | |
tree | f9b069045369aa336dac1f1479a5c4776303b725 | |
parent | 9e221e55b61e9f1cd0caf292ca609a4ca26f1d4d (diff) | |
download | libguestfs-c87956837e962072fff61edef5b18e55ad42d730.tar.gz libguestfs-c87956837e962072fff61edef5b18e55ad42d730.tar.xz libguestfs-c87956837e962072fff61edef5b18e55ad42d730.zip |
launch: Avoid double-close when qemu exits early.
The stdin and stdout of the qemu process are aliased to g->fd:
g->fd[0] = wfd[1];
g->fd[1] = rfd[0];
However if the child exits early, then child_cleanup closes g->fd[0],
g->fd[1], AND the code at the cleanup1 label closes wfd[1], rfd[0],
resulting in a double-close.
Avoid this case by setting wfd[1], rfd[0] to -1. In the cleanup1
label, only close wfd[1], rfd[0] if they are not -1, and add the same
for g->fd[0], g->fd[1].
-rw-r--r-- | src/launch.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/src/launch.c b/src/launch.c index 86e1bc56..3cd16f41 100644 --- a/src/launch.c +++ b/src/launch.c @@ -1018,6 +1018,7 @@ launch_appliance (guestfs_h *g) g->fd[0] = wfd[1]; /* stdin of child */ g->fd[1] = rfd[0]; /* stdout of child */ + wfd[1] = rfd[0] = -1; } else { g->fd[0] = open ("/dev/null", O_RDWR|O_CLOEXEC); if (g->fd[0] == -1) { @@ -1028,6 +1029,7 @@ launch_appliance (guestfs_h *g) if (g->fd[1] == -1) { perrorf (g, "dup"); close (g->fd[0]); + g->fd[0] = -1; goto cleanup1; } } @@ -1098,13 +1100,15 @@ launch_appliance (guestfs_h *g) cleanup1: if (!g->direct) { - close (wfd[1]); - close (rfd[0]); + if (wfd[1] >= 0) close (wfd[1]); + if (rfd[1] >= 0) close (rfd[0]); } if (g->pid > 0) kill (g->pid, 9); if (g->recoverypid > 0) kill (g->recoverypid, 9); if (g->pid > 0) waitpid (g->pid, NULL, 0); if (g->recoverypid > 0) waitpid (g->recoverypid, NULL, 0); + if (g->fd[0] >= 0) close (g->fd[0]); + if (g->fd[1] >= 0) close (g->fd[1]); g->fd[0] = -1; g->fd[1] = -1; g->pid = 0; |