]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
stat: fix determination of max name length on BSD systems
authorPádraig Brady <P@draigBrady.com>
Wed, 30 Aug 2017 06:42:54 +0000 (23:42 -0700)
committerPádraig Brady <P@draigBrady.com>
Wed, 30 Aug 2017 06:42:54 +0000 (23:42 -0700)
We only use one of statfs or statvfs for `stat -f`
and on the BSDs we use statfs which doesn't have the
f_namelen member.  However on OpenBSD and later FreeBSD
systems statfs does provide f_namemax, so use that.

* NEWS: Mention the improvement for OpenBSD and FreeBSD.
* m4/stat-prog.m4: Check for f_namemax in the statfs struct.
* src/stat.c: Return '?' rather than '*' when we can't
determine the max length of the file system.
* tests/ln/sf-1.sh: This test was failing on all BSDs
due to '*' being returned for the max length which
caused the test to attempt to create 1Mi+1 names.
The test now uses a short name when we can't determine
the max name length to use.

Reported by Assaf Gordon on various BSD based systems.

NEWS
m4/stat-prog.m4
src/stat.c
tests/ln/sf-1.sh

diff --git a/NEWS b/NEWS
index 94806bd0a543e330acc20394ce992d21f11871b9..cc4a56e82d5fd1cfba66fd7f4eea00bc6add92da 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -104,6 +104,9 @@ GNU coreutils NEWS                                    -*- outline -*-
 
   mv --verbose now distinguishes rename and copy operations.
 
+  stat -f -c %l, used to output the max file name length on a file system,
+  is now supported on FreeBSD and OpenBSD.
+
   tail -f now exits immediately if the output is piped
   and the reader of the pipe terminates.
 
index 8d29232122a1eb2583b26bd5a96bfb67e5a36e0f..13c2dbbeb0e61091156c9e738bd156bdc839ef36 100644 (file)
@@ -72,8 +72,9 @@ AC_INCLUDES_DEFAULT
       [AC_DEFINE([STRUCT_STATVFS_F_FSID_IS_INTEGER], [1],
          [Define to 1 if the f_fsid member of struct statvfs is an integer.])])
   else
-    AC_CHECK_MEMBERS([struct statfs.f_namelen, struct statfs.f_type,
-                     struct statfs.f_frsize],,, [$statfs_includes])
+    AC_CHECK_MEMBERS([struct statfs.f_namelen, struct statfs.f_namemax,
+                      struct statfs.f_type, struct statfs.f_frsize],,,
+                     [$statfs_includes])
     if test $ac_cv_header_OS_h != yes; then
       AC_COMPILE_IFELSE(
         [AC_LANG_PROGRAM(
index 87b3ff43fcc44030eda9d877fde940d5371bb30d..19f5438722d50813a88bafb3d8c05ac1e724ab40 100644 (file)
@@ -92,6 +92,8 @@
 # define HAVE_STRUCT_STATXFS_F_TYPE HAVE_STRUCT_STATFS_F_TYPE
 # if HAVE_STRUCT_STATFS_F_NAMELEN
 #  define SB_F_NAMEMAX(S) ((S)->f_namelen)
+# elif HAVE_STRUCT_STATFS_F_NAMEMAX
+#  define SB_F_NAMEMAX(S) ((S)->f_namemax)
 # endif
 # define STATFS statfs
 # if HAVE_OS_H /* BeOS */
@@ -139,8 +141,9 @@ statfs (char const *filename, struct fs_info *buf)
 #ifdef SB_F_NAMEMAX
 # define OUT_NAMEMAX out_uint
 #else
-/* NetBSD 1.5.2 has neither f_namemax nor f_namelen.  */
-# define SB_F_NAMEMAX(S) "*"
+/* Depending on whether statvfs or statfs is used,
+   neither f_namemax or f_namelen may be available.  */
+# define SB_F_NAMEMAX(S) "?"
 # define OUT_NAMEMAX out_string
 #endif
 
index 492fce9035423286262ec9e447ce45fc812bebc5..c6dafdf704a452680061064cbb2a4c33d16ba032 100755 (executable)
@@ -33,12 +33,10 @@ esac
 
 # Ensure we replace symlinks that don't or can't link to an existing target.
 # coreutils-8.22 would fail to replace {ENOTDIR,ELOOP,ENAMETOOLONG}_link below.
-name_max=$(stat -f -c %l .) || skip_ 'Error determining NAME_MAX'
-# Apply a limit since AIX returns 2^32-1 which would trigger resource issues.
-name_limit=$((1024*1024))
-test "$name_max" -lt "$name_limit" || name_max="$name_limit"
+# We apply a limit since AIX returns 2^32-1 which would trigger resource issues.
+name_max=$(stat -f -c %l .) && test "$name_max" -lt $((1024*1024)) ||
+  name_max=1 # skip this portion of the test
 name_max_plus1=$(expr $name_max + 1)
-test $name_max_plus1 -gt 1 || skip_ 'Error determining NAME_MAX'
 long_name=$(printf '%0*d' $name_max_plus1 0)
 
 for f in '' f; do