treewide: use utimensat(2) instead of legacy utime(3p)
Now that a compatibility wrapper for utimensat(2) has been introduced, migrate all call sites across the codebase to use utimensat(2) instead of the legacy utime(3p) interface: - In `commit-graph.c`, use utimensat(2) with UTIME_OMIT and the computed timestamp `now` to bump the commit-graph modification time consistently across all files without needing an extra stat(2) call to preserve atime. - In `copy.c`, use utimensat(2) to copy full sub-second access and modification timestamps from the source file. - In `odb/source-packed.c`, `odb/source-loose.c`, and `object-file.c`, use utimensat(2) with `struct timespec` to freshen file timestamps. - In `builtin/pack-objects.c`, update the pack timestamp with utimensat(2). - In `rerere.c`, touch the postimage file with utimensat(2) passing NULL to set both atime and mtime to current time. - In `t/helper/test-chmtime.c`, update file modification times using utimensat(2). Signed-off-by: Alexey Samsonov <vonosmas@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>jch
parent
be2b0a8f00
commit
2c8ab1aa3e
|
|
@ -1438,11 +1438,13 @@ static void write_pack_file(void)
|
|||
} else if (!last_mtime) {
|
||||
last_mtime = st.st_mtime;
|
||||
} else {
|
||||
struct utimbuf utb;
|
||||
utb.actime = st.st_atime;
|
||||
utb.modtime = --last_mtime;
|
||||
if (utime(pack_tmp_name, &utb) < 0)
|
||||
warning_errno(_("failed utime() on %s"), pack_tmp_name);
|
||||
struct timespec times[2];
|
||||
times[0].tv_sec = st.st_atime;
|
||||
times[0].tv_nsec = ST_ATIME_NSEC(st);
|
||||
times[1].tv_sec = --last_mtime;
|
||||
times[1].tv_nsec = 0;
|
||||
if (utimensat(AT_FDCWD, pack_tmp_name, times, 0) < 0)
|
||||
warning_errno(_("failed utimensat() on %s"), pack_tmp_name);
|
||||
}
|
||||
|
||||
strbuf_addf(&tmpname, "%s-%s.", base_name,
|
||||
|
|
|
|||
|
|
@ -2484,18 +2484,13 @@ static void mark_commit_graphs(struct write_commit_graph_context *ctx)
|
|||
{
|
||||
uint32_t i;
|
||||
time_t now = time(NULL);
|
||||
struct timespec times[2] = {
|
||||
{ .tv_nsec = UTIME_OMIT },
|
||||
{ .tv_sec = now, .tv_nsec = 0 },
|
||||
};
|
||||
|
||||
for (i = ctx->num_commit_graphs_after - 1; i < ctx->num_commit_graphs_before; i++) {
|
||||
struct stat st;
|
||||
struct utimbuf updated_time;
|
||||
|
||||
if (stat(ctx->commit_graph_filenames_before[i], &st) < 0)
|
||||
continue;
|
||||
|
||||
updated_time.actime = st.st_atime;
|
||||
updated_time.modtime = now;
|
||||
utime(ctx->commit_graph_filenames_before[i], &updated_time);
|
||||
}
|
||||
for (i = ctx->num_commit_graphs_after - 1; i < ctx->num_commit_graphs_before; i++)
|
||||
utimensat(AT_FDCWD, ctx->commit_graph_filenames_before[i], times, 0);
|
||||
}
|
||||
|
||||
static void expire_commit_graphs(struct write_commit_graph_context *ctx)
|
||||
|
|
|
|||
10
copy.c
10
copy.c
|
|
@ -23,12 +23,14 @@ int copy_fd(int ifd, int ofd)
|
|||
static int copy_times(const char *dst, const char *src)
|
||||
{
|
||||
struct stat st;
|
||||
struct utimbuf times;
|
||||
struct timespec times[2];
|
||||
if (stat(src, &st) < 0)
|
||||
return -1;
|
||||
times.actime = st.st_atime;
|
||||
times.modtime = st.st_mtime;
|
||||
if (utime(dst, ×) < 0)
|
||||
times[0].tv_sec = st.st_atime;
|
||||
times[0].tv_nsec = ST_ATIME_NSEC(st);
|
||||
times[1].tv_sec = st.st_mtime;
|
||||
times[1].tv_nsec = ST_MTIME_NSEC(st);
|
||||
if (utimensat(AT_FDCWD, dst, times, 0) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,15 +69,17 @@ const char *odb_loose_path(struct odb_source_loose *loose,
|
|||
/* Returns 1 if we have successfully freshened the file, 0 otherwise. */
|
||||
static int freshen_file(const char *fn, const time_t *mtime)
|
||||
{
|
||||
struct utimbuf times, *timesp = NULL;
|
||||
struct timespec times[2], *timesp = NULL;
|
||||
|
||||
if (mtime) {
|
||||
times.actime = *mtime;
|
||||
times.modtime = *mtime;
|
||||
timesp = ×
|
||||
times[0].tv_sec = *mtime;
|
||||
times[0].tv_nsec = 0;
|
||||
times[1].tv_sec = *mtime;
|
||||
times[1].tv_nsec = 0;
|
||||
timesp = times;
|
||||
}
|
||||
|
||||
return !utime(fn, timesp);
|
||||
return !utimensat(AT_FDCWD, fn, timesp, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -807,14 +807,14 @@ static int write_loose_object(struct odb_source_loose *loose,
|
|||
close_loose_object(loose, fd, tmp_file.buf);
|
||||
|
||||
if (mtime) {
|
||||
struct utimbuf utb = {
|
||||
.actime = *mtime,
|
||||
.modtime = *mtime,
|
||||
struct timespec times[2] = {
|
||||
{ .tv_sec = *mtime },
|
||||
{ .tv_sec = *mtime },
|
||||
};
|
||||
|
||||
if (utime(tmp_file.buf, &utb) < 0 &&
|
||||
if (utimensat(AT_FDCWD, tmp_file.buf, times, 0) < 0 &&
|
||||
!(flags & ODB_WRITE_OBJECT_SILENT))
|
||||
warning_errno(_("failed utime() on %s"), tmp_file.buf);
|
||||
warning_errno(_("failed utimensat() on %s"), tmp_file.buf);
|
||||
}
|
||||
|
||||
return finalize_object_file_flags(loose->base.odb->repo, tmp_file.buf, filename.buf,
|
||||
|
|
|
|||
|
|
@ -574,13 +574,15 @@ static int odb_source_packed_freshen_object(struct odb_source *source,
|
|||
const time_t *mtime)
|
||||
{
|
||||
struct odb_source_packed *packed = odb_source_packed_downcast(source);
|
||||
struct utimbuf times, *timesp = NULL;
|
||||
struct timespec times[2], *timesp = NULL;
|
||||
struct pack_entry e;
|
||||
|
||||
if (mtime) {
|
||||
times.actime = *mtime;
|
||||
times.modtime = *mtime;
|
||||
timesp = ×
|
||||
times[0].tv_sec = *mtime;
|
||||
times[0].tv_nsec = 0;
|
||||
times[1].tv_sec = *mtime;
|
||||
times[1].tv_nsec = 0;
|
||||
timesp = times;
|
||||
}
|
||||
|
||||
if (!find_pack_entry(packed, oid, &e))
|
||||
|
|
@ -589,7 +591,7 @@ static int odb_source_packed_freshen_object(struct odb_source *source,
|
|||
return 0;
|
||||
if (e.p->freshened)
|
||||
return 1;
|
||||
if (utime(e.p->pack_name, timesp))
|
||||
if (utimensat(AT_FDCWD, e.p->pack_name, timesp, 0))
|
||||
return 0;
|
||||
e.p->freshened = 1;
|
||||
|
||||
|
|
|
|||
4
rerere.c
4
rerere.c
|
|
@ -658,8 +658,8 @@ static int merge(struct index_state *istate, const struct rerere_id *id, const c
|
|||
* A successful replay of recorded resolution.
|
||||
* Mark that "postimage" was used to help gc.
|
||||
*/
|
||||
if (utime(rerere_path(&buf, id, "postimage"), NULL) < 0)
|
||||
warning_errno(_("failed utime() on '%s'"),
|
||||
if (utimensat(AT_FDCWD, rerere_path(&buf, id, "postimage"), NULL, 0) < 0)
|
||||
warning_errno(_("failed utimensat() on '%s'"),
|
||||
rerere_path(&buf, id, "postimage"));
|
||||
|
||||
/* Update "path" with the resolution */
|
||||
|
|
|
|||
|
|
@ -105,7 +105,8 @@ int cmd__chmtime(int argc, const char **argv)
|
|||
|
||||
for (; i < argc; i++) {
|
||||
struct stat sb;
|
||||
struct utimbuf utb;
|
||||
struct timespec times[2];
|
||||
int64_t mtime_sec;
|
||||
uintmax_t mtime;
|
||||
|
||||
if (stat(argv[i], &sb) < 0) {
|
||||
|
|
@ -123,22 +124,26 @@ int cmd__chmtime(int argc, const char **argv)
|
|||
}
|
||||
#endif
|
||||
|
||||
utb.actime = sb.st_atime;
|
||||
utb.modtime = set_eq ? set_time : sb.st_mtime + set_time;
|
||||
mtime_sec = set_eq ? set_time : sb.st_mtime + set_time;
|
||||
|
||||
mtime = utb.modtime < 0 ? 0: utb.modtime;
|
||||
times[0].tv_sec = sb.st_atime;
|
||||
times[0].tv_nsec = ST_ATIME_NSEC(sb);
|
||||
times[1].tv_sec = mtime_sec;
|
||||
times[1].tv_nsec = 0;
|
||||
|
||||
mtime = mtime_sec < 0 ? 0 : mtime_sec;
|
||||
if (get) {
|
||||
printf("%"PRIuMAX"\n", mtime);
|
||||
} else if (verbose) {
|
||||
printf("%"PRIuMAX"\t%s\n", mtime, argv[i]);
|
||||
}
|
||||
|
||||
if (utb.modtime != sb.st_mtime && utime(argv[i], &utb) < 0) {
|
||||
if (mtime_sec != sb.st_mtime && utimensat(AT_FDCWD, argv[i], times, 0) < 0) {
|
||||
#ifdef GIT_WINDOWS_NATIVE
|
||||
if (S_ISDIR(sb.st_mode)) {
|
||||
/*
|
||||
* NEEDSWORK: The Windows version of `utime()`
|
||||
* (aka `mingw_utime()`) does not correctly
|
||||
* NEEDSWORK: The Windows version of `utimensat()`
|
||||
* (aka `mingw_utimensat()`) does not correctly
|
||||
* handle directory arguments, since it uses
|
||||
* `_wopen()`. Ignore it for now since this
|
||||
* is just a test.
|
||||
|
|
|
|||
Loading…
Reference in New Issue