]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
tail: prefer readlink to lstat+S_ISLNK
authorPaul Eggert <eggert@cs.ucla.edu>
Sat, 2 Aug 2025 19:58:06 +0000 (12:58 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Mon, 4 Aug 2025 02:48:06 +0000 (19:48 -0700)
When not already calling lstat for some other reason,
prefer readlink to lstat+S_ISLNK,
as readlink does not suffer from EOVERFLOW issues.
* src/rmdir.c (main):
* src/tail.c (recheck, any_symlinks):
* src/test.c (unary_operator):

src/rmdir.c
src/tail.c
src/test.c

index 88fcb2521dfbfc9c6f24af629e9efd22cd048aa5..fead0bb198da67139e5593cde143d588bbfa4213 100644 (file)
@@ -269,8 +269,8 @@ main (int argc, char **argv)
                       /* Ensure the last component was a symlink.  */
                       char *dir_arg = xstrdup (dir);
                       strip_trailing_slashes (dir);
-                      ret = lstat (dir, &st);
-                      if (ret == 0 && S_ISLNK (st.st_mode))
+                      char linkbuf[1];
+                      if (0 <= readlink (dir, linkbuf, 1))
                         {
                           error (0, 0,
                                  _("failed to remove %s:"
index 2579f4e13b4fc252fbe3571aa0d672177a6b178e..5543cc24cd2a306e35448d241d0fd2450a3f21ae 100644 (file)
@@ -975,8 +975,8 @@ recheck (struct File_spec *f, bool blocking)
      then mark the file as not tailable.  */
   f->tailable = !(reopen_inaccessible_files && fd < 0);
 
-  if (! disable_inotify && ! lstat (f->name, &new_stats)
-      && S_ISLNK (new_stats.st_mode))
+  char linkbuf[1];
+  if (! disable_inotify && 0 <= readlink (f->name, linkbuf, 1))
     {
       /* Diagnose the edge case where a regular file is changed
          to a symlink.  We avoid inotify with symlinks since
@@ -1352,9 +1352,9 @@ any_non_remote_file (const struct File_spec *f, int n_files)
 static bool
 any_symlinks (const struct File_spec *f, int n_files)
 {
-  struct stat st;
+  char linkbuf[1];
   for (int i = 0; i < n_files; i++)
-    if (lstat (f[i].name, &st) == 0 && S_ISLNK (st.st_mode))
+    if (0 <= readlink (f[i].name, linkbuf, 1))
       return true;
   return false;
 }
index fd9aa0d29487da9fd4c3758b45c1c31f8c5a8b03..583cf74c9c69e13b09081b053a7f4a5efcc6fc45 100644 (file)
@@ -464,8 +464,8 @@ unary_operator (void)
 
     case 'h':                  /* File is a symbolic link? */
       unary_advance ();
-      return (lstat (argv[pos - 1], &stat_buf) == 0
-              && S_ISLNK (stat_buf.st_mode));
+      char linkbuf[1];
+      return 0 <= readlink (argv[pos - 1], linkbuf, 1);
 
     case 'u':                  /* File is setuid? */
       unary_advance ();