commit 1785f84a3a2f8d9dd6b73551560405f87a2e2ebb from: Stefan Sperling date: Sun Dec 23 22:15:42 2018 UTC eliminate got_object_open() round-trip when opening commits commit - 4c838a52b058826b33b06295771b4cd1553100d1 commit + 1785f84a3a2f8d9dd6b73551560405f87a2e2ebb blob - 14bd628bae7ca8d8048fca27f37f546c5aca6701 blob + c3257cfa278471697b8fe6e3e8a8cb6396d55453 --- lib/got_lib_object.h +++ lib/got_lib_object.h @@ -37,6 +37,7 @@ struct got_object { }; struct got_commit_object { + struct got_object *obj; struct got_object_id *tree_id; unsigned int nparents; struct got_object_id_queue parent_ids; blob - dcc76200ee994833fb286f365a9b936071eb118e blob + 5c3980f2f01b211568497aa87e29167f3de13b4d --- lib/got_lib_object_parse.h +++ lib/got_lib_object_parse.h @@ -22,8 +22,7 @@ const struct got_error *got_object_read_header_privsep const struct got_error *got_object_read_blob_privsep(size_t *, int, int, struct got_repository *repo); const struct got_error *got_object_read_commit_privsep( - struct got_commit_object **, struct got_object *, int, - struct got_repository *); + struct got_commit_object **, int, struct got_repository *); const struct got_error *got_object_read_tree_privsep(struct got_tree_object **, struct got_object *, int, struct got_repository *); const struct got_error *got_object_read_tag_privsep(struct got_tag_object **, @@ -45,9 +44,12 @@ struct got_packidx; const struct got_error *got_object_packed_read_privsep(struct got_object **, struct got_repository *, struct got_pack *, struct got_packidx *, int, struct got_object_id *); -const struct got_error *got_object_read_packed_commit_privsep( - struct got_commit_object **, struct got_object *, struct got_pack *); +const struct got_error * +got_object_read_packed_commit_privsep(struct got_commit_object **, + struct got_pack *, struct got_packidx *, int, struct got_object_id *); const struct got_error *got_object_read_packed_tree_privsep( struct got_tree_object **, struct got_object *, struct got_pack *); const struct got_error *got_object_read_packed_tag_privsep( struct got_tag_object **, struct got_object *, struct got_pack *); +const struct got_error *got_object_parse_header(struct got_object **, char *, size_t); +const struct got_error *got_object_read_header(struct got_object **, int); blob - 871454f5b88c501bfe8560503f16b0d734fafba9 blob + 6f054bf24aa9628a786b47cf1f64635dec753297 --- lib/got_lib_privsep.h +++ lib/got_lib_privsep.h @@ -111,8 +111,7 @@ struct got_imsg_error { } __attribute__((__packed__)); /* - * Structure for GOT_IMSG_TREE_REQUEST, GOT_IMSG_COMMIT_REQUEST, - * and GOT_IMSG_OBJECT data. + * Structure for GOT_IMSG_TREE_REQUEST and GOT_IMSG_OBJECT data. */ struct got_imsg_object { uint8_t id[SHA1_DIGEST_LENGTH]; @@ -219,6 +218,8 @@ const struct got_error *got_privsep_recv_imsg(struct i void got_privsep_send_error(struct imsgbuf *, const struct got_error *); const struct got_error *got_privsep_send_obj_req(struct imsgbuf *, int, struct got_object *); +const struct got_error *got_privsep_send_commit_req(struct imsgbuf *, int, + struct got_object_id *, int); const struct got_error *got_privsep_send_blob_req(struct imsgbuf *, int); const struct got_error *got_privsep_send_blob_outfd(struct imsgbuf *, int); const struct got_error *got_privsep_send_tmpfd(struct imsgbuf *, int); blob - 5ca1099575ba902e52bb4dda0fbe2091bb0300c1 blob + 41e5235fe66dc73bcd2f261027677ff112f16817 --- lib/object.c +++ lib/object.c @@ -296,12 +296,15 @@ got_object_resolve_id_str(struct got_object_id **id, static const struct got_error * open_commit(struct got_commit_object **commit, - struct got_repository *repo, struct got_object *obj, int check_cache) + struct got_repository *repo, struct got_object_id *id, int check_cache) { const struct got_error *err = NULL; + struct got_packidx *packidx = NULL; + int idx; + char *path_packfile; if (check_cache) { - *commit = got_repo_get_cached_commit(repo, &obj->id); + *commit = got_repo_get_cached_commit(repo, id); if (*commit != NULL) { (*commit)->refcnt++; return NULL; @@ -309,31 +312,36 @@ open_commit(struct got_commit_object **commit, } else *commit = NULL; - if (obj->type != GOT_OBJ_TYPE_COMMIT) - return got_error(GOT_ERR_OBJ_TYPE); + err = got_repo_search_packidx(&packidx, &idx, repo, id); + if (err == NULL) { + struct got_pack *pack = NULL; - if (obj->flags & GOT_OBJ_FLAG_PACKED) { - struct got_pack *pack; - pack = got_repo_get_cached_pack(repo, obj->path_packfile); + err = get_packfile_path(&path_packfile, packidx); + if (err) + return err; + + pack = got_repo_get_cached_pack(repo, path_packfile); if (pack == NULL) { - err = got_repo_cache_pack(&pack, repo, - obj->path_packfile, NULL); + err = got_repo_cache_pack(&pack, repo, path_packfile, + packidx); if (err) return err; } - err = got_object_read_packed_commit_privsep(commit, obj, pack); - } else { + err = got_object_read_packed_commit_privsep(commit, pack, + packidx, idx, id); + } else if (err->code == GOT_ERR_NO_OBJ) { int fd; - err = open_loose_object(&fd, got_object_get_id(obj), repo); + + err = open_loose_object(&fd, id, repo); if (err) return err; - err = got_object_read_commit_privsep(commit, obj, fd, repo); + err = got_object_read_commit_privsep(commit, fd, repo); close(fd); } if (err == NULL) { (*commit)->refcnt++; - err = got_repo_cache_commit(repo, &obj->id, *commit); + err = got_repo_cache_commit(repo, id, *commit); } return err; @@ -343,34 +351,20 @@ const struct got_error * got_object_open_as_commit(struct got_commit_object **commit, struct got_repository *repo, struct got_object_id *id) { - const struct got_error *err; - struct got_object *obj; - *commit = got_repo_get_cached_commit(repo, id); if (*commit != NULL) { (*commit)->refcnt++; return NULL; } - err = got_object_open(&obj, repo, id); - if (err) - return err; - if (obj->type != GOT_OBJ_TYPE_COMMIT) { - err = got_error(GOT_ERR_OBJ_TYPE); - goto done; - } - - err = open_commit(commit, repo, obj, 0); -done: - got_object_close(obj); - return err; + return open_commit(commit, repo, id, 0); } const struct got_error * got_object_commit_open(struct got_commit_object **commit, struct got_repository *repo, struct got_object *obj) { - return open_commit(commit, repo, obj, 1); + return open_commit(commit, repo, got_object_get_id(obj), 1); } const struct got_error * @@ -1173,48 +1167,137 @@ done: pack->privsep_child = NULL; } else err = request_packed_object(obj, pack, idx, id); + return err; +} + +static const struct got_error * +receive_commit(struct got_commit_object **commit, struct imsgbuf *ibuf) +{ + const struct got_error *err = NULL; + struct got_object *obj; + + err = got_privsep_recv_obj(&obj, ibuf); + if (err) + return err; + + err = got_privsep_recv_commit(commit, ibuf); + if (err) + got_object_close(obj); + else + (*commit)->obj = obj; /* XXX should be embedded */ + return err; } static const struct got_error * request_commit(struct got_commit_object **commit, struct got_repository *repo, - struct got_object *obj, int fd) + int fd) { const struct got_error *err = NULL; struct imsgbuf *ibuf; ibuf = repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_COMMIT].ibuf; - err = got_privsep_send_obj_req(ibuf, fd, obj); + err = got_privsep_send_commit_req(ibuf, fd, NULL, -1); if (err) return err; - return got_privsep_recv_commit(commit, ibuf); + return receive_commit(commit, ibuf); } +static const struct got_error * +request_packed_commit(struct got_commit_object **commit, struct got_pack *pack, + int pack_idx, struct got_object_id *id) +{ + const struct got_error *err = NULL; + + err = got_privsep_send_commit_req(pack->privsep_child->ibuf, -1, id, + pack_idx); + if (err) + return err; + + return receive_commit(commit, pack->privsep_child->ibuf); +} + const struct got_error * got_object_read_packed_commit_privsep(struct got_commit_object **commit, - struct got_object *obj, struct got_pack *pack) + struct got_pack *pack, struct got_packidx *packidx, int idx, + struct got_object_id *id) { const struct got_error *err = NULL; + int imsg_fds[2]; + pid_t pid; + struct imsgbuf *ibuf; - err = got_privsep_send_obj_req(pack->privsep_child->ibuf, -1, obj); - if (err) + if (pack->privsep_child) + return request_packed_commit(commit, pack, idx, id); + + ibuf = calloc(1, sizeof(*ibuf)); + if (ibuf == NULL) + return got_error_from_errno(); + + pack->privsep_child = calloc(1, sizeof(*pack->privsep_child)); + if (pack->privsep_child == NULL) { + err = got_error_from_errno(); + free(ibuf); return err; + } - return got_privsep_recv_commit(commit, pack->privsep_child->ibuf); + if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fds) == -1) { + err = got_error_from_errno(); + goto done; + } + + pid = fork(); + if (pid == -1) { + err = got_error_from_errno(); + goto done; + } else if (pid == 0) { + exec_privsep_child(imsg_fds, GOT_PATH_PROG_READ_PACK, + pack->path_packfile); + /* not reached */ + } + + close(imsg_fds[1]); + pack->privsep_child->imsg_fd = imsg_fds[0]; + pack->privsep_child->pid = pid; + imsg_init(ibuf, imsg_fds[0]); + pack->privsep_child->ibuf = ibuf; + + err = got_privsep_init_pack_child(ibuf, pack, packidx); + if (err) { + const struct got_error *child_err; + err = got_privsep_send_stop(pack->privsep_child->imsg_fd); + child_err = got_privsep_wait_for_child( + pack->privsep_child->pid); + if (child_err && err == NULL) + err = child_err; + free(ibuf); + free(pack->privsep_child); + pack->privsep_child = NULL; + return err; + } + +done: + if (err) { + free(ibuf); + free(pack->privsep_child); + pack->privsep_child = NULL; + } else + err = request_packed_commit(commit, pack, idx, id); + return err; } const struct got_error * got_object_read_commit_privsep(struct got_commit_object **commit, - struct got_object *obj, int obj_fd, struct got_repository *repo) + int obj_fd, struct got_repository *repo) { int imsg_fds[2]; pid_t pid; struct imsgbuf *ibuf; if (repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_COMMIT].imsg_fd != -1) - return request_commit(commit, repo, obj, obj_fd); + return request_commit(commit, repo, obj_fd); ibuf = calloc(1, sizeof(*ibuf)); if (ibuf == NULL) @@ -1239,7 +1322,7 @@ got_object_read_commit_privsep(struct got_commit_objec imsg_init(ibuf, imsg_fds[0]); repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_COMMIT].ibuf = ibuf; - return request_commit(commit, repo, obj, obj_fd); + return request_commit(commit, repo, obj_fd); } static const struct got_error * blob - 21d3471c2b584757cf15d68aad56eb7edd8d3d02 blob + b98b1784a35735c7c85b744968f43221f3a449a3 --- lib/object_parse.c +++ lib/object_parse.c @@ -140,6 +140,111 @@ got_object_qid_free(struct got_object_qid *qid) { free(qid->id); free(qid); +} + +const struct got_error * +got_object_parse_header(struct got_object **obj, char *buf, size_t len) +{ + const char *obj_tags[] = { + GOT_OBJ_TAG_COMMIT, + GOT_OBJ_TAG_TREE, + GOT_OBJ_TAG_BLOB, + GOT_OBJ_TAG_TAG, + }; + const int obj_types[] = { + GOT_OBJ_TYPE_COMMIT, + GOT_OBJ_TYPE_TREE, + GOT_OBJ_TYPE_BLOB, + GOT_OBJ_TYPE_TAG, + }; + int type = 0; + size_t size = 0, hdrlen = 0; + int i; + char *p = strchr(buf, '\0'); + + *obj = NULL; + + if (p == NULL) + return got_error(GOT_ERR_BAD_OBJ_HDR); + + hdrlen = strlen(buf) + 1 /* '\0' */; + + for (i = 0; i < nitems(obj_tags); i++) { + const char *tag = obj_tags[i]; + size_t tlen = strlen(tag); + const char *errstr; + + if (strncmp(buf, tag, tlen) != 0) + continue; + + type = obj_types[i]; + if (len <= tlen) + return got_error(GOT_ERR_BAD_OBJ_HDR); + size = strtonum(buf + tlen, 0, LONG_MAX, &errstr); + if (errstr != NULL) + return got_error(GOT_ERR_BAD_OBJ_HDR); + break; + } + + if (type == 0) + return got_error(GOT_ERR_BAD_OBJ_HDR); + + *obj = calloc(1, sizeof(**obj)); + if (*obj == NULL) + return got_error_from_errno(); + (*obj)->type = type; + (*obj)->hdrlen = hdrlen; + (*obj)->size = size; + return NULL; +} + +const struct got_error * +got_object_read_header(struct got_object **obj, int fd) +{ + const struct got_error *err; + struct got_zstream_buf zb; + char *buf; + const size_t zbsize = 64; + size_t outlen, totlen; + int nbuf = 1; + + *obj = NULL; + + buf = malloc(zbsize); + if (buf == NULL) + return got_error_from_errno(); + + err = got_inflate_init(&zb, buf, zbsize); + if (err) + return err; + + totlen = 0; + do { + err = got_inflate_read_fd(&zb, fd, &outlen); + if (err) + goto done; + if (outlen == 0) + break; + totlen += outlen; + if (strchr(zb.outbuf, '\0') == NULL) { + char *newbuf; + nbuf++; + newbuf = recallocarray(buf, nbuf - 1, nbuf, zbsize); + if (newbuf == NULL) { + err = got_error_from_errno(); + goto done; + } + buf = newbuf; + zb.outbuf = newbuf + totlen; + zb.outlen = (nbuf * zbsize) - totlen; + } + } while (strchr(zb.outbuf, '\0') == NULL); + + err = got_object_parse_header(obj, buf, totlen); +done: + free(buf); + got_inflate_end(&zb); + return err; } struct got_commit_object * @@ -272,6 +377,7 @@ got_object_commit_close(struct got_commit_object *comm free(commit->author); free(commit->committer); free(commit->logmsg); + got_object_close(commit->obj); free(commit); } blob - d95f5012099136dd65c3fbc85cbf8a99a89abdf7 blob + 2a15c7e9acf60b2624a4d24a64501982eb1dbf81 --- lib/privsep.c +++ lib/privsep.c @@ -233,7 +233,7 @@ got_privsep_send_obj_req(struct imsgbuf *ibuf, int fd, imsg_code = GOT_IMSG_TREE_REQUEST; break; case GOT_OBJ_TYPE_COMMIT: - imsg_code = GOT_IMSG_COMMIT_REQUEST; + abort(); /* should not get here */ break; case GOT_OBJ_TYPE_BLOB: imsg_code = GOT_IMSG_BLOB_REQUEST; @@ -260,6 +260,30 @@ got_privsep_send_obj_req(struct imsgbuf *ibuf, int fd, } if (imsg_compose(ibuf, imsg_code, 0, 0, fd, iobjp, iobj_size) == -1) + return got_error_from_errno(); + + return flush_imsg(ibuf); +} + +const struct got_error * +got_privsep_send_commit_req(struct imsgbuf *ibuf, int fd, + struct got_object_id *id, int pack_idx) +{ + struct got_imsg_packed_object iobj, *iobjp; + size_t len; + + if (id) { /* commit is packed */ + iobj.idx = pack_idx; + memcpy(iobj.id, id->sha1, sizeof(iobj.id)); + iobjp = &iobj; + len = sizeof(iobj); + } else { + iobjp = NULL; + len = 0; + } + + if (imsg_compose(ibuf, GOT_IMSG_COMMIT_REQUEST, 0, 0, fd, iobjp, len) + == -1) return got_error_from_errno(); return flush_imsg(ibuf); blob - 9ebca90a5bf3e71ea9503fc697e1aa8fa2034493 blob + eeafefcdae2da3791cde557835ec32b1b3c58c3b --- libexec/got-read-commit/got-read-commit.c +++ libexec/got-read-commit/got-read-commit.c @@ -48,30 +48,41 @@ catch_sigint(int signo) } static const struct got_error * -read_commit_object(struct got_commit_object **commit, struct got_object *obj, - FILE *f) +read_commit_object(struct got_commit_object **commit, FILE *f) { + struct got_object *obj; const struct got_error *err = NULL; size_t len; uint8_t *p; - if (obj->flags & GOT_OBJ_FLAG_PACKED) - err = got_read_file_to_mem(&p, &len, f); - else - err = got_inflate_to_mem(&p, &len, f); + err = got_inflate_to_mem(&p, &len, f); if (err) return err; + err = got_object_parse_header(&obj, p, len); + if (err) + return err; + if (len < obj->hdrlen + obj->size) { err = got_error(GOT_ERR_BAD_OBJ_DATA); goto done; } + if (obj->type != GOT_OBJ_TYPE_COMMIT) { + err = got_error(GOT_ERR_OBJ_TYPE); + goto done; + } + /* Skip object header. */ len -= obj->hdrlen; err = got_object_parse_commit(commit, p + obj->hdrlen, len); - free(p); done: + free(p); + if (err) + got_object_close(obj); + else + (*commit)->obj = obj; /* XXX should be embedded in struct */ + return err; } @@ -79,9 +90,7 @@ int main(int argc, char *argv[]) { const struct got_error *err = NULL; - struct got_commit_object *commit = NULL; struct imsgbuf ibuf; - size_t datalen; signal(SIGINT, catch_sigint); @@ -98,9 +107,8 @@ main(int argc, char *argv[]) while (1) { struct imsg imsg; - struct got_imsg_object iobj; FILE *f = NULL; - struct got_object *obj = NULL; + struct got_commit_object *commit = NULL; if (sigint_received) { err = got_error(GOT_ERR_CANCELLED); @@ -122,32 +130,11 @@ main(int argc, char *argv[]) goto done; } - datalen = imsg.hdr.len - IMSG_HEADER_SIZE; - if (datalen != sizeof(iobj)) { - err = got_error(GOT_ERR_PRIVSEP_LEN); - goto done; - } - - memcpy(&iobj, imsg.data, sizeof(iobj)); - if (iobj.type != GOT_OBJ_TYPE_COMMIT) { - err = got_error(GOT_ERR_OBJ_TYPE); - goto done; - } - if (imsg.fd == -1) { err = got_error(GOT_ERR_PRIVSEP_NO_FD); goto done; } - obj = calloc(1, sizeof(*obj)); - if (obj == NULL) { - err = got_error_from_errno(); - goto done; - } - obj->type = iobj.type; - obj->hdrlen = iobj.hdrlen; - obj->size = iobj.size; - /* Always assume file offset zero. */ f = fdopen(imsg.fd, "rb"); if (f == NULL) { @@ -155,10 +142,17 @@ main(int argc, char *argv[]) goto done; } - err = read_commit_object(&commit, obj, f); + err = read_commit_object(&commit, f); if (err) goto done; + /* XXX This flushes the pipe, should only fill it instead. */ + err = got_privsep_send_obj(&ibuf, commit->obj); + if (err) + goto done; + + /* XXX Assumes full imsg buf size, should take obj into + * account when above flush is removed. */ err = got_privsep_send_commit(&ibuf, commit); done: if (f) @@ -166,8 +160,6 @@ done: else if (imsg.fd != -1) close(imsg.fd); imsg_free(&imsg); - if (obj) - got_object_close(obj); if (err) break; } blob - ae3722c08c1905a6e64dee0e34ec327baf6cb82c blob + e6339341b9614a7bf218a689c25d8212ef1025e2 --- libexec/got-read-object/got-read-object.c +++ libexec/got-read-object/got-read-object.c @@ -36,6 +36,7 @@ #include "got_lib_delta.h" #include "got_lib_inflate.h" #include "got_lib_object.h" +#include "got_lib_object_parse.h" #include "got_lib_privsep.h" #ifndef nitems @@ -55,112 +56,6 @@ catch_sigint(int signo) sigint_received = 1; } -static const struct got_error * -parse_object_header(struct got_object **obj, char *buf, size_t len) -{ - const char *obj_tags[] = { - GOT_OBJ_TAG_COMMIT, - GOT_OBJ_TAG_TREE, - GOT_OBJ_TAG_BLOB, - GOT_OBJ_TAG_TAG, - }; - const int obj_types[] = { - GOT_OBJ_TYPE_COMMIT, - GOT_OBJ_TYPE_TREE, - GOT_OBJ_TYPE_BLOB, - GOT_OBJ_TYPE_TAG, - }; - int type = 0; - size_t size = 0, hdrlen = 0; - int i; - char *p = strchr(buf, '\0'); - - *obj = NULL; - - if (p == NULL) - return got_error(GOT_ERR_BAD_OBJ_HDR); - - hdrlen = strlen(buf) + 1 /* '\0' */; - - for (i = 0; i < nitems(obj_tags); i++) { - const char *tag = obj_tags[i]; - size_t tlen = strlen(tag); - const char *errstr; - - if (strncmp(buf, tag, tlen) != 0) - continue; - - type = obj_types[i]; - if (len <= tlen) - return got_error(GOT_ERR_BAD_OBJ_HDR); - size = strtonum(buf + tlen, 0, LONG_MAX, &errstr); - if (errstr != NULL) - return got_error(GOT_ERR_BAD_OBJ_HDR); - break; - } - - if (type == 0) - return got_error(GOT_ERR_BAD_OBJ_HDR); - - *obj = calloc(1, sizeof(**obj)); - if (*obj == NULL) - return got_error_from_errno(); - (*obj)->type = type; - (*obj)->hdrlen = hdrlen; - (*obj)->size = size; - return NULL; -} - -static const struct got_error * -read_object_header(struct got_object **obj, int fd) -{ - const struct got_error *err; - struct got_zstream_buf zb; - char *buf; - const size_t zbsize = 64; - size_t outlen, totlen; - int nbuf = 1; - - *obj = NULL; - - buf = malloc(zbsize); - if (buf == NULL) - return got_error_from_errno(); - - err = got_inflate_init(&zb, buf, zbsize); - if (err) - return err; - - totlen = 0; - do { - err = got_inflate_read_fd(&zb, fd, &outlen); - if (err) - goto done; - if (outlen == 0) - break; - totlen += outlen; - if (strchr(zb.outbuf, '\0') == NULL) { - char *newbuf; - nbuf++; - newbuf = recallocarray(buf, nbuf - 1, nbuf, zbsize); - if (newbuf == NULL) { - err = got_error_from_errno(); - goto done; - } - buf = newbuf; - zb.outbuf = newbuf + totlen; - zb.outlen = (nbuf * zbsize) - totlen; - } - } while (strchr(zb.outbuf, '\0') == NULL); - - err = parse_object_header(obj, buf, totlen); -done: - free(buf); - got_inflate_end(&zb); - return err; -} - - int main(int argc, char *argv[]) { @@ -210,7 +105,7 @@ main(int argc, char *argv[]) goto done; } - err = read_object_header(&obj, imsg.fd); + err = got_object_read_header(&obj, imsg.fd); if (err) goto done; blob - e5d58ee0bb72b099f33b72f3367599d9f6fee2eb blob + 92227336ac9362deae0f19afe555b42461ad7b04 --- libexec/got-read-pack/got-read-pack.c +++ libexec/got-read-pack/got-read-pack.c @@ -121,13 +121,21 @@ commit_request(struct imsg *imsg, struct imsgbuf *ibuf struct got_packidx *packidx, struct got_object_cache *objcache) { const struct got_error *err = NULL; - struct got_object *obj = NULL; + struct got_imsg_packed_object iobj; + struct got_object *obj; struct got_commit_object *commit = NULL; uint8_t *buf; size_t len; + struct got_object_id id; + size_t datalen; - err = get_object(&obj, imsg, ibuf, pack, packidx, objcache, - GOT_OBJ_TYPE_COMMIT); + datalen = imsg->hdr.len - IMSG_HEADER_SIZE; + if (datalen != sizeof(iobj)) + return got_error(GOT_ERR_PRIVSEP_LEN); + memcpy(&iobj, imsg->data, sizeof(iobj)); + memcpy(id.sha1, iobj.id, SHA1_DIGEST_LENGTH); + + err = got_packfile_open_object(&obj, pack, packidx, iobj.idx, &id); if (err) return err; @@ -138,10 +146,22 @@ commit_request(struct imsg *imsg, struct imsgbuf *ibuf obj->size = len; err = got_object_parse_commit(&commit, buf, len); free(buf); + if (err) { + got_object_close(obj); + return err; + } else + commit->obj = obj; /* XXX should be embedded */ + + /* XXX This flushes the pipe, should only fill it instead. */ + err = got_privsep_send_obj(ibuf, commit->obj); + if (err) { + got_object_commit_close(commit); + return err; + } + /* XXX Assumes full imsg buf size, should take obj into + * account when above flush is removed. */ err = got_privsep_send_commit(ibuf, commit); - if (obj) - got_object_close(obj); got_object_commit_close(commit); if (err) { if (err->code == GOT_ERR_PRIVSEP_PIPE)