From 8ec11f3e7220fc84c5c019e91a58253d838c89a8 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 23 Jul 2022 12:11:49 -0700 Subject: [PATCH] =?utf8?q?rm:=20don=E2=80=99t=20assume=20st=5Fsize=20is=20?= =?utf8?q?nonnegative?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit * src/remove.c: Include stat-time.h. (cache_fstatat, cache_stat_init): Use negative st->st_atim.tv_sec to determine whether the stat is cached, not negative st->st_size. On non-POSIX platforms that lack st_atim.tv_sec, don’t bother to cache. --- src/remove.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/remove.c b/src/remove.c index b5d1ea8a2f..e2f27ca4fb 100644 --- a/src/remove.c +++ b/src/remove.c @@ -28,6 +28,7 @@ #include "ignore-value.h" #include "remove.h" #include "root-dev-ino.h" +#include "stat-time.h" #include "write-any-file.h" #include "xfts.h" #include "yesno.h" @@ -62,29 +63,37 @@ enum Prompt_action # define DT_LNK 2 #endif -/* Like fstatat, but cache the result. If ST->st_size is -1, the - status has not been gotten yet. If less than -1, fstatat failed - with errno == ST->st_ino. Otherwise, the status has already - been gotten, so return 0. */ +/* Like fstatat, but cache on POSIX-compatible systems. */ static int cache_fstatat (int fd, char const *file, struct stat *st, int flag) { - if (st->st_size == -1 && fstatat (fd, file, st, flag) != 0) +#if HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC + /* If ST->st_atim.tv_nsec is -1, the status has not been gotten yet. + If less than -1, fstatat failed with errno == ST->st_ino. + Otherwise, the status has already been gotten, so return 0. */ + if (0 <= st->st_atim.tv_nsec) + return 0; + if (st->st_atim.tv_nsec == -1) { - st->st_size = -2; + if (fstatat (fd, file, st, flag) == 0) + return 0; + st->st_atim.tv_nsec = -2; st->st_ino = errno; } - if (0 <= st->st_size) - return 0; - errno = (int) st->st_ino; + errno = st->st_ino; return -1; +#else + return fstatat (fd, file, st, flag); +#endif } /* Initialize a fstatat cache *ST. Return ST for convenience. */ static inline struct stat * cache_stat_init (struct stat *st) { - st->st_size = -1; +#if HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC + st->st_atim.tv_nsec = -1; +#endif return st; } -- 2.47.2