Commit Diff


commit - 34b3c35b08058d7664122b8f9c0bf226e68b5fc4
commit + 01d78e9e349d8547e36bfe47e4c53acfcef2973d
blob - 8c63c1485e235199cc2ba118a4a8617670a97c05
blob + 681905dc26b73d6a41382533ca6a87a306c8a240
--- lib/send.c
+++ lib/send.c
@@ -70,6 +70,7 @@
 #include "got_lib_pack_create.h"
 #include "got_lib_dial.h"
 #include "got_lib_worktree_cvg.h"
+#include "got_lib_poll.h"
 
 #ifndef nitems
 #define nitems(_a)	(sizeof((_a)) / sizeof((_a)[0]))
@@ -108,6 +109,7 @@ got_send_connect(pid_t *sendpid, int *sendfd, const ch
 struct pack_progress_arg {
     got_send_progress_cb progress_cb;
     void *progress_arg;
+    int sendfd;
 
     int ncolored;
     int nfound;
@@ -133,6 +135,25 @@ pack_progress(void *arg, int ncolored, int nfound, int
 	if (err)
 		return err;
 
+	/*
+	 * Detect the server closing our connection while we are
+	 * busy creating a pack file.
+	 *
+	 * XXX This should be a temporary workaround. A better fix would
+	 * be to avoid use of an on-disk tempfile for pack file data.
+	 * Instead we could stream pack file data to got-send-pack while
+	 * the pack file is being generated. Write errors in got-send-pack
+	 * would then automatically abort the creation of pack file data.
+	 */
+	err = got_poll_fd(a->sendfd, 0, 0);
+	if (err && err->code != GOT_ERR_TIMEOUT) {
+		if (err->code == GOT_ERR_EOF) {
+			err = got_error_msg(GOT_ERR_EOF,
+			    "server unexpectedly closed the connection");
+		}
+		return err;
+	}
+	 
 	a->ncolored= ncolored;
 	a->nfound = nfound;
 	a->ntrees = ntrees;
@@ -591,6 +612,7 @@ got_send_pack(const char *remote_name, struct got_path
 		memset(&ppa, 0, sizeof(ppa));
 		ppa.progress_cb = progress_cb;
 		ppa.progress_arg = progress_arg;
+		ppa.sendfd = sendfd;
 		err = got_pack_create(packsha1, packfd, delta_cache,
 		    their_ids, ntheirs, our_ids, nours, repo, 0, 1, 0,
 		    pack_progress, &ppa, &rl, cancel_cb, cancel_arg);