diff options
author | Tony Cook <tony@develop-help.com> | 2021-07-09 10:22:40 +1000 |
---|---|---|
committer | Tony Cook <tony@develop-help.com> | 2021-09-01 10:59:44 +1000 |
commit | 9b5699737a6b587546239d586832f420cf7f2dea (patch) | |
tree | 37f4fec318866b00f20095ba66f60faa44788cd6 /Configure | |
parent | b852e1da77b497e086508451bebff00541073fb1 (diff) | |
download | perl-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-x | Configure | 72 |
1 files changed, 72 insertions, 0 deletions
@@ -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' |