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:
Junio C Hamano
2010-02-05 21:08:53 -08:00
11 changed files with 290 additions and 90 deletions

View File

@ -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)