summaryrefslogtreecommitdiff
path: root/Configure
diff options
context:
space:
mode:
authorTony Cook <tony@develop-help.com>2021-07-09 10:22:40 +1000
committerTony Cook <tony@develop-help.com>2021-09-01 10:59:44 +1000
commit9b5699737a6b587546239d586832f420cf7f2dea (patch)
tree37f4fec318866b00f20095ba66f60faa44788cd6 /Configure
parentb852e1da77b497e086508451bebff00541073fb1 (diff)
downloadperl-9b5699737a6b587546239d586832f420cf7f2dea.tar.gz
detect struct stat.st_dev's size and signedness, and return it safely
On FreeBSD dev_t (and hence the st_dev member of struct stat) is an unsigned 64-bit integer, and the previous simple PUSHi() corrupted that. A previous version of this reflected the st_ino code and implemented our own number to string conversion, but a system with such a large st_dev should be assumed to have inttypes.h, and an intmax_t which is no smaller than st_dev. The st_ino code could probably be changed similarly, but 64-bit inode numbers are not a new thing, so it may be riskier.
Diffstat (limited to 'Configure')
-rwxr-xr-xConfigure72
1 files changed, 72 insertions, 0 deletions
diff --git a/Configure b/Configure
index 55e2ebb50f..08f2445a40 100755
--- a/Configure
+++ b/Configure
@@ -1321,6 +1321,8 @@ shsharp=''
spitshell=''
src=''
ssizetype=''
+st_dev_sign=''
+st_dev_size=''
st_ino_sign=''
st_ino_size=''
startperl=''
@@ -22744,6 +22746,74 @@ else
fi
$rm_try
+: Check the size of st_dev
+$echo " "
+$echo "Checking the size of st_dev..." >&4
+$cat > try.c <<EOCP
+#include <sys/stat.h>
+#include <stdio.h>
+#$i_stdlib I_STDLIB
+#ifdef I_STDLIB
+#include <stdlib.h>
+#endif
+int main() {
+ struct stat st;
+ printf("%d\n", (int)sizeof(st.st_dev));
+ exit(0);
+}
+EOCP
+set try
+if eval $compile_ok; then
+ val=`$run ./try`
+ case "$val" in
+ '') st_dev_size=4
+ $echo "(I can't execute the test program--guessing $st_dev_size.)" >&4
+ ;;
+ *) st_dev_size=$val
+ $echo "Your st_dev is $st_dev_size bytes long."
+ ;;
+ esac
+else
+ st_dev_size=4
+ $echo "(I can't compile the test program--guessing $st_dev_size.)" >&4
+fi
+$rm_try
+
+: Check if st_dev is signed
+$echo " "
+$echo "Checking the sign of st_dev..." >&4
+$cat > try.c <<EOCP
+#include <sys/stat.h>
+#include <stdio.h>
+int main() {
+ struct stat foo;
+ foo.st_dev = -1;
+ if (foo.st_dev < 0)
+ printf("-1\n");
+ else
+ printf("1\n");
+}
+EOCP
+set try
+if eval $compile; then
+ val=`$run ./try`
+ case "$val" in
+ '') st_dev_sign=1
+ $echo "(I can't execute the test program--guessing unsigned.)" >&4
+ ;;
+ *) st_dev_sign=$val
+ case "$st_dev_sign" in
+ 1) $echo "Your st_dev is unsigned." ;;
+ -1) $echo "Your st_dev is signed." ;;
+ esac
+ ;;
+ esac
+else
+ st_dev_sign=1
+ $echo "(I can't compile the test program--guessing unsigned.)" >&4
+fi
+$rm_try
+
: see what type of char stdio uses.
echo " "
echo '#include <stdio.h>' | $cppstdin $cppminus > stdioh
@@ -25299,6 +25369,8 @@ srand48_r_proto='$srand48_r_proto'
srandom_r_proto='$srandom_r_proto'
src='$src'
ssizetype='$ssizetype'
+st_dev_sign='$st_dev_sign'
+st_dev_size='$st_dev_size'
st_ino_sign='$st_ino_sign'
st_ino_size='$st_ino_size'
startperl='$startperl'