Take a pointer to the `struct lock_file` initialized
with an earlier call to `hold_lock_file_for_update()`,
close the file descriptor and rename the lockfile to its
- final destination.
+ final destination. Returns 0 upon success, a negative
+ value on failure to close(2) or rename(2).
rollback_lock_file::
with an earlier call to `hold_lock_file_for_update()`,
close the file descriptor and remove the lockfile.
+close_lock_file::
+ Take a pointer to the `struct lock_file` initialized
+ with an earlier call to `hold_lock_file_for_update()`,
+ and close the file descriptor. Returns 0 upon success,
+ a negative value on failure to close(2).
+
Because the structure is used in an `atexit(3)` handler, its
storage has to stay throughout the life of the program. It
cannot be an auto variable allocated on the stack.
and simply `exit(3)` from the program, an `atexit(3)` handler
will close and remove the lockfile.
-You should not close the file descriptor you obtained from
-`hold_lock_file_for_update` function yourself. The `struct
+If you need to close the file descriptor you obtained from
+`hold_lock_file_for_update` function yourself, do so by calling
+`close_lock_file()`. You should never call `close(2)` yourself!
+Otherwise the `struct
lock_file` structure still remembers that the file descriptor
needs to be closed, and a later call to `commit_lock_file()` or
`rollback_lock_file()` will result in duplicate calls to
extern int hold_locked_index(struct lock_file *, int);
extern int commit_locked_index(struct lock_file *);
extern void set_alternate_index_output(const char *);
-
+extern int close_lock_file(struct lock_file *);
extern void rollback_lock_file(struct lock_file *);
extern int delete_ref(const char *, const unsigned char *sha1);
while (lock_file_list) {
if (lock_file_list->owner == me &&
lock_file_list->filename[0]) {
- close(lock_file_list->fd);
+ if (lock_file_list->fd >= 0)
+ close(lock_file_list->fd);
unlink(lock_file_list->filename);
}
lock_file_list = lock_file_list->next;
return fd;
}
+int close_lock_file(struct lock_file *lk)
+{
+ int fd = lk->fd;
+ lk->fd = -1;
+ return close(fd);
+}
+
int commit_lock_file(struct lock_file *lk)
{
char result_file[PATH_MAX];
- int i;
- close(lk->fd);
+ size_t i;
+ if (lk->fd >= 0 && close_lock_file(lk))
+ return -1;
strcpy(result_file, lk->filename);
i = strlen(result_file) - 5; /* .lock */
result_file[i] = 0;
- i = rename(lk->filename, result_file);
+ if (rename(lk->filename, result_file))
+ return -1;
lk->filename[0] = 0;
- return i;
+ return 0;
}
int hold_locked_index(struct lock_file *lk, int die_on_error)
int commit_locked_index(struct lock_file *lk)
{
if (alternate_index_output) {
- int result = rename(lk->filename, alternate_index_output);
+ if (lk->fd >= 0 && close_lock_file(lk))
+ return -1;
+ if (rename(lk->filename, alternate_index_output))
+ return -1;
lk->filename[0] = 0;
- return result;
+ return 0;
}
else
return commit_lock_file(lk);
void rollback_lock_file(struct lock_file *lk)
{
if (lk->filename[0]) {
- close(lk->fd);
+ if (lk->fd >= 0)
+ close(lk->fd);
unlink(lk->filename);
}
lk->filename[0] = 0;