Skip to content
This repository was archived by the owner on Nov 9, 2017. It is now read-only.

Commit c460c0e

Browse files
peffgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 6308767 commit c460c0e

File tree

3 files changed

+18
-1
lines changed

3 files changed

+18
-1
lines changed

Documentation/technical/api-run-command.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,13 @@ terminated), of which .argv[0] is the program name to run (usually
109109
without a path). If the command to run is a git command, set argv[0] to
110110
the command name without the 'git-' prefix and set .git_cmd = 1.
111111

112+
Note that the ownership of the memory pointed to by .argv stays with the
113+
caller, but it should survive until `finish_command` completes. If the
114+
.argv member is NULL, `start_command` will point it at the .args
115+
`argv_array` (so you may use one or the other, but you must use exactly
116+
one). The memory in .args will be cleaned up automatically during
117+
`finish_command` (or during `start_command` when it is unsuccessful).
118+
112119
The members .in, .out, .err are used to redirect stdin, stdout,
113120
stderr as follows:
114121

run-command.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,9 @@ int start_command(struct child_process *cmd)
279279
int failed_errno;
280280
char *str;
281281

282+
if (!cmd->argv)
283+
cmd->argv = cmd->args.argv;
284+
282285
/*
283286
* In case of errors we must keep the promise to close FDs
284287
* that have been passed in via ->in and ->out.
@@ -328,6 +331,7 @@ int start_command(struct child_process *cmd)
328331
fail_pipe:
329332
error("cannot create %s pipe for %s: %s",
330333
str, cmd->argv[0], strerror(failed_errno));
334+
argv_array_clear(&cmd->args);
331335
errno = failed_errno;
332336
return -1;
333337
}
@@ -519,6 +523,7 @@ int start_command(struct child_process *cmd)
519523
close_pair(fderr);
520524
else if (cmd->err)
521525
close(cmd->err);
526+
argv_array_clear(&cmd->args);
522527
errno = failed_errno;
523528
return -1;
524529
}
@@ -543,7 +548,9 @@ int start_command(struct child_process *cmd)
543548

544549
int finish_command(struct child_process *cmd)
545550
{
546-
return wait_or_whine(cmd->pid, cmd->argv[0]);
551+
int ret = wait_or_whine(cmd->pid, cmd->argv[0]);
552+
argv_array_clear(&cmd->args);
553+
return ret;
547554
}
548555

549556
int run_command(struct child_process *cmd)

run-command.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@
55
#include <pthread.h>
66
#endif
77

8+
#include "argv-array.h"
9+
810
struct child_process {
911
const char **argv;
12+
struct argv_array args;
1013
pid_t pid;
1114
/*
1215
* Using .in, .out, .err:

0 commit comments

Comments
 (0)