diff options
-rw-r--r-- | Documentation/technical/api-lockfile.txt | 7 | ||||
-rw-r--r-- | lockfile.c | 28 |
2 files changed, 22 insertions, 13 deletions
diff --git a/Documentation/technical/api-lockfile.txt b/Documentation/technical/api-lockfile.txt index 6538610759..d3bf940ad4 100644 --- a/Documentation/technical/api-lockfile.txt +++ b/Documentation/technical/api-lockfile.txt @@ -162,9 +162,10 @@ close_lock_file:: Take a pointer to the `struct lock_file` initialized with an earlier call to `hold_lock_file_for_update` or `hold_lock_file_for_append`, and close the file descriptor. - Return 0 upon success or a negative value on failure to - close(2). Usually `commit_lock_file` or `rollback_lock_file` - should be called after `close_lock_file`. + Return 0 upon success. On failure to `close(2)`, return a + negative value and rollback the lock file. Usually + `commit_lock_file` or `rollback_lock_file` should eventually + be called if `close_lock_file` succeeds. reopen_lock_file:: diff --git a/lockfile.c b/lockfile.c index c897dd8a93..1d18c67ea8 100644 --- a/lockfile.c +++ b/lockfile.c @@ -37,13 +37,14 @@ * lockfile, and owner holds the PID of the process that locked the * file. * - * - Locked, lockfile closed (after close_lock_file()). Same as the - * previous state, except that the lockfile is closed and fd is -1. + * - Locked, lockfile closed (after successful close_lock_file()). + * Same as the previous state, except that the lockfile is closed + * and fd is -1. * - * - Unlocked (after commit_lock_file(), rollback_lock_file(), or a - * failed attempt to lock). In this state, filename[0] == '\0' and - * fd is -1. The object is left registered in the lock_file_list, - * and on_list is set. + * - Unlocked (after commit_lock_file(), rollback_lock_file(), a + * failed attempt to lock, or a failed close_lock_file()). In this + * state, filename[0] == '\0' and fd is -1. The object is left + * registered in the lock_file_list, and on_list is set. */ static struct lock_file *lock_file_list; @@ -284,7 +285,13 @@ int close_lock_file(struct lock_file *lk) return 0; lk->fd = -1; - return close(fd); + if (close(fd)) { + int save_errno = errno; + rollback_lock_file(lk); + errno = save_errno; + return -1; + } + return 0; } int reopen_lock_file(struct lock_file *lk) @@ -330,7 +337,8 @@ void rollback_lock_file(struct lock_file *lk) if (!lk->filename[0]) return; - close_lock_file(lk); - unlink_or_warn(lk->filename); - lk->filename[0] = 0; + if (!close_lock_file(lk)) { + unlink_or_warn(lk->filename); + lk->filename[0] = 0; + } } |