Code

diff: fix textconv error zombies
authorJohannes Sixt <j6t@kdbg.org>
Tue, 30 Mar 2010 17:36:03 +0000 (19:36 +0200)
committerJunio C Hamano <gitster@pobox.com>
Tue, 30 Mar 2010 21:46:33 +0000 (14:46 -0700)
To make the code simpler, run_textconv lumps all of its
error checking into one conditional. However, the
short-circuit means that an error in reading will prevent us
from calling finish_command, leaving a zombie child.
Clean up properly after errors.

Based-on-work-by: Jeff King <peff@peff.net>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
diff.c

diff --git a/diff.c b/diff.c
index 0d465faa1e546382267dc0779116a013647ecf41..99059231b4e9d7eac9eb2d63ce6baa4d43190b95 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -3865,6 +3865,7 @@ static char *run_textconv(const char *pgm, struct diff_filespec *spec,
        const char **arg = argv;
        struct child_process child;
        struct strbuf buf = STRBUF_INIT;
+       int err = 0;
 
        temp = prepare_temp_file(spec->path, spec);
        *arg++ = pgm;
@@ -3875,16 +3876,20 @@ static char *run_textconv(const char *pgm, struct diff_filespec *spec,
        child.use_shell = 1;
        child.argv = argv;
        child.out = -1;
-       if (start_command(&child) != 0 ||
-           strbuf_read(&buf, child.out, 0) < 0 ||
-           finish_command(&child) != 0) {
-               close(child.out);
-               strbuf_release(&buf);
+       if (start_command(&child)) {
                remove_tempfile();
-               error("error running textconv command '%s'", pgm);
                return NULL;
        }
+
+       if (strbuf_read(&buf, child.out, 0) < 0)
+               err = error("error reading from textconv command '%s'", pgm);
        close(child.out);
+
+       if (finish_command(&child) || err) {
+               strbuf_release(&buf);
+               remove_tempfile();
+               return NULL;
+       }
        remove_tempfile();
 
        return strbuf_detach(&buf, outsize);