diff options
Diffstat (limited to 'builtin')
-rw-r--r-- | builtin/apply.c | 44 |
1 files changed, 33 insertions, 11 deletions
diff --git a/builtin/apply.c b/builtin/apply.c index c787ead93c..3145e03940 100644 --- a/builtin/apply.c +++ b/builtin/apply.c @@ -4150,38 +4150,48 @@ static int add_index_file(struct apply_state *state, return 0; } +/* + * Returns: + * -1 if an unrecoverable error happened + * 0 if everything went well + * 1 if a recoverable error happened + */ static int try_create_file(const char *path, unsigned int mode, const char *buf, unsigned long size) { - int fd; + int fd, res; struct strbuf nbuf = STRBUF_INIT; if (S_ISGITLINK(mode)) { struct stat st; if (!lstat(path, &st) && S_ISDIR(st.st_mode)) return 0; - return mkdir(path, 0777); + return !!mkdir(path, 0777); } if (has_symlinks && S_ISLNK(mode)) /* Although buf:size is counted string, it also is NUL * terminated. */ - return symlink(buf, path); + return !!symlink(buf, path); fd = open(path, O_CREAT | O_EXCL | O_WRONLY, (mode & 0100) ? 0777 : 0666); if (fd < 0) - return -1; + return 1; if (convert_to_working_tree(path, buf, size, &nbuf)) { size = nbuf.len; buf = nbuf.buf; } - write_or_die(fd, buf, size); + + res = write_in_full(fd, buf, size) < 0; + if (res) + error_errno(_("failed to write to '%s'"), path); strbuf_release(&nbuf); - if (close(fd) < 0) - die_errno(_("closing file '%s'"), path); - return 0; + if (close(fd) < 0 && !res) + return error_errno(_("closing file '%s'"), path); + + return res ? -1 : 0; } /* @@ -4195,15 +4205,24 @@ static void create_one_file(struct apply_state *state, const char *buf, unsigned long size) { + int res; + if (state->cached) return; - if (!try_create_file(path, mode, buf, size)) + + res = try_create_file(path, mode, buf, size); + if (res < 0) + exit(128); + if (!res) return; if (errno == ENOENT) { if (safe_create_leading_directories(path)) return; - if (!try_create_file(path, mode, buf, size)) + res = try_create_file(path, mode, buf, size); + if (res < 0) + exit(128); + if (!res) return; } @@ -4222,7 +4241,10 @@ static void create_one_file(struct apply_state *state, for (;;) { char newpath[PATH_MAX]; mksnpath(newpath, sizeof(newpath), "%s~%u", path, nr); - if (!try_create_file(newpath, mode, buf, size)) { + res = try_create_file(newpath, mode, buf, size); + if (res < 0) + exit(128); + if (!res) { if (!rename(newpath, path)) return; unlink_or_warn(newpath); |