When the file descriptor of 'FILE *fp' is assigned to child_process.out and then start_command or run_command is run, the standard output of the child process is expected to be outputed to fp. start_command will always close fp in this case. However, sometimes fp is not expected to be closed since further IO may be still performmed on fp. This patch disables the auto closing behavious of start_command and corrects all codes which depend on this kind of behaviour. Following is a case that the auto closing behaviour is not expected. When adding submodule summary feature to builtin-commit, in wt_status_print, I want to output the submodule summary between changed and untracked files as the following patch shows wt_status_print_changed(s); + wt_status_print_submodule_summary(s); wt_status_print_untracked(s); All the three calls will output to s->fp (which points to a file instead of standard output when doing committing). So I don't want s->fp to be closed after wt_status_print_submodule_summary(s) which calls run_command. +static void wt_status_print_submodule_summary(struct wt_status *s) +{ + struct child_process sm_summary; + memset(&sm_summary, 0, sizeof(sm_summary)); + ... + sm_summary.out = fileno(s->fp); + ... + run_command(&sm_summary); +} Signed-off-by: Ping Yin <pkufranky@xxxxxxxxx> --- bundle.c | 1 + convert.c | 1 + run-command.c | 4 ---- upload-pack.c | 3 ++- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/bundle.c b/bundle.c index e4d60cd..fc253fb 100644 --- a/bundle.c +++ b/bundle.c @@ -336,6 +336,7 @@ int unbundle(struct bundle_header *header, int bundle_fd) memset(&ip, 0, sizeof(ip)); ip.argv = argv_index_pack; ip.in = bundle_fd; + ip.close_in = 1; ip.no_stdout = 1; ip.git_cmd = 1; if (run_command(&ip)) diff --git a/convert.c b/convert.c index 4df7559..ce7bed0 100644 --- a/convert.c +++ b/convert.c @@ -212,6 +212,7 @@ static int filter_buffer(int fd, void *data) child_process.argv = argv; child_process.in = -1; child_process.out = fd; + child_process.close_out = 1; if (start_command(&child_process)) return error("cannot fork to run external filter %s", params->cmd); diff --git a/run-command.c b/run-command.c index 476d00c..4e5f58d 100644 --- a/run-command.c +++ b/run-command.c @@ -115,13 +115,9 @@ int start_command(struct child_process *cmd) if (need_in) close(fdin[0]); - else if (cmd->in) - close(cmd->in); if (need_out) close(fdout[1]); - else if (cmd->out > 1) - close(cmd->out); if (need_err) close(fderr[1]); diff --git a/upload-pack.c b/upload-pack.c index 7e04311..7aeda80 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -163,7 +163,8 @@ static void create_pack_file(void) argv[arg++] = NULL; memset(&pack_objects, 0, sizeof(pack_objects)); - pack_objects.in = rev_list.out; /* start_command closes it */ + pack_objects.in = rev_list.out; + pack_objects.close_in = 1; /* finish_command closes rev_list.out */ pack_objects.out = -1; pack_objects.err = -1; pack_objects.git_cmd = 1; -- 1.5.3.5.1878.gb1da0-dirty - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html