]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
ls: suppress "Permission denied" errors on NFS
authorPádraig Brady <P@draigBrady.com>
Wed, 8 Jan 2025 21:46:05 +0000 (21:46 +0000)
committerPádraig Brady <P@draigBrady.com>
Fri, 10 Jan 2025 14:46:40 +0000 (14:46 +0000)
NFS (on Linux 6.12 at least) was seen to return EACCES
from listxattr() for files without read access.
We started using listxattr() in coreutils 9.4.

* src/ls.c (gobble_file): Map EACCES from file_has_aclinfo()
to '?', rather than displaying the error.
* doc/coreutils.texi (ls invocation): Document the '?' flag.
* NEWS: Mention the bug fix.
Addresses https://bugs.gnu.org/74692

NEWS
doc/coreutils.texi
src/ls.c

diff --git a/NEWS b/NEWS
index 31093fb4fba9550dfdcf66c26e02176e2e079aed..0db68b307e6d4f6767625bafa00749b10ddb2955 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,12 @@ GNU coreutils NEWS                                    -*- outline -*-
   first and last characters, and single quotes in the string.
   [bug introduced in coreutils-8.26]
 
+  ls -l may now mark files with a '?' character after the mode bits
+  if it is unable to read alternate access method details, which may
+  happen on NFS with files without read permission.
+  Previously ls would have output "Permission denied" errors.
+  [bug introduced in coreutils-9.4]
+
   mv works again with macFUSE file systems.  Previously it would
   have exited with a "Function not implemented" error.
   [bug introduced in coreutils-8.28]
index 585760741107eff92e7c4e121bb02e863f5f6334..ec58f6cf2a65dd947968b105212624f2d94206c2 100644 (file)
@@ -8084,6 +8084,10 @@ with a security context, but no other alternate access method.
 A file with any other combination of alternate access methods
 is marked with a @samp{+} character.
 
+@command{ls} uses a @samp{?} character to indicate it is unable to determine
+whether alternate access methods apply to the file, which may happen for
+example with some NFS setups with files without read permission.
+
 @item -n
 @itemx --numeric-uid-gid
 @opindex -n
index a42c7707ab58f823e7e0d5d61032027d94f687e2..50937071bfef8e0f88c59d36d0798f5e68cb9aef 100644 (file)
--- a/src/ls.c
+++ b/src/ls.c
@@ -199,6 +199,7 @@ static char const d_type_filetype[UCHAR_MAX + 1] =
 enum acl_type
   {
     ACL_T_NONE,
+    ACL_T_UNKNOWN,
     ACL_T_LSM_CONTEXT_ONLY,
     ACL_T_YES
   };
@@ -3518,14 +3519,20 @@ gobble_file (char const *name, enum filetype type, ino_t inode,
       int n = file_has_aclinfo_cache (full_name, f, &ai, aclinfo_flags);
       bool have_acl = 0 < n;
       bool have_scontext = !ai.scontext_err;
+
+      /* Let the user know via '?' if errno is EACCES, which can
+         happen with Linux kernel 6.12 on an NFS file system.
+         That's better than a longwinded diagnostic.  */
+      bool cannot_access_acl = n < 0 && errno == EACCES;
+
       f->acl_type = (!have_scontext && !have_acl
-                     ? ACL_T_NONE
+                     ? (cannot_access_acl ? ACL_T_UNKNOWN : ACL_T_NONE)
                      : (have_scontext && !have_acl
                         ? ACL_T_LSM_CONTEXT_ONLY
                         : ACL_T_YES));
       any_has_acl |= f->acl_type != ACL_T_NONE;
 
-      if (format == long_format && n < 0)
+      if (format == long_format && n < 0 && !cannot_access_acl)
         error (0, ai.u.err, "%s", quotef (full_name));
       else
         {
@@ -4302,6 +4309,8 @@ print_long_format (const struct fileinfo *f)
     modebuf[10] = '.';
   else if (f->acl_type == ACL_T_YES)
     modebuf[10] = '+';
+  else if (f->acl_type == ACL_T_UNKNOWN)
+    modebuf[10] = '?';
 
   switch (time_type)
     {