builtin/apply: make try_create_file() return -1 on error
To libify `git apply` functionality we have to signal errors to the caller instead of die()ing. To do that in a compatible manner with the rest of the error handling in "builtin/apply.c", try_create_file() should return -1 in case of error. Unfortunately try_create_file() currently returns -1 to signal a recoverable error. To fix that, let's make it return 1 in case of a recoverable error and -1 in case of an unrecoverable error. Helped-by: Eric Sunshine <sunshine@sunshineco.com> Helped-by: Jeff King <peff@peff.net> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Christian Couder committed
Sep 4, 2016 at 22:18 UTC
739d8a16b5f1fefc42177c4619605c8cddb3a094
1 file changed
+33
-11
builtin/apply.c
+33
-11
@@ -4150,38 +4150,48 @@ static int add_index_file(struct apply_state *state,
4150
return 0;
4151
}
4152
4153
+/*
4154
+ * Returns:
4155
+ * -1 if an unrecoverable error happened
4156
+ * 0 if everything went well
4157
+ * 1 if a recoverable error happened
4158
+ */
4159
static int try_create_file(const char *path, unsigned int mode, const char *buf, unsigned long size)
4160
{
4155
- int fd;
4161
+ int fd, res;
4162
struct strbuf nbuf = STRBUF_INIT;
4163
4164
if (S_ISGITLINK(mode)) {
4165
struct stat st;
4166
if (!lstat(path, &st) && S_ISDIR(st.st_mode))
4167
return 0;
4162
- return mkdir(path, 0777);
4168
+ return !!mkdir(path, 0777);
4169
}
4170
4171
if (has_symlinks && S_ISLNK(mode))
4172
/* Although buf:size is counted string, it also is NUL
4173
* terminated.
4174
*/
4169
- return symlink(buf, path);
4175
+ return !!symlink(buf, path);
4176
4177
fd = open(path, O_CREAT | O_EXCL | O_WRONLY, (mode & 0100) ? 0777 : 0666);
4178
if (fd < 0)
4173
- return -1;
4179
+ return 1;
4180
4181
if (convert_to_working_tree(path, buf, size, &nbuf)) {
4182
size = nbuf.len;
4183
buf = nbuf.buf;
4184
}
4179
- write_or_die(fd, buf, size);
4185
+
4186
+ res = write_in_full(fd, buf, size) < 0;
4187
+ if (res)
4188
+ error_errno(_("failed to write to '%s'"), path);
4189
strbuf_release(&nbuf);
4190
4182
- if (close(fd) < 0)
4183
- die_errno(_("closing file '%s'"), path);
4184
- return 0;
4191
+ if (close(fd) < 0 && !res)
4192
+ return error_errno(_("closing file '%s'"), path);
4193
+
4194
+ return res ? -1 : 0;
4195
}
4196
4197
/*
@@ -4195,15 +4205,24 @@ static void create_one_file(struct apply_state *state,
4205
const char *buf,
4206
unsigned long size)
4207
{
4208
+ int res;
4209
+
4210
if (state->cached)
4211
return;
4200
- if (!try_create_file(path, mode, buf, size))
4212
+
4213
+ res = try_create_file(path, mode, buf, size);
4214
+ if (res < 0)
4215
+ exit(128);
4216
+ if (!res)
4217
return;
4218
4219
if (errno == ENOENT) {
4220
if (safe_create_leading_directories(path))
4221
return;
4206
- if (!try_create_file(path, mode, buf, size))
4222
+ res = try_create_file(path, mode, buf, size);
4223
+ if (res < 0)
4224
+ exit(128);
4225
+ if (!res)
4226
return;
4227
}
4228
@@ -4222,7 +4241,10 @@ static void create_one_file(struct apply_state *state,
4241
for (;;) {
4242
char newpath[PATH_MAX];
4243
mksnpath(newpath, sizeof(newpath), "%s~%u", path, nr);
4225
- if (!try_create_file(newpath, mode, buf, size)) {
4244
+ res = try_create_file(newpath, mode, buf, size);
4245
+ if (res < 0)
4246
+ exit(128);
4247
+ if (!res) {
4248
if (!rename(newpath, path))
4249
return;
4250
unlink_or_warn(newpath);