Commit Diff


commit - 66cba96f002a13482c34efaaf5ace08a33f45ec4
commit + 20eb36d0c1c6656066cb9febb9e6988c1eac5c2a
blob - c3c32e39f4990b11e465475f5888368aaaac553f
blob + 14911d3169374e71dc20c2e4255fbe01f188b729
--- got/got.c
+++ got/got.c
@@ -980,7 +980,7 @@ cmd_clone(int argc, char *argv[])
 	struct got_pathlist_head refs, symrefs;
 	struct got_pathlist_entry *pe;
 	struct got_object_id *pack_hash = NULL;
-	int ch;
+	int ch, fetchfd = -1;
 
 	TAILQ_INIT(&refs);
 	TAILQ_INIT(&symrefs);
@@ -1007,6 +1007,10 @@ cmd_clone(int argc, char *argv[])
 
 	err = got_fetch_parse_uri(&proto, &host, &port, &server_path,
 	    &repo_name, argv[0]);
+	if (err)
+		goto done;
+
+	err = got_fetch_connect(&fetchfd, proto, host, port, server_path);
 	if (err)
 		goto done;
 
@@ -1031,7 +1035,7 @@ cmd_clone(int argc, char *argv[])
 	if (err)
 		goto done;
 
-	err = got_fetch(&pack_hash, &refs, &symrefs,
+	err = got_fetch(&pack_hash, &refs, &symrefs, fetchfd,
 	    proto, host, port, server_path, repo_name, branch_filter, repo);
 	if (err)
 		goto done;
@@ -1096,6 +1100,8 @@ cmd_clone(int argc, char *argv[])
 	}
 
 done:
+	if (fetchfd != -1 && close(fetchfd) == -1 && err == NULL)
+		err = got_error_from_errno("close");
 	if (repo)
 		got_repo_close(repo);
 	TAILQ_FOREACH(pe, &refs, entry) {
blob - 7b366507306fb9ce4b3c3a9d29e4d2b1044d2f19
blob + 600d8380690a460eb5dc3bc7b0bf1af363c1aaa5
--- include/got_fetch.h
+++ include/got_fetch.h
@@ -21,7 +21,10 @@
 const struct got_error *got_fetch_parse_uri(char **, char **, char **,
     char **, char **, const char *);
 
+const struct got_error *got_fetch_connect(int *, const char *, const char *,
+    const char *, const char *);
+
 const struct got_error *got_fetch(struct got_object_id **,
-	struct got_pathlist_head *, struct got_pathlist_head *,
+	struct got_pathlist_head *, struct got_pathlist_head *, int,
 	const char *, const char *, const char *, const char *,
 	const char *, const char *, struct got_repository *);
blob - 93751d15f248e33311d9591c8be94427dd8279f6
blob + 617c092b660b823d34b1543c2e24debb60a4f138
--- lib/fetch.c
+++ lib/fetch.c
@@ -179,6 +179,25 @@ done:
 			close(fd);
 	} else
 		*fetchfd = fd;
+	return err;
+}
+
+const struct got_error *
+got_fetch_connect(int *fetchfd, const char *proto, const char *host,
+    const char *port, const char *server_path)
+{
+	const struct got_error *err = NULL;
+
+	*fetchfd = -1;
+
+	if (strcmp(proto, "ssh") == 0 || strcmp(proto, "git+ssh") == 0)
+		err = dial_ssh(fetchfd, host, port, server_path, "upload");
+	else if (strcmp(proto, "git") == 0)
+		err = dial_git(fetchfd, host, port, server_path, "upload");
+	else if (strcmp(proto, "http") == 0 || strcmp(proto, "git+http") == 0)
+		err = got_error_path(proto, GOT_ERR_NOT_IMPL);
+	else
+		err = got_error_path(proto, GOT_ERR_BAD_PROTO);
 	return err;
 }
 
@@ -280,12 +299,12 @@ done:
 
 const struct got_error*
 got_fetch(struct got_object_id **pack_hash, struct got_pathlist_head *refs,
-    struct got_pathlist_head *symrefs, const char *proto, const char *host,
-    const char *port, const char *server_path, const char *repo_name,
-    const char *branch_filter, struct got_repository *repo)
+    struct got_pathlist_head *symrefs, int fetchfd, const char *proto,
+    const char *host, const char *port, const char *server_path,
+    const char *repo_name, const char *branch_filter, struct got_repository *repo)
 {
-	int imsg_fetchfds[2], imsg_idxfds[2], fetchfd = -1;
-	int packfd = -1, npackfd = -1, idxfd = -1, nidxfd = -1;
+	int imsg_fetchfds[2], imsg_idxfds[2];
+	int packfd = -1, npackfd = -1, idxfd = -1, nidxfd = -1, nfetchfd = -1;
 	int status, done = 0;
 	const struct got_error *err;
 	struct imsgbuf ibuf;
@@ -298,8 +317,6 @@ got_fetch(struct got_object_id **pack_hash, struct got
 
 	*pack_hash = NULL;
 
-	fetchfd = -1;
-
 	if (asprintf(&path, "%s/%s/fetching.pack",
 	    repo_path, GOT_OBJECTS_PACK_DIR) == -1) {
 		err = got_error_from_errno("asprintf");
@@ -329,17 +346,6 @@ got_fetch(struct got_object_id **pack_hash, struct got
 		goto done;
 	}
 
-	if (strcmp(proto, "ssh") == 0 || strcmp(proto, "git+ssh") == 0)
-		err = dial_ssh(&fetchfd, host, port, server_path, "upload");
-	else if (strcmp(proto, "git") == 0)
-		err = dial_git(&fetchfd, host, port, server_path, "upload");
-	else if (strcmp(proto, "http") == 0 || strcmp(proto, "git+http") == 0)
-		err = got_error(GOT_ERR_BAD_PROTO);
-	else
-		err = got_error(GOT_ERR_BAD_PROTO);
-	if (err)
-		goto done;
-
 	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fetchfds) == -1) {
 		err = got_error_from_errno("socketpair");
 		goto done;
@@ -359,10 +365,15 @@ got_fetch(struct got_object_id **pack_hash, struct got
 		goto done;
 	}
 	imsg_init(&ibuf, imsg_fetchfds[0]);
-	err = got_privsep_send_fetch_req(&ibuf, fetchfd);
+	nfetchfd = dup(fetchfd);
+	if (nfetchfd == -1) {
+		err = got_error_from_errno("dup");
+		goto done;
+	}
+	err = got_privsep_send_fetch_req(&ibuf, nfetchfd);
 	if (err != NULL)
 		goto done;
-	fetchfd = -1;
+	nfetchfd = -1;
 	err = got_privsep_send_tmpfd(&ibuf, npackfd);
 	if (err != NULL)
 		goto done;
@@ -457,7 +468,7 @@ got_fetch(struct got_object_id **pack_hash, struct got
 	}
 
 done:
-	if (fetchfd != -1 && close(fetchfd) == -1 && err == NULL)
+	if (nfetchfd != -1 && close(nfetchfd) == -1 && err == NULL)
 		err = got_error_from_errno("close");
 	if (npackfd != -1 && close(npackfd) == -1 && err == NULL)
 		err = got_error_from_errno("close");