mirror of
https://github.com/git/git.git
synced 2024-11-19 00:44:22 +01:00
run-command: do not pass child process data into callbacks
The expected way to pass data into the callback is to pass them via the customizable callback pointer. The error reporting in default_{start_failure, task_finished} is not user friendly enough, that we want to encourage using the child data for such purposes. Furthermore the struct child data is cleaned by the run-command API, before we access them in the callbacks, leading to use-after-free situations. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
62104ba14a
commit
2a73b3dad0
@ -902,35 +902,18 @@ struct parallel_processes {
|
|||||||
struct strbuf buffered_output; /* of finished children */
|
struct strbuf buffered_output; /* of finished children */
|
||||||
};
|
};
|
||||||
|
|
||||||
static int default_start_failure(struct child_process *cp,
|
static int default_start_failure(struct strbuf *err,
|
||||||
struct strbuf *err,
|
|
||||||
void *pp_cb,
|
void *pp_cb,
|
||||||
void *pp_task_cb)
|
void *pp_task_cb)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
strbuf_addstr(err, "Starting a child failed:");
|
|
||||||
for (i = 0; cp->argv[i]; i++)
|
|
||||||
strbuf_addf(err, " %s", cp->argv[i]);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int default_task_finished(int result,
|
static int default_task_finished(int result,
|
||||||
struct child_process *cp,
|
|
||||||
struct strbuf *err,
|
struct strbuf *err,
|
||||||
void *pp_cb,
|
void *pp_cb,
|
||||||
void *pp_task_cb)
|
void *pp_task_cb)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!result)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
strbuf_addf(err, "A child failed with return code %d:", result);
|
|
||||||
for (i = 0; cp->argv[i]; i++)
|
|
||||||
strbuf_addf(err, " %s", cp->argv[i]);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1048,8 +1031,7 @@ static int pp_start_one(struct parallel_processes *pp)
|
|||||||
pp->children[i].process.no_stdin = 1;
|
pp->children[i].process.no_stdin = 1;
|
||||||
|
|
||||||
if (start_command(&pp->children[i].process)) {
|
if (start_command(&pp->children[i].process)) {
|
||||||
code = pp->start_failure(&pp->children[i].process,
|
code = pp->start_failure(&pp->children[i].err,
|
||||||
&pp->children[i].err,
|
|
||||||
pp->data,
|
pp->data,
|
||||||
&pp->children[i].data);
|
&pp->children[i].data);
|
||||||
strbuf_addbuf(&pp->buffered_output, &pp->children[i].err);
|
strbuf_addbuf(&pp->buffered_output, &pp->children[i].err);
|
||||||
@ -1117,7 +1099,7 @@ static int pp_collect_finished(struct parallel_processes *pp)
|
|||||||
|
|
||||||
code = finish_command(&pp->children[i].process);
|
code = finish_command(&pp->children[i].process);
|
||||||
|
|
||||||
code = pp->task_finished(code, &pp->children[i].process,
|
code = pp->task_finished(code,
|
||||||
&pp->children[i].err, pp->data,
|
&pp->children[i].err, pp->data,
|
||||||
&pp->children[i].data);
|
&pp->children[i].data);
|
||||||
|
|
||||||
|
@ -158,8 +158,7 @@ typedef int (*get_next_task_fn)(struct child_process *cp,
|
|||||||
* To send a signal to other child processes for abortion, return
|
* To send a signal to other child processes for abortion, return
|
||||||
* the negative signal number.
|
* the negative signal number.
|
||||||
*/
|
*/
|
||||||
typedef int (*start_failure_fn)(struct child_process *cp,
|
typedef int (*start_failure_fn)(struct strbuf *err,
|
||||||
struct strbuf *err,
|
|
||||||
void *pp_cb,
|
void *pp_cb,
|
||||||
void *pp_task_cb);
|
void *pp_task_cb);
|
||||||
|
|
||||||
@ -178,7 +177,6 @@ typedef int (*start_failure_fn)(struct child_process *cp,
|
|||||||
* the negative signal number.
|
* the negative signal number.
|
||||||
*/
|
*/
|
||||||
typedef int (*task_finished_fn)(int result,
|
typedef int (*task_finished_fn)(int result,
|
||||||
struct child_process *cp,
|
|
||||||
struct strbuf *err,
|
struct strbuf *err,
|
||||||
void *pp_cb,
|
void *pp_cb,
|
||||||
void *pp_task_cb);
|
void *pp_task_cb);
|
||||||
@ -192,9 +190,8 @@ typedef int (*task_finished_fn)(int result,
|
|||||||
* (both stdout and stderr) is routed to stderr in a manner that output
|
* (both stdout and stderr) is routed to stderr in a manner that output
|
||||||
* from different tasks does not interleave.
|
* from different tasks does not interleave.
|
||||||
*
|
*
|
||||||
* If start_failure_fn or task_finished_fn are NULL, default handlers
|
* start_failure_fn and task_finished_fn can be NULL to omit any
|
||||||
* will be used. The default handlers will print an error message on
|
* special handling.
|
||||||
* error without issuing an emergency stop.
|
|
||||||
*/
|
*/
|
||||||
int run_processes_parallel(int n,
|
int run_processes_parallel(int n,
|
||||||
get_next_task_fn,
|
get_next_task_fn,
|
||||||
|
@ -705,8 +705,7 @@ static int get_next_submodule(struct child_process *cp,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fetch_start_failure(struct child_process *cp,
|
static int fetch_start_failure(struct strbuf *err,
|
||||||
struct strbuf *err,
|
|
||||||
void *cb, void *task_cb)
|
void *cb, void *task_cb)
|
||||||
{
|
{
|
||||||
struct submodule_parallel_fetch *spf = cb;
|
struct submodule_parallel_fetch *spf = cb;
|
||||||
@ -716,8 +715,8 @@ static int fetch_start_failure(struct child_process *cp,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fetch_finish(int retvalue, struct child_process *cp,
|
static int fetch_finish(int retvalue, struct strbuf *err,
|
||||||
struct strbuf *err, void *cb, void *task_cb)
|
void *cb, void *task_cb)
|
||||||
{
|
{
|
||||||
struct submodule_parallel_fetch *spf = cb;
|
struct submodule_parallel_fetch *spf = cb;
|
||||||
|
|
||||||
|
@ -41,7 +41,6 @@ static int no_job(struct child_process *cp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int task_finished(int result,
|
static int task_finished(int result,
|
||||||
struct child_process *cp,
|
|
||||||
struct strbuf *err,
|
struct strbuf *err,
|
||||||
void *pp_cb,
|
void *pp_cb,
|
||||||
void *pp_task_cb)
|
void *pp_task_cb)
|
||||||
|
Loading…
Reference in New Issue
Block a user