Merge branch 'sp/maint-push-sideband' into sp/push-sideband
* sp/maint-push-sideband: receive-pack: Send hook output over side band #2 receive-pack: Wrap status reports inside side-band-64k receive-pack: Refactor how capabilities are shown to the client send-pack: demultiplex a sideband stream with status data run-command: support custom fd-set in async run-command: Allow stderr to be a caller supplied pipe Update git fsck --full short description to mention packs Conflicts: run-command.c
This commit is contained in:
@ -233,6 +233,9 @@ fail_pipe:
|
||||
else if (need_err) {
|
||||
dup2(fderr[1], 2);
|
||||
close_pair(fderr);
|
||||
} else if (cmd->err > 1) {
|
||||
dup2(cmd->err, 2);
|
||||
close(cmd->err);
|
||||
}
|
||||
|
||||
if (cmd->no_stdout)
|
||||
@ -325,6 +328,8 @@ fail_pipe:
|
||||
fherr = open("/dev/null", O_RDWR);
|
||||
else if (need_err)
|
||||
fherr = dup(fderr[1]);
|
||||
else if (cmd->err > 2)
|
||||
fherr = dup(cmd->err);
|
||||
|
||||
if (cmd->no_stdout)
|
||||
fhout = open("/dev/null", O_RDWR);
|
||||
@ -394,6 +399,8 @@ fail_pipe:
|
||||
|
||||
if (need_err)
|
||||
close(fderr[1]);
|
||||
else if (cmd->err)
|
||||
close(cmd->err);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -444,17 +451,51 @@ int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const
|
||||
static unsigned __stdcall run_thread(void *data)
|
||||
{
|
||||
struct async *async = data;
|
||||
return async->proc(async->fd_for_proc, async->data);
|
||||
return async->proc(async->proc_in, async->proc_out, async->data);
|
||||
}
|
||||
#endif
|
||||
|
||||
int start_async(struct async *async)
|
||||
{
|
||||
int pipe_out[2];
|
||||
int need_in, need_out;
|
||||
int fdin[2], fdout[2];
|
||||
int proc_in, proc_out;
|
||||
|
||||
if (pipe(pipe_out) < 0)
|
||||
return error("cannot create pipe: %s", strerror(errno));
|
||||
async->out = pipe_out[0];
|
||||
need_in = async->in < 0;
|
||||
if (need_in) {
|
||||
if (pipe(fdin) < 0) {
|
||||
if (async->out > 0)
|
||||
close(async->out);
|
||||
return error("cannot create pipe: %s", strerror(errno));
|
||||
}
|
||||
async->in = fdin[1];
|
||||
}
|
||||
|
||||
need_out = async->out < 0;
|
||||
if (need_out) {
|
||||
if (pipe(fdout) < 0) {
|
||||
if (need_in)
|
||||
close_pair(fdin);
|
||||
else if (async->in)
|
||||
close(async->in);
|
||||
return error("cannot create pipe: %s", strerror(errno));
|
||||
}
|
||||
async->out = fdout[0];
|
||||
}
|
||||
|
||||
if (need_in)
|
||||
proc_in = fdin[0];
|
||||
else if (async->in)
|
||||
proc_in = async->in;
|
||||
else
|
||||
proc_in = -1;
|
||||
|
||||
if (need_out)
|
||||
proc_out = fdout[1];
|
||||
else if (async->out)
|
||||
proc_out = async->out;
|
||||
else
|
||||
proc_out = -1;
|
||||
|
||||
#ifndef WIN32
|
||||
/* Flush stdio before fork() to avoid cloning buffers */
|
||||
@ -463,24 +504,47 @@ int start_async(struct async *async)
|
||||
async->pid = fork();
|
||||
if (async->pid < 0) {
|
||||
error("fork (async) failed: %s", strerror(errno));
|
||||
close_pair(pipe_out);
|
||||
return -1;
|
||||
goto error;
|
||||
}
|
||||
if (!async->pid) {
|
||||
close(pipe_out[0]);
|
||||
exit(!!async->proc(pipe_out[1], async->data));
|
||||
if (need_in)
|
||||
close(fdin[1]);
|
||||
if (need_out)
|
||||
close(fdout[0]);
|
||||
exit(!!async->proc(proc_in, proc_out, async->data));
|
||||
}
|
||||
close(pipe_out[1]);
|
||||
|
||||
if (need_in)
|
||||
close(fdin[0]);
|
||||
else if (async->in)
|
||||
close(async->in);
|
||||
|
||||
if (need_out)
|
||||
close(fdout[1]);
|
||||
else if (async->out)
|
||||
close(async->out);
|
||||
#else
|
||||
async->fd_for_proc = pipe_out[1];
|
||||
async->proc_in = proc_in;
|
||||
async->proc_out = proc_out;
|
||||
async->tid = (HANDLE) _beginthreadex(NULL, 0, run_thread, async, 0, NULL);
|
||||
if (!async->tid) {
|
||||
error("cannot create thread: %s", strerror(errno));
|
||||
close_pair(pipe_out);
|
||||
return -1;
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (need_in)
|
||||
close_pair(fdin);
|
||||
else if (async->in)
|
||||
close(async->in);
|
||||
|
||||
if (need_out)
|
||||
close_pair(fdout);
|
||||
else if (async->out)
|
||||
close(async->out);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int finish_async(struct async *async)
|
||||
|
Reference in New Issue
Block a user