Skip to content

Commit cf6950d

Browse files
mhaggergitster
authored andcommitted
lockfile: change lock_file::filename into a strbuf
For now, we still make sure to allocate at least PATH_MAX characters for the strbuf because resolve_symlink() doesn't know how to expand the space for its return value. (That will be fixed in a moment.) Another alternative would be to just use a strbuf as scratch space in lock_file() but then store a pointer to the naked string in struct lock_file. But lock_file objects are often reused. By reusing the same strbuf, we can avoid having to reallocate the string most times when a lock_file object is reused. Helped-by: Torsten Bögershausen <[email protected]> Signed-off-by: Michael Haggerty <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 3e88e8f commit cf6950d

File tree

8 files changed

+47
-52
lines changed

8 files changed

+47
-52
lines changed

builtin/commit.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix
341341
die(_("unable to create temporary index"));
342342

343343
old_index_env = getenv(INDEX_ENVIRONMENT);
344-
setenv(INDEX_ENVIRONMENT, index_lock.filename, 1);
344+
setenv(INDEX_ENVIRONMENT, index_lock.filename.buf, 1);
345345

346346
if (interactive_add(argc, argv, prefix, patch_interactive) != 0)
347347
die(_("interactive add failed"));
@@ -352,7 +352,7 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix
352352
unsetenv(INDEX_ENVIRONMENT);
353353

354354
discard_cache();
355-
read_cache_from(index_lock.filename);
355+
read_cache_from(index_lock.filename.buf);
356356
if (update_main_cache_tree(WRITE_TREE_SILENT) == 0) {
357357
if (reopen_lock_file(&index_lock) < 0)
358358
die(_("unable to write index file"));
@@ -362,7 +362,7 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix
362362
warning(_("Failed to update main cache tree"));
363363

364364
commit_style = COMMIT_NORMAL;
365-
return index_lock.filename;
365+
return index_lock.filename.buf;
366366
}
367367

368368
/*
@@ -385,7 +385,7 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix
385385
if (write_locked_index(&the_index, &index_lock, CLOSE_LOCK))
386386
die(_("unable to write new_index file"));
387387
commit_style = COMMIT_NORMAL;
388-
return index_lock.filename;
388+
return index_lock.filename.buf;
389389
}
390390

391391
/*
@@ -472,9 +472,9 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix
472472
die(_("unable to write temporary index file"));
473473

474474
discard_cache();
475-
read_cache_from(false_lock.filename);
475+
read_cache_from(false_lock.filename.buf);
476476

477-
return false_lock.filename;
477+
return false_lock.filename.buf;
478478
}
479479

480480
static int run_status(FILE *fp, const char *index_file, const char *prefix, int nowarn,

builtin/reflog.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused,
431431
write_str_in_full(lock->lock_fd, "\n") != 1 ||
432432
close_ref(lock) < 0)) {
433433
status |= error("Couldn't write %s",
434-
lock->lk->filename);
434+
lock->lk->filename.buf);
435435
unlink(newlog_path);
436436
} else if (rename(newlog_path, log_file)) {
437437
status |= error("cannot rename %s to %s",

cache.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ struct lock_file {
580580
volatile int fd;
581581
volatile pid_t owner;
582582
char on_list;
583-
char filename[PATH_MAX];
583+
struct strbuf filename;
584584
};
585585
#define LOCK_DIE_ON_ERROR 1
586586
#define LOCK_NODEREF 2

config.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2024,9 +2024,9 @@ int git_config_set_multivar_in_file(const char *config_filename,
20242024
MAP_PRIVATE, in_fd, 0);
20252025
close(in_fd);
20262026

2027-
if (chmod(lock->filename, st.st_mode & 07777) < 0) {
2027+
if (chmod(lock->filename.buf, st.st_mode & 07777) < 0) {
20282028
error("chmod on %s failed: %s",
2029-
lock->filename, strerror(errno));
2029+
lock->filename.buf, strerror(errno));
20302030
ret = CONFIG_NO_WRITE;
20312031
goto out_free;
20322032
}
@@ -2106,7 +2106,7 @@ int git_config_set_multivar_in_file(const char *config_filename,
21062106
return ret;
21072107

21082108
write_err_out:
2109-
ret = write_error(lock->filename);
2109+
ret = write_error(lock->filename.buf);
21102110
goto out_free;
21112111

21122112
}
@@ -2207,9 +2207,9 @@ int git_config_rename_section_in_file(const char *config_filename,
22072207

22082208
fstat(fileno(config_file), &st);
22092209

2210-
if (chmod(lock->filename, st.st_mode & 07777) < 0) {
2210+
if (chmod(lock->filename.buf, st.st_mode & 07777) < 0) {
22112211
ret = error("chmod on %s failed: %s",
2212-
lock->filename, strerror(errno));
2212+
lock->filename.buf, strerror(errno));
22132213
goto out;
22142214
}
22152215

@@ -2230,7 +2230,7 @@ int git_config_rename_section_in_file(const char *config_filename,
22302230
}
22312231
store.baselen = strlen(new_name);
22322232
if (!store_write_section(out_fd, new_name)) {
2233-
ret = write_error(lock->filename);
2233+
ret = write_error(lock->filename.buf);
22342234
goto out;
22352235
}
22362236
/*
@@ -2256,7 +2256,7 @@ int git_config_rename_section_in_file(const char *config_filename,
22562256
continue;
22572257
length = strlen(output);
22582258
if (write_in_full(out_fd, output, length) != length) {
2259-
ret = write_error(lock->filename);
2259+
ret = write_error(lock->filename.buf);
22602260
goto out;
22612261
}
22622262
}

lockfile.c

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@
4747
* failed attempt to lock, or a failed close_lock_file()). In this
4848
* state:
4949
* - active is unset
50-
* - filename[0] == '\0' (usually, though there are transitory states
51-
* in which this condition doesn't hold). Client code should *not*
52-
* rely on this fact!
50+
* - filename is empty (usually, though there are transitory
51+
* states in which this condition doesn't hold). Client code should
52+
* *not* rely on the filename being empty in this state.
5353
* - fd is -1
5454
* - the object is left registered in the lock_file_list, and
5555
* on_list is set.
@@ -170,13 +170,6 @@ static char *resolve_symlink(char *p, size_t s)
170170
/* Make sure errno contains a meaningful value on error */
171171
static int lock_file(struct lock_file *lk, const char *path, int flags)
172172
{
173-
/*
174-
* subtract LOCK_SUFFIX_LEN from size to make sure there's
175-
* room for adding ".lock" for the lock file name:
176-
*/
177-
static const size_t max_path_len = sizeof(lk->filename) -
178-
LOCK_SUFFIX_LEN;
179-
180173
if (!lock_file_list) {
181174
/* One-time initialization */
182175
sigchain_push_common(remove_lock_file_on_signal);
@@ -191,30 +184,32 @@ static int lock_file(struct lock_file *lk, const char *path, int flags)
191184
lk->fd = -1;
192185
lk->active = 0;
193186
lk->owner = 0;
194-
lk->filename[0] = 0;
187+
strbuf_init(&lk->filename, PATH_MAX);
195188
lk->next = lock_file_list;
196189
lock_file_list = lk;
197190
lk->on_list = 1;
191+
} else if (lk->filename.len) {
192+
/* This shouldn't happen, but better safe than sorry. */
193+
die("BUG: lock_file(\"%s\") called with improperly-reset lock_file object",
194+
path);
198195
}
199196

200-
if (strlen(path) >= max_path_len) {
201-
errno = ENAMETOOLONG;
202-
return -1;
197+
strbuf_addstr(&lk->filename, path);
198+
if (!(flags & LOCK_NODEREF)) {
199+
resolve_symlink(lk->filename.buf, lk->filename.alloc);
200+
strbuf_setlen(&lk->filename, strlen(lk->filename.buf));
203201
}
204-
strcpy(lk->filename, path);
205-
if (!(flags & LOCK_NODEREF))
206-
resolve_symlink(lk->filename, max_path_len);
207-
strcat(lk->filename, LOCK_SUFFIX);
208-
lk->fd = open(lk->filename, O_RDWR | O_CREAT | O_EXCL, 0666);
202+
strbuf_addstr(&lk->filename, LOCK_SUFFIX);
203+
lk->fd = open(lk->filename.buf, O_RDWR | O_CREAT | O_EXCL, 0666);
209204
if (lk->fd < 0) {
210-
lk->filename[0] = 0;
205+
strbuf_reset(&lk->filename);
211206
return -1;
212207
}
213208
lk->owner = getpid();
214209
lk->active = 1;
215-
if (adjust_shared_perm(lk->filename)) {
210+
if (adjust_shared_perm(lk->filename.buf)) {
216211
int save_errno = errno;
217-
error("cannot fix permission bits on %s", lk->filename);
212+
error("cannot fix permission bits on %s", lk->filename.buf);
218213
rollback_lock_file(lk);
219214
errno = save_errno;
220215
return -1;
@@ -313,7 +308,7 @@ int reopen_lock_file(struct lock_file *lk)
313308
die(_("BUG: reopen a lockfile that is still open"));
314309
if (!lk->active)
315310
die(_("BUG: reopen a lockfile that has been committed"));
316-
lk->fd = open(lk->filename, O_WRONLY);
311+
lk->fd = open(lk->filename.buf, O_WRONLY);
317312
return lk->fd;
318313
}
319314

@@ -329,9 +324,9 @@ int commit_lock_file(struct lock_file *lk)
329324
return -1;
330325

331326
/* remove ".lock": */
332-
strbuf_add(&result_file, lk->filename,
333-
strlen(lk->filename) - LOCK_SUFFIX_LEN);
334-
err = rename(lk->filename, result_file.buf);
327+
strbuf_add(&result_file, lk->filename.buf,
328+
lk->filename.len - LOCK_SUFFIX_LEN);
329+
err = rename(lk->filename.buf, result_file.buf);
335330
strbuf_reset(&result_file);
336331
if (err) {
337332
int save_errno = errno;
@@ -341,7 +336,7 @@ int commit_lock_file(struct lock_file *lk)
341336
}
342337

343338
lk->active = 0;
344-
lk->filename[0] = 0;
339+
strbuf_reset(&lk->filename);
345340
return 0;
346341
}
347342

@@ -359,8 +354,8 @@ void rollback_lock_file(struct lock_file *lk)
359354
return;
360355

361356
if (!close_lock_file(lk)) {
362-
unlink_or_warn(lk->filename);
357+
unlink_or_warn(lk->filename.buf);
363358
lk->active = 0;
364-
lk->filename[0] = 0;
359+
strbuf_reset(&lk->filename);
365360
}
366361
}

read-cache.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2044,10 +2044,10 @@ static int commit_locked_index(struct lock_file *lk)
20442044
if (alternate_index_output) {
20452045
if (close_lock_file(lk))
20462046
return -1;
2047-
if (rename(lk->filename, alternate_index_output))
2047+
if (rename(lk->filename.buf, alternate_index_output))
20482048
return -1;
20492049
lk->active = 0;
2050-
lk->filename[0] = 0;
2050+
strbuf_reset(&lk->filename);
20512051
return 0;
20522052
} else {
20532053
return commit_lock_file(lk);

refs.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2607,8 +2607,8 @@ static int delete_ref_loose(struct ref_lock *lock, int flag)
26072607
* lockfile name, minus ".lock":
26082608
*/
26092609
char *loose_filename = xmemdupz(
2610-
lock->lk->filename,
2611-
strlen(lock->lk->filename) - LOCK_SUFFIX_LEN);
2610+
lock->lk->filename.buf,
2611+
lock->lk->filename.len - LOCK_SUFFIX_LEN);
26122612
int err = unlink_or_warn(loose_filename);
26132613
free(loose_filename);
26142614
if (err && errno != ENOENT)
@@ -2972,7 +2972,7 @@ int write_ref_sha1(struct ref_lock *lock,
29722972
write_in_full(lock->lock_fd, &term, 1) != 1 ||
29732973
close_ref(lock) < 0) {
29742974
int save_errno = errno;
2975-
error("Couldn't write %s", lock->lk->filename);
2975+
error("Couldn't write %s", lock->lk->filename.buf);
29762976
unlock_ref(lock);
29772977
errno = save_errno;
29782978
return -1;

shallow.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -269,8 +269,8 @@ void setup_alternate_shallow(struct lock_file *shallow_lock,
269269
if (write_shallow_commits(&sb, 0, extra)) {
270270
if (write_in_full(fd, sb.buf, sb.len) != sb.len)
271271
die_errno("failed to write to %s",
272-
shallow_lock->filename);
273-
*alternate_shallow_file = shallow_lock->filename;
272+
shallow_lock->filename.buf);
273+
*alternate_shallow_file = shallow_lock->filename.buf;
274274
} else
275275
/*
276276
* is_repository_shallow() sees empty string as "no
@@ -316,7 +316,7 @@ void prune_shallow(int show_only)
316316
if (write_shallow_commits_1(&sb, 0, NULL, SEEN_ONLY)) {
317317
if (write_in_full(fd, sb.buf, sb.len) != sb.len)
318318
die_errno("failed to write to %s",
319-
shallow_lock.filename);
319+
shallow_lock.filename.buf);
320320
commit_lock_file(&shallow_lock);
321321
} else {
322322
unlink(git_path("shallow"));

0 commit comments

Comments
 (0)