From patchwork Sun Mar 19 06:43:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Eggert X-Patchwork-Id: 13180233 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 86984C7618A for ; Sun, 19 Mar 2023 06:53:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230035AbjCSGxW (ORCPT ); Sun, 19 Mar 2023 02:53:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56682 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229541AbjCSGxT (ORCPT ); Sun, 19 Mar 2023 02:53:19 -0400 Received: from zimbra.cs.ucla.edu (zimbra.cs.ucla.edu [131.179.128.68]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 694E022DD1 for ; Sat, 18 Mar 2023 23:53:14 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 4131F160066 for ; Sat, 18 Mar 2023 23:44:13 -0700 (PDT) Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id dkdarnmKsWmQ; Sat, 18 Mar 2023 23:44:11 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 6FBBB160054; Sat, 18 Mar 2023 23:44:11 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.9.2 zimbra.cs.ucla.edu 6FBBB160054 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cs.ucla.edu; s=78364E5A-2AF3-11ED-87FA-8298ECA2D365; t=1679208251; bh=W85bXyL8cf+k1CFEpcuvxumEeyW0yTANJWnZOMNKT9M=; h=From:To:Subject:Date:Message-Id:MIME-Version: Content-Transfer-Encoding; b=vBCRxvCe7V63h5jaoXfjDaGNK+it4rN1asAvyU4ddu7JOHEgxRTG0sIfn65Cas1UM gQ0Sfv4+jawkTIfF317JiPp7dE/bWuisnSJqZ8P1oy16UMRel2OMLBEnuYISOfGxco ZVJ76Fwdt2YxPCSrPy1cWMooOQ/2Y8KYeud2pwiY= X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id FL5SY5VwqrBr; Sat, 18 Mar 2023 23:44:11 -0700 (PDT) Received: from penguin.cs.ucla.edu (Penguin.CS.UCLA.EDU [131.179.64.200]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id 3E112160045; Sat, 18 Mar 2023 23:44:11 -0700 (PDT) From: Paul Eggert To: git@vger.kernel.org Cc: Paul Eggert Subject: [PATCH 1/2] git-compat-util: time_now for current time Date: Sat, 18 Mar 2023 23:43:52 -0700 Message-Id: <20230319064353.686226-2-eggert@cs.ucla.edu> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230319064353.686226-1-eggert@cs.ucla.edu> References: <20230319064353.686226-1-eggert@cs.ucla.edu> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Add a function time_now to get the current time as a time_t value. All uses of time(NULL) or time(&xxx) changed to use this new function. This refactoring does not change behavior. Signed-off-by: Paul Eggert --- archive.c | 2 +- blame.c | 2 +- builtin/bugreport.c | 2 +- builtin/credential-cache--daemon.c | 4 ++-- builtin/diagnose.c | 2 +- builtin/fast-import.c | 2 +- builtin/fsmonitor--daemon.c | 4 ++-- builtin/gc.c | 2 +- builtin/log.c | 2 +- builtin/receive-pack.c | 2 +- builtin/reflog.c | 2 +- commit-graph.c | 4 ++-- compat/nedmalloc/malloc.c.h | 2 +- credential.c | 4 ++-- date.c | 6 +++--- git-compat-util.h | 5 +++++ http-backend.c | 2 +- http-push.c | 6 +++--- rerere.c | 2 +- run-command.c | 4 ++-- t/helper/test-chmtime.c | 4 ++-- t/helper/test-simple-ipc.c | 4 ++-- 22 files changed, 37 insertions(+), 32 deletions(-) diff --git a/archive.c b/archive.c index 1c2ca78e52..5cdafc9b56 100644 --- a/archive.c +++ b/archive.c @@ -472,7 +472,7 @@ static void parse_treeish_arg(const char **argv, archive_time = commit->date; } else { commit_oid = NULL; - archive_time = time(NULL); + archive_time = time_now(); } if (ar_args->mtime_option) archive_time = approxidate(ar_args->mtime_option); diff --git a/blame.c b/blame.c index e45d8a3bf9..df14c1dfe4 100644 --- a/blame.c +++ b/blame.c @@ -192,7 +192,7 @@ static struct commit *fake_working_tree_commit(struct repository *r, struct strbuf msg = STRBUF_INIT; repo_read_index(r); - time(&now); + now = time_now(); commit = alloc_commit_node(r); commit->object.parsed = 1; commit->date = now; diff --git a/builtin/bugreport.c b/builtin/bugreport.c index 5bc254be80..bba5820787 100644 --- a/builtin/bugreport.c +++ b/builtin/bugreport.c @@ -98,7 +98,7 @@ int cmd_bugreport(int argc, const char **argv, const char *prefix) struct strbuf buffer = STRBUF_INIT; struct strbuf report_path = STRBUF_INIT; int report = -1; - time_t now = time(NULL); + time_t now = time_now(); struct tm tm; enum diagnose_mode diagnose = DIAGNOSE_NONE; char *option_output = NULL; diff --git a/builtin/credential-cache--daemon.c b/builtin/credential-cache--daemon.c index 6e509d02c3..7a87df16d2 100644 --- a/builtin/credential-cache--daemon.c +++ b/builtin/credential-cache--daemon.c @@ -27,7 +27,7 @@ static void cache_credential(struct credential *c, int timeout) /* take ownership of pointers */ memcpy(&e->item, c, sizeof(*c)); memset(c, 0, sizeof(*c)); - e->expiration = time(NULL) + timeout; + e->expiration = time_now() + timeout; } static struct credential_cache_entry *lookup_credential(const struct credential *c) @@ -54,7 +54,7 @@ static timestamp_t check_expirations(void) { static timestamp_t wait_for_entry_until; int i = 0; - timestamp_t now = time(NULL); + timestamp_t now = time_now(); timestamp_t next = TIME_MAX; /* diff --git a/builtin/diagnose.c b/builtin/diagnose.c index d52015c67a..c502096e6c 100644 --- a/builtin/diagnose.c +++ b/builtin/diagnose.c @@ -11,7 +11,7 @@ static const char * const diagnose_usage[] = { int cmd_diagnose(int argc, const char **argv, const char *prefix) { struct strbuf zip_path = STRBUF_INIT; - time_t now = time(NULL); + time_t now = time_now(); struct tm tm; enum diagnose_mode mode = DIAGNOSE_STATS; char *option_output = NULL; diff --git a/builtin/fast-import.c b/builtin/fast-import.c index f7548ff4a3..9096f52075 100644 --- a/builtin/fast-import.c +++ b/builtin/fast-import.c @@ -335,7 +335,7 @@ static void write_crash_report(const char *err) fprintf(rpt, "fast-import crash report:\n"); fprintf(rpt, " fast-import process: %"PRIuMAX"\n", (uintmax_t) getpid()); fprintf(rpt, " parent process : %"PRIuMAX"\n", (uintmax_t) getppid()); - fprintf(rpt, " at %s\n", show_date(time(NULL), 0, DATE_MODE(ISO8601))); + fprintf(rpt, " at %s\n", show_date(time_now(), 0, DATE_MODE(ISO8601))); fputc('\n', rpt); fputs("fatal: ", rpt); diff --git a/builtin/fsmonitor--daemon.c b/builtin/fsmonitor--daemon.c index cae804a190..45cc8134cc 100644 --- a/builtin/fsmonitor--daemon.c +++ b/builtin/fsmonitor--daemon.c @@ -415,7 +415,7 @@ static struct fsmonitor_token_data *fsmonitor_new_token_data(void) * events to accumulate. */ if (test_env_value) - batch->pinned_time = time(NULL); + batch->pinned_time = time_now(); return token; } @@ -772,7 +772,7 @@ static int do_handle_client(struct fsmonitor_daemon_state *state, */ token_data = state->current_token_data; batch_head = token_data->batch_head; - ((struct fsmonitor_batch *)batch_head)->pinned_time = time(NULL); + ((struct fsmonitor_batch *)batch_head)->pinned_time = time_now(); /* * FSMonitor Protocol V2 requires that we send a response header diff --git a/builtin/gc.c b/builtin/gc.c index c58fe8c936..029bd2ba5c 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -450,7 +450,7 @@ static const char *lock_repo_for_gc(int force, pid_t* ret_pid) * after the user verifies that no gc is * running. */ - time(NULL) - st.st_mtime <= 12 * 3600 && + time_now() - st.st_mtime <= 12 * 3600 && fscanf(fp, scan_fmt, &pid, locking_host) == 2 && /* be gentle to concurrent "gc" on remote hosts */ (strcmp(locking_host, my_host) || !kill(pid, 0) || errno == EPERM); diff --git a/builtin/log.c b/builtin/log.c index b62e629ba8..bdc62d9b9e 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -1168,7 +1168,7 @@ static void gen_message_id(struct rev_info *info, char *base) { struct strbuf buf = STRBUF_INIT; strbuf_addf(&buf, "%s.%"PRItime".git.%s", base, - (timestamp_t) time(NULL), + (timestamp_t) time_now(), git_committer_info(IDENT_NO_NAME|IDENT_NO_DATE|IDENT_STRICT)); info->message_id = strbuf_detach(&buf, NULL); } diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index fe68c79ee3..3fedeea65c 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -2504,7 +2504,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix) git_config(receive_pack_config, NULL); if (cert_nonce_seed) - push_cert_nonce = prepare_push_cert_nonce(service_dir, time(NULL)); + push_cert_nonce = prepare_push_cert_nonce(service_dir, time_now()); if (0 <= transfer_unpack_limit) unpack_limit = transfer_unpack_limit; diff --git a/builtin/reflog.c b/builtin/reflog.c index 270681dcdf..013673e768 100644 --- a/builtin/reflog.c +++ b/builtin/reflog.c @@ -237,7 +237,7 @@ static int cmd_reflog_show(int argc, const char **argv, const char *prefix) static int cmd_reflog_expire(int argc, const char **argv, const char *prefix) { struct cmd_reflog_expire_cb cmd = { 0 }; - timestamp_t now = time(NULL); + timestamp_t now = time_now(); int i, status, do_all, all_worktrees = 1; unsigned int flags = 0; int verbose = 0; diff --git a/commit-graph.c b/commit-graph.c index 5e6098ff35..4c75d96fc4 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -2196,7 +2196,7 @@ static void merge_commit_graphs(struct write_commit_graph_context *ctx) static void mark_commit_graphs(struct write_commit_graph_context *ctx) { uint32_t i; - time_t now = time(NULL); + time_t now = time_now(); for (i = ctx->num_commit_graphs_after - 1; i < ctx->num_commit_graphs_before; i++) { struct stat st; @@ -2217,7 +2217,7 @@ static void expire_commit_graphs(struct write_commit_graph_context *ctx) DIR *dir; struct dirent *de; size_t dirnamelen; - timestamp_t expire_time = time(NULL); + timestamp_t expire_time = time_now(); if (ctx->opts && ctx->opts->expire_time) expire_time = ctx->opts->expire_time; diff --git a/compat/nedmalloc/malloc.c.h b/compat/nedmalloc/malloc.c.h index 814845d4b3..4c30a49e60 100644 --- a/compat/nedmalloc/malloc.c.h +++ b/compat/nedmalloc/malloc.c.h @@ -3085,7 +3085,7 @@ static int init_mparams(void) { #ifdef WIN32 magic = (size_t)(GetTickCount() ^ (size_t)0x55555555U); #else - magic = (size_t)(time(0) ^ (size_t)0x55555555U); + magic = (size_t)(time_now() ^ (size_t)0x55555555U); #endif magic |= (size_t)8U; /* ensure nonzero */ magic &= ~(size_t)7U; /* improve chances of fault for bad values */ diff --git a/credential.c b/credential.c index ea40a2a410..dc750fa502 100644 --- a/credential.c +++ b/credential.c @@ -356,7 +356,7 @@ void credential_fill(struct credential *c) for (i = 0; i < c->helpers.nr; i++) { credential_do(c, c->helpers.items[i].string, "get"); - if (c->password_expiry_utc < time(NULL)) { + if (c->password_expiry_utc < time_now()) { /* Discard expired password */ FREE_AND_NULL(c->password); /* Reset expiry to maintain consistency */ @@ -380,7 +380,7 @@ void credential_approve(struct credential *c) if (c->approved) return; - if (!c->username || !c->password || c->password_expiry_utc < time(NULL)) + if (!c->username || !c->password || c->password_expiry_utc < time_now()) return; credential_apply_config(c); diff --git a/date.c b/date.c index 6f45eeb356..16717be397 100644 --- a/date.c +++ b/date.c @@ -597,7 +597,7 @@ static int match_multi_number(timestamp_t num, char c, const char *date, case '/': case '.': if (!now) - now = time(NULL); + now = time_now(); refuse_future = NULL; if (gmtime_r(&now, &now_tm)) refuse_future = &now_tm; @@ -712,7 +712,7 @@ static int match_digit(const char *date, struct tm *tm, int *offset, int *tm_gmt unsigned int num2 = (num % 10000) / 100; unsigned int num3 = num % 100; if (n == 8) - set_date(num1, num2, num3, NULL, time(NULL), tm); + set_date(num1, num2, num3, NULL, time_now(), tm); else if (n == 6 && set_time(num1, num2, num3, tm) == 0 && *end == '.' && isdigit(end[1])) strtoul(end + 1, &end, 10); @@ -1041,7 +1041,7 @@ void datestamp(struct strbuf *out) int offset; struct tm tm = { 0 }; - time(&now); + now = time_now(); offset = tm_to_time_t(localtime_r(&now, &tm)) - now; offset /= 60; diff --git a/git-compat-util.h b/git-compat-util.h index 1e6592624d..d05f4bac22 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -339,6 +339,11 @@ static inline const char *precompose_string_if_needed(const char *in) int compat_mkdir_wo_trailing_slash(const char*, mode_t); #endif +static inline time_t time_now(void) +{ + return time(NULL); +} + #ifdef NO_STRUCT_ITIMERVAL struct itimerval { struct timeval it_interval; diff --git a/http-backend.c b/http-backend.c index 9cfc6f2541..d533989e32 100644 --- a/http-backend.c +++ b/http-backend.c @@ -113,7 +113,7 @@ static void hdr_nocache(struct strbuf *hdr) static void hdr_cache_forever(struct strbuf *hdr) { - timestamp_t now = time(NULL); + timestamp_t now = time_now(); hdr_date(hdr, "Date", now); hdr_date(hdr, "Expires", now + 31536000); hdr_str(hdr, "Cache-Control", "public, max-age=31536000"); diff --git a/http-push.c b/http-push.c index 88aa045ecb..d8158667a0 100644 --- a/http-push.c +++ b/http-push.c @@ -459,7 +459,7 @@ static int refresh_lock(struct remote_lock *lock) fprintf(stderr, "LOCK HTTP error %ld\n", results.http_code); } else { - lock->start_time = time(NULL); + lock->start_time = time_now(); rc = 1; } } @@ -473,7 +473,7 @@ static int refresh_lock(struct remote_lock *lock) static void check_locks(void) { struct remote_lock *lock = repo->locks; - time_t current_time = time(NULL); + time_t current_time = time_now(); int time_remaining; while (lock) { @@ -933,7 +933,7 @@ static struct remote_lock *lock_remote(const char *path, long timeout) FREE_AND_NULL(lock); } else { lock->url = url; - lock->start_time = time(NULL); + lock->start_time = time_now(); lock->next = repo->locks; repo->locks = lock; } diff --git a/rerere.c b/rerere.c index a67abaab07..ac36a9c234 100644 --- a/rerere.c +++ b/rerere.c @@ -1179,7 +1179,7 @@ void rerere_gc(struct repository *r, struct string_list *rr) DIR *dir; struct dirent *e; int i; - timestamp_t now = time(NULL); + timestamp_t now = time_now(); timestamp_t cutoff_noresolve = now - 15 * 86400; timestamp_t cutoff_resolve = now - 60 * 86400; diff --git a/run-command.c b/run-command.c index ba617655b2..fbf9afdb27 100644 --- a/run-command.c +++ b/run-command.c @@ -1864,7 +1864,7 @@ enum start_bg_result start_bg_command(struct child_process *cmd, goto done; } - time(&time_limit); + time_limit = time_now(); time_limit += timeout_sec; wait: @@ -1891,7 +1891,7 @@ enum start_bg_result start_bg_command(struct child_process *cmd, */ time_t now; - time(&now); + now = time_now(); if (now < time_limit) goto wait; diff --git a/t/helper/test-chmtime.c b/t/helper/test-chmtime.c index dc28890a18..f48a07f6f7 100644 --- a/t/helper/test-chmtime.c +++ b/t/helper/test-chmtime.c @@ -7,7 +7,7 @@ * * test-tool chmtime = file... * - * Relative to the current time as returned by time(3): + * Relative to the current time as returned by time_now(): * * test-tool chmtime =+ (or =-) file... * @@ -60,7 +60,7 @@ static int timespec_arg(const char *arg, long int *set_time, int *set_eq) return 0; } if ((*set_eq && *set_time < 0) || *set_eq == 2) { - time_t now = time(NULL); + time_t now = time_now(); *set_time += now; } return 1; diff --git a/t/helper/test-simple-ipc.c b/t/helper/test-simple-ipc.c index 3d1436da59..2267cd9fac 100644 --- a/t/helper/test-simple-ipc.c +++ b/t/helper/test-simple-ipc.c @@ -411,7 +411,7 @@ static int client__stop_server(void) time_t time_limit, now; enum ipc_active_state s; - time(&time_limit); + time_limit = time_now(); time_limit += cl_args.max_wait_sec; cl_args.token = "quit"; @@ -434,7 +434,7 @@ static int client__stop_server(void) return 0; } - time(&now); + now = time_now(); if (now > time_limit) return error("daemon has not shutdown yet"); } From patchwork Sun Mar 19 06:43:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Eggert X-Patchwork-Id: 13180232 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6E191C7618A for ; Sun, 19 Mar 2023 06:53:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229997AbjCSGxU (ORCPT ); Sun, 19 Mar 2023 02:53:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56580 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229938AbjCSGxQ (ORCPT ); Sun, 19 Mar 2023 02:53:16 -0400 X-Greylist: delayed 546 seconds by postgrey-1.37 at lindbergh.monkeyblade.net; Sat, 18 Mar 2023 23:53:14 PDT Received: from zimbra.cs.ucla.edu (zimbra.cs.ucla.edu [131.179.128.68]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C84ED206B3 for ; Sat, 18 Mar 2023 23:53:14 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id C6EB316006A for ; Sat, 18 Mar 2023 23:44:16 -0700 (PDT) Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id 02a5hMAfVb9T; Sat, 18 Mar 2023 23:44:16 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id E0E84160054; Sat, 18 Mar 2023 23:44:15 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.9.2 zimbra.cs.ucla.edu E0E84160054 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cs.ucla.edu; s=78364E5A-2AF3-11ED-87FA-8298ECA2D365; t=1679208255; bh=rzit9Do7A7WxrlLM+e6ILmwozG7oCg8MsY8OonRAJj8=; h=From:To:Subject:Date:Message-Id:MIME-Version: Content-Transfer-Encoding; b=cvmq/wJUR7oNBkextWZ+5j8xul/Q032ZhbICAvU3RZeJGBd5FJd6yZhbBErO3b8Wz gWZksrWg3TGrjAnxU8tTZhSqbuW2rdsN4Dalb6GsMGB44uJLiX4QcJsK/EjRDXjF5y OZXEQmXcAnkCJ+6rox14/lEELHyRNKh/4QVPDuQA= X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id O37ExH3DymmP; Sat, 18 Mar 2023 23:44:15 -0700 (PDT) Received: from penguin.cs.ucla.edu (Penguin.CS.UCLA.EDU [131.179.64.200]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id 9ECBD160045; Sat, 18 Mar 2023 23:44:15 -0700 (PDT) From: Paul Eggert To: git@vger.kernel.org Cc: Paul Eggert Subject: [PATCH 2/2] git-compat-util: use gettimeofday for current time Date: Sat, 18 Mar 2023 23:43:53 -0700 Message-Id: <20230319064353.686226-3-eggert@cs.ucla.edu> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230319064353.686226-1-eggert@cs.ucla.edu> References: <20230319064353.686226-1-eggert@cs.ucla.edu> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Use gettimeofday instead of time(NULL) to get current time. This avoids clock skew on glibc 2.31+ on Linux, where in the first 1 to 2.5 ms of every second, time(NULL) returns a value that is one less than the tv_sec part of higher-resolution timestamps such as those returned by gettimeofday or timespec_get, or those in the file system. There are similar clock skew problems on AIX and MS-Windows, which have problems in the first 5 ms of every second. Without this patch, users can observe Git issuing a timestamp T+1 before it issues timestamp T, because Git sometimes uses time(NULL) or time(&t) and sometimes uses higher-res methods like gettimeofday. Although strictly speaking users should tolerate this behavuior because a superuser can always change the clock back, this is a quality of implementation issue and users naturally expect Git to issue timestamps in increasing order unless the superuser has fiddled with the system clock. This patch always uses gettimeofday(...) instead of time(...), and I have verified that the resulting .o files never refer to the name 'time'. A trickier patch would change only those calls for which timestamp monotonicity is user-visible. Such a patch would require more expertise about Git internals, though, and would be harder to maintain later. Another possibility would be to change Git's documentation to warn users that Git does not always issue timestamps in increasing order. However, Git users would likely be either dismayed by this possibility, or confused by the level of detail that any such documentation would require. Yet another possibility would be to fix the Linux kernel so that the time syscall is consistent with the other timestamp syscalls. I suppose this has not been done due to performance implications. (Git's use of timestamps is rare enough that performance is not a significant consideration for git.) However, this wouldn't fix Git's problem on older Linux kernels, or on AIX or MS-Windows. Signed-off-by: Paul Eggert Signed-off-by: Junio C Hamano --- git-compat-util.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/git-compat-util.h b/git-compat-util.h index d05f4bac22..dcd9e5ca65 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -341,7 +341,10 @@ int compat_mkdir_wo_trailing_slash(const char*, mode_t); static inline time_t time_now(void) { - return time(NULL); + /* Avoid time(NULL), which can disagree with gettimeofday etc. */ + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec; } #ifdef NO_STRUCT_ITIMERVAL