run-command: store an optional argv_array

All child_process structs need to point to an argv. For
flexibility, we do not mandate the use of a dynamic
argv_array. However, because the child_process does not own
the memory, this can make memory management with a
separate argv_array difficult.

For example, if a function calls start_command but not
finish_command, the argv memory must persist. The code needs
to arrange to clean up the argv_array separately after
finish_command runs. As a result, some of our code in this
situation just leaks the memory.

To help such cases, this patch adds a built-in argv_array to
the child_process, which gets cleaned up automatically (both
in finish_command and when start_command fails).  Callers
may use it if they choose, but can continue to use the raw
argv if they wish.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Jeff King
2014-05-15 04:33:26 -04:00
committed by Junio C Hamano
parent 6308767f0b
commit c460c0ecdc
3 changed files with 18 additions and 1 deletions

View File

@ -279,6 +279,9 @@ int start_command(struct child_process *cmd)
int failed_errno;
char *str;
if (!cmd->argv)
cmd->argv = cmd->args.argv;
/*
* In case of errors we must keep the promise to close FDs
* that have been passed in via ->in and ->out.
@ -328,6 +331,7 @@ int start_command(struct child_process *cmd)
fail_pipe:
error("cannot create %s pipe for %s: %s",
str, cmd->argv[0], strerror(failed_errno));
argv_array_clear(&cmd->args);
errno = failed_errno;
return -1;
}
@ -519,6 +523,7 @@ fail_pipe:
close_pair(fderr);
else if (cmd->err)
close(cmd->err);
argv_array_clear(&cmd->args);
errno = failed_errno;
return -1;
}
@ -543,7 +548,9 @@ fail_pipe:
int finish_command(struct child_process *cmd)
{
return wait_or_whine(cmd->pid, cmd->argv[0]);
int ret = wait_or_whine(cmd->pid, cmd->argv[0]);
argv_array_clear(&cmd->args);
return ret;
}
int run_command(struct child_process *cmd)