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);