158
return -1;
159
}
160
161
-static const char **prepare_shell_cmd(const char **argv)
161
+static const char **prepare_shell_cmd(struct argv_array *out, const char **argv)
162
{
163
- int argc, nargc = 0;
164
- const char **nargv;
165
-
166
- for (argc = 0; argv[argc]; argc++)
167
- ; /* just counting */
168
- /* +1 for NULL, +3 for "sh -c" plus extra $0 */
169
- nargv = xmalloc(sizeof(*nargv) * (argc + 1 + 3));
170
-
171
- if (argc < 1)
163
+ if (!argv[0])
164
die("BUG: shell command is empty");
165
166
if (strcspn(argv[0], "|&;<>()$`\\\"' \t\n*?[#~=%") != strlen(argv[0])) {
167
#ifndef GIT_WINDOWS_NATIVE
176
- nargv[nargc++] = SHELL_PATH;
168
+ argv_array_push(out, SHELL_PATH);
169
#else
178
- nargv[nargc++] = "sh";
170
+ argv_array_push(out, "sh");
171
#endif
180
- nargv[nargc++] = "-c";
181
-
182
- if (argc < 2)
183
- nargv[nargc++] = argv[0];
184
- else {
185
- struct strbuf arg0 = STRBUF_INIT;
186
- strbuf_addf(&arg0, "%s \"$@\"", argv[0]);
187
- nargv[nargc++] = strbuf_detach(&arg0, NULL);
188
- }
189
- }
172
+ argv_array_push(out, "-c");
173
191
- for (argc = 0; argv[argc]; argc++)
192
- nargv[nargc++] = argv[argc];
193
- nargv[nargc] = NULL;
174
+ /*
175
+ * If we have no extra arguments, we do not even need to
176
+ * bother with the "$@" magic.
177
+ */
178
+ if (!argv[1])
179
+ argv_array_push(out, argv[0]);
180
+ else
181
+ argv_array_pushf(out, "%s \"$@\"", argv[0]);
182
+ }
183
195
- return nargv;
184
+ argv_array_pushv(out, argv);
185
+ return out->argv;
186
}
187
188
#ifndef GIT_WINDOWS_NATIVE
189
static int execv_shell_cmd(const char **argv)
190
{
201
- const char **nargv = prepare_shell_cmd(argv);
202
- trace_argv_printf(nargv, "trace: exec:");
203
- sane_execvp(nargv[0], (char **)nargv);
204
- free(nargv);
191
+ struct argv_array nargv = ARGV_ARRAY_INIT;
192
+ prepare_shell_cmd(&nargv, argv);
193
+ trace_argv_printf(nargv.argv, "trace: exec:");
194
+ sane_execvp(nargv.argv[0], (char **)nargv.argv);
195
+ argv_array_clear(&nargv);
196
return -1;
197
}
198
#endif
446
{
447
int fhin = 0, fhout = 1, fherr = 2;
448
const char **sargv = cmd->argv;
449
+ struct argv_array nargv = ARGV_ARRAY_INIT;
450
451
if (cmd->no_stdin)
452
fhin = open("/dev/null", O_RDWR);
472
fhout = dup(cmd->out);
473
474
if (cmd->git_cmd)
483
- cmd->argv = prepare_git_cmd(cmd->argv);
475
+ cmd->argv = prepare_git_cmd(&nargv, cmd->argv);
476
else if (cmd->use_shell)
485
- cmd->argv = prepare_shell_cmd(cmd->argv);
477
+ cmd->argv = prepare_shell_cmd(&nargv, cmd->argv);
478
479
cmd->pid = mingw_spawnvpe(cmd->argv[0], cmd->argv, (char**) cmd->env,
480
cmd->dir, fhin, fhout, fherr);
484
if (cmd->clean_on_exit && cmd->pid >= 0)
485
mark_child_for_cleanup(cmd->pid);
486
495
- if (cmd->git_cmd)
496
- free(cmd->argv);
497
-
487
+ argv_array_clear(&nargv);
488
cmd->argv = sargv;
489
if (fhin != 0)
490
close(fhin);