commit - 1b484788fec38ce9936267c176e77f653d749b8d
commit + f9d376997dd2e84bf84c3c9a4da842d1b5565e9d
blob - 69e5ee6dd5a6df3bf8e940c5cf259a8fea557966
blob + 6332563c1a68c343f8f860c77299ff6dbe5f18f3
--- got/got.c
+++ got/got.c
struct got_tree_object *tree1 = NULL, *tree2 = NULL;
struct got_diff_blob_output_unidiff_arg arg;
FILE *f1 = NULL, *f2 = NULL;
+ int fd1 = -1, fd2 = -1;
if (tree_id1) {
err = got_object_open_as_tree(&tree1, repo, tree_id1);
f1 = got_opentemp();
if (f1 == NULL) {
err = got_error_from_errno("got_opentemp");
+ goto done;
+ }
+
+ fd1 = got_opentempfd();
+ if (fd1 == -1) {
+ err = got_error_from_errno("got_opentempfd");
goto done;
}
}
err = got_error_from_errno("got_opentemp");
goto done;
}
-
+ fd2 = got_opentempfd();
+ if (fd2 == -1) {
+ err = got_error_from_errno("got_opentempfd");
+ goto done;
+ }
arg.diff_context = diff_context;
arg.ignore_whitespace = ignore_whitespace;
arg.force_text_diff = force_text_diff;
arg.nlines = 0;
while (path[0] == '/')
path++;
- err = got_diff_tree(tree1, tree2, f1, f2, path, path, repo,
+ err = got_diff_tree(tree1, tree2, f1, f2, fd1, fd2, path, path, repo,
got_diff_blob_output_unidiff, &arg, 1);
done:
if (tree1)
err = got_error_from_errno("fclose");
if (f2 && fclose(f2) == EOF && err == NULL)
err = got_error_from_errno("fclose");
+ if (fd1 != -1 && close(fd1) == -1 && err == NULL)
+ err = got_error_from_errno("close");
+ if (fd2 != -1 && close(fd2) == -1 && err == NULL)
+ err = got_error_from_errno("close");
return err;
}
if (err)
goto done;
- err = got_diff_tree(tree1, tree2, NULL, NULL, "", "", repo,
+ err = got_diff_tree(tree1, tree2, NULL, NULL, -1, -1, "", "", repo,
got_diff_tree_collect_changed_paths, paths, 0);
done:
if (tree1)
struct print_diff_arg *a = arg;
const struct got_error *err = NULL;
struct got_blob_object *blob1 = NULL;
- int fd = -1, fd1 = -1;
+ int fd = -1, fd1 = -1, fd2 = -1;
FILE *f1 = NULL, *f2 = NULL;
char *abspath = NULL, *label1 = NULL;
struct stat sb;
err = got_error_from_errno("got_opentemp");
goto done;
}
- err = got_diff_objects_as_blobs(NULL, NULL, f1, f2,
+ 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_diff_objects_as_blobs(NULL, NULL, f1, f2, fd1, fd2,
blob_id, staged_blob_id, label1, label2, a->diff_context,
a->ignore_whitespace, a->force_text_diff, a->repo, stdout);
goto done;
done:
if (fd1 != -1 && close(fd1) == -1 && err == NULL)
err = got_error_from_errno("close");
+ if (fd2 != -1 && close(fd2) == -1 && err == NULL)
+ err = got_error_from_errno("close");
if (blob1)
got_object_blob_close(blob1);
if (f1 && fclose(f1) == EOF && err == NULL)
struct got_pathlist_head paths;
struct got_pathlist_entry *pe;
FILE *f1 = NULL, *f2 = NULL;
+ int fd1 = -1, fd2 = -1;
int *pack_fds = NULL;
TAILQ_INIT(&refs);
goto done;
}
+ fd1 = got_opentempfd();
+ if (fd1 == -1) {
+ error = got_error_from_errno("got_opentempfd");
+ goto done;
+ }
+
+ fd2 = got_opentempfd();
+ if (fd2 == -1) {
+ error = got_error_from_errno("got_opentempfd");
+ goto done;
+ }
+
switch (type1 == GOT_OBJ_TYPE_ANY ? type2 : type1) {
case GOT_OBJ_TYPE_BLOB:
error = got_diff_objects_as_blobs(NULL, NULL, f1, f2,
- ids[0], ids[1], NULL, NULL, diff_context,
+ fd1, fd2, ids[0], ids[1], NULL, NULL, diff_context,
ignore_whitespace, force_text_diff, repo, stdout);
break;
case GOT_OBJ_TYPE_TREE:
- error = got_diff_objects_as_trees(NULL, NULL, f1, f2,
+ error = got_diff_objects_as_trees(NULL, NULL, f1, f2, fd1, fd2,
ids[0], ids[1], &paths, "", "", diff_context,
ignore_whitespace, force_text_diff, repo, stdout);
break;
case GOT_OBJ_TYPE_COMMIT:
printf("diff %s %s\n", labels[0], labels[1]);
error = got_diff_objects_as_commits(NULL, NULL, f1, f2,
- ids[0], ids[1], &paths, diff_context, ignore_whitespace,
- force_text_diff, repo, stdout);
+ fd1, fd2, ids[0], ids[1], &paths, diff_context,
+ ignore_whitespace, force_text_diff, repo, stdout);
break;
default:
error = got_error(GOT_ERR_OBJ_TYPE);
error = got_error_from_errno("fclose");
if (f2 && fclose(f2) == EOF && error == NULL)
error = got_error_from_errno("fclose");
+ if (fd1 != -1 && close(fd1) == -1 && error == NULL)
+ error = got_error_from_errno("close");
+ if (fd2 != -1 && close(fd2) == -1 && error == NULL)
+ error = got_error_from_errno("close");
return error;
}
cpp_arg.path_prefix++;
cpp_arg.len = strlen(cpp_arg.path_prefix);
cpp_arg.errcode = errcode;
- err = got_diff_tree(tree1, tree2, NULL, NULL, "", "", repo,
+ err = got_diff_tree(tree1, tree2, NULL, NULL, -1, -1, "", "", repo,
check_path_prefix_in_diff, &cpp_arg, 0);
done:
if (tree1)
blob - bfc88e3dd1798a85fee5a3c83f0c80d976b6a896
blob + eb1c8f8f3ddec6a14375a8af819bc150fecf1abc
--- gotweb/gotweb.c
+++ gotweb/gotweb.c
{
const struct got_error *error;
FILE *f = NULL, *f1 = NULL, *f2 = NULL;
+ int fd1 = -1, fd2 = -1;
struct got_object_id *id1 = NULL, *id2 = NULL;
char *label1 = NULL, *label2 = NULL, *line = NULL;
int obj_type;
goto done;
}
+ fd1 = got_opentempfd();
+ if (fd1 == -1) {
+ error = got_error_from_errno("got_opentempfd");
+ goto done;
+ }
+
+ fd2 = got_opentempfd();
+ if (fd2 == -1) {
+ error = got_error_from_errno("got_opentempfd");
+ goto done;
+ }
+
if (header->parent_id != NULL &&
strncmp(header->parent_id, "/dev/null", 9) != 0) {
error = got_repo_match_object_id(&id1, &label1,
switch (obj_type) {
case GOT_OBJ_TYPE_BLOB:
error = got_diff_objects_as_blobs(NULL, NULL, f1, f2,
- id1, id2, NULL, NULL, 3, 0, 0, gw_trans->repo, f);
+ fd1, fd2, id1, id2, NULL, NULL, 3, 0, 0,
+ gw_trans->repo, f);
break;
case GOT_OBJ_TYPE_TREE:
error = got_diff_objects_as_trees(NULL, NULL, f1, f2,
- id1, id2, NULL, "", "", 3, 0, 0, gw_trans->repo, f);
+ fd1, fd2, id1, id2, NULL, "", "", 3, 0, 0,
+ gw_trans->repo, f);
break;
case GOT_OBJ_TYPE_COMMIT:
error = got_diff_objects_as_commits(NULL, NULL, f1, f2,
- id1, id2, NULL, 3, 0, 0, gw_trans->repo, f);
+ fd1, fd2, id1, id2, NULL, 3, 0, 0, gw_trans->repo, f);
break;
default:
error = got_error(GOT_ERR_OBJ_TYPE);
error = got_error_from_errno("fclose");
if (f2 && fclose(f2) == EOF && error == NULL)
error = got_error_from_errno("fclose");
+ if (fd1 != -1 && close(fd1) == -1 && error == NULL)
+ error = got_error_from_errno("close");
+ if (fd2 != -1 && close(fd2) == -1 && error == NULL)
+ error = got_error_from_errno("close");
free(line);
free(label1);
free(label2);
blob - 4f537113e196997bfae7b568a9d90ab8fe9e77b0
blob + c587513f34441a66ffd34aa5788327dc50f06c7d
--- include/got_diff.h
+++ include/got_diff.h
* Diffing of blob content can be suppressed by passing zero for the
* 'diff_content' parameter. The callback will then only receive blob
* object IDs and diff labels, but NULL pointers instead of blob objects.
- * If 'diff_content' is set, two open temporary files must be provided
- * for internal use; these files can be obtained from got_opentemp()
+ * If 'diff_content' is set, two open temporary FILEs and two open
+ * temporary file descriptors must be provided for internal use; these
+ * files can be obtained from got_opentemp() and got_opentempfd(),
* and must be closed by the caller. Otherwise the files can be NULL.
* The set of arguments relating to either tree may be NULL to indicate
* that no content is present on its respective side of the diff.
*/
const struct got_error *got_diff_tree(struct got_tree_object *,
- struct got_tree_object *, FILE *, FILE *, const char *, const char *,
+ struct got_tree_object *, FILE *, FILE *, int, int,
+ const char *, const char *,
struct got_repository *, got_diff_blob_cb cb, void *cb_arg, int);
/*
* Diff two objects, assuming both objects are blobs. Two const char * diff
* header labels may be provided which will be used to identify each blob in
* the diff output. If a label is NULL, use the blob's SHA1 checksum instead.
- * Two open temporary files must be provided for internal use; these files
- * can be obtained from got_opentemp() and must be closed by the caller.
- * The set of arguments relating to either blob may be NULL to indicate
+ * Two open temporary files and two temporary file descriptors must be
+ * provided for internal use; these files can be obtained from
+ * got_opentemp() and got_opentempfd(), and must be closed by the caller.
+ * The set of arguments relating to either blob may be NULL/-1 to indicate
* that no content is present on its respective side of the diff.
* The number of context lines to show in the diff must be specified as well.
* Write unified diff text to the provided output FILE.
* array of line offsets for, and the number of lines in, the unidiff text.
*/
const struct got_error *got_diff_objects_as_blobs(off_t **, size_t *,
- FILE *, FILE *, struct got_object_id *, struct got_object_id *,
+ FILE *, FILE *, int, int, struct got_object_id *, struct got_object_id *,
const char *, const char *, int, int, int,
struct got_repository *, FILE *);
* header labels may be provided which will be used to identify each blob in
* the trees. If a label is NULL, use the blob's SHA1 checksum instead.
* The number of context lines to show in diffs must be specified.
- * Two open temporary files must be provided for internal use; these files
- * can be obtained from got_opentemp() and must be closed by the caller.
+ * Two open temporary files and two temporary file descriptors must be
+ * provided for internal use; these files can be obtained from
+ * got_opentemp() and got_opentempfd(), and must be closed by the caller.
+ * If 'diff_content' is not set, the files may be NULL / -1.
* The set of arguments relating to either tree may be NULL to indicate
* that no content is present on its respective side of the diff.
* Write unified diff text to the provided output FILE.
* array of line offsets for, and the number of lines in, the unidiff text.
*/
const struct got_error *got_diff_objects_as_trees(off_t **, size_t *,
- FILE *, FILE *, struct got_object_id *, struct got_object_id *,
+ FILE *, FILE *, int, int, struct got_object_id *, struct got_object_id *,
struct got_pathlist_head *, const char *, const char *, int, int, int,
struct got_repository *, FILE *);
/*
* Diff two objects, assuming both objects are commits.
* The number of context lines to show in diffs must be specified.
- * Two open temporary files must be provided for internal use; these files
- * can be obtained from got_opentemp() and must be closed by the caller.
+ * Two open temporary files and two temporary file descriptors must be
+ * provided for internal use; these files can be obtained from
+ * got_opentemp() and got_opentempfd(), and must be closed by the caller.
* The set of arguments relating to either commit may be NULL to indicate
* that no content is present on its respective side of the diff.
* Write unified diff text to the provided output FILE.
* array of line offsets for, and the number of lines in, the unidiff text.
*/
const struct got_error *got_diff_objects_as_commits(off_t **, size_t *,
- FILE *, FILE *, struct got_object_id *, struct got_object_id *,
+ FILE *, FILE *, int, int, struct got_object_id *, struct got_object_id *,
struct got_pathlist_head *, int, int, int, struct got_repository *, FILE *);
#define GOT_DIFF_MAX_CONTEXT 64
blob - 7bc3ad07ee796048b5285aabebb4e367fe9de9d5
blob + 13a1b0bf323c1c003dbb7b2473b2d1a20c202a43
--- lib/diff.c
+++ lib/diff.c
}
static const struct got_error *
-diff_added_blob(struct got_object_id *id, FILE *f, const char *label,
- mode_t mode, struct got_repository *repo,
+diff_added_blob(struct got_object_id *id, FILE *f, int fd,
+ const char *label, mode_t mode, struct got_repository *repo,
got_diff_blob_cb cb, void *cb_arg)
{
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;
- 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;
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;
static const struct got_error *
diff_modified_blob(struct got_object_id *id1, struct got_object_id *id2,
- FILE *f1, FILE *f2, const char *label1, const char *label2,
+ FILE *f1, FILE *f2, int fd1, int fd2,
+ const char *label1, const char *label2,
mode_t mode1, mode_t mode2, struct got_repository *repo,
got_diff_blob_cb cb, void *cb_arg)
{
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;
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;
}
static const struct got_error *
-diff_deleted_blob(struct got_object_id *id, FILE *f, const char *label,
- mode_t mode, struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg)
+diff_deleted_blob(struct got_object_id *id, FILE *f, int fd,
+ const char *label, mode_t mode, struct got_repository *repo,
+ got_diff_blob_cb cb, void *cb_arg)
{
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;
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;
}
static const struct got_error *
-diff_added_tree(struct got_object_id *id, FILE *f, const char *label,
+diff_added_tree(struct got_object_id *id, FILE *f, int fd, const char *label,
struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg,
int diff_content)
{
if (err)
goto done;
- err = got_diff_tree(NULL, tree, NULL, f, NULL, label,
+ err = got_diff_tree(NULL, tree, NULL, f, -1, fd, NULL, label,
repo, cb, cb_arg, diff_content);
done:
if (tree)
static const struct got_error *
diff_modified_tree(struct got_object_id *id1, struct got_object_id *id2,
- FILE *f1, FILE *f2, const char *label1, const char *label2,
+ FILE *f1, FILE *f2, int fd1, int fd2,
+ const char *label1, const char *label2,
struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg,
int diff_content)
{
if (err)
goto done;
- err = got_diff_tree(tree1, tree2, f1, f2, label1, label2,
- repo, cb, cb_arg, diff_content);
+ err = got_diff_tree(tree1, tree2, f1, f2, fd1, fd2,
+ label1, label2, repo, cb, cb_arg, diff_content);
done:
if (tree1)
}
static const struct got_error *
-diff_deleted_tree(struct got_object_id *id, FILE *f, const char *label,
- struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg,
- int diff_content)
+diff_deleted_tree(struct got_object_id *id, FILE *f, int fd,
+ const char *label, struct got_repository *repo,
+ got_diff_blob_cb cb, void *cb_arg, int diff_content)
{
const struct got_error *err;
struct got_object *treeobj = NULL;
if (err)
goto done;
- err = got_diff_tree(tree, NULL, f, NULL, label, NULL,
+ err = got_diff_tree(tree, NULL, f, NULL, fd, -1, label, NULL,
repo, cb, cb_arg, diff_content);
done:
if (tree)
static const struct got_error *
diff_entry_old_new(struct got_tree_entry *te1, struct got_tree_entry *te2,
- FILE *f1, FILE *f2, const char *label1, const char *label2,
+ FILE *f1, FILE *f2, int fd1, int fd2,
+ const char *label1, const char *label2,
struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg,
int diff_content)
{
if (te2 == NULL) {
if (S_ISDIR(te1->mode))
- err = diff_deleted_tree(&te1->id, f1, label1, repo,
- cb, cb_arg, diff_content);
+ err = diff_deleted_tree(&te1->id, f1, fd1, label1,
+ repo, cb, cb_arg, diff_content);
else {
if (diff_content)
- err = diff_deleted_blob(&te1->id, f1, label1,
- te1->mode, repo, cb, cb_arg);
+ err = diff_deleted_blob(&te1->id, f1, fd1,
+ label1, te1->mode, repo, cb, cb_arg);
else
err = cb(cb_arg, NULL, NULL, NULL, NULL,
&te1->id, NULL, label1, NULL,
if (S_ISDIR(te1->mode) && S_ISDIR(te2->mode)) {
if (!id_match)
return diff_modified_tree(&te1->id, &te2->id, f1, f2,
- label1, label2, repo, cb, cb_arg, diff_content);
+ fd1, fd2, label1, label2, repo, cb, cb_arg,
+ diff_content);
} else if ((S_ISREG(te1->mode) || S_ISLNK(te1->mode)) &&
(S_ISREG(te2->mode) || S_ISLNK(te2->mode))) {
if (!id_match ||
(te2->mode & (S_IFLNK | S_IXUSR))) {
if (diff_content)
return diff_modified_blob(&te1->id, &te2->id,
- f1, f2, label1, label2, te1->mode,
- te2->mode, repo, cb, cb_arg);
+ f1, f2, fd1, fd2, label1, label2,
+ te1->mode, te2->mode, repo, cb, cb_arg);
else
return cb(cb_arg, NULL, NULL, NULL, NULL,
&te1->id, &te2->id, label1, label2,
static const struct got_error *
diff_entry_new_old(struct got_tree_entry *te2,
- struct got_tree_entry *te1, FILE *f2, const char *label2,
+ struct got_tree_entry *te1, FILE *f2, int fd2, const char *label2,
struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg,
int diff_content)
{
return NULL;
if (S_ISDIR(te2->mode))
- return diff_added_tree(&te2->id, f2, label2,
+ return diff_added_tree(&te2->id, f2, fd2, label2,
repo, cb, cb_arg, diff_content);
if (diff_content)
- return diff_added_blob(&te2->id, f2, label2, te2->mode,
- repo, cb, cb_arg);
+ return diff_added_blob(&te2->id, f2, fd2,
+ label2, te2->mode, repo, cb, cb_arg);
return cb(cb_arg, NULL, NULL, NULL, NULL, NULL, &te2->id,
NULL, label2, 0, te2->mode, repo);
const struct got_error *
got_diff_tree(struct got_tree_object *tree1, struct got_tree_object *tree2,
- FILE *f1, FILE *f2, const char *label1, const char *label2,
+ FILE *f1, FILE *f2, int fd1, int fd2,
+ const char *label1, const char *label2,
struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg,
int diff_content)
{
return
got_error_from_errno("asprintf");
}
- err = diff_entry_old_new(te1, te, f1, f2, l1, l2,
- repo, cb, cb_arg, diff_content);
+ err = diff_entry_old_new(te1, te, f1, f2, fd1, fd2,
+ l1, l2, repo, cb, cb_arg, diff_content);
if (err)
break;
}
return
got_error_from_errno("asprintf");
}
- err = diff_entry_new_old(te2, te, f2, l2, repo,
+ err = diff_entry_new_old(te2, te, f2, fd2, l2, repo,
cb, cb_arg, diff_content);
if (err)
break;
const struct got_error *
got_diff_objects_as_blobs(off_t **line_offsets, size_t *nlines,
- FILE *f1, FILE *f2, struct got_object_id *id1, struct got_object_id *id2,
+ FILE *f1, FILE *f2, int fd1, int fd2,
+ struct got_object_id *id1, struct got_object_id *id2,
const char *label1, const char *label2, int diff_context,
int ignore_whitespace, int force_text_diff,
struct got_repository *repo, FILE *outfile)
{
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, fd1);
if (err)
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;
static const struct got_error *
diff_paths(struct got_tree_object *tree1, struct got_tree_object *tree2,
- FILE *f1, FILE *f2, struct got_pathlist_head *paths,
+ FILE *f1, FILE *f2, int fd1, int fd2, struct got_pathlist_head *paths,
struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg)
{
const struct got_error *err = NULL;
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;
goto done;
}
err = got_diff_tree(subtree1, subtree2, f1, f2,
+ fd1, fd2,
id1 ? pe->path : "/dev/null",
id2 ? pe->path : "/dev/null",
repo, cb, cb_arg, 1);
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);
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;
static const struct got_error *
diff_objects_as_trees(off_t **line_offsets, size_t *nlines,
- FILE *f1, FILE *f2, struct got_object_id *id1, struct got_object_id *id2,
+ FILE *f1, FILE *f2, int fd1, int fd2,
+ struct got_object_id *id1, struct got_object_id *id2,
struct got_pathlist_head *paths, const char *label1, const char *label2,
int diff_context, int ignore_whitespace, int force_text_diff,
struct got_repository *repo, FILE *outfile)
arg.nlines = 0;
}
if (paths == NULL || TAILQ_EMPTY(paths)) {
- err = got_diff_tree(tree1, tree2, f1, f2, label1, label2,
- repo, got_diff_blob_output_unidiff, &arg, 1);
+ err = got_diff_tree(tree1, tree2, f1, f2, fd1, fd2,
+ label1, label2, repo,
+ got_diff_blob_output_unidiff, &arg, 1);
} else {
- err = diff_paths(tree1, tree2, f1, f2, paths, repo,
+ err = diff_paths(tree1, tree2, f1, f2, fd1, fd2, paths, repo,
got_diff_blob_output_unidiff, &arg);
}
if (want_lineoffsets) {
const struct got_error *
got_diff_objects_as_trees(off_t **line_offsets, size_t *nlines,
- FILE *f1, FILE *f2, struct got_object_id *id1, struct got_object_id *id2,
+ FILE *f1, FILE *f2, int fd1, int fd2,
+ struct got_object_id *id1, struct got_object_id *id2,
struct got_pathlist_head *paths, const char *label1, const char *label2,
int diff_context, int ignore_whitespace, int force_text_diff,
struct got_repository *repo, FILE *outfile)
goto done;
}
- err = diff_objects_as_trees(line_offsets, nlines, f1, f2, id1, id2,
- paths, label1, label2, diff_context, ignore_whitespace,
+ err = diff_objects_as_trees(line_offsets, nlines, f1, f2, fd1, fd2,
+ id1, id2, paths, label1, label2, diff_context, ignore_whitespace,
force_text_diff, repo, outfile);
done:
free(idstr);
const struct got_error *
got_diff_objects_as_commits(off_t **line_offsets, size_t *nlines,
- FILE *f1, FILE *f2, struct got_object_id *id1, struct got_object_id *id2,
+ FILE *f1, FILE *f2, int fd1, int fd2,
+ struct got_object_id *id1, struct got_object_id *id2,
struct got_pathlist_head *paths,
int diff_context, int ignore_whitespace, int force_text_diff,
struct got_repository *repo, FILE *outfile)
if (err)
goto done;
- err = diff_objects_as_trees(line_offsets, nlines, f1, f2,
+ err = diff_objects_as_trees(line_offsets, nlines, f1, f2, fd1, fd2,
commit1 ? got_object_commit_get_tree_id(commit1) : NULL,
got_object_commit_get_tree_id(commit2), paths, "", "",
diff_context, ignore_whitespace, force_text_diff, repo, outfile);
blob - 8decec3748ea2448a4255cba6eccf77ced9fab2a
blob + 3ffd653ef429fab490d06ba6a953185254e7c117
--- lib/error.c
+++ lib/error.c
{
size_t i;
+ if (code == GOT_ERR_PRIVSEP_LEN) abort();
for (i = 0; i < nitems(got_errors); i++) {
if (code == got_errors[i].code)
return &got_errors[i];
blob - d2ba8bff2999366cb470b0e5b15c07f8d2a96442
blob + 12ae8e569a5cb16540cc4d70ad34d56c0964258a
--- lib/object.c
+++ lib/object.c
goto done;
}
+ if (ftruncate(outfd, 0L) == -1) {
+ err = got_error_from_errno("ftruncate");
+ goto done;
+ }
+ if (lseek(outfd, SEEK_SET, 0) == -1) {
+ err = got_error_from_errno("lseek");
+ goto done;
+ }
+
err = got_repo_search_packidx(&packidx, &idx, repo, id);
if (err == NULL) {
struct got_pack *pack = NULL;
blob - bde5fed8d73d8b12076780fe47b0782a4fdb69db
blob + 18f13a154b509692bfadad8d3d5873d52e5bd66b
--- lib/worktree.c
+++ lib/worktree.c
struct merge_file_cb_arg arg;
char *label_orig = NULL;
FILE *f1 = NULL, *f2 = NULL;
+ int fd1 = -1, fd2 = -1;
if (commit_id1) {
err = got_object_open_as_commit(&commit1, repo, commit_id1);
f2 = got_opentemp();
if (f2 == NULL) {
err = got_error_from_errno("got_opentemp");
+ 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;
+ }
+
cmc_arg.worktree = worktree;
cmc_arg.fileindex = fileindex;
cmc_arg.repo = repo;
- err = got_diff_tree(tree1, tree2, f1, f2, "", "", repo,
+ err = got_diff_tree(tree1, tree2, f1, f2, fd1, fd2, "", "", repo,
check_merge_conflicts, &cmc_arg, 0);
if (err)
goto done;
arg.label_orig = label_orig;
arg.commit_id2 = commit_id2;
arg.allow_bad_symlinks = 1; /* preserve bad symlinks across merges */
- err = got_diff_tree(tree1, tree2, f1, f2, "", "", repo,
+ err = got_diff_tree(tree1, tree2, f1, f2, fd1, fd2, "", "", repo,
merge_file_cb, &arg, 1);
sync_err = sync_fileindex(fileindex, fileindex_path);
if (sync_err && err == NULL)
err = got_error_from_errno("fclose");
if (f2 && fclose(f2) == EOF && err == NULL)
err = got_error_from_errno("fclose");
+ if (fd1 != -1 && close(fd1) == -1 && err == NULL)
+ err = got_error_from_errno("close");
+ if (fd2 != -1 && close(fd2) == -1 && err == NULL)
+ err = got_error_from_errno("close");
free(label_orig);
return err;
}
blob - 0b32bf9f96120b686083e5da9c0c904bb272a486
blob + 3ec7da1db803f36693a814f77125861f3ac2095e
--- tog/tog.c
+++ tog/tog.c
struct got_object_id *id1, *id2;
const char *label1, *label2;
FILE *f, *f1, *f2;
+ int fd1, fd2;
int first_displayed_line;
int last_displayed_line;
int eof;
if (err)
goto done;
- err = got_diff_tree(tree1, tree2, NULL, NULL, "", "", repo,
+ err = got_diff_tree(tree1, tree2, NULL, NULL, -1, -1, "", "", repo,
got_diff_tree_collect_changed_paths, paths, 0);
done:
if (tree1)
switch (obj_type) {
case GOT_OBJ_TYPE_BLOB:
err = got_diff_objects_as_blobs(&s->line_offsets, &s->nlines,
- s->f1, s->f2, s->id1, s->id2, s->label1, s->label2,
- s->diff_context, s->ignore_whitespace, s->force_text_diff,
- s->repo, s->f);
+ s->f1, s->f2, s->fd1, s->fd2, s->id1, s->id2,
+ s->label1, s->label2, s->diff_context,
+ s->ignore_whitespace, s->force_text_diff, s->repo, s->f);
break;
case GOT_OBJ_TYPE_TREE:
err = got_diff_objects_as_trees(&s->line_offsets, &s->nlines,
- s->f1, s->f2, s->id1, s->id2, NULL, "", "", s->diff_context,
- s->ignore_whitespace, s->force_text_diff, s->repo, s->f);
+ s->f1, s->f2, s->fd1, s->fd2, s->id1, s->id2, NULL, "", "",
+ s->diff_context, s->ignore_whitespace, s->force_text_diff,
+ s->repo, s->f);
break;
case GOT_OBJ_TYPE_COMMIT: {
const struct got_object_id_queue *parent_ids;
got_object_commit_close(commit2);
err = got_diff_objects_as_commits(&s->line_offsets, &s->nlines,
- s->f1, s->f2, s->id1, s->id2, NULL, s->diff_context,
- s->ignore_whitespace, s->force_text_diff, s->repo, s->f);
+ s->f1, s->f2, s->fd1, s->fd2, s->id1, s->id2, NULL,
+ s->diff_context, s->ignore_whitespace, s->force_text_diff,
+ s->repo, s->f);
break;
}
default:
if (s->f && fclose(s->f) == EOF)
err = got_error_from_errno("fclose");
s->f = NULL;
- if (s->f1 && fclose(s->f1) == EOF)
+ if (s->f1 && fclose(s->f1) == EOF && err == NULL)
err = got_error_from_errno("fclose");
s->f1 = NULL;
- if (s->f2 && fclose(s->f2) == EOF)
+ if (s->f2 && fclose(s->f2) == EOF && err == NULL)
err = got_error_from_errno("fclose");
s->f2 = NULL;
+ if (s->fd1 != -1 && close(s->fd1) == -1 && err == NULL)
+ err = got_error_from_errno("close");
+ s->fd1 = -1;
+ if (s->fd2 != -1 && close(s->fd2) == -1 && err == NULL)
+ err = got_error_from_errno("close");
+ s->fd2 = -1;
free_colors(&s->colors);
free(s->line_offsets);
s->line_offsets = NULL;
struct tog_diff_view_state *s = &view->state.diff;
memset(s, 0, sizeof(*s));
+ s->fd1 = -1;
+ s->fd2 = -1;
if (id1 != NULL && id2 != NULL) {
int type1, type2;
goto done;
}
+ s->fd1 = got_opentempfd();
+ if (s->fd1 == -1) {
+ err = got_error_from_errno("got_opentempfd");
+ goto done;
+ }
+
+ s->fd2 = got_opentempfd();
+ if (s->fd2 == -1) {
+ err = got_error_from_errno("got_opentempfd");
+ goto done;
+ }
+
s->first_displayed_line = 1;
s->last_displayed_line = view->nlines;
s->diff_context = diff_context;