From: Jarkko Hietaniemi Date: Mon, 21 Apr 2003 06:50:42 +0000 (+0000) Subject: Introduce two new Configure symbols: X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=15b61c98f82f3010e6eaa852f9fa5251de9e6dd9;p=p5sagit%2Fp5-mst-13.2.git Introduce two new Configure symbols: [1] d_faststdio = d_stdstdio && d_stdio_ptr_lval && (d_stdio_cnt_lval || d_stdio_ptr_lval_sets_cnt) [2] usefaststdio = do we use fast stdio if we have it? For 5.[68], we do. For anything else, we don't. (At least, unless otherwise instructed by -Dusefaststdio.) This means that for bleadperl we no more use stdio, but instead default to perlio: the effect of PERLIO=perlio, in other words. (PERLIO=stdio will still switch to using stdio.) This change may endanger extensions using FILE*-- but if we are to migrate fully to perlio, better start swallowing the poison now. For maintperl, the usefaststdio still defaults to yes. p4raw-id: //depot/perl@19286 --- diff --git a/Configure b/Configure index f7a4050..b8116b9 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 Sun Apr 20 11:44:59 EET DST 2003 [metaconfig 3.0 PL70] +# Generated on Mon Apr 21 10:31:53 EET DST 2003 [metaconfig 3.0 PL70] # (with additional metaconfig patches by perlbug@perl.org) cat >c1$$ </dev/null 2>&1 ; then + echo "(Looks like you have stdio.h from BSD.)" + case "$stdio_ptr" in + '') stdio_ptr='((fp)->_p)' + ptr_lval=$define + ;; + *) ptr_lval=$d_stdio_ptr_lval;; + esac + case "$stdio_cnt" in + '') stdio_cnt='((fp)->_r)' + cnt_lval=$define + ;; + *) cnt_lval=$d_stdio_cnt_lval;; + esac + case "$stdio_base" in + '') stdio_base='((fp)->_ub._base ? (fp)->_ub._base : (fp)->_bf._base)';; + esac + case "$stdio_bufsiz" in + '') stdio_bufsiz='((fp)->_ub._base ? (fp)->_ub._size : (fp)->_bf._size)';; + esac +elif $contains '_IO_fpos_t' `./findhdr stdio.h` `./findhdr libio.h` >/dev/null 2>&1 ; then + echo "(Looks like you have stdio.h from Linux.)" + case "$stdio_ptr" in + '') stdio_ptr='((fp)->_IO_read_ptr)' + ptr_lval=$define + ;; + *) ptr_lval=$d_stdio_ptr_lval;; + esac + case "$stdio_cnt" in + '') stdio_cnt='((fp)->_IO_read_end - (fp)->_IO_read_ptr)' + cnt_lval=$undef + ;; + *) cnt_lval=$d_stdio_cnt_lval;; + esac + case "$stdio_base" in + '') stdio_base='((fp)->_IO_read_base)';; + esac + case "$stdio_bufsiz" in + '') stdio_bufsiz='((fp)->_IO_read_end - (fp)->_IO_read_base)';; + esac +else + case "$stdio_ptr" in + '') stdio_ptr='((fp)->_ptr)' + ptr_lval=$define + ;; + *) ptr_lval=$d_stdio_ptr_lval;; + esac + case "$stdio_cnt" in + '') stdio_cnt='((fp)->_cnt)' + cnt_lval=$define + ;; + *) cnt_lval=$d_stdio_cnt_lval;; + esac + case "$stdio_base" in + '') stdio_base='((fp)->_base)';; + esac + case "$stdio_bufsiz" in + '') stdio_bufsiz='((fp)->_cnt + (fp)->_ptr - (fp)->_base)';; + esac +fi -echo " " -: See if fcntl-based locking works. -$cat >try.c <&4 +$cat >try.c < #$i_stdlib I_STDLIB #ifdef I_STDLIB #include #endif -#include -#include -#include -$signal_t blech(x) int x; { exit(3); } +#define FILE_ptr(fp) $stdio_ptr +#define FILE_cnt(fp) $stdio_cnt int main() { -#if defined(F_SETLK) && defined(F_SETLKW) - struct flock flock; - int retval, fd; - fd = open("try.c", O_RDONLY); - flock.l_type = F_RDLCK; - flock.l_whence = SEEK_SET; - flock.l_start = flock.l_len = 0; - signal(SIGALRM, blech); - alarm(10); - retval = fcntl(fd, F_SETLK, &flock); - close(fd); - (retval < 0 ? exit(2) : exit(0)); -#else - exit(2); -#endif + FILE *fp = fopen("try.c", "r"); + char c = getc(fp); + if ( + 18 <= FILE_cnt(fp) && + strncmp(FILE_ptr(fp), "include \n", 18) == 0 + ) + exit(0); + exit(1); } -EOCP -echo "Checking if fcntl-based file locking works... " -case "$d_fcntl" in -"$define") - set try - if eval $compile_ok; then - if $run ./try; then - echo "Yes, it seems to work." - val="$define" - else - echo "Nope, it didn't work." - val="$undef" - case "$?" in - 3) $cat >&4 < 2.2.9. +# A. Dougherty, June 3, 2002. +case "$d_gnulibc" in +$define) + case "$gnulibc_version" in + 2.[01]*) ;; + 2.2) ;; + 2.2.[0-9]) ;; + *) echo "But I will not snoop inside glibc $gnulibc_version stdio buffers." + val="$undef" + ;; + esac ;; esac -set d_fcntl_can_lock +set d_stdstdio eval $setvar -$rm -f try* +: Can _ptr be used as an lvalue? +case "$d_stdstdio$ptr_lval" in +$define$define) val=$define ;; +*) val=$undef ;; +esac +set d_stdio_ptr_lval +eval $setvar -: check for fd_set items -$cat <try.c <&4 +$cat >try.c < +/* Can we scream? */ +/* Eat dust sed :-) */ +/* In the buffer space, no one can hear you scream. */ #$i_stdlib I_STDLIB #ifdef I_STDLIB #include #endif -#$i_systime I_SYS_TIME -#$i_sysselct I_SYS_SELECT -#$d_socket HAS_SOCKET +#define FILE_ptr(fp) $stdio_ptr +#define FILE_cnt(fp) $stdio_cnt #include -#ifdef HAS_SOCKET -#include /* Might include */ -#endif -#ifdef I_SYS_TIME -#include -#endif -#ifdef I_SYS_SELECT -#include -#endif int main() { - fd_set fds; - -#ifdef TRYBITS - if(fds.fds_bits); -#endif - -#if defined(FD_SET) && defined(FD_CLR) && defined(FD_ISSET) && defined(FD_ZERO) - exit(0); -#else - exit(1); -#endif -} -EOCP -set try -DTRYBITS -if eval $compile; then - d_fds_bits="$define" - d_fd_set="$define" - echo "Well, your system knows about the normal fd_set typedef..." >&4 - if $run ./try; then + FILE *fp = fopen("try.c", "r"); + int c; + char *ptr; + size_t cnt; + if (!fp) { + puts("Fail even to read"); + exit(1); + } + c = getc(fp); /* Read away the first # */ + if (c == EOF) { + puts("Fail even to read"); + exit(1); + } + if (!( + 18 <= FILE_cnt(fp) && + strncmp(FILE_ptr(fp), "include \n", 18) == 0 + )) { + puts("Fail even to read"); + exit (1); + } + ptr = (char*) FILE_ptr(fp); + cnt = (size_t)FILE_cnt(fp); + + FILE_ptr(fp) += 42; + + if ((char*)FILE_ptr(fp) != (ptr + 42)) { + printf("Fail ptr check %p != %p", FILE_ptr(fp), (ptr + 42)); + exit (1); + } + if (FILE_cnt(fp) <= 20) { + printf ("Fail (<20 chars to test)"); + exit (1); + } + if (strncmp(FILE_ptr(fp), "Eat dust sed :-) */\n", 20) != 0) { + puts("Fail compare"); + exit (1); + } + if (cnt == FILE_cnt(fp)) { + puts("Pass_unchanged"); + exit (0); + } + if (FILE_cnt(fp) == (cnt - 42)) { + puts("Pass_changed"); + exit (0); + } + printf("Fail count was %d now %d\n", cnt, FILE_cnt(fp)); + return 1; + +} +EOP + set try + if eval $compile && $to try.c; then + case `$run ./try` in + Pass_changed) + echo "Increasing ptr in your stdio decreases cnt by the same amount. Good." >&4 + d_stdio_ptr_lval_sets_cnt="$define" ;; + Pass_unchanged) + echo "Increasing ptr in your stdio leaves cnt unchanged. Good." >&4 + d_stdio_ptr_lval_nochange_cnt="$define" ;; + Fail*) + echo "Increasing ptr in your stdio didn't do exactly what I expected. We'll not be doing that then." >&4 ;; + *) + echo "It appears attempting to set ptr in your stdio is a bad plan." >&4 ;; + esac + else + echo "It seems we can't set ptr in your stdio. Nevermind." >&4 + fi + $rm -f try.c try + ;; +esac + +: see if _base is also standard +val="$undef" +case "$d_stdstdio" in +$define) + $cat >try.c < +#$i_stdlib I_STDLIB +#ifdef I_STDLIB +#include +#endif +#define FILE_base(fp) $stdio_base +#define FILE_bufsiz(fp) $stdio_bufsiz +int main() { + FILE *fp = fopen("try.c", "r"); + char c = getc(fp); + if ( + 19 <= FILE_bufsiz(fp) && + strncmp(FILE_base(fp), "#include \n", 19) == 0 + ) + exit(0); + exit(1); +} +EOP + set try + if eval $compile && $to try.c; then + if $run ./try; then + echo "And its _base field acts std." + val="$define" + else + echo "But its _base field isn't std." + fi + else + echo "However, it seems to be lacking the _base field." + fi + $rm -f try.c try + ;; +esac +set d_stdiobase +eval $setvar + +: see if fast_stdio exists +val="$undef" +case "$d_stdstdio:$d_stdio_ptr_lval" in +"$define:$define") + case "$d_stdio_cnt_lval$d_stdio_ptr_lval_sets_cnt" in + *$define*) + echo "You seem to have 'fast stdio' to directly manipulate the stdio buffers." >& 4 + val="$define" + ;; + esac + ;; +esac +set d_faststdio +eval $setvar + + + +: see if fchdir exists +set fchdir d_fchdir +eval $inlibc + +: see if fchmod exists +set fchmod d_fchmod +eval $inlibc + +: see if fchown exists +set fchown d_fchown +eval $inlibc + +: see if this is an fcntl system +set fcntl d_fcntl +eval $inlibc + +echo " " +: See if fcntl-based locking works. +$cat >try.c < +#endif +#include +#include +#include +$signal_t blech(x) int x; { exit(3); } +int main() { +#if defined(F_SETLK) && defined(F_SETLKW) + struct flock flock; + int retval, fd; + fd = open("try.c", O_RDONLY); + flock.l_type = F_RDLCK; + flock.l_whence = SEEK_SET; + flock.l_start = flock.l_len = 0; + signal(SIGALRM, blech); + alarm(10); + retval = fcntl(fd, F_SETLK, &flock); + close(fd); + (retval < 0 ? exit(2) : exit(0)); +#else + exit(2); +#endif +} +EOCP +echo "Checking if fcntl-based file locking works... " +case "$d_fcntl" in +"$define") + set try + if eval $compile_ok; then + if $run ./try; then + echo "Yes, it seems to work." + val="$define" + else + echo "Nope, it didn't work." + val="$undef" + case "$?" in + 3) $cat >&4 <try.c < +#endif +#$i_systime I_SYS_TIME +#$i_sysselct I_SYS_SELECT +#$d_socket HAS_SOCKET +#include +#ifdef HAS_SOCKET +#include /* Might include */ +#endif +#ifdef I_SYS_TIME +#include +#endif +#ifdef I_SYS_SELECT +#include +#endif +int main() { + fd_set fds; + +#ifdef TRYBITS + if(fds.fds_bits); +#endif + +#if defined(FD_SET) && defined(FD_CLR) && defined(FD_ISSET) && defined(FD_ZERO) + exit(0); +#else + exit(1); +#endif +} +EOCP +set try -DTRYBITS +if eval $compile; then + d_fds_bits="$define" + d_fd_set="$define" + echo "Well, your system knows about the normal fd_set typedef..." >&4 + if $run ./try; then echo "and you have the normal fd_set macros (just as I'd expect)." >&4 d_fd_macros="$define" else @@ -15902,274 +16219,6 @@ case "$d_statfs_f_flags" in *) echo "No, it doesn't." ;; esac -: see if _ptr and _cnt from stdio act std -echo " " - -if $contains '_lbfsize' `./findhdr stdio.h` >/dev/null 2>&1 ; then - echo "(Looks like you have stdio.h from BSD.)" - case "$stdio_ptr" in - '') stdio_ptr='((fp)->_p)' - ptr_lval=$define - ;; - *) ptr_lval=$d_stdio_ptr_lval;; - esac - case "$stdio_cnt" in - '') stdio_cnt='((fp)->_r)' - cnt_lval=$define - ;; - *) cnt_lval=$d_stdio_cnt_lval;; - esac - case "$stdio_base" in - '') stdio_base='((fp)->_ub._base ? (fp)->_ub._base : (fp)->_bf._base)';; - esac - case "$stdio_bufsiz" in - '') stdio_bufsiz='((fp)->_ub._base ? (fp)->_ub._size : (fp)->_bf._size)';; - esac -elif $contains '_IO_fpos_t' `./findhdr stdio.h` `./findhdr libio.h` >/dev/null 2>&1 ; then - echo "(Looks like you have stdio.h from Linux.)" - case "$stdio_ptr" in - '') stdio_ptr='((fp)->_IO_read_ptr)' - ptr_lval=$define - ;; - *) ptr_lval=$d_stdio_ptr_lval;; - esac - case "$stdio_cnt" in - '') stdio_cnt='((fp)->_IO_read_end - (fp)->_IO_read_ptr)' - cnt_lval=$undef - ;; - *) cnt_lval=$d_stdio_cnt_lval;; - esac - case "$stdio_base" in - '') stdio_base='((fp)->_IO_read_base)';; - esac - case "$stdio_bufsiz" in - '') stdio_bufsiz='((fp)->_IO_read_end - (fp)->_IO_read_base)';; - esac -else - case "$stdio_ptr" in - '') stdio_ptr='((fp)->_ptr)' - ptr_lval=$define - ;; - *) ptr_lval=$d_stdio_ptr_lval;; - esac - case "$stdio_cnt" in - '') stdio_cnt='((fp)->_cnt)' - cnt_lval=$define - ;; - *) cnt_lval=$d_stdio_cnt_lval;; - esac - case "$stdio_base" in - '') stdio_base='((fp)->_base)';; - esac - case "$stdio_bufsiz" in - '') stdio_bufsiz='((fp)->_cnt + (fp)->_ptr - (fp)->_base)';; - esac -fi - -: test whether _ptr and _cnt really work -echo "Checking how std your stdio is..." >&4 -$cat >try.c < -#$i_stdlib I_STDLIB -#ifdef I_STDLIB -#include -#endif -#define FILE_ptr(fp) $stdio_ptr -#define FILE_cnt(fp) $stdio_cnt -int main() { - FILE *fp = fopen("try.c", "r"); - char c = getc(fp); - if ( - 18 <= FILE_cnt(fp) && - strncmp(FILE_ptr(fp), "include \n", 18) == 0 - ) - exit(0); - exit(1); -} -EOP -val="$undef" -set try -if eval $compile && $to try.c; then - if $run ./try; then - echo "Your stdio acts pretty std." - val="$define" - else - echo "Your stdio isn't very std." - fi -else - echo "Your stdio doesn't appear very std." -fi -$rm -f try.c try - -# glibc 2.2.90 and above apparently change stdio streams so Perl's -# direct buffer manipulation no longer works. The Configure tests -# should be changed to correctly detect this, but until then, -# the following check should at least let perl compile and run. -# (This quick fix should be updated before 5.8.1.) -# To be defensive, reject all unknown versions, and all versions > 2.2.9. -# A. Dougherty, June 3, 2002. -case "$d_gnulibc" in -$define) - case "$gnulibc_version" in - 2.[01]*) ;; - 2.2) ;; - 2.2.[0-9]) ;; - *) echo "But I will not snoop inside glibc $gnulibc_version stdio buffers." - val="$undef" - ;; - esac - ;; -esac -set d_stdstdio -eval $setvar - -: Can _ptr be used as an lvalue? -case "$d_stdstdio$ptr_lval" in -$define$define) val=$define ;; -*) val=$undef ;; -esac -set d_stdio_ptr_lval -eval $setvar - -: Can _cnt be used as an lvalue? -case "$d_stdstdio$cnt_lval" in -$define$define) val=$define ;; -*) val=$undef ;; -esac -set d_stdio_cnt_lval -eval $setvar - - -: test whether setting _ptr sets _cnt as a side effect -d_stdio_ptr_lval_sets_cnt="$undef" -d_stdio_ptr_lval_nochange_cnt="$undef" -case "$d_stdio_ptr_lval$d_stdstdio" in -$define$define) - echo "Checking to see what happens if we set the stdio ptr..." >&4 -$cat >try.c < -/* Can we scream? */ -/* Eat dust sed :-) */ -/* In the buffer space, no one can hear you scream. */ -#$i_stdlib I_STDLIB -#ifdef I_STDLIB -#include -#endif -#define FILE_ptr(fp) $stdio_ptr -#define FILE_cnt(fp) $stdio_cnt -#include -int main() { - FILE *fp = fopen("try.c", "r"); - int c; - char *ptr; - size_t cnt; - if (!fp) { - puts("Fail even to read"); - exit(1); - } - c = getc(fp); /* Read away the first # */ - if (c == EOF) { - puts("Fail even to read"); - exit(1); - } - if (!( - 18 <= FILE_cnt(fp) && - strncmp(FILE_ptr(fp), "include \n", 18) == 0 - )) { - puts("Fail even to read"); - exit (1); - } - ptr = (char*) FILE_ptr(fp); - cnt = (size_t)FILE_cnt(fp); - - FILE_ptr(fp) += 42; - - if ((char*)FILE_ptr(fp) != (ptr + 42)) { - printf("Fail ptr check %p != %p", FILE_ptr(fp), (ptr + 42)); - exit (1); - } - if (FILE_cnt(fp) <= 20) { - printf ("Fail (<20 chars to test)"); - exit (1); - } - if (strncmp(FILE_ptr(fp), "Eat dust sed :-) */\n", 20) != 0) { - puts("Fail compare"); - exit (1); - } - if (cnt == FILE_cnt(fp)) { - puts("Pass_unchanged"); - exit (0); - } - if (FILE_cnt(fp) == (cnt - 42)) { - puts("Pass_changed"); - exit (0); - } - printf("Fail count was %d now %d\n", cnt, FILE_cnt(fp)); - return 1; - -} -EOP - set try - if eval $compile && $to try.c; then - case `$run ./try` in - Pass_changed) - echo "Increasing ptr in your stdio decreases cnt by the same amount. Good." >&4 - d_stdio_ptr_lval_sets_cnt="$define" ;; - Pass_unchanged) - echo "Increasing ptr in your stdio leaves cnt unchanged. Good." >&4 - d_stdio_ptr_lval_nochange_cnt="$define" ;; - Fail*) - echo "Increasing ptr in your stdio didn't do exactly what I expected. We'll not be doing that then." >&4 ;; - *) - echo "It appears attempting to set ptr in your stdio is a bad plan." >&4 ;; - esac - else - echo "It seems we can't set ptr in your stdio. Nevermind." >&4 - fi - $rm -f try.c try - ;; -esac - -: see if _base is also standard -val="$undef" -case "$d_stdstdio" in -$define) - $cat >try.c < -#$i_stdlib I_STDLIB -#ifdef I_STDLIB -#include -#endif -#define FILE_base(fp) $stdio_base -#define FILE_bufsiz(fp) $stdio_bufsiz -int main() { - FILE *fp = fopen("try.c", "r"); - char c = getc(fp); - if ( - 19 <= FILE_bufsiz(fp) && - strncmp(FILE_base(fp), "#include \n", 19) == 0 - ) - exit(0); - exit(1); -} -EOP - set try - if eval $compile && $to try.c; then - if $run ./try; then - echo "And its _base field acts std." - val="$define" - else - echo "But its _base field isn't std." - fi - else - echo "However, it seems to be lacking the _base field." - fi - $rm -f try.c try - ;; -esac -set d_stdiobase -eval $setvar - $cat >&4 <$CONFIG_H -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un */ #$d_dlsymun DLSYM_NEEDS_UNDERSCORE /**/ +/* HAS_FAST_STDIO: + * This symbol, if defined, indicates that the "fast stdio" + * is available to manipulate the stdio buffers directly. + */ +#$d_faststdio HAS_FAST_STDIO /**/ + /* HAS_FCHDIR: * This symbol, if defined, indicates that the fchdir routine is * available to change directory using a file descriptor. @@ -3316,6 +3322,14 @@ sed <$CONFIG_H -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un #$use64bitall USE_64_BIT_ALL /**/ #endif +/* USE_FAST_STDIO: + * This symbol, if defined, indicates that Perl should + * be built to use 'fast stdio'. + */ +#ifndef USE_FAST_STDIO +#$usefaststdio USE_FAST_STDIO /**/ +#endif + /* USE_LARGE_FILES: * This symbol, if defined, indicates that large file support * should be used when available. diff --git a/perlio.c b/perlio.c index e6c985c..63a159f 100644 --- a/perlio.c +++ b/perlio.c @@ -3227,16 +3227,16 @@ PerlIO_funcs PerlIO_stdio = { #ifdef USE_STDIO_PTR PerlIOStdio_get_ptr, PerlIOStdio_get_cnt, -#if (defined(STDIO_PTR_LVALUE) && (defined(STDIO_CNT_LVALUE) || defined(STDIO_PTR_LVAL_SETS_CNT))) - PerlIOStdio_set_ptrcnt -#else /* STDIO_PTR_LVALUE */ - NULL -#endif /* STDIO_PTR_LVALUE */ -#else /* USE_STDIO_PTR */ +# if defined(HAS_FAST_STDIO) && defined(USE_FAST_STDIO) + PerlIOStdio_get_ptr, +# else + NULL, +# endif /* HAS_FAST_STDIO && USE_FAST_STDIO */ +#else + NULL, NULL, NULL, - NULL -#endif /* USE_STDIO_PTR */ +#endif /* USE_STDIO_PTR */ }; /* Note that calls to PerlIO_exportFILE() are reversed using diff --git a/t/io/layers.t b/t/io/layers.t index 0e733ad..9a58de2 100644 --- a/t/io/layers.t +++ b/t/io/layers.t @@ -25,12 +25,8 @@ plan tests => 43; use Config; my $DOSISH = $^O =~ /^(?:MSWin32|cygwin|os2|dos|NetWare|mint)$/ ? 1 : 0; -my $NONSTDIO = exists $ENV{PERLIO} && $ENV{PERLIO} ne 'stdio' ? 1 : 0; -my $FASTSTDIO = - $Config{d_stdstdio} && - $Config{d_stdio_ptr_lval} && - ($Config{d_stdio_cnt_lval} || - $Config{d_stdio_ptr_lval_sets_cnt}) ? 1 : 0; +my $NONSTDIO = exists $ENV{PERLIO} && $ENV{PERLIO} ne 'stdio' ? 1 : 0; +my $FASTSTDIO = $Config{d_faststdio} && $Config{usefaststdio} ? 1 : 0; print <<__EOH__; # PERLIO = $PERLIO