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);