66#include "archive.h"
77#include "pkt-line.h"
88#include "sideband.h"
9+ #include "run-command.h"
910
1011static const char upload_archive_usage [] =
1112 "git upload-archive <repo>" ;
@@ -18,28 +19,17 @@ static const char lostchild[] =
1819
1920#define MAX_ARGS (64)
2021
21- static int run_upload_archive ( int argc , const char * * argv , const char * prefix )
22+ static void prepare_argv ( const char * * sent_argv , const char * * argv )
2223{
23- const char * sent_argv [MAX_ARGS ];
2424 const char * arg_cmd = "argument " ;
2525 char * p , buf [4096 ];
2626 int sent_argc ;
2727 int len ;
2828
29- if (argc != 2 )
30- usage (upload_archive_usage );
31-
32- if (strlen (argv [1 ]) + 1 > sizeof (buf ))
33- die ("insanely long repository name" );
34-
35- strcpy (buf , argv [1 ]); /* enter-repo smudges its argument */
36-
37- if (!enter_repo (buf , 0 ))
38- die ("'%s' does not appear to be a git repository" , buf );
39-
4029 /* put received options in sent_argv[] */
41- sent_argc = 1 ;
42- sent_argv [0 ] = "git-upload-archive" ;
30+ sent_argc = 2 ;
31+ sent_argv [0 ] = "archive" ;
32+ sent_argv [1 ] = "--remote-request" ;
4333 for (p = buf ;;) {
4434 /* This will die if not enough free space in buf */
4535 len = packet_read_line (0 , p , (buf + sizeof buf ) - p );
@@ -62,9 +52,6 @@ static int run_upload_archive(int argc, const char **argv, const char *prefix)
6252 * p ++ = 0 ;
6353 }
6454 sent_argv [sent_argc ] = NULL ;
65-
66- /* parse all options sent by the client */
67- return write_archive (sent_argc , sent_argv , prefix , 0 , NULL , 1 );
6855}
6956
7057__attribute__((format (printf , 1 , 2 )))
@@ -96,48 +83,35 @@ static ssize_t process_input(int child_fd, int band)
9683
9784int cmd_upload_archive (int argc , const char * * argv , const char * prefix )
9885{
99- pid_t writer ;
100- int fd1 [2 ], fd2 [2 ];
101- /*
102- * Set up sideband subprocess.
103- *
104- * We (parent) monitor and read from child, sending its fd#1 and fd#2
105- * multiplexed out to our fd#1. If the child dies, we tell the other
106- * end over channel #3.
107- */
108- if (pipe (fd1 ) < 0 || pipe (fd2 ) < 0 ) {
109- int err = errno ;
110- packet_write (1 , "NACK pipe failed on the remote side\n" );
111- die ("upload-archive: %s" , strerror (err ));
112- }
113- writer = fork ();
114- if (writer < 0 ) {
86+ const char * sent_argv [MAX_ARGS ];
87+ struct child_process cld = { sent_argv };
88+ cld .out = cld .err = -1 ;
89+ cld .git_cmd = 1 ;
90+
91+ if (argc != 2 )
92+ usage (upload_archive_usage );
93+
94+ if (!enter_repo (argv [1 ], 0 ))
95+ die ("'%s' does not appear to be a git repository" , argv [1 ]);
96+
97+ prepare_argv (sent_argv , argv );
98+ if (start_command (& cld )) {
11599 int err = errno ;
116100 packet_write (1 , "NACK fork failed on the remote side\n" );
117101 die ("upload-archive: %s" , strerror (err ));
118102 }
119- if (!writer ) {
120- /* child - connect fd#1 and fd#2 to the pipe */
121- dup2 (fd1 [1 ], 1 );
122- dup2 (fd2 [1 ], 2 );
123- close (fd1 [1 ]); close (fd2 [1 ]);
124- close (fd1 [0 ]); close (fd2 [0 ]); /* we do not read from pipe */
125-
126- exit (run_upload_archive (argc , argv , prefix ));
127- }
128103
129104 /* parent - read from child, multiplex and send out to fd#1 */
130- close (fd1 [1 ]); close (fd2 [1 ]); /* we do not write to pipe */
131105 packet_write (1 , "ACK\n" );
132106 packet_flush (1 );
133107
134108 while (1 ) {
135109 struct pollfd pfd [2 ];
136110 int status ;
137111
138- pfd [0 ].fd = fd1 [ 0 ] ;
112+ pfd [0 ].fd = cld . out ;
139113 pfd [0 ].events = POLLIN ;
140- pfd [1 ].fd = fd2 [ 0 ] ;
114+ pfd [1 ].fd = cld . err ;
141115 pfd [1 ].events = POLLIN ;
142116 if (poll (pfd , 2 , -1 ) < 0 ) {
143117 if (errno != EINTR ) {
@@ -156,7 +130,7 @@ int cmd_upload_archive(int argc, const char **argv, const char *prefix)
156130 if (process_input (pfd [0 ].fd , 1 ))
157131 continue ;
158132
159- if (waitpid (writer , & status , 0 ) < 0 )
133+ if (waitpid (cld . pid , & status , 0 ) < 0 )
160134 error_clnt ("%s" , lostchild );
161135 else if (!WIFEXITED (status ) || WEXITSTATUS (status ) > 0 )
162136 error_clnt ("%s" , deadchild );
0 commit comments