To finish libifying the apply functionality, apply_all_patches() should not
die() or exit() in case of error, but return -1.
While doing that we must take care that file descriptors are properly closed
and, if needed, reset a sensible value.
Also, according to the lockfile API, when finished with a lockfile, one
should either commit it or roll it back.
This is even more important now that the same lockfile can be passed
to init_apply_state() many times to be reused by series of calls to
the apply lib functions.
Helped-by: Nguyễn Thái Ngọc Duy [off-list ref]
Helped-by: Johannes Schindelin [off-list ref]
Helped-by: Eric Sunshine [off-list ref]
Signed-off-by: Christian Couder <redacted>
---
builtin/apply.c | 40 +++++++++++++++++++++++++++-------------
1 file changed, 27 insertions(+), 13 deletions(-)
diff --git a/builtin/apply.c b/builtin/apply.c
index a27fdd3..c27be35 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -4558,7 +4558,7 @@ static int apply_all_patches(struct apply_state *state,
if (!strcmp(arg, "-")) {
res = apply_patch(state, 0, "<stdin>", options);
if (res < 0)
- exit(1);
+ goto rollback_end;
errs |= res;
read_stdin = 0;
continue;@@ -4568,21 +4568,23 @@ static int apply_all_patches(struct apply_state *state,
arg);
fd = open(arg, O_RDONLY);
- if (fd < 0)
- die_errno(_("can't open patch '%s'"), arg);
+ if (fd < 0) {
+ error(_("can't open patch '%s': %s"), arg, strerror(errno));
+ goto rollback_end;
+ }
read_stdin = 0;
set_default_whitespace_mode(state);
res = apply_patch(state, fd, arg, options);
+ close(fd);
if (res < 0)
- exit(1);
+ goto rollback_end;
errs |= res;
- close(fd);
}
set_default_whitespace_mode(state);
if (read_stdin) {
res = apply_patch(state, 0, "<stdin>", options);
if (res < 0)
- exit(1);
+ goto rollback_end;
errs |= res;
}
@@ -4596,11 +4598,13 @@ static int apply_all_patches(struct apply_state *state,
squelched),
squelched);
}
- if (state->ws_error_action == die_on_ws_error)
- die(Q_("%d line adds whitespace errors.",
- "%d lines add whitespace errors.",
- state->whitespace_error),
- state->whitespace_error);
+ if (state->ws_error_action == die_on_ws_error) {
+ error(Q_("%d line adds whitespace errors.",
+ "%d lines add whitespace errors.",
+ state->whitespace_error),
+ state->whitespace_error);
+ goto rollback_end;
+ }
if (state->applied_after_fixing_ws && state->apply)
warning("%d line%s applied after"
" fixing whitespace errors.",@@ -4614,12 +4618,22 @@ static int apply_all_patches(struct apply_state *state,
}
if (state->update_index) {
- if (write_locked_index(&the_index, state->lock_file, COMMIT_LOCK))
- die(_("Unable to write new index file"));
+ res = write_locked_index(&the_index, state->lock_file, COMMIT_LOCK);
+ if (res) {
+ error(_("Unable to write new index file"));
+ goto rollback_end;
+ }
state->newfd = -1;
}
return !!errs;
+
+rollback_end:
+ if (state->newfd >= 0) {
+ rollback_lock_file(state->lock_file);
+ state->newfd = -1;
+ }
+ return -1;
}
int cmd_apply(int argc, const char **argv, const char *prefix)--
2.9.0.rc2.411.g3e2ca28