upload-archive: use start_command instead of fork
The POSIX-function fork is not supported on Windows. Use our start_command API instead, respawning ourselves in a special "writer" mode to follow the alternate code path. Remove the NOT_MINGW-prereq for t5000, as git-archive --remote now works. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
f56ef114ee
commit
1bc01efed1
@ -133,6 +133,7 @@ extern int cmd_update_index(int argc, const char **argv, const char *prefix);
|
||||
extern int cmd_update_ref(int argc, const char **argv, const char *prefix);
|
||||
extern int cmd_update_server_info(int argc, const char **argv, const char *prefix);
|
||||
extern int cmd_upload_archive(int argc, const char **argv, const char *prefix);
|
||||
extern int cmd_upload_archive_writer(int argc, const char **argv, const char *prefix);
|
||||
extern int cmd_upload_tar(int argc, const char **argv, const char *prefix);
|
||||
extern int cmd_var(int argc, const char **argv, const char *prefix);
|
||||
extern int cmd_verify_tag(int argc, const char **argv, const char *prefix);
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "archive.h"
|
||||
#include "pkt-line.h"
|
||||
#include "sideband.h"
|
||||
#include "run-command.h"
|
||||
|
||||
static const char upload_archive_usage[] =
|
||||
"git upload-archive <repo>";
|
||||
@ -13,12 +14,9 @@ static const char upload_archive_usage[] =
|
||||
static const char deadchild[] =
|
||||
"git upload-archive: archiver died with error";
|
||||
|
||||
static const char lostchild[] =
|
||||
"git upload-archive: archiver process was lost";
|
||||
|
||||
#define MAX_ARGS (64)
|
||||
|
||||
static int run_upload_archive(int argc, const char **argv, const char *prefix)
|
||||
int cmd_upload_archive_writer(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
const char *sent_argv[MAX_ARGS];
|
||||
const char *arg_cmd = "argument ";
|
||||
@ -96,8 +94,8 @@ static ssize_t process_input(int child_fd, int band)
|
||||
|
||||
int cmd_upload_archive(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
pid_t writer;
|
||||
int fd1[2], fd2[2];
|
||||
struct child_process writer = { argv };
|
||||
|
||||
/*
|
||||
* Set up sideband subprocess.
|
||||
*
|
||||
@ -105,39 +103,24 @@ int cmd_upload_archive(int argc, const char **argv, const char *prefix)
|
||||
* multiplexed out to our fd#1. If the child dies, we tell the other
|
||||
* end over channel #3.
|
||||
*/
|
||||
if (pipe(fd1) < 0 || pipe(fd2) < 0) {
|
||||
argv[0] = "upload-archive--writer";
|
||||
writer.out = writer.err = -1;
|
||||
writer.git_cmd = 1;
|
||||
if (start_command(&writer)) {
|
||||
int err = errno;
|
||||
packet_write(1, "NACK pipe failed on the remote side\n");
|
||||
packet_write(1, "NACK unable to spawn subprocess\n");
|
||||
die("upload-archive: %s", strerror(err));
|
||||
}
|
||||
writer = fork();
|
||||
if (writer < 0) {
|
||||
int err = errno;
|
||||
packet_write(1, "NACK fork failed on the remote side\n");
|
||||
die("upload-archive: %s", strerror(err));
|
||||
}
|
||||
if (!writer) {
|
||||
/* child - connect fd#1 and fd#2 to the pipe */
|
||||
dup2(fd1[1], 1);
|
||||
dup2(fd2[1], 2);
|
||||
close(fd1[1]); close(fd2[1]);
|
||||
close(fd1[0]); close(fd2[0]); /* we do not read from pipe */
|
||||
|
||||
exit(run_upload_archive(argc, argv, prefix));
|
||||
}
|
||||
|
||||
/* parent - read from child, multiplex and send out to fd#1 */
|
||||
close(fd1[1]); close(fd2[1]); /* we do not write to pipe */
|
||||
packet_write(1, "ACK\n");
|
||||
packet_flush(1);
|
||||
|
||||
while (1) {
|
||||
struct pollfd pfd[2];
|
||||
int status;
|
||||
|
||||
pfd[0].fd = fd1[0];
|
||||
pfd[0].fd = writer.out;
|
||||
pfd[0].events = POLLIN;
|
||||
pfd[1].fd = fd2[0];
|
||||
pfd[1].fd = writer.err;
|
||||
pfd[1].events = POLLIN;
|
||||
if (poll(pfd, 2, -1) < 0) {
|
||||
if (errno != EINTR) {
|
||||
@ -156,9 +139,7 @@ int cmd_upload_archive(int argc, const char **argv, const char *prefix)
|
||||
if (process_input(pfd[0].fd, 1))
|
||||
continue;
|
||||
|
||||
if (waitpid(writer, &status, 0) < 0)
|
||||
error_clnt("%s", lostchild);
|
||||
else if (!WIFEXITED(status) || WEXITSTATUS(status) > 0)
|
||||
if (finish_command(&writer))
|
||||
error_clnt("%s", deadchild);
|
||||
packet_flush(1);
|
||||
break;
|
||||
|
1
git.c
1
git.c
@ -434,6 +434,7 @@ static void handle_internal_command(int argc, const char **argv)
|
||||
{ "update-ref", cmd_update_ref, RUN_SETUP },
|
||||
{ "update-server-info", cmd_update_server_info, RUN_SETUP },
|
||||
{ "upload-archive", cmd_upload_archive },
|
||||
{ "upload-archive--writer", cmd_upload_archive_writer },
|
||||
{ "var", cmd_var, RUN_SETUP_GENTLY },
|
||||
{ "verify-pack", cmd_verify_pack },
|
||||
{ "verify-tag", cmd_verify_tag, RUN_SETUP },
|
||||
|
@ -96,7 +96,7 @@ test_expect_success 'git archive with --output' \
|
||||
'git archive --output=b4.tar HEAD &&
|
||||
test_cmp b.tar b4.tar'
|
||||
|
||||
test_expect_success NOT_MINGW 'git archive --remote' \
|
||||
test_expect_success 'git archive --remote' \
|
||||
'git archive --remote=. HEAD >b5.tar &&
|
||||
test_cmp b.tar b5.tar'
|
||||
|
||||
@ -266,7 +266,7 @@ test_expect_success 'archive --list mentions user filter' '
|
||||
grep "^bar\$" output
|
||||
'
|
||||
|
||||
test_expect_success NOT_MINGW 'archive --list shows only enabled remote filters' '
|
||||
test_expect_success 'archive --list shows only enabled remote filters' '
|
||||
git archive --list --remote=. >output &&
|
||||
! grep "^tar\.foo\$" output &&
|
||||
grep "^bar\$" output
|
||||
@ -298,7 +298,7 @@ test_expect_success 'extension matching requires dot' '
|
||||
test_cmp b.tar config-implicittar.foo
|
||||
'
|
||||
|
||||
test_expect_success NOT_MINGW 'only enabled filters are available remotely' '
|
||||
test_expect_success 'only enabled filters are available remotely' '
|
||||
test_must_fail git archive --remote=. --format=tar.foo HEAD \
|
||||
>remote.tar.foo &&
|
||||
git archive --remote=. --format=bar >remote.bar HEAD &&
|
||||
@ -341,12 +341,12 @@ test_expect_success GZIP,GUNZIP 'extract tgz file' '
|
||||
test_cmp b.tar j.tar
|
||||
'
|
||||
|
||||
test_expect_success GZIP,NOT_MINGW 'remote tar.gz is allowed by default' '
|
||||
test_expect_success GZIP 'remote tar.gz is allowed by default' '
|
||||
git archive --remote=. --format=tar.gz HEAD >remote.tar.gz &&
|
||||
test_cmp j.tgz remote.tar.gz
|
||||
'
|
||||
|
||||
test_expect_success GZIP,NOT_MINGW 'remote tar.gz can be disabled' '
|
||||
test_expect_success GZIP 'remote tar.gz can be disabled' '
|
||||
git config tar.tar.gz.remote false &&
|
||||
test_must_fail git archive --remote=. --format=tar.gz HEAD \
|
||||
>remote.tar.gz
|
||||
|
Loading…
Reference in New Issue
Block a user