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-28 09:49:08 +0100 |
commit | 84f5e3d4e37597fb71879dd5f1e8a6fc852a0d5b (patch) | |
tree | 4a1268bed1881a872efe0200edd5b81bb90a484f /src | |
parent | 429b909bf4d0f6c1321ee32c35ae7e0546d09fcb (diff) | |
download | libguestfs-84f5e3d4e37597fb71879dd5f1e8a6fc852a0d5b.tar.gz libguestfs-84f5e3d4e37597fb71879dd5f1e8a6fc852a0d5b.tar.xz libguestfs-84f5e3d4e37597fb71879dd5f1e8a6fc852a0d5b.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].
(cherry picked from commit c87956837e962072fff61edef5b18e55ad42d730)
Diffstat (limited to 'src')
-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 34c13a0b..fb0172b9 100644 --- a/src/launch.c +++ b/src/launch.c @@ -923,6 +923,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); if (g->fd[0] == -1) { @@ -933,6 +934,7 @@ launch_appliance (guestfs_h *g) if (g->fd[1] == -1) { perrorf (g, "dup"); close (g->fd[0]); + g->fd[0] = -1; goto cleanup1; } } @@ -1003,13 +1005,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; |