From: Paul Eggert Date: Sat, 23 Jul 2022 19:11:49 +0000 (-0700) Subject: rm: don’t assume st_size is nonnegative X-Git-Tag: v9.2~173 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8ec11f3e7220fc84c5c019e91a58253d838c89a8;p=thirdparty%2Fcoreutils.git rm: don’t assume st_size is nonnegative * 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. --- 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; }