diff options
author | Christian Couder <christian.couder@gmail.com> | 2016-09-04 22:18:18 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2016-09-07 12:29:53 -0700 |
commit | 739d8a16b5f1fefc42177c4619605c8cddb3a094 (patch) | |
tree | 2ffafc9fba7040559313088d2a5299e6ad520ef5 | |
parent | ccceb7bb13a37b1834bc1c455e40abc710997dd3 (diff) | |
download | git-739d8a16b5f1fefc42177c4619605c8cddb3a094.tar.gz |
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>
-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); |