From: Jarkko Hietaniemi <jhi@iki.fi>
Date: Wed, 27 Oct 1999 13:06:27 +0000 (+0000)
Subject: Nosuid checking for statfs() people: from Spider Boardman.
X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=0545a864a6e98637ff6d2f3cd3c8e85ae311d4e6;p=p5sagit%2Fp5-mst-13.2.git

Nosuid checking for statfs() people: from Spider Boardman.

p4raw-id: //depot/cfgperl@4465
---

diff --git a/Configure b/Configure
index 659daef..5aa9068 100755
--- a/Configure
+++ b/Configure
@@ -20,7 +20,7 @@
 
 # $Id: Head.U,v 3.0.1.9 1997/02/28 15:02:09 ram Exp $
 #
-# Generated on Tue Oct 26 16:44:39 EET DST 1999 [metaconfig 3.0 PL70]
+# Generated on Wed Oct 27 14:42:21 EET DST 1999 [metaconfig 3.0 PL70]
 # (with additional metaconfig patches by perlbug@perl.com)
 
 cat >/tmp/c1$$ <<EOF
@@ -355,6 +355,7 @@ d_flock=''
 d_fork=''
 d_fseeko=''
 d_fsetpos=''
+d_fstatfs=''
 d_ftello=''
 d_ftime=''
 d_gettimeod=''
@@ -512,9 +513,10 @@ sockethdr=''
 socketlib=''
 d_sqrtl=''
 d_statblks=''
-d_fstatfs=''
+d_fs_data_s=''
 d_statfs=''
-d_statfsflags=''
+d_statfs_f_flags=''
+d_statfs_s=''
 d_fstatvfs=''
 d_statvfs=''
 d_stdio_cnt_lval=''
@@ -555,6 +557,7 @@ d_umask=''
 d_semctl_semid_ds=''
 d_semctl_semun=''
 d_union_semun=''
+d_ustat=''
 d_vfork=''
 usevfork=''
 d_voidsig=''
@@ -648,12 +651,14 @@ i_sysresrc=''
 i_syssecrt=''
 i_sysselct=''
 i_sysstat=''
+i_sysstatfs=''
 i_sysstatvfs=''
 i_systimes=''
 i_systypes=''
 d_iovec_s=''
 i_sysuio=''
 i_sysun=''
+i_sysvfs=''
 i_syswait=''
 i_sgtty=''
 i_termio=''
@@ -663,6 +668,7 @@ i_systimek=''
 i_time=''
 timeincl=''
 i_unistd=''
+i_ustat=''
 i_utime=''
 i_values=''
 i_stdarg=''
@@ -7713,8 +7719,9 @@ while $test $# -ge 2; do
 	esac ;
     shift 2;
 done > try.c;
-echo "int main () { struct $struct foo; foo.$field = 0; }" >> try.c;
-if $cc $optimize $ccflags -c try.c >/dev/null 2>&1; then
+echo "int main () { struct $struct foo; char* bar; bar = (char*)foo.$field; }" >> try.c;
+set try;
+if eval $compile; then
 	val="$define";
 else
 	val="$undef";
@@ -8664,13 +8671,23 @@ $rm -f try.*
 set d_fpos64_t
 eval $setvar
 
-: see if fseeko exists
-set fseeko d_fseeko
-eval $inlibc
-
-: see if fsetpos exists
-set fsetpos d_fsetpos
-eval $inlibc
+hasstruct='varname=$1; struct=$2; shift; shift;
+while $test $# -ge 2; do
+	case "$1" in
+	$define) echo "#include <$2>";;
+	esac ;
+    shift 2;
+done > try.c;
+echo "int main () { struct $struct foo; }" >> try.c;
+set try;
+if eval $compile; then
+	val="$define";
+else
+	val="$undef";
+fi;
+set $varname;
+eval $setvar;
+$rm -f try.c try.o'
 
 : see if this is a sys/param system
 set sys/param.h i_sysparam
@@ -8680,25 +8697,68 @@ eval $inhdr
 set sys/mount.h i_sysmount
 eval $inhdr
 
+: see if sys/types.h has to be included
+set sys/types.h i_systypes
+eval $inhdr
+
+: see if this is a sys/vfs.h system
+set sys/vfs.h i_sysvfs
+eval $inhdr
+
+: see if this is a sys/statfs.h system
+set sys/statfs.h i_sysstatfs
+eval $inhdr
+
 
 : see if statfs exists
 set statfs d_statfs
 eval $inlibc
 
-: see if fstatfs exists
-set fstatfs d_fstatfs
-eval $inlibc
+echo "Checking to see if your system supports struct statfs..." >&4
+set d_statfs_s statfs $i_systypes sys/types.h $i_sysparam sys/param.h $i_sysmount sys/mount.h $i_sysvfs sys/vfs.h $i_sysstatfs sys/statfs.h
+eval $hasstruct
+case "$d_statfs_s" in
+"$define")      echo "Yup, it does."     >&4 ;;
+*)              echo "Nope, it doesn't." >&4 ;;
+esac
 
-: see if statfs knows about mount flags
-case "$d_statfs" in
-define)	set d_statfsflags statfs f_flags $i_sysparam sys/param.h $i_sysmount sys/mount.h
+: see if struct statfs knows about f_flags
+case "$d_statfs_s" in
+define)	
+	echo "Checking to see if your struct statfs has f_flags field..." >&4
+	set d_statfs_f_flags statfs f_flags $i_systypes sys/types.h $i_sysparam sys/param.h $i_sysmount sys/mount.h $i_sysvfs sys/vfs.h $i_sysstatfs sys/statfs.h
 	eval $hasfield
 	;;
 *)	val="$undef"
-	set d_statfsflags
+	set d_statfs_f_flags
 	eval $setvar
 	;;
 esac
+case "$d_statfs_f_flags" in
+"$define")      echo "Yup, it does."     >&4 ;;
+*)              echo "Nope, it doesn't." >&4 ;;
+esac
+
+echo "Checking to see if your system supports struct fs_data..." >&4
+set d_fs_data_s fs_data $i_systypes sys/types.h $i_sysparam sys/param.h $i_sysmount sys/mount.h
+eval $hasstruct
+case "$d_fs_data_s" in
+"$define")      echo "Yup, it does."     >&4 ;;
+*)              echo "Nope, it doesn't." >&4 ;;
+esac
+
+: see if fseeko exists
+set fseeko d_fseeko
+eval $inlibc
+
+: see if fsetpos exists
+set fsetpos d_fsetpos
+eval $inlibc
+
+
+: see if fstatfs exists
+set fstatfs d_fstatfs
+eval $inlibc
 
 
 : see if statvfs exists
@@ -10621,10 +10681,6 @@ eval $inlibc
 set tcsetpgrp d_tcsetpgrp
 eval $inlibc
 
-: see if sys/types.h has to be included
-set sys/types.h i_systypes
-eval $inhdr
-
 : see if prototype for telldir is available
 echo " "
 set d_telldirproto telldir $i_systypes sys/types.h $i_dirent dirent.h
@@ -10728,6 +10784,10 @@ eval $setvar
 set umask d_umask
 eval $inlibc
 
+: see if ustat exists
+set ustat d_ustat
+eval $inlibc
+
 : backward compatibility for d_hvfork
 if test X$d_hvfork != X; then
 	d_vfork="$d_hvfork"
@@ -13113,6 +13173,10 @@ eval $inhdr
 set sys/wait.h i_syswait
 eval $inhdr
 
+: see if this is a ustat.h system
+set ustat.h i_ustat
+eval $inhdr
+
 : see if this is an utime system
 set utime.h i_utime
 eval $inhdr
@@ -13587,6 +13651,7 @@ d_flock='$d_flock'
 d_fork='$d_fork'
 d_fpathconf='$d_fpathconf'
 d_fpos64_t='$d_fpos64_t'
+d_fs_data_s='$d_fs_data_s'
 d_fseeko='$d_fseeko'
 d_fsetpos='$d_fsetpos'
 d_fstatfs='$d_fstatfs'
@@ -13750,7 +13815,8 @@ d_sockpair='$d_sockpair'
 d_sqrtl='$d_sqrtl'
 d_statblks='$d_statblks'
 d_statfs='$d_statfs'
-d_statfsflags='$d_statfsflags'
+d_statfs_f_flags='$d_statfs_f_flags'
+d_statfs_s='$d_statfs_s'
 d_statvfs='$d_statvfs'
 d_stdio_cnt_lval='$d_stdio_cnt_lval'
 d_stdio_ptr_lval='$d_stdio_ptr_lval'
@@ -13785,6 +13851,7 @@ d_tzname='$d_tzname'
 d_umask='$d_umask'
 d_uname='$d_uname'
 d_union_semun='$d_union_semun'
+d_ustat='$d_ustat'
 d_vendorbin='$d_vendorbin'
 d_vendorlib='$d_vendorlib'
 d_vfork='$d_vfork'
@@ -13891,6 +13958,7 @@ i_syssecrt='$i_syssecrt'
 i_sysselct='$i_sysselct'
 i_syssockio='$i_syssockio'
 i_sysstat='$i_sysstat'
+i_sysstatfs='$i_sysstatfs'
 i_sysstatvfs='$i_sysstatvfs'
 i_systime='$i_systime'
 i_systimek='$i_systimek'
@@ -13898,11 +13966,13 @@ i_systimes='$i_systimes'
 i_systypes='$i_systypes'
 i_sysuio='$i_sysuio'
 i_sysun='$i_sysun'
+i_sysvfs='$i_sysvfs'
 i_syswait='$i_syswait'
 i_termio='$i_termio'
 i_termios='$i_termios'
 i_time='$i_time'
 i_unistd='$i_unistd'
+i_ustat='$i_ustat'
 i_utime='$i_utime'
 i_values='$i_values'
 i_varargs='$i_varargs'
diff --git a/Porting/Glossary b/Porting/Glossary
index 876bfe9..b0fb54d 100644
--- a/Porting/Glossary
+++ b/Porting/Glossary
@@ -534,6 +534,10 @@ d_fpathconf (d_pathconf.U):
 d_fpos64_t (io64.U):
 	This symbol will be defined if the C compiler supports fpos64_t.
 
+d_fs_data_s (d_statfs.U):
+	This variable conditionally defines the HAS_STRUCT_FS_DATA symbol,
+	which indicates that the struct fs_data is supported.
+
 d_fseeko (d_fseeko.U):
 	This variable conditionally defines the HAS_FSEEKO symbol, which
 	indicates to the C program that the fseeko() routine is available.
@@ -542,7 +546,7 @@ d_fsetpos (d_fsetpos.U):
 	This variable conditionally defines HAS_FSETPOS if fsetpos() is
 	available to set the file position indicator.
 
-d_fstatfs (d_statfs.U):
+d_fstatfs (d_fstatfs.U):
 	This variable conditionally defines the HAS_FSTATFS symbol, which
 	indicates to the C program that the fstatfs() routine is available.
 
@@ -1327,12 +1331,16 @@ d_statfs (d_statfs.U):
 	This variable conditionally defines the HAS_STATFS symbol, which
 	indicates to the C program that the statfs() routine is available.
 
-d_statfsflags (d_statfs.U):
-	This variable conditionally defines the HAS_STRUCT_STATFS_FLAGS
+d_statfs_f_flags (d_statfs.U):
+	This variable conditionally defines the HAS_STRUCT_STATFS_F_FLAGS
 	symbol, which indicates to struct statfs from has f_flags member.
 	This kind of struct statfs is coming from sys/mount.h (BSD),
 	not from sys/statfs.h (SYSV).
 
+d_statfs_s (d_statfs.U):
+	This variable conditionally defines the HAS_STRUCT_STATFS symbol,
+	which indicates that the struct statfs is supported.
+
 d_statvfs (d_statvfs.U):
 	This variable conditionally defines the HAS_STATVFS symbol, which
 	indicates to the C program that the statvfs() routine is available.
@@ -1487,6 +1495,10 @@ d_union_semun (d_union_semun.U):
 	This variable conditionally defines HAS_UNION_SEMUN if the
 	union semun is defined by including <sys/sem.h>.
 
+d_ustat (d_ustat.U):
+	This variable conditionally defines HAS_USTAT if ustat() is
+	available to query file system statistics by dev_t.
+
 d_vendorbin (vendorbin.U):
 	This variable conditionally defines PERL_VENDORBIN.
 
@@ -1973,6 +1985,10 @@ i_sysstat (i_sysstat.U):
 	This variable conditionally defines the I_SYS_STAT symbol,
 	and indicates whether a C program should include <sys/stat.h>.
 
+i_sysstatfs (i_sysstatfs.U):
+	This variable conditionally defines the I_SYSSTATFS symbol,
+	and indicates whether a C program should include <sys/statfs.h>.
+
 i_sysstatvfs (i_sysstatvfs.U):
 	This variable conditionally defines the I_SYSSTATVFS symbol,
 	and indicates whether a C program should include <sys/statvfs.h>.
@@ -2003,6 +2019,10 @@ i_sysun (i_sysun.U):
 	to the C program that it should include <sys/un.h> to get UNIX
 	domain socket definitions.
 
+i_sysvfs (i_sysvfs.U):
+	This variable conditionally defines the I_SYSVFS symbol,
+	and indicates whether a C program should include <sys/vfs.h>.
+
 i_syswait (i_syswait.U):
 	This variable conditionally defines I_SYS_WAIT, which indicates
 	to the C program that it should include <sys/wait.h>.
@@ -2025,6 +2045,10 @@ i_unistd (i_unistd.U):
 	This variable conditionally defines the I_UNISTD symbol, and indicates
 	whether a C program should include <unistd.h>.
 
+i_ustat (i_ustat.U):
+	This variable conditionally defines the I_USTAT symbol, and indicates
+	whether a C program should include <ustat.h>.
+
 i_utime (i_utime.U):
 	This variable conditionally defines the I_UTIME symbol, and indicates
 	whether a C program should include <utime.h>.
diff --git a/Porting/config.sh b/Porting/config.sh
index f3c46a2..dce5791 100644
--- a/Porting/config.sh
+++ b/Porting/config.sh
@@ -8,7 +8,7 @@
 
 # Package name      : perl5
 # Source directory  : .
-# Configuration time: Tue Oct 26 16:45:55 EET DST 1999
+# Configuration time: Wed Oct 27 15:23:59 EET DST 1999
 # Configured by     : jhi
 # Target system     : osf1 alpha.hut.fi v4.0 878 alpha 
 
@@ -56,7 +56,7 @@ ccflags='-pthread -std -DLANGUAGE_C'
 ccsymbols='__LANGUAGE_C__=1 _LONGLONG=1 LANGUAGE_C=1 SYSTYPE_BSD=1'
 cf_by='jhi'
 cf_email='yourname@yourhost.yourplace.com'
-cf_time='Tue Oct 26 16:45:55 EET DST 1999'
+cf_time='Wed Oct 27 15:23:59 EET DST 1999'
 chgrp=''
 chmod=''
 chown=''
@@ -148,6 +148,7 @@ d_flock='define'
 d_fork='define'
 d_fpathconf='define'
 d_fpos64_t='undef'
+d_fs_data_s='undef'
 d_fseeko='undef'
 d_fsetpos='define'
 d_fstatfs='define'
@@ -311,7 +312,8 @@ d_sockpair='define'
 d_sqrtl='define'
 d_statblks='define'
 d_statfs='define'
-d_statfsflags='define'
+d_statfs_f_flags='define'
+d_statfs_s='define'
 d_statvfs='define'
 d_stdio_cnt_lval='define'
 d_stdio_ptr_lval='define'
@@ -346,6 +348,7 @@ d_tzname='define'
 d_umask='define'
 d_uname='define'
 d_union_semun='undef'
+d_ustat='define'
 d_vendorbin='undef'
 d_vendorlib='undef'
 d_vfork='undef'
@@ -452,6 +455,7 @@ i_syssecrt='define'
 i_sysselct='define'
 i_syssockio=''
 i_sysstat='define'
+i_sysstatfs='undef'
 i_sysstatvfs='define'
 i_systime='define'
 i_systimek='undef'
@@ -459,11 +463,13 @@ i_systimes='define'
 i_systypes='define'
 i_sysuio='define'
 i_sysun='define'
+i_sysvfs='undef'
 i_syswait='define'
 i_termio='undef'
 i_termios='define'
 i_time='undef'
 i_unistd='define'
+i_ustat='define'
 i_utime='define'
 i_values='define'
 i_varargs='undef'
diff --git a/Porting/config_H b/Porting/config_H
index 345ec01..1b96031 100644
--- a/Porting/config_H
+++ b/Porting/config_H
@@ -17,7 +17,7 @@
 /*
  * Package name      : perl5
  * Source directory  : .
- * Configuration time: Tue Oct 26 16:45:55 EET DST 1999
+ * Configuration time: Wed Oct 27 15:23:59 EET DST 1999
  * Configured by     : jhi
  * Target system     : osf1 alpha.hut.fi v4.0 878 alpha 
  */
@@ -2184,6 +2184,11 @@
  */
 /*#define HAS_FSEEKO		/ **/
 
+/* HAS_FSTATFS:
+ *	This symbol, if defined, indicates that the fstatfs routine is
+ *	available to stat filesystems by file descriptors.
+ */
+#define HAS_FSTATFS		/**/
 /* HAS_FTELLO:
  *	This symbol, if defined, indicates that the ftello routine is
  *	available to ftell beyond 32 bits (useful for ILP32 hosts).
@@ -2259,20 +2264,31 @@
  */
 #define HAS_SQRTL		/**/
 
-/* HAS_FSTATFS:
- *	This symbol, if defined, indicates that the fstatfs routine is
- *	available to stat filesystems by file descriptors.
+/* HAS_STATFS:
+ *	This symbol, if defined, indicates that the statfs routine is
+ *	available to stat filesystems by filenames.
+ */
+/* HAS_STRUCT_STATFS:
+ *	This symbol, if defined, indicates that the struct statfs
+ *	to do statfs() is supported.
+ */
+/* HAS_STRUCT_FS_DATA:
+ *	This symbol, if defined, indicates that the struct fs_data
+ *	to do statfs() is supported.
  */
-/* HAS_STRUCT_STATFS_FLAGS:
+/* HAS_STRUCT_STATFS_F_FLAGS:
  *	This symbol, if defined, indicates that the struct statfs
  *	does have the f_flags member containing the mount flags of
- *	the filesystem holding the file.
+ *	the filesystem containing the file.
  *	This kind of struct statfs is coming from <sys/mount.h> (BSD 4.3),
  *	not from <sys/statfs.h> (SYSV).  Older BSDs (like Ultrix) do not
- *	have statfs() and struct statfs, they have getmnt().
+ *	have statfs() and struct statfs, they have ustat() and statfs()
+ *	with struct fs_data.
  */
-#define HAS_FSTATFS		/**/
-#define HAS_STRUCT_STATFS_FLAGS		/**/
+#define HAS_STATFS		/**/
+#define HAS_STRUCT_STATFS	/**/
+/*#define HAS_STRUCT_FS_DATA	/ **/
+#define HAS_STRUCT_STATFS_F_FLAGS		/**/
 
 /* HAS_FSTATVFS:
  *	This symbol, if defined, indicates that the fstatvfs routine is
@@ -2288,6 +2304,12 @@
  */
 #define	HAS_TELLDIR_PROTO	/**/
 
+/* HAS_USTAT:
+ *	This symbol, if defined, indicates that the ustat system call is
+ *	available to query file system statistics by dev_t.
+ */
+#define HAS_USTAT		/**/
+
 /* HAS_WRITEV:
  *	This symbol, if defined, indicates that the writev routine is
  *	available to do scatter writes.
@@ -2381,12 +2403,29 @@
  */
 #define	I_SYS_MOUNT		/**/
 
+/* I_SYS_STATFS:
+ *	This symbol, if defined, indicates that <sys/statfs.h> exists.
+ */
+/*#define	I_SYS_STATFS		/ **/
+
 /* I_SYS_STATVFS:
  *	This symbol, if defined, indicates that <sys/statvfs.h> exists and
  *	should be included.
  */
 #define	I_SYS_STATVFS		/**/
 
+/* I_SYS_VFS:
+ *	This symbol, if defined, indicates that <sys/vfs.h> exists and
+ *	should be included.
+ */
+/*#define	I_SYS_VFS		/ **/
+
+/* I_USTAT:
+ *	This symbol, if defined, indicates that <ustat.h> exists and
+ *	should be included.
+ */
+#define	I_USTAT		/**/
+
 /* HAS_OFF64_T:
  *	This symbol will be defined if the C compiler supports off64_t.
  */
diff --git a/config_h.SH b/config_h.SH
index a0be5e3..a12916e 100644
--- a/config_h.SH
+++ b/config_h.SH
@@ -2198,6 +2198,11 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un-
  */
 #$d_fseeko HAS_FSEEKO		/**/
 
+/* HAS_FSTATFS:
+ *	This symbol, if defined, indicates that the fstatfs routine is
+ *	available to stat filesystems by file descriptors.
+ */
+#$d_fstatfs HAS_FSTATFS		/**/
 /* HAS_FTELLO:
  *	This symbol, if defined, indicates that the ftello routine is
  *	available to ftell beyond 32 bits (useful for ILP32 hosts).
@@ -2273,20 +2278,31 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un-
  */
 #$d_sqrtl HAS_SQRTL		/**/
 
-/* HAS_FSTATFS:
- *	This symbol, if defined, indicates that the fstatfs routine is
- *	available to stat filesystems by file descriptors.
+/* HAS_STATFS:
+ *	This symbol, if defined, indicates that the statfs routine is
+ *	available to stat filesystems by filenames.
+ */
+/* HAS_STRUCT_STATFS:
+ *	This symbol, if defined, indicates that the struct statfs
+ *	to do statfs() is supported.
+ */
+/* HAS_STRUCT_FS_DATA:
+ *	This symbol, if defined, indicates that the struct fs_data
+ *	to do statfs() is supported.
  */
-/* HAS_STRUCT_STATFS_FLAGS:
+/* HAS_STRUCT_STATFS_F_FLAGS:
  *	This symbol, if defined, indicates that the struct statfs
  *	does have the f_flags member containing the mount flags of
- *	the filesystem holding the file.
+ *	the filesystem containing the file.
  *	This kind of struct statfs is coming from <sys/mount.h> (BSD 4.3),
  *	not from <sys/statfs.h> (SYSV).  Older BSDs (like Ultrix) do not
- *	have statfs() and struct statfs, they have getmnt().
+ *	have statfs() and struct statfs, they have ustat() and statfs()
+ *	with struct fs_data.
  */
-#$d_fstatfs HAS_FSTATFS		/**/
-#$d_statfsflags HAS_STRUCT_STATFS_FLAGS		/**/
+#$d_statfs HAS_STATFS		/**/
+#$d_statfs_s HAS_STRUCT_STATFS	/**/
+#$d_fs_data_s HAS_STRUCT_FS_DATA	/**/
+#$d_statfs_f_flags HAS_STRUCT_STATFS_F_FLAGS		/**/
 
 /* HAS_FSTATVFS:
  *	This symbol, if defined, indicates that the fstatvfs routine is
@@ -2302,6 +2318,12 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un-
  */
 #$d_telldirproto	HAS_TELLDIR_PROTO	/**/
 
+/* HAS_USTAT:
+ *	This symbol, if defined, indicates that the ustat system call is
+ *	available to query file system statistics by dev_t.
+ */
+#$d_ustat HAS_USTAT		/**/
+
 /* HAS_WRITEV:
  *	This symbol, if defined, indicates that the writev routine is
  *	available to do scatter writes.
@@ -2395,12 +2417,29 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un-
  */
 #$i_sysmount	I_SYS_MOUNT		/**/
 
+/* I_SYS_STATFS:
+ *	This symbol, if defined, indicates that <sys/statfs.h> exists.
+ */
+#$i_sysstatfs	I_SYS_STATFS		/**/
+
 /* I_SYS_STATVFS:
  *	This symbol, if defined, indicates that <sys/statvfs.h> exists and
  *	should be included.
  */
 #$i_sysstatvfs	I_SYS_STATVFS		/**/
 
+/* I_SYS_VFS:
+ *	This symbol, if defined, indicates that <sys/vfs.h> exists and
+ *	should be included.
+ */
+#$i_sysvfs	I_SYS_VFS		/**/
+
+/* I_USTAT:
+ *	This symbol, if defined, indicates that <ustat.h> exists and
+ *	should be included.
+ */
+#$i_ustat	I_USTAT		/**/
+
 /* HAS_OFF64_T:
  *	This symbol will be defined if the C compiler supports off64_t.
  */
diff --git a/perl.c b/perl.c
index 4fb1771..ce151ab 100644
--- a/perl.c
+++ b/perl.c
@@ -2180,13 +2180,15 @@ sed %s -e \"/^[^#]/b\" \
 STATIC int
 S_fd_on_nosuid_fs(pTHX_ int fd)
 {
-    int on_nosuid  = 0;
-    int check_okay = 0;
+    int check_okay = 0; /* able to do all the required sys/libcalls */
+    int on_nosuid  = 0; /* the fd is on a nosuid fs */
 /*
- * Preferred order: fstatvfs(), fstatfs(), getmntent().
+ * Preferred order: fstatvfs(), fstatfs(), ustat()+statfs(), getmntent().
  * fstatvfs() is UNIX98.
- * fstatfs() is BSD.
- * getmntent() is O(number-of-mounted-filesystems) and can hang.
+ * fstatfs() is 4.3 BSD.
+ * ustat()+statfs() is pre-4.3 BSD.
+ * getmntent() is O(number-of-mounted-filesystems) and can hang on
+ * an irrelevant filesystem while trying to reach the right one.
  */
 
 #   ifdef HAS_FSTATVFS
@@ -2194,24 +2196,40 @@ S_fd_on_nosuid_fs(pTHX_ int fd)
     check_okay = fstatvfs(fd, &stfs) == 0;
     on_nosuid  = check_okay && (stfs.f_flag  & ST_NOSUID);
 #   else
-#       if defined(HAS_FSTATFS) && defined(HAS_STRUCT_STATFS_FLAGS)
+#       ifdef PERL_MOUNT_NOSUID
+#           if defined(HAS_FSTATFS) && defined(HAS_STRUCT_STATFS_F_FLAGS)
     struct statfs  stfs;
     check_okay = fstatfs(fd, &stfs)  == 0;
-#           undef PERL_MOUNT_NOSUID
-#           if !defined(PERL_MOUNT_NOSUID) && defined(MNT_NOSUID)
-#              define PERL_MOUNT_NOSUID MNT_NOSUID
-#           endif
-#           if !defined(PERL_MOUNT_NOSUID) && defined(MS_NOSUID)
-#              define PERL_MOUNT_NOSUID MS_NOSUID
-#           endif
-#           if !defined(PERL_MOUNT_NOSUID) && defined(M_NOSUID)
-#              define PERL_MOUNT_NOSUID M_NOSUID
-#           endif
-#           ifdef PERL_MOUNT_NOSUID
     on_nosuid  = check_okay && (stfs.f_flags & PERL_MOUNT_NOSUID);
-#           endif
+#           else
+#               if defined(HAS_FSTAT) && \
+		   defined(HAS_USTAT) && \
+		   defined(HAS_STATFS) && \
+		   defined(HAS_STRUCT_FS_DATA) /* no struct statfs */
+    struct stat fdst;
+    if (fstat(fd, &fdst) == 0) {
+	struct ustat us;
+	if (ustat(fdst.st_dev, &us) == 0) {
+	    struct fs_data fsd;
+	    if (statfs(PL_origfilename, &fsd) == 0) {
+		size_t cmplen = sizeof(us.f_fname);
+		if (sizeof(fsd.fd_req.path) < cmplen)
+		    cmplen = sizeof(fsd.fd_req.path);
+		if (strnEQ(fsd.fd_req.path, us.f_fname, cmplen) &&
+		    fdst.st_dev == fsd.fd_req.dev) {
+			check_okay = 1;
+			on_nosuid = fsd.fd_req.flags & PERL_MOUNT_NOSUID;
+		    }
+		}
+	    }
+	}
+    }
+#               endif /* fstat+ustat+statfs */
+#           endif /* statfs */
 #       else
-#           if defined(HAS_GETMNTENT) && defined(HAS_HASMNTOPT) && defined(MNTOPT_NOSUID)
+#           if defined(HAS_GETMNTENT) && \
+	       defined(HAS_HASMNTOPT) && \
+	       defined(MNTOPT_NOSUID)
     FILE		*mtab = fopen("/etc/mtab", "r");
     struct mntent	*entry;
     struct stat		stb, fsb;
@@ -2231,11 +2249,12 @@ S_fd_on_nosuid_fs(pTHX_ int fd)
     }
     if (mtab)
 	fclose(mtab);
-#           endif /* mntent */
-#       endif /* statfs */
+#           endif /* getmntent */
+#       endif /* PERL_MOUNT_NOSUID: fstatfs or fstat+ustat+statfs */
 #   endif /* statvfs */
+
     if (!check_okay) 
-	Perl_croak(aTHX_ "Can't check filesystem of script \"%s\"", PL_origfilename);
+	Perl_croak(aTHX_ "Can't check filesystem of script \"%s\" for nosuid", PL_origfilename);
     return on_nosuid;
 }
 #endif /* IAMSUID */
diff --git a/perl.h b/perl.h
index 501c635..ddad5ce 100644
--- a/perl.h
+++ b/perl.h
@@ -3207,6 +3207,40 @@ typedef struct am_table_short AMTS;
 #ifdef I_MNTENT
 #   include <mntent.h>          /* for getmntent() */
 #endif
+#ifdef I_SYS_STATFS
+#   include <sys/statfs.h>      /* for some statfs() */
+#endif
+#ifdef I_SYS_VFS
+#   include <sys/vfs.h>         /* for some statfs() */
+#endif
+#ifdef I_USTAT
+#   include <ustat.h>           /* for ustat() */
+#endif
+
+#if !defined(PERL_MOUNT_NOSUID) && defined(MOUNT_NOSUID)
+#    define PERL_MOUNT_NOSUID MOUNT_NOSUID
+#endif
+#if !defined(PERL_MOUNT_NOSUID) && defined(MNT_NOSUID)
+#    define PERL_MOUNT_NOSUID MNT_NOSUID
+#endif
+#if !defined(PERL_MOUNT_NOSUID) && defined(MS_NOSUID)
+#   define PERL_MOUNT_NOSUID MS_NOSUID
+#endif
+#if !defined(PERL_MOUNT_NOSUID) && defined(M_NOSUID)
+#   define PERL_MOUNT_NOSUID M_NOSUID
+#endif
+
+#ifdef HAS_STRUCT_STATFS
+#   define PERL_STRUCT_STATFS statfs
+#   ifdef HAS_STRUCT_STATFS_F_FLAGS
+#       define PERL_STRUCT_STATFS_FLAGS(s) s.f_flags
+#   endif
+#else
+#   ifdef HAS_STRUCT_FS_DATA
+#       define PERL_STRUCT_STATFS statfs
+#       define PERL_STRUCT_STATFS_FLAGS(s) s.fd_req.flags
+#   endif
+#endif
 
 #endif /* IAMSUID */
 
diff --git a/pod/perldiag.pod b/pod/perldiag.pod
index 5b1c324..006c2d9 100644
--- a/pod/perldiag.pod
+++ b/pod/perldiag.pod
@@ -636,7 +636,7 @@ Something like this will reproduce the error:
 (F) You called C<perl -x/foo/bar>, but C</foo/bar> is not a directory
 that you can chdir to, possibly because it doesn't exist.
 
-=item Can't check filesystem of script "%s"
+=item Can't check filesystem of script "%s" for nosuid
 
 (P) For some reason you can't check the filesystem of the script for nosuid.