Skip to content

Commit 850d2fe

Browse files
peffgitster
authored andcommitted
convert manual allocations to argv_array
There are many manual argv allocations that predate the argv_array API. Switching to that API brings a few advantages: 1. We no longer have to manually compute the correct final array size (so it's one less thing we can screw up). 2. In many cases we had to make a separate pass to count, then allocate, then fill in the array. Now we can do it in one pass, making the code shorter and easier to follow. 3. argv_array handles memory ownership for us, making it more obvious when things should be free()d and and when not. Most of these cases are pretty straightforward. In some, we switch from "run_command_v" to "run_command" which lets us directly use the argv_array embedded in "struct child_process". Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b992657 commit 850d2fe

File tree

7 files changed

+43
-76
lines changed

7 files changed

+43
-76
lines changed

builtin/grep.c

+5-5
Original file line numberDiff line numberDiff line change
@@ -354,17 +354,17 @@ static void append_path(struct grep_opt *opt, const void *data, size_t len)
354354
static void run_pager(struct grep_opt *opt, const char *prefix)
355355
{
356356
struct string_list *path_list = opt->output_priv;
357-
const char **argv = xmalloc(sizeof(const char *) * (path_list->nr + 1));
357+
struct child_process child = CHILD_PROCESS_INIT;
358358
int i, status;
359359

360360
for (i = 0; i < path_list->nr; i++)
361-
argv[i] = path_list->items[i].string;
362-
argv[path_list->nr] = NULL;
361+
argv_array_push(&child.args, path_list->items[i].string);
362+
child.dir = prefix;
363+
child.use_shell = 1;
363364

364-
status = run_command_v_opt_cd_env(argv, RUN_USING_SHELL, prefix, NULL);
365+
status = run_command(&child);
365366
if (status)
366367
exit(status);
367-
free(argv);
368368
}
369369

370370
static int grep_cache(struct grep_opt *opt, const struct pathspec *pathspec, int cached)

builtin/receive-pack.c

+3-9
Original file line numberDiff line numberDiff line change
@@ -1031,7 +1031,6 @@ static void run_update_post_hook(struct command *commands)
10311031
{
10321032
struct command *cmd;
10331033
int argc;
1034-
const char **argv;
10351034
struct child_process proc = CHILD_PROCESS_INIT;
10361035
const char *hook;
10371036

@@ -1044,21 +1043,16 @@ static void run_update_post_hook(struct command *commands)
10441043
if (!argc || !hook)
10451044
return;
10461045

1047-
argv = xmalloc(sizeof(*argv) * (2 + argc));
1048-
argv[0] = hook;
1049-
1050-
for (argc = 1, cmd = commands; cmd; cmd = cmd->next) {
1046+
argv_array_push(&proc.args, hook);
1047+
for (cmd = commands; cmd; cmd = cmd->next) {
10511048
if (cmd->error_string || cmd->did_not_exist)
10521049
continue;
1053-
argv[argc] = xstrdup(cmd->ref_name);
1054-
argc++;
1050+
argv_array_push(&proc.args, cmd->ref_name);
10551051
}
1056-
argv[argc] = NULL;
10571052

10581053
proc.no_stdin = 1;
10591054
proc.stdout_to_stderr = 1;
10601055
proc.err = use_sideband ? -1 : 0;
1061-
proc.argv = argv;
10621056

10631057
if (!start_command(&proc)) {
10641058
if (use_sideband)

builtin/remote-ext.c

+5-21
Original file line numberDiff line numberDiff line change
@@ -114,30 +114,14 @@ static char *strip_escapes(const char *str, const char *service,
114114
}
115115
}
116116

117-
/* Should be enough... */
118-
#define MAXARGUMENTS 256
119-
120-
static const char **parse_argv(const char *arg, const char *service)
117+
static void parse_argv(struct argv_array *out, const char *arg, const char *service)
121118
{
122-
int arguments = 0;
123-
int i;
124-
const char **ret;
125-
char *temparray[MAXARGUMENTS + 1];
126-
127119
while (*arg) {
128-
char *expanded;
129-
if (arguments == MAXARGUMENTS)
130-
die("remote-ext command has too many arguments");
131-
expanded = strip_escapes(arg, service, &arg);
120+
char *expanded = strip_escapes(arg, service, &arg);
132121
if (expanded)
133-
temparray[arguments++] = expanded;
122+
argv_array_push(out, expanded);
123+
free(expanded);
134124
}
135-
136-
ret = xmalloc((arguments + 1) * sizeof(char *));
137-
for (i = 0; i < arguments; i++)
138-
ret[i] = temparray[i];
139-
ret[arguments] = NULL;
140-
return ret;
141125
}
142126

143127
static void send_git_request(int stdin_fd, const char *serv, const char *repo,
@@ -158,7 +142,7 @@ static int run_child(const char *arg, const char *service)
158142
child.in = -1;
159143
child.out = -1;
160144
child.err = 0;
161-
child.argv = parse_argv(arg, service);
145+
parse_argv(&child.args, arg, service);
162146

163147
if (start_command(&child) < 0)
164148
die("Can't run specified command");

daemon.c

+5-7
Original file line numberDiff line numberDiff line change
@@ -808,7 +808,7 @@ static void check_dead_children(void)
808808
cradle = &blanket->next;
809809
}
810810

811-
static char **cld_argv;
811+
static struct argv_array cld_argv = ARGV_ARRAY_INIT;
812812
static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen)
813813
{
814814
struct child_process cld = CHILD_PROCESS_INIT;
@@ -842,7 +842,7 @@ static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen)
842842
#endif
843843
}
844844

845-
cld.argv = (const char **)cld_argv;
845+
cld.argv = cld_argv.argv;
846846
cld.in = incoming;
847847
cld.out = dup(incoming);
848848

@@ -1374,12 +1374,10 @@ int main(int argc, char **argv)
13741374
write_file(pid_file, "%"PRIuMAX, (uintmax_t) getpid());
13751375

13761376
/* prepare argv for serving-processes */
1377-
cld_argv = xmalloc(sizeof (char *) * (argc + 2));
1378-
cld_argv[0] = argv[0]; /* git-daemon */
1379-
cld_argv[1] = "--serve";
1377+
argv_array_push(&cld_argv, argv[0]); /* git-daemon */
1378+
argv_array_push(&cld_argv, "--serve");
13801379
for (i = 1; i < argc; ++i)
1381-
cld_argv[i+1] = argv[i];
1382-
cld_argv[argc+1] = NULL;
1380+
argv_array_push(&cld_argv, argv[i]);
13831381

13841382
return serve(&listen_addr, listen_port, cred);
13851383
}

git.c

+5-9
Original file line numberDiff line numberDiff line change
@@ -239,19 +239,15 @@ static int handle_alias(int *argcp, const char ***argv)
239239
alias_string = alias_lookup(alias_command);
240240
if (alias_string) {
241241
if (alias_string[0] == '!') {
242-
const char **alias_argv;
243-
int argc = *argcp, i;
242+
struct child_process child = CHILD_PROCESS_INIT;
244243

245244
commit_pager_choice();
246245

247-
/* build alias_argv */
248-
alias_argv = xmalloc(sizeof(*alias_argv) * (argc + 1));
249-
alias_argv[0] = alias_string + 1;
250-
for (i = 1; i < argc; ++i)
251-
alias_argv[i] = (*argv)[i];
252-
alias_argv[argc] = NULL;
246+
child.use_shell = 1;
247+
argv_array_push(&child.args, alias_string + 1);
248+
argv_array_pushv(&child.args, (*argv) + 1);
253249

254-
ret = run_command_v_opt(alias_argv, RUN_USING_SHELL);
250+
ret = run_command(&child);
255251
if (ret >= 0) /* normal exit */
256252
exit(ret);
257253

line-log.c

+9-13
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "graph.h"
1515
#include "userdiff.h"
1616
#include "line-log.h"
17+
#include "argv-array.h"
1718

1819
static void range_set_grow(struct range_set *rs, size_t extra)
1920
{
@@ -746,22 +747,17 @@ void line_log_init(struct rev_info *rev, const char *prefix, struct string_list
746747
add_line_range(rev, commit, range);
747748

748749
if (!rev->diffopt.detect_rename) {
749-
int i, count = 0;
750-
struct line_log_data *r = range;
750+
struct line_log_data *r;
751+
struct argv_array array = ARGV_ARRAY_INIT;
751752
const char **paths;
752-
while (r) {
753-
count++;
754-
r = r->next;
755-
}
756-
paths = xmalloc((count+1)*sizeof(char *));
757-
r = range;
758-
for (i = 0; i < count; i++) {
759-
paths[i] = xstrdup(r->path);
760-
r = r->next;
761-
}
762-
paths[count] = NULL;
753+
754+
for (r = range; r; r = r->next)
755+
argv_array_push(&array, r->path);
756+
paths = argv_array_detach(&array);
757+
763758
parse_pathspec(&rev->diffopt.pathspec, 0,
764759
PATHSPEC_PREFER_FULL, "", paths);
760+
/* strings are now owned by pathspec */
765761
free(paths);
766762
}
767763
}

remote-curl.c

+11-12
Original file line numberDiff line numberDiff line change
@@ -845,23 +845,22 @@ static void parse_fetch(struct strbuf *buf)
845845

846846
static int push_dav(int nr_spec, char **specs)
847847
{
848-
const char **argv = xmalloc((10 + nr_spec) * sizeof(char*));
849-
int argc = 0, i;
848+
struct child_process child = CHILD_PROCESS_INIT;
849+
size_t i;
850850

851-
argv[argc++] = "http-push";
852-
argv[argc++] = "--helper-status";
851+
child.git_cmd = 1;
852+
argv_array_push(&child.args, "http-push");
853+
argv_array_push(&child.args, "--helper-status");
853854
if (options.dry_run)
854-
argv[argc++] = "--dry-run";
855+
argv_array_push(&child.args, "--dry-run");
855856
if (options.verbosity > 1)
856-
argv[argc++] = "--verbose";
857-
argv[argc++] = url.buf;
857+
argv_array_push(&child.args, "--verbose");
858+
argv_array_push(&child.args, url.buf);
858859
for (i = 0; i < nr_spec; i++)
859-
argv[argc++] = specs[i];
860-
argv[argc++] = NULL;
860+
argv_array_push(&child.args, specs[i]);
861861

862-
if (run_command_v_opt(argv, RUN_GIT_CMD))
863-
die("git-%s failed", argv[0]);
864-
free(argv);
862+
if (run_command(&child))
863+
die("git-http-push failed");
865864
return 0;
866865
}
867866

0 commit comments

Comments
 (0)