patch_file: move file ownership to parent ok stsp@
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
diff --git a/lib/patch.c b/lib/patch.c
index 7167f54..cb80bed 100644
--- a/lib/patch.c
+++ b/lib/patch.c
@@ -455,14 +455,12 @@ apply_hunk(FILE *tmp, struct got_patch_hunk *h, int *lineno)
}
static const struct got_error *
-patch_file(struct got_patch *p, const char *path, FILE *tmp, int nop,
- mode_t *mode)
+patch_file(struct got_patch *p, FILE *orig, FILE *tmp, int nop, mode_t *mode)
{
const struct got_error *err = NULL;
struct got_patch_hunk *h;
struct stat sb;
int lineno = 0;
- FILE *orig;
off_t copypos, pos;
char *line = NULL;
size_t linesize = 0;
@@ -477,15 +475,8 @@ patch_file(struct got_patch *p, const char *path, FILE *tmp, int nop,
return apply_hunk(tmp, h, &lineno);
}
- if ((orig = fopen(path, "r")) == NULL) {
- err = got_error_from_errno2("fopen", path);
- goto done;
- }
-
- if (fstat(fileno(orig), &sb) == -1) {
- err = got_error_from_errno("fstat");
- goto done;
- }
+ if (fstat(fileno(orig), &sb) == -1)
+ return got_error_from_errno("fstat");
*mode = sb.st_mode;
copypos = 0;
@@ -495,11 +486,11 @@ patch_file(struct got_patch *p, const char *path, FILE *tmp, int nop,
if (err != NULL && err->code == GOT_ERR_HUNK_FAILED)
h->err = err;
if (err != NULL)
- goto done;
+ return err;
if (!nop)
err = copy(tmp, orig, copypos, pos);
if (err != NULL)
- goto done;
+ return err;
copypos = pos;
err = test_hunk(orig, h);
@@ -508,20 +499,16 @@ patch_file(struct got_patch *p, const char *path, FILE *tmp, int nop,
* try to apply the hunk again starting the search
* after the previous partial match.
*/
- if (fseeko(orig, pos, SEEK_SET) == -1) {
- err = got_error_from_errno("fseeko");
- goto done;
- }
+ if (fseeko(orig, pos, SEEK_SET) == -1)
+ return got_error_from_errno("fseeko");
linelen = getline(&line, &linesize, orig);
- if (linelen == -1) {
- err = got_error_from_errno("getline");
- goto done;
- }
+ if (linelen == -1)
+ return got_error_from_errno("getline");
lineno++;
goto tryagain;
}
if (err != NULL)
- goto done;
+ return err;
if (lineno + 1 != h->old_from)
h->offset = lineno + 1 - h->old_from;
@@ -529,13 +516,11 @@ patch_file(struct got_patch *p, const char *path, FILE *tmp, int nop,
if (!nop)
err = apply_hunk(tmp, h, &lineno);
if (err != NULL)
- goto done;
+ return err;
copypos = ftello(orig);
- if (copypos == -1) {
- err = got_error_from_errno("ftello");
- goto done;
- }
+ if (copypos == -1)
+ return got_error_from_errno("ftello");
}
if (p->new == NULL && sb.st_size != copypos) {
@@ -545,9 +530,6 @@ patch_file(struct got_patch *p, const char *path, FILE *tmp, int nop,
} else if (!nop && !feof(orig))
err = copy(tmp, orig, copypos, -1);
-done:
- if (orig != NULL && fclose(orig) == EOF && err == NULL)
- err = got_error_from_errno("fclose");
return err;
}
@@ -600,7 +582,7 @@ apply_patch(struct got_worktree *worktree, struct got_repository *repo,
int file_renamed = 0;
char *oldpath = NULL, *newpath = NULL;
char *tmppath = NULL, *template = NULL, *parent = NULL;
- FILE *tmp = NULL;
+ FILE *oldfile = NULL, *tmp = NULL;
mode_t mode = GOT_DEFAULT_FILE_MODE;
if (asprintf(&oldpath, "%s/%s", got_worktree_get_root_path(worktree),
@@ -623,11 +605,16 @@ apply_patch(struct got_worktree *worktree, struct got_repository *repo,
goto done;
}
+ if (p->old != NULL && (oldfile = fopen(oldpath, "r")) == NULL) {
+ err = got_error_from_errno2("open", oldpath);
+ goto done;
+ }
+
if (!nop)
err = got_opentemp_named(&tmppath, &tmp, template);
if (err)
goto done;
- err = patch_file(p, oldpath, tmp, nop, &mode);
+ err = patch_file(p, oldfile, tmp, nop, &mode);
if (err)
goto done;
@@ -691,6 +678,8 @@ done:
err = got_error_from_errno("fclose");
free(tmppath);
free(oldpath);
+ if (oldfile != NULL && fclose(oldfile) == EOF && err == NULL)
+ err = got_error_from_errno("fclose");
free(newpath);
return err;
}