Download raw body.
move got_opentempfd out of open_blob
On Tue, Jun 28, 2022 at 01:23:33PM +0200, Stefan Sperling wrote: > On Tue, Jun 28, 2022 at 04:36:28AM -0600, Tracey Emery wrote: > > This moves got_opentempfd out of open_blob. All regress passes. There > > are also a couple of white-space removals in here. > > > @@ -3575,8 +3586,12 @@ diff_blobs(struct got_object_id *blob_id1, struct got_ > > err = got_diff_blob(NULL, NULL, blob1, blob2, f1, f2, path, path, > > diff_context, ignore_whitespace, force_text_diff, outfile); > > done: > > + if (fd1 != -1 && close(fd1) != 0 && err == NULL) > > Please check close() == -1 instead of != 0. done > The man page says errno is valid after -1 was returned. > There are more instances of != 0 in this patch which should be adjusted. > > > @@ -4619,12 +4634,16 @@ print_diff(void *arg, unsigned char status, unsigned c > > struct print_diff_arg *a = arg; > > const struct got_error *err = NULL; > > struct got_blob_object *blob1 = NULL; > > - int fd = -1; > > + int fd = -1, fd1 = -1; > > FILE *f1 = NULL, *f2 = NULL; > > char *abspath = NULL, *label1 = NULL; > > struct stat sb; > > off_t size1 = 0; > > > > + fd1 = got_opentempfd(); > > + if (fd1 == -1) > > + return got_error_from_errno("got_opentempfd"); > > + > > if (a->diff_staged) { > > if (staged_status != GOT_STATUS_MODIFY && > > staged_status != GOT_STATUS_ADD && > > Error handling in here does 'return err' and will now leak this open fd. think i got them all. thanks. > > blob - 773169c32d3cb119ac330201afe43d53b115085a > > file + lib/diff.c > > --- lib/diff.c > > +++ lib/diff.c > > @@ -280,18 +280,25 @@ diff_added_blob(struct got_object_id *id, FILE *f, con > > const struct got_error *err; > > struct got_blob_object *blob = NULL; > > struct got_object *obj = NULL; > > + int fd = -1; > > > > + fd = got_opentempfd(); > > + if (fd == -1) > > + return got_error_from_errno("got_opentempfd"); > > + > > err = got_object_open(&obj, repo, id); > > if (err) > > return err; > > Another leak above. > > This brings opentemp() calls back to lib/diff.c, so I guess we'll have > to do more follow-up work here to move them up even further... Yes, I'm aware. This and blame need to be done separately. At least this gets us up one more level. > > @@ -820,13 +872,13 @@ diff_paths(struct got_tree_object *tree1, struct got_t > > type2 == GOT_OBJ_TYPE_BLOB) { > > if (id1) { > > err = got_object_open_as_blob(&blob1, repo, > > - id1, 8192); > > + id1, 8192, fd1); > > if (err) > > goto done; > > } > > if (id2) { > > err = got_object_open_as_blob(&blob2, repo, > > - id2, 8192); > > + id2, 8192, fd2); > > if (err) > > goto done; > > } > > Above code runs in a loop. > Don't we need to call ftruncate() on fd1/fd2 before reusing them? indeed ok, i hope i got it all. i'm going a bit cross-eyed at the moment. :) -- Tracey Emery diff /home/tracey/src/got commit - db0dfdd7e5c2c5a38ed7c3291a0615132bcb5945 path + /home/tracey/src/got blob - 64274b1e95d79a3dbf5649704740d1ec966b24fc file + got/got.c --- got/got.c +++ got/got.c @@ -3548,9 +3548,20 @@ diff_blobs(struct got_object_id *blob_id1, struct got_ const struct got_error *err = NULL; struct got_blob_object *blob1 = NULL, *blob2 = NULL; FILE *f1 = NULL, *f2 = NULL; + int fd1 = -1, fd2 = -1; + fd1 = got_opentempfd(); + if (fd1 == -1) + return got_error_from_errno("got_opentempfd"); + fd2 = got_opentempfd(); + if (fd2 == -1) { + err = got_error_from_errno("got_opentempfd"); + goto done; + } + if (blob_id1) { - err = got_object_open_as_blob(&blob1, repo, blob_id1, 8192); + err = got_object_open_as_blob(&blob1, repo, blob_id1, 8192, + fd1); if (err) goto done; f1 = got_opentemp(); @@ -3560,7 +3571,7 @@ diff_blobs(struct got_object_id *blob_id1, struct got_ } } - err = got_object_open_as_blob(&blob2, repo, blob_id2, 8192); + err = got_object_open_as_blob(&blob2, repo, blob_id2, 8192, fd2); if (err) goto done; @@ -3575,8 +3586,12 @@ diff_blobs(struct got_object_id *blob_id1, struct got_ err = got_diff_blob(NULL, NULL, blob1, blob2, f1, f2, path, path, diff_context, ignore_whitespace, force_text_diff, outfile); done: + if (fd1 != -1 && close(fd1) == -1 && err == NULL) + err = got_error_from_errno("close"); if (blob1) got_object_blob_close(blob1); + if (fd2 != -1 && close(fd2) == -1 && err == NULL) + err = got_error_from_errno("close"); got_object_blob_close(blob2); if (f1 && fclose(f1) == EOF && err == NULL) err = got_error_from_errno("fclose"); @@ -4619,7 +4634,7 @@ print_diff(void *arg, unsigned char status, unsigned c struct print_diff_arg *a = arg; const struct got_error *err = NULL; struct got_blob_object *blob1 = NULL; - int fd = -1; + int fd = -1, fd1 = -1; FILE *f1 = NULL, *f2 = NULL; char *abspath = NULL, *label1 = NULL; struct stat sb; @@ -4684,11 +4699,17 @@ print_diff(void *arg, unsigned char status, unsigned c goto done; } + fd1 = got_opentempfd(); + if (fd1 == -1) { + err = got_error_from_errno("got_opentempfd"); + goto done; + } + if (staged_status == GOT_STATUS_ADD || staged_status == GOT_STATUS_MODIFY) { char *id_str; err = got_object_open_as_blob(&blob1, a->repo, staged_blob_id, - 8192); + 8192, fd1); if (err) goto done; err = got_object_id_str(&id_str, staged_blob_id); @@ -4701,7 +4722,8 @@ print_diff(void *arg, unsigned char status, unsigned c } free(id_str); } else if (status != GOT_STATUS_ADD) { - err = got_object_open_as_blob(&blob1, a->repo, blob_id, 8192); + err = got_object_open_as_blob(&blob1, a->repo, blob_id, 8192, + fd1); if (err) goto done; } @@ -4717,7 +4739,7 @@ print_diff(void *arg, unsigned char status, unsigned c fd = openat(dirfd, de_name, O_RDONLY | O_NOFOLLOW | O_CLOEXEC); if (fd == -1) { - if (!got_err_open_nofollow_on_symlink()) { + if (!got_err_open_nofollow_on_symlink()) { err = got_error_from_errno2("openat", abspath); goto done; @@ -4764,12 +4786,14 @@ print_diff(void *arg, unsigned char status, unsigned c blob1); if (err) goto done; - } + } err = got_diff_blob_file(blob1, f1, size1, label1, f2, sb.st_size, path, a->diff_context, a->ignore_whitespace, a->force_text_diff, stdout); done: + if (fd1 != -1 && close(fd1) == -1 && err == NULL) + err = got_error_from_errno("close"); if (blob1) got_object_blob_close(blob1); if (f1 && fclose(f1) == EOF && err == NULL) @@ -5292,10 +5316,14 @@ cmd_blame(int argc, char *argv[]) struct got_blob_object *blob = NULL; char *commit_id_str = NULL; struct blame_cb_args bca; - int ch, obj_type, i; + int ch, obj_type, i, fd = -1; off_t filesize; int *pack_fds = NULL; + fd = got_opentempfd(); + if (fd == -1) + return got_error_from_errno("got_opentempfd"); + memset(&bca, 0, sizeof(bca)); #ifndef PROFILE @@ -5446,7 +5474,7 @@ cmd_blame(int argc, char *argv[]) goto done; } - error = got_object_open_as_blob(&blob, repo, obj_id, 8192); + error = got_object_open_as_blob(&blob, repo, obj_id, 8192, fd); if (error) goto done; bca.f = got_opentemp(); @@ -5488,6 +5516,8 @@ done: free(obj_id); if (commit) got_object_commit_close(commit); + if (fd != -1 && close(fd) == -1 && error == NULL) + error = got_error_from_errno("close"); if (blob) got_object_blob_close(blob); if (worktree) @@ -12229,13 +12259,22 @@ cat_blob(struct got_object_id *id, struct got_reposito { const struct got_error *err; struct got_blob_object *blob; + int fd = -1; - err = got_object_open_as_blob(&blob, repo, id, 8192); + fd = got_opentempfd(); + if (fd == -1) + return got_error_from_errno("got_opentempfd"); + + err = got_object_open_as_blob(&blob, repo, id, 8192, fd); if (err) - return err; + goto done; err = got_object_blob_dump_to_file(NULL, NULL, NULL, outfile, blob); - got_object_blob_close(blob); +done: + if (fd != -1 && close(fd) == -1 && err == NULL) + err = got_error_from_errno("close"); + if (blob) + got_object_blob_close(blob); return err; } blob - 0a162cbd301d5069ad3612113a16489ad4b7fd87 file + include/got_object.h --- include/got_object.h +++ include/got_object.h @@ -260,7 +260,7 @@ const struct got_error *got_object_tree_path_changed(i * The caller must dispose of the blob with got_object_blob_close(). */ const struct got_error *got_object_open_as_blob(struct got_blob_object **, - struct got_repository *, struct got_object_id *, size_t); + struct got_repository *, struct got_object_id *, size_t, int); /* Dispose of a blob object. */ const struct got_error *got_object_blob_close(struct got_blob_object *); blob - 5e6b96770dafdf895ef7140b2fc28b3d2c8e370b file + lib/blame.c --- lib/blame.c +++ lib/blame.c @@ -204,6 +204,7 @@ blame_commit(struct got_blame *blame, struct got_objec struct got_object_id *pblob_id = NULL; struct got_blob_object *pblob = NULL; struct diff_result *diff_result = NULL; + int fd = -1; err = got_object_open_as_commit(&commit, repo, id); if (err) @@ -215,6 +216,12 @@ blame_commit(struct got_blame *blame, struct got_objec return NULL; } + fd = got_opentempfd(); + if (fd == -1) { + err = got_error_from_errno("got_opentempfd"); + goto done; + } + err = got_object_open_as_commit(&pcommit, repo, &pid->id); if (err) goto done; @@ -226,7 +233,7 @@ blame_commit(struct got_blame *blame, struct got_objec goto done; } - err = got_object_open_as_blob(&pblob, repo, pblob_id, 8192); + err = got_object_open_as_blob(&pblob, repo, pblob_id, 8192, fd); if (err) goto done; @@ -273,6 +280,8 @@ done: if (pcommit) got_object_commit_close(pcommit); free(pblob_id); + if (fd != -1 && close(fd) == -1 && err == NULL) + err = got_error_from_errno("close"); if (pblob) got_object_blob_close(pblob); return err; @@ -507,9 +516,13 @@ blame_open(struct got_blame **blamep, const char *path struct got_blob_object *blob = NULL; struct got_blame *blame = NULL; struct got_object_id *id = NULL; - int lineno; + int lineno, fd = -1; struct got_commit_graph *graph = NULL; + fd = got_opentempfd(); + if (fd == -1) + return got_error_from_errno("got_opentempfd"); + *blamep = NULL; err = got_object_open_as_commit(&start_commit, repo, start_commit_id); @@ -520,7 +533,7 @@ blame_open(struct got_blame **blamep, const char *path if (err) goto done; - err = got_object_open_as_blob(&blob, repo, obj_id, 8192); + err = got_object_open_as_blob(&blob, repo, obj_id, 8192, fd); if (err) goto done; @@ -632,6 +645,8 @@ done: if (graph) got_commit_graph_close(graph); free(obj_id); + if (fd != -1 && close(fd) == -1 && err == NULL) + err = got_error_from_errno("close"); if (blob) got_object_blob_close(blob); if (start_commit) blob - 773169c32d3cb119ac330201afe43d53b115085a file + lib/diff.c --- lib/diff.c +++ lib/diff.c @@ -280,18 +280,27 @@ diff_added_blob(struct got_object_id *id, FILE *f, con const struct got_error *err; struct got_blob_object *blob = NULL; struct got_object *obj = NULL; + int fd = -1; err = got_object_open(&obj, repo, id); if (err) return err; - err = got_object_blob_open(&blob, repo, obj, 8192); + fd = got_opentempfd(); + if (fd == -1) { + err = got_error_from_errno("got_opentempfd"); + goto done; + } + + err = got_object_blob_open(&blob, repo, obj, 8192, fd); if (err) goto done; err = cb(cb_arg, NULL, blob, NULL, f, NULL, id, NULL, label, 0, mode, repo); done: got_object_close(obj); + if (fd != -1 && close(fd) == -1 && err == NULL) + err = got_error_from_errno("close"); if (blob) got_object_blob_close(blob); return err; @@ -308,10 +317,23 @@ diff_modified_blob(struct got_object_id *id1, struct g struct got_object *obj2 = NULL; struct got_blob_object *blob1 = NULL; struct got_blob_object *blob2 = NULL; + int fd1 = -1, fd2 = -1; err = got_object_open(&obj1, repo, id1); if (err) return err; + + fd1 = got_opentempfd(); + if (fd1 == -1) { + err = got_error_from_errno("got_opentempfd"); + goto done; + } + fd2 = got_opentempfd(); + if (fd2 == -1) { + err = got_error_from_errno("got_opentempfd"); + goto done; + } + if (obj1->type != GOT_OBJ_TYPE_BLOB) { err = got_error(GOT_ERR_OBJ_TYPE); goto done; @@ -325,11 +347,11 @@ diff_modified_blob(struct got_object_id *id1, struct g goto done; } - err = got_object_blob_open(&blob1, repo, obj1, 8192); + err = got_object_blob_open(&blob1, repo, obj1, 8192, fd1); if (err) goto done; - err = got_object_blob_open(&blob2, repo, obj2, 8192); + err = got_object_blob_open(&blob2, repo, obj2, 8192, fd2); if (err) goto done; @@ -340,8 +362,12 @@ done: got_object_close(obj1); if (obj2) got_object_close(obj2); + if (fd1 != -1 && close(fd1) == -1 && err == NULL) + err = got_error_from_errno("close"); if (blob1) got_object_blob_close(blob1); + if (fd2 != -1 && close(fd2) == -1 && err == NULL) + err = got_error_from_errno("close"); if (blob2) got_object_blob_close(blob2); return err; @@ -354,18 +380,25 @@ diff_deleted_blob(struct got_object_id *id, FILE *f, c const struct got_error *err; struct got_blob_object *blob = NULL; struct got_object *obj = NULL; + int fd = -1; + fd = got_opentempfd(); + if (fd == -1) + return got_error_from_errno("got_opentempfd"); + err = got_object_open(&obj, repo, id); if (err) return err; - err = got_object_blob_open(&blob, repo, obj, 8192); + err = got_object_blob_open(&blob, repo, obj, 8192, fd); if (err) goto done; err = cb(cb_arg, blob, NULL, f, NULL, id, NULL, label, NULL, mode, 0, repo); done: got_object_close(obj); + if (fd != -1 && close(fd) == -1 && err == NULL) + err = got_error_from_errno("close"); if (blob) got_object_blob_close(blob); return err; @@ -723,17 +756,27 @@ got_diff_objects_as_blobs(off_t **line_offsets, size_t { const struct got_error *err; struct got_blob_object *blob1 = NULL, *blob2 = NULL; + int fd1 = -1, fd2 = -1; if (id1 == NULL && id2 == NULL) return got_error(GOT_ERR_NO_OBJ); + fd1 = got_opentempfd(); + if (fd1 == -1) + return got_error_from_errno("got_opentempfd"); + fd2 = got_opentempfd(); + if (fd2 == -1) { + err = got_error_from_errno("got_opentempfd"); + goto done; + } + if (id1) { - err = got_object_open_as_blob(&blob1, repo, id1, 8192); + err = got_object_open_as_blob(&blob1, repo, id1, 8192, fd1); if (err) goto done; } if (id2) { - err = got_object_open_as_blob(&blob2, repo, id2, 8192); + err = got_object_open_as_blob(&blob2, repo, id2, 8192, fd2); if (err) goto done; } @@ -741,8 +784,12 @@ got_diff_objects_as_blobs(off_t **line_offsets, size_t label1, label2, diff_context, ignore_whitespace, force_text_diff, outfile); done: + if (fd1 != -1 && close(fd1) == -1 && err == NULL) + err = got_error_from_errno("close"); if (blob1) got_object_blob_close(blob1); + if (fd2 != -1 && close(fd2) == -1 && err == NULL) + err = got_error_from_errno("close"); if (blob2) got_object_blob_close(blob2); return err; @@ -758,7 +805,16 @@ diff_paths(struct got_tree_object *tree1, struct got_t struct got_object_id *id1 = NULL, *id2 = NULL; struct got_tree_object *subtree1 = NULL, *subtree2 = NULL; struct got_blob_object *blob1 = NULL, *blob2 = NULL; + int fd1 = -1, fd2 = -1; + fd1 = got_opentempfd(); + if (fd1 == -1) + return got_error_from_errno("got_opentempfd"); + fd2 = got_opentempfd(); + if (fd2 == -1) { + err = got_error_from_errno("got_opentempfd"); + goto done; + } TAILQ_FOREACH(pe, paths, entry) { int type1 = GOT_OBJ_TYPE_ANY, type2 = GOT_OBJ_TYPE_ANY; mode_t mode1 = 0, mode2 = 0; @@ -820,13 +876,13 @@ diff_paths(struct got_tree_object *tree1, struct got_t type2 == GOT_OBJ_TYPE_BLOB) { if (id1) { err = got_object_open_as_blob(&blob1, repo, - id1, 8192); + id1, 8192, fd1); if (err) goto done; } if (id2) { err = got_object_open_as_blob(&blob2, repo, - id2, 8192); + id2, 8192, fd2); if (err) goto done; } @@ -860,6 +916,10 @@ diff_paths(struct got_tree_object *tree1, struct got_t err = got_error(GOT_ERR_OBJ_TYPE); goto done; } + if (ftruncate(fd1, 0L) == -1) + return got_error_from_errno("ftruncate"); + if (ftruncate(fd2, 0L) == -1) + return got_error_from_errno("ftruncate"); } done: free(id1); @@ -868,8 +928,12 @@ done: got_object_tree_close(subtree1); if (subtree2) got_object_tree_close(subtree2); + if (fd1 != -1 && close(fd1) == -1 && err == NULL) + err = got_error_from_errno("close"); if (blob1) got_object_blob_close(blob1); + if (fd2 != -1 && close(fd2) == -1 && err == NULL) + err = got_error_from_errno("close"); if (blob2) got_object_blob_close(blob2); return err; blob - 58f6ea9d97872411048d72595be2da70a1bb58ae file + lib/got_lib_object.h --- lib/got_lib_object.h +++ lib/got_lib_object.h @@ -123,7 +123,7 @@ const struct got_error *got_object_commit_open(struct const struct got_error *got_object_tree_open(struct got_tree_object **, struct got_repository *, struct got_object *); const struct got_error *got_object_blob_open(struct got_blob_object **, - struct got_repository *, struct got_object *, size_t); + struct got_repository *, struct got_object *, size_t, int); char *got_object_blob_id_str(struct got_blob_object*, char *, size_t); const struct got_error *got_object_tag_open(struct got_tag_object **, struct got_repository *, struct got_object *); blob - 06dc960b0d46db574b800f47ce6891fc926fa989 file + lib/object.c --- lib/object.c +++ lib/object.c @@ -1160,19 +1160,30 @@ got_tree_entry_get_symlink_target(char **link_target, { const struct got_error *err = NULL; struct got_blob_object *blob = NULL; + int fd = -1; *link_target = NULL; if (!got_object_tree_entry_is_symlink(te)) return got_error(GOT_ERR_TREE_ENTRY_TYPE); + fd = got_opentempfd(); + if (fd == -1) { + err = got_error_from_errno("got_opentempfd"); + goto done; + } + err = got_object_open_as_blob(&blob, repo, - got_tree_entry_get_id(te), PATH_MAX); + got_tree_entry_get_id(te), PATH_MAX, fd); if (err) - return err; + goto done; err = got_object_blob_read_to_str(link_target, blob); - got_object_blob_close(blob); +done: + if (fd != -1 && close(fd) == -1 && err == NULL) + err = got_error_from_errno("close"); + if (blob) + got_object_blob_close(blob); if (err) { free(*link_target); *link_target = NULL; @@ -1337,14 +1348,13 @@ read_blob_privsep(uint8_t **outbuf, size_t *size, size static const struct got_error * open_blob(struct got_blob_object **blob, struct got_repository *repo, - struct got_object_id *id, size_t blocksize) + struct got_object_id *id, size_t blocksize, int outfd) { const struct got_error *err = NULL; struct got_packidx *packidx = NULL; int idx; char *path_packfile = NULL; uint8_t *outbuf; - int outfd; size_t size, hdrlen; struct stat sb; @@ -1352,10 +1362,6 @@ open_blob(struct got_blob_object **blob, struct got_re if (*blob == NULL) return got_error_from_errno("calloc"); - outfd = got_opentempfd(); - if (outfd == -1) - return got_error_from_errno("got_opentempfd"); - (*blob)->read_buf = malloc(blocksize); if ((*blob)->read_buf == NULL) { err = got_error_from_errno("malloc"); @@ -1398,9 +1404,6 @@ open_blob(struct got_blob_object **blob, struct got_re } if (outbuf) { - if (close(outfd) == -1 && err == NULL) - err = got_error_from_errno("close"); - outfd = -1; (*blob)->f = fmemopen(outbuf, size, "rb"); if ((*blob)->f == NULL) { err = got_error_from_errno("fmemopen"); @@ -1438,25 +1441,25 @@ done: if (*blob) { got_object_blob_close(*blob); *blob = NULL; - } else if (outfd != -1) - close(outfd); + } } return err; } const struct got_error * got_object_open_as_blob(struct got_blob_object **blob, - struct got_repository *repo, struct got_object_id *id, - size_t blocksize) + struct got_repository *repo, struct got_object_id *id, size_t blocksize, + int outfd) { - return open_blob(blob, repo, id, blocksize); + return open_blob(blob, repo, id, blocksize, outfd); } const struct got_error * got_object_blob_open(struct got_blob_object **blob, - struct got_repository *repo, struct got_object *obj, size_t blocksize) + struct got_repository *repo, struct got_object *obj, size_t blocksize, + int outfd) { - return open_blob(blob, repo, got_object_get_id(obj), blocksize); + return open_blob(blob, repo, got_object_get_id(obj), blocksize, outfd); } const struct got_error * blob - 1bc4c535c2483d8ebfffd91a5553da6d6da60ce8 file + lib/patch.c --- lib/patch.c +++ lib/patch.c @@ -588,6 +588,7 @@ open_blob(char **path, FILE **fp, const char *blobid, const struct got_error *err = NULL; struct got_blob_object *blob = NULL; struct got_object_id id, *idptr, *matched_id = NULL; + int fd = -1; *fp = NULL; *path = NULL; @@ -605,7 +606,13 @@ open_blob(char **path, FILE **fp, const char *blobid, idptr = &id; } - err = got_object_open_as_blob(&blob, repo, idptr, 8192); + fd = got_opentempfd(); + if (fd == -1) { + err = got_error_from_errno("got_opentempfd"); + goto done; + } + + err = got_object_open_as_blob(&blob, repo, idptr, 8192, fd); if (err) goto done; @@ -618,6 +625,8 @@ open_blob(char **path, FILE **fp, const char *blobid, goto done; done: + if (fd != -1 && close(fd) == -1 && err == NULL) + err = got_error_from_errno("close"); if (blob) got_object_blob_close(blob); if (matched_id != NULL) blob - ae1ce6d136c77ab98e72f28c8a75c47893044c9b file + lib/worktree.c --- lib/worktree.c +++ lib/worktree.c @@ -1629,7 +1629,7 @@ get_file_status(unsigned char *status, struct stat *sb const struct got_error *err = NULL; struct got_object_id id; size_t hdrlen; - int fd = -1; + int fd = -1, fd1 = -1; FILE *f = NULL; uint8_t fbuf[8192]; struct got_blob_object *blob = NULL; @@ -1706,7 +1706,12 @@ get_file_status(unsigned char *status, struct stat *sb else memcpy(id.sha1, ie->blob_sha1, sizeof(id.sha1)); - err = got_object_open_as_blob(&blob, repo, &id, sizeof(fbuf)); + fd1 = got_opentempfd(); + if (fd1 == -1) { + err = got_error_from_errno("got_opentempfd"); + goto done; + } + err = got_object_open_as_blob(&blob, repo, &id, sizeof(fbuf), fd1); if (err) goto done; @@ -1769,6 +1774,8 @@ get_file_status(unsigned char *status, struct stat *sb } else if (xbit_differs(ie, sb->st_mode)) *status = GOT_STATUS_MODE_CHANGE; done: + if (fd1 != -1 && close(fd1) == -1 && err == NULL) + err = got_error_from_errno("close"); if (blob) got_object_blob_close(blob); if (f != NULL && fclose(f) == EOF && err == NULL) @@ -1802,9 +1809,10 @@ update_blob(struct got_worktree *worktree, { const struct got_error *err = NULL; struct got_blob_object *blob = NULL; - char *ondisk_path; + char *ondisk_path = NULL; unsigned char status = GOT_STATUS_NO_CHANGE; struct stat sb; + int fd1 = -1, fd2 = -1; if (asprintf(&ondisk_path, "%s/%s", worktree->root_path, path) == -1) return got_error_from_errno("asprintf"); @@ -1886,7 +1894,12 @@ update_blob(struct got_worktree *worktree, } } - err = got_object_open_as_blob(&blob, repo, &te->id, 8192); + fd1 = got_opentempfd(); + if (fd1 == -1) { + err = got_error_from_errno("got_opentempfd"); + goto done; + } + err = got_object_open_as_blob(&blob, repo, &te->id, 8192, fd1); if (err) goto done; @@ -1895,9 +1908,15 @@ update_blob(struct got_worktree *worktree, struct got_blob_object *blob2 = NULL; char *label_orig = NULL; if (got_fileindex_entry_has_blob(ie)) { + fd2 = got_opentempfd(); + if (fd2 == -1) { + err = got_error_from_errno("got_opentempfd"); + goto done; + } struct got_object_id id2; memcpy(id2.sha1, ie->blob_sha1, SHA1_DIGEST_LENGTH); - err = got_object_open_as_blob(&blob2, repo, &id2, 8192); + err = got_object_open_as_blob(&blob2, repo, &id2, 8192, + fd2); if (err) goto done; } @@ -1931,6 +1950,10 @@ update_blob(struct got_worktree *worktree, progress_cb, progress_arg); } free(label_orig); + if (fd2 != -1 && close(fd2) == -1 && err == NULL) { + err = got_error_from_errno("close"); + goto done; + } if (blob2) got_object_blob_close(blob2); if (err) @@ -1989,6 +2012,11 @@ update_blob(struct got_worktree *worktree, GOT_FILEIDX_MODE_BAD_SYMLINK); } } + + if (fd1 != -1 && close(fd1) == -1 && err == NULL) { + err = got_error_from_errno("close"); + goto done; + } got_object_blob_close(blob); done: free(ondisk_path); @@ -4405,7 +4433,7 @@ create_patched_content(char **path_outfile, int revers const struct got_error *err, *free_err; struct got_blob_object *blob = NULL; FILE *f1 = NULL, *f2 = NULL, *outfile = NULL; - int fd2 = -1; + int fd = -1, fd2 = -1; char link_target[PATH_MAX]; ssize_t link_len = 0; char *path1 = NULL, *id_str = NULL; @@ -4483,7 +4511,13 @@ create_patched_content(char **path_outfile, int revers rewind(f2); } - err = got_object_open_as_blob(&blob, repo, blob_id, 8192); + fd = got_opentempfd(); + if (fd == -1) { + err = got_error_from_errno("got_opentempfd"); + goto done; + } + + err = got_object_open_as_blob(&blob, repo, blob_id, 8192, fd); if (err) goto done; @@ -4547,6 +4581,8 @@ create_patched_content(char **path_outfile, int revers } done: free(id_str); + if (fd != -1 && close(fd) == -1 && err == NULL) + err = got_error_from_errno("close"); if (blob) got_object_blob_close(blob); free_err = got_diffreg_result_free(diffreg_result); @@ -4589,6 +4625,7 @@ revert_file(void *arg, unsigned char status, unsigned char *tree_path = NULL, *te_name; char *ondisk_path = NULL, *path_content = NULL; struct got_blob_object *blob = NULL; + int fd = -1; /* Reverting a staged deletion is a no-op. */ if (status == GOT_STATUS_DELETE && @@ -4718,7 +4755,13 @@ revert_file(void *arg, unsigned char status, unsigned } else memcpy(id.sha1, ie->blob_sha1, SHA1_DIGEST_LENGTH); - err = got_object_open_as_blob(&blob, a->repo, &id, 8192); + fd = got_opentempfd(); + if (fd == -1) { + err = got_error_from_errno("got_opentempfd"); + goto done; + } + + err = got_object_open_as_blob(&blob, a->repo, &id, 8192, fd); if (err) goto done; @@ -4794,6 +4837,8 @@ done: free(path_content); free(parent_path); free(tree_path); + if (fd != -1 && close(fd) == -1 && err == NULL) + err = got_error_from_errno("close"); if (blob) got_object_blob_close(blob); if (tree) @@ -8254,6 +8299,7 @@ create_unstaged_content(char **path_unstaged_content, struct got_diffreg_result *diffreg_result = NULL; int line_cur1 = 1, line_cur2 = 1, n = 0, nchunks_used = 0; int have_content = 0, have_rejected_content = 0, i = 0, nchanges = 0; + int fd1 = -1, fd2 = -1; *path_unstaged_content = NULL; *path_new_staged_content = NULL; @@ -8261,7 +8307,19 @@ create_unstaged_content(char **path_unstaged_content, err = got_object_id_str(&label1, blob_id); if (err) return err; - err = got_object_open_as_blob(&blob, repo, blob_id, 8192); + + fd1 = got_opentempfd(); + if (fd1 == -1) { + err = got_error_from_errno("got_opentempfd"); + goto done; + } + fd2 = got_opentempfd(); + if (fd2 == -1) { + err = got_error_from_errno("got_opentempfd"); + goto done; + } + + err = got_object_open_as_blob(&blob, repo, blob_id, 8192, fd1); if (err) goto done; @@ -8273,7 +8331,8 @@ create_unstaged_content(char **path_unstaged_content, if (err) goto done; - err = got_object_open_as_blob(&staged_blob, repo, staged_blob_id, 8192); + err = got_object_open_as_blob(&staged_blob, repo, staged_blob_id, 8192, + fd2); if (err) goto done; @@ -8309,7 +8368,7 @@ create_unstaged_content(char **path_unstaged_content, } /* Count the number of actual changes in the diff result. */ for (n = 0; n < diffreg_result->result->chunks.len; n += nchunks_used) { - struct diff_chunk_context cc = {}; + struct diff_chunk_context cc = {}; diff_chunk_context_load_change(&cc, &nchunks_used, diffreg_result->result, n, 0); nchanges++; @@ -8334,8 +8393,12 @@ create_unstaged_content(char **path_unstaged_content, outfile, rejectfile); done: free(label1); + if (fd1 != -1 && close(fd1) == -1 && err == NULL) + err = got_error_from_errno("close"); if (blob) got_object_blob_close(blob); + if (fd2 != -1 && close(fd2) == -1 && err == NULL) + err = got_error_from_errno("close"); if (staged_blob) got_object_blob_close(staged_blob); free_err = got_diffreg_result_free(diffreg_result); @@ -8537,6 +8600,7 @@ unstage_path(void *arg, unsigned char status, char *id_str = NULL, *label_orig = NULL; int local_changes_subsumed; struct stat sb; + int fd1 = -1, fd2 = -1; if (staged_status != GOT_STATUS_ADD && staged_status != GOT_STATUS_MODIFY && @@ -8561,10 +8625,21 @@ unstage_path(void *arg, unsigned char status, goto done; } + fd1 = got_opentempfd(); + if (fd1 == -1) { + err = got_error_from_errno("got_opentempfd"); + goto done; + } + fd2 = got_opentempfd(); + if (fd2 == -1) { + err = got_error_from_errno("got_opentempfd"); + goto done; + } + switch (staged_status) { case GOT_STATUS_MODIFY: err = got_object_open_as_blob(&blob_base, a->repo, - blob_id, 8192); + blob_id, 8192, fd1); if (err) break; /* fall through */ @@ -8588,7 +8663,7 @@ unstage_path(void *arg, unsigned char status, } } err = got_object_open_as_blob(&blob_staged, a->repo, - staged_blob_id, 8192); + staged_blob_id, 8192, fd2); if (err) break; switch (got_fileindex_entry_staged_filetype_get(ie)) { @@ -8659,8 +8734,12 @@ unstage_path(void *arg, unsigned char status, } done: free(ondisk_path); + if (fd1 != -1 && close(fd1) == -1 && err == NULL) + err = got_error_from_errno("close"); if (blob_base) got_object_blob_close(blob_base); + if (fd2 != -1 && close(fd2) == -1 && err == NULL) + err = got_error_from_errno("close"); if (blob_staged) got_object_blob_close(blob_staged); free(id_str);
move got_opentempfd out of open_blob