Skip to content

Commit 751bace

Browse files
mhaggergitster
authored andcommitted
commit_lock_file_to(): refactor a helper out of commit_lock_file()
commit_locked_index(), when writing to an alternate index file, duplicates (poorly) the code in commit_lock_file(). And anyway, it shouldn't have to know so much about the internal workings of lockfile objects. So extract a new function commit_lock_file_to() that does the work common to the two functions, and call it from both commit_lock_file() and commit_locked_index(). Signed-off-by: Michael Haggerty <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 0c0d6e8 commit 751bace

File tree

4 files changed

+50
-38
lines changed

4 files changed

+50
-38
lines changed

Documentation/technical/api-lockfile.txt

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -49,35 +49,34 @@ The caller:
4949
When finished writing, the caller can:
5050

5151
* Close the file descriptor and rename the lockfile to its final
52-
destination by calling `commit_lock_file`.
52+
destination by calling `commit_lock_file` or `commit_lock_file_to`.
5353

5454
* Close the file descriptor and remove the lockfile by calling
5555
`rollback_lock_file`.
5656

5757
* Close the file descriptor without removing or renaming the lockfile
5858
by calling `close_lock_file`, and later call `commit_lock_file`,
59-
`rollback_lock_file`, or `reopen_lock_file`.
59+
`commit_lock_file_to`, `rollback_lock_file`, or `reopen_lock_file`.
6060

6161
Even after the lockfile is committed or rolled back, the `lock_file`
6262
object must not be freed or altered by the caller. However, it may be
6363
reused; just pass it to another call of `hold_lock_file_for_update` or
6464
`hold_lock_file_for_append`.
6565

6666
If the program exits before you have called one of `commit_lock_file`,
67-
`rollback_lock_file`, or `close_lock_file`, an `atexit(3)` handler
68-
will close and remove the lockfile, rolling back any uncommitted
69-
changes.
67+
`commit_lock_file_to`, `rollback_lock_file`, or `close_lock_file`, an
68+
`atexit(3)` handler will close and remove the lockfile, rolling back
69+
any uncommitted changes.
7070

7171
If you need to close the file descriptor you obtained from a
7272
`hold_lock_file_*` function yourself, do so by calling
7373
`close_lock_file`. You should never call `close(2)` yourself!
7474
Otherwise the `struct lock_file` structure would still think that the
75-
file descriptor needs to be closed, and a later call to
76-
`commit_lock_file` or `rollback_lock_file` or program exit would
75+
file descriptor needs to be closed, and a commit or rollback would
7776
result in duplicate calls to `close(2)`. Worse yet, if you `close(2)`
7877
and then later open another file descriptor for a completely different
79-
purpose, then a call to `commit_lock_file` or `rollback_lock_file`
80-
might close that unrelated file descriptor.
78+
purpose, then a commit or rollback might close that unrelated file
79+
descriptor.
8180

8281

8382
Error handling
@@ -100,9 +99,9 @@ unable_to_lock_die::
10099

101100
Emit an appropriate error message and `die()`.
102101

103-
Similarly, `commit_lock_file` and `close_lock_file` return 0 on
104-
success. On failure they set `errno` appropriately, do their best to
105-
roll back the lockfile, and return -1.
102+
Similarly, `commit_lock_file`, `commit_lock_file_to`, and
103+
`close_lock_file` return 0 on success. On failure they set `errno`
104+
appropriately, do their best to roll back the lockfile, and return -1.
106105

107106

108107
Flags
@@ -156,6 +155,12 @@ commit_lock_file::
156155
`commit_lock_file` for a `lock_file` object that is not
157156
currently locked.
158157

158+
commit_lock_file_to::
159+
160+
Like `commit_lock_file()`, except that it takes an explicit
161+
`path` argument to which the lockfile should be renamed. The
162+
`path` must be on the same filesystem as the lock file.
163+
159164
rollback_lock_file::
160165

161166
Take a pointer to the `struct lock_file` initialized with an
@@ -172,8 +177,9 @@ close_lock_file::
172177
`hold_lock_file_for_append`, and close the file descriptor.
173178
Return 0 upon success. On failure to `close(2)`, return a
174179
negative value and roll back the lock file. Usually
175-
`commit_lock_file` or `rollback_lock_file` should eventually
176-
be called if `close_lock_file` succeeds.
180+
`commit_lock_file`, `commit_lock_file_to`, or
181+
`rollback_lock_file` should eventually be called if
182+
`close_lock_file` succeeds.
177183

178184
reopen_lock_file::
179185

cache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,7 @@ extern void unable_to_lock_message(const char *path, int err,
590590
extern NORETURN void unable_to_lock_die(const char *path, int err);
591591
extern int hold_lock_file_for_update(struct lock_file *, const char *path, int);
592592
extern int hold_lock_file_for_append(struct lock_file *, const char *path, int);
593+
extern int commit_lock_file_to(struct lock_file *, const char *path);
593594
extern int commit_lock_file(struct lock_file *);
594595
extern int reopen_lock_file(struct lock_file *);
595596
extern void update_index_if_able(struct index_state *, struct lock_file *);

lockfile.c

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@
4343
* Same as the previous state, except that the lockfile is closed
4444
* and fd is -1.
4545
*
46-
* - Unlocked (after commit_lock_file(), rollback_lock_file(), a
47-
* failed attempt to lock, or a failed close_lock_file()). In this
48-
* state:
46+
* - Unlocked (after commit_lock_file(), commit_lock_file_to(),
47+
* rollback_lock_file(), a failed attempt to lock, or a failed
48+
* close_lock_file()). In this state:
4949
* - active is unset
5050
* - filename is empty (usually, though there are transitory
5151
* states in which this condition doesn't hold). Client code should
@@ -284,23 +284,15 @@ int reopen_lock_file(struct lock_file *lk)
284284
return lk->fd;
285285
}
286286

287-
int commit_lock_file(struct lock_file *lk)
287+
int commit_lock_file_to(struct lock_file *lk, const char *path)
288288
{
289-
static struct strbuf result_file = STRBUF_INIT;
290-
int err;
291-
292289
if (!lk->active)
293-
die("BUG: attempt to commit unlocked object");
290+
die("BUG: attempt to commit unlocked object to \"%s\"", path);
294291

295292
if (close_lock_file(lk))
296293
return -1;
297294

298-
/* remove ".lock": */
299-
strbuf_add(&result_file, lk->filename.buf,
300-
lk->filename.len - LOCK_SUFFIX_LEN);
301-
err = rename(lk->filename.buf, result_file.buf);
302-
strbuf_reset(&result_file);
303-
if (err) {
295+
if (rename(lk->filename.buf, path)) {
304296
int save_errno = errno;
305297
rollback_lock_file(lk);
306298
errno = save_errno;
@@ -312,6 +304,26 @@ int commit_lock_file(struct lock_file *lk)
312304
return 0;
313305
}
314306

307+
int commit_lock_file(struct lock_file *lk)
308+
{
309+
static struct strbuf result_file = STRBUF_INIT;
310+
int err;
311+
312+
if (!lk->active)
313+
die("BUG: attempt to commit unlocked object");
314+
315+
if (lk->filename.len <= LOCK_SUFFIX_LEN ||
316+
strcmp(lk->filename.buf + lk->filename.len - LOCK_SUFFIX_LEN, LOCK_SUFFIX))
317+
die("BUG: lockfile filename corrupt");
318+
319+
/* remove ".lock": */
320+
strbuf_add(&result_file, lk->filename.buf,
321+
lk->filename.len - LOCK_SUFFIX_LEN);
322+
err = commit_lock_file_to(lk, result_file.buf);
323+
strbuf_reset(&result_file);
324+
return err;
325+
}
326+
315327
int hold_locked_index(struct lock_file *lk, int die_on_error)
316328
{
317329
return hold_lock_file_for_update(lk, get_index_file(),

read-cache.c

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2041,17 +2041,10 @@ void set_alternate_index_output(const char *name)
20412041

20422042
static int commit_locked_index(struct lock_file *lk)
20432043
{
2044-
if (alternate_index_output) {
2045-
if (close_lock_file(lk))
2046-
return -1;
2047-
if (rename(lk->filename.buf, alternate_index_output))
2048-
return -1;
2049-
lk->active = 0;
2050-
strbuf_reset(&lk->filename);
2051-
return 0;
2052-
} else {
2044+
if (alternate_index_output)
2045+
return commit_lock_file_to(lk, alternate_index_output);
2046+
else
20532047
return commit_lock_file(lk);
2054-
}
20552048
}
20562049

20572050
static int do_write_locked_index(struct index_state *istate, struct lock_file *lock,

0 commit comments

Comments
 (0)