close_lock_file(): new function in the lockfile API
The lockfile API is a handy way to obtain a file that is cleaned
up if you die(). But sometimes you would need this sequence to
work:
1. hold_lock_file_for_update() to get a file descriptor for
writing;
2. write the contents out, without being able to decide if the
results should be committed or rolled back;
3. do something else that makes the decision --- and this
"something else" needs the lockfile not to have an open file
descriptor for writing (e.g. Windows do not want a open file
to be renamed);
4. call commit_lock_file() or rollback_lock_file() as
appropriately.
This adds close_lock_file() you can call between step 2 and 3 in
the above sequence.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
0c0478cac8
commit
d6cf61bfd4
30
lockfile.c
30
lockfile.c
@ -13,7 +13,8 @@ static void remove_lock_file(void)
|
||||
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;
|
||||
@ -159,17 +160,26 @@ int hold_lock_file_for_update(struct lock_file *lk, const char *path, int die_on
|
||||
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)
|
||||
@ -185,9 +195,12 @@ void set_alternate_index_output(const char *name)
|
||||
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);
|
||||
@ -196,7 +209,8 @@ int commit_locked_index(struct 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;
|
||||
|
||||
Reference in New Issue
Block a user