On 29/08/17 10:46, Assaf Gordon wrote:
> On 29/08/17 11:26 AM, Pádraig Brady wrote:
>> On 29/08/17 10:12, Assaf Gordon wrote:
>>> 2.
>>> On OpenBSD 6.1, FreeBSD 11p1,
>>> "tests/ln/sf-1" fails with "argument list too long".
>>
>> Oh is the $((1024*1024)) not working on the BSDs?
>> That construct is used elsewhere in tests?
>>
> Just got results from Mac OS X, which also fail with
> "argument list too long", but the log is more helpful:
> ======
> +name_max='*'
> +name_limit=1048576
> +test '*' -lt 1048576
> ./tests/ln/sf-1.sh: line 39: test: *: integer expression expected
> +name_max=1048576
> ++expr 1048576 + 1
> +name_max_plus1=1048577

> Argument list too long
> +fail=1
> =======

The attached should fix up this stat test issue,
and improve `stat -f -c %l` on FreeBSD and OpenBSD.

cheers,
Pádraig
From f169345506ac5a095cd100d016c84dc44b33e851 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <[email protected]>
Date: Tue, 29 Aug 2017 23:42:54 -0700
Subject: [PATCH] stat: fix determination of max name length on BSD systems

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             | 3 +++
 m4/stat-prog.m4  | 5 +++--
 src/stat.c       | 7 +++++--
 tests/ln/sf-1.sh | 8 +++-----
 4 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/NEWS b/NEWS
index 94806bd..cc4a56e 100644
--- 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.
 
diff --git a/m4/stat-prog.m4 b/m4/stat-prog.m4
index 8d29232..13c2dbb 100644
--- a/m4/stat-prog.m4
+++ b/m4/stat-prog.m4
@@ -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(
diff --git a/src/stat.c b/src/stat.c
index 87b3ff4..19f5438 100644
--- a/src/stat.c
+++ b/src/stat.c
@@ -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
 
diff --git a/tests/ln/sf-1.sh b/tests/ln/sf-1.sh
index 492fce9..c6dafdf 100755
--- a/tests/ln/sf-1.sh
+++ b/tests/ln/sf-1.sh
@@ -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
-- 
2.9.3

Reply via email to