From c460c0ecdca46be85f6d9c845f9df7ce0e45c3c2 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Thu, 15 May 2014 04:33:26 -0400 Subject: 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 Signed-off-by: Junio C Hamano --- run-command.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'run-command.c') diff --git a/run-command.c b/run-command.c index 75abc478c..be07d4ad3 100644 --- a/run-command.c +++ b/run-command.c @@ -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) -- cgit v1.2.1