commit 8f2d01a65f173c54cbafab8621d74165029afc94 from: Stefan Sperling date: Wed Mar 18 16:10:32 2020 UTC send fetch progress over imsg commit - 018e0a9a451218ebe68b2af160d30a71754a6c41 commit + 8f2d01a65f173c54cbafab8621d74165029afc94 blob - 68675291cc8ebbbdcb82b2cd4b07f9b4e5a36f80 blob + 8276f9a1088600076d7eb934659ea6055dd3b2a0 --- lib/fetch.c +++ lib/fetch.c @@ -253,8 +253,8 @@ got_fetch(char *uri, char *branch_filter, char *destdi char proto[GOT_PROTOMAX], host[GOT_HOSTMAX], port[GOT_PORTMAX]; char repo[GOT_REPOMAX], path[GOT_PATHMAX]; int imsg_fetchfds[2], imsg_idxfds[2], fetchfd; - int packfd = -1, npackfd, idxfd = -1, nidxfd, status; - struct got_object_id packhash; + int packfd = -1, npackfd, idxfd = -1, nidxfd, status, done = 0; + struct got_object_id *packhash = NULL; const struct got_error *err; struct imsgbuf ibuf; pid_t pid; @@ -323,9 +323,27 @@ got_fetch(char *uri, char *branch_filter, char *destdi npackfd = dup(packfd); if (npackfd == -1) return got_error_from_errno("dup"); - err = got_privsep_wait_fetch_done(&ibuf, &packhash); - if (err != NULL) - return err; + while (!done) { + struct got_object_id *id; + char *refname; + err = got_privsep_recv_fetch_progress(&done, + &id, &refname, &ibuf); + if (err != NULL) + return err; + if (done) { + packhash = got_object_id_dup(id); + if (packhash == NULL) + return got_error_from_errno( + "got_object_id_dup"); + } else { + char *id_str; + /* TODO Use a progress callback */ + err = got_object_id_str(&id_str, id); + if (err) + return err; + printf( "%.12s %s\n", id_str, refname); + } + } if (waitpid(pid, &status, 0) == -1) return got_error_from_errno("child exit"); @@ -340,7 +358,7 @@ got_fetch(char *uri, char *branch_filter, char *destdi return got_error_from_errno("close"); imsg_init(&ibuf, imsg_idxfds[0]); - err = got_privsep_send_index_pack_req(&ibuf, npackfd, &packhash); + err = got_privsep_send_index_pack_req(&ibuf, npackfd, packhash); if (err != NULL) return err; err = got_privsep_send_tmpfd(&ibuf, nidxfd); @@ -355,7 +373,7 @@ got_fetch(char *uri, char *branch_filter, char *destdi if (waitpid(pid, &status, 0) == -1) return got_error_from_errno("child exit"); - err = got_object_id_str(&id_str, &packhash); + err = got_object_id_str(&id_str, packhash); if (err) return err; if (asprintf(&packpath, "objects/pack/pack-%s.pack", id_str) == -1) @@ -374,6 +392,7 @@ got_fetch(char *uri, char *branch_filter, char *destdi free(idxpath); free(packpath); free(default_destdir); + free(packhash); return NULL; } blob - f02d6fb268ae009d8ca3e8aaf043bf0a8fcfdbcd blob + 4b14f8cacd48ffe10d30e6cf407481cd9e12e27f --- lib/got_lib_privsep.h +++ lib/got_lib_privsep.h @@ -325,12 +325,10 @@ const struct got_error *got_privsep_wait_index_pack_do const struct got_error *got_privsep_send_fetch_req(struct imsgbuf *, int); const struct got_error *got_privsep_send_fetch_progress(struct imsgbuf *, struct got_object_id *, const char *); -const struct got_error *got_privsep_recv_fetch_progress(struct got_object_id **, - char **, struct imsgbuf *); +const struct got_error *got_privsep_recv_fetch_progress(int *, + struct got_object_id **, char **, struct imsgbuf *); const struct got_error *got_privsep_send_fetch_done(struct imsgbuf *, struct got_object_id); -const struct got_error *got_privsep_wait_fetch_done(struct imsgbuf *, - struct got_object_id*); const struct got_error *got_privsep_get_imsg_obj(struct got_object **, struct imsg *, struct imsgbuf *); const struct got_error *got_privsep_recv_obj(struct got_object **, blob - 868e4fb0aff2bb0a202abedcadd1c8e9d0463fa6 blob + 642c62a8f986362d8cddddd8fbeb351284c09e39 --- lib/privsep.c +++ lib/privsep.c @@ -462,7 +462,7 @@ got_privsep_send_fetch_done(struct imsgbuf *ibuf, stru const struct got_error * -got_privsep_recv_fetch_progress(struct got_object_id **refid, +got_privsep_recv_fetch_progress(int *done, struct got_object_id **id, char **refname, struct imsgbuf *ibuf) { const struct got_error *err = NULL; @@ -472,7 +472,8 @@ got_privsep_recv_fetch_progress(struct got_object_id * MIN(sizeof(struct got_imsg_error), sizeof(struct got_imsg_fetch_progress)); - *refid = NULL; + *done = 0; + *id = NULL; *refname = NULL; err = got_privsep_recv_imsg(&imsg, ibuf, min_datalen); @@ -485,12 +486,12 @@ got_privsep_recv_fetch_progress(struct got_object_id * err = recv_imsg_error(&imsg, datalen); break; case GOT_IMSG_FETCH_PROGRESS: - *refid = malloc(sizeof(**refid)); - if (*refid == NULL) { + *id = malloc(sizeof(**id)); + if (*id == NULL) { err = got_error_from_errno("malloc"); break; } - memcpy((*refid)->sha1, imsg.data, SHA1_DIGEST_LENGTH); + memcpy((*id)->sha1, imsg.data, SHA1_DIGEST_LENGTH); if (datalen <= SHA1_DIGEST_LENGTH) { err = got_error(GOT_ERR_PRIVSEP_MSG); break; @@ -499,8 +500,21 @@ got_privsep_recv_fetch_progress(struct got_object_id * datalen - SHA1_DIGEST_LENGTH); if (*refname == NULL) { err = got_error_from_errno("strndup"); + break; + } + break; + case GOT_IMSG_FETCH_DONE: + *id = malloc(sizeof(**id)); + if (*id == NULL) { + err = got_error_from_errno("malloc"); break; } + if (datalen != SHA1_DIGEST_LENGTH) { + err = got_error(GOT_ERR_PRIVSEP_MSG); + break; + } + memcpy((*id)->sha1, imsg.data, SHA1_DIGEST_LENGTH); + *done = 1; break; default: err = got_error(GOT_ERR_PRIVSEP_MSG); @@ -508,36 +522,15 @@ got_privsep_recv_fetch_progress(struct got_object_id * } if (err) { - free(*refid); - *refid = NULL; + free(*id); + *id = NULL; free(*refname); *refname = NULL; } imsg_free(&imsg); return err; -} - -const struct got_error * -got_privsep_wait_fetch_done(struct imsgbuf *ibuf, struct got_object_id *hash) -{ - const struct got_error *err = NULL; - struct imsg imsg; - - err = got_privsep_recv_imsg(&imsg, ibuf, 0); - if (err) - return err; - if (imsg.hdr.type == GOT_IMSG_FETCH_DONE && - imsg.hdr.len - sizeof(imsg.hdr) == SHA1_DIGEST_LENGTH) { - memcpy(hash->sha1, imsg.data, SHA1_DIGEST_LENGTH); - imsg_free(&imsg); - return NULL; - } - - imsg_free(&imsg); - return got_error(GOT_ERR_PRIVSEP_MSG); } - const struct got_error * got_privsep_send_index_pack_req(struct imsgbuf *ibuf, int fd, struct got_object_id *hash) { blob - f3c5837fb024575d0c038ec7bf356dddad56fe17 blob + fd5a8956eba30a51fd86cb24e4899fdd933dc621 --- libexec/got-fetch-pack/got-fetch-pack.c +++ libexec/got-fetch-pack/got-fetch-pack.c @@ -282,7 +282,8 @@ got_tokenize_refline(char *line, char **sp, size_t nsp } static const struct got_error * -fetch_pack(int fd, int packfd, struct got_object_id *packid) +fetch_pack(int fd, int packfd, struct got_object_id *packid, + struct imsgbuf *ibuf) { const struct got_error *err = NULL; char buf[GOT_PKTMAX], *sp[3]; @@ -346,7 +347,9 @@ fetch_pack(int fd, int packfd, struct got_object_id *p if (got_resolve_remote_ref(&have[nref], sp[1]) == -1) memset(&have[nref], 0, sizeof(have[nref])); - // TODO: send IMSG with progress. + err = got_privsep_send_fetch_progress(ibuf, &want[nref], sp[1]); + if (err) + goto done; if (chattygit) fprintf(stderr, "remote %s\n", sp[1]); nref++; @@ -403,7 +406,8 @@ fetch_pack(int fd, int packfd, struct got_object_id *p } buf[n] = 0; - fprintf(stderr, "fetching...\n"); + if (chattygit) + fprintf(stderr, "fetching...\n"); packsz = 0; while (1) { ssize_t w; @@ -434,7 +438,7 @@ fetch_pack(int fd, int packfd, struct got_object_id *p done: free(have); free(want); - return 0; + return err; } @@ -487,7 +491,7 @@ main(int argc, char **argv) } packfd = imsg.fd; - err = fetch_pack(fetchfd, packfd, &packid); + err = fetch_pack(fetchfd, packfd, &packid, &ibuf); if (err) goto done; done: