@matheusbsbs / matheus-bagliano / commits / da1fbed3ff
Fork 0

diff: fix textconv error zombies

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>

Johannes Sixt committed Mar 30, 2010 at 19:36 UTC da1fbed3fff6ed2d64399ff26d8a9ab3bcf00540
1 file changed +11 -6
diff.c
+11 -6
@@ -3865,6 +3865,7 @@ static char *run_textconv(const char *pgm, struct diff_filespec *spec,
3865 const char **arg = argv;
3866 struct child_process child;
3867 struct strbuf buf = STRBUF_INIT;
3868 + int err = 0;
3869
3870 temp = prepare_temp_file(spec->path, spec);
3871 *arg++ = pgm;
@@ -3875,16 +3876,20 @@ static char *run_textconv(const char *pgm, struct diff_filespec *spec,
3876 child.use_shell = 1;
3877 child.argv = argv;
3878 child.out = -1;
3878 - if (start_command(&child) != 0 ||
3879 - strbuf_read(&buf, child.out, 0) < 0 ||
3880 - finish_command(&child) != 0) {
3881 - close(child.out);
3882 - strbuf_release(&buf);
3879 + if (start_command(&child)) {
3880 remove_tempfile();
3884 - error("error running textconv command '%s'", pgm);
3881 return NULL;
3882 }
3883 +
3884 + if (strbuf_read(&buf, child.out, 0) < 0)
3885 + err = error("error reading from textconv command '%s'", pgm);
3886 close(child.out);
3887 +
3888 + if (finish_command(&child) || err) {
3889 + strbuf_release(&buf);
3890 + remove_tempfile();
3891 + return NULL;
3892 + }
3893 remove_tempfile();
3894
3895 return strbuf_detach(&buf, outsize);