summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/technical/api-lockfile.txt7
-rw-r--r--lockfile.c28
2 files changed, 22 insertions, 13 deletions
diff --git a/Documentation/technical/api-lockfile.txt b/Documentation/technical/api-lockfile.txt
index 6538610..d3bf940 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 c897dd8..1d18c67 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;
+ }
}