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: Eric Sunshine <sunsh...@sunshineco.com> Helped-by: Nguyễn Thái Ngọc Duy <pclo...@gmail.com> Helped-by: Johannes Schindelin <johannes.schinde...@gmx.de> Signed-off-by: Christian Couder <chrisc...@tuxfamily.org> --- 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.362.g3cd93d0 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html