From f169345506ac5a095cd100d016c84dc44b33e851 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= 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