From 64146e94dc72d3744ff47b109f77be9bafda3113 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 9 Jun 2017 10:53:53 -0600 Subject: [PATCH] rktio: first cut at moving Racket OS wrappers to a library The world doesn't need yet another cross-platform I/O library, but it's getting one. This one has exactly the things that Racket needs, and pulling it out will make it reusable from other VMs while improving the Racket code organization. This first step just gets started. --- racket/src/configure | 6 +- racket/src/racket/configure.ac | 4 +- racket/src/racket/make-configure | 5 + racket/src/rktio/Makefile.in | 21 + racket/src/rktio/configure | 5110 +++++++++++++++++++++++++++ racket/src/rktio/configure.ac | 196 + racket/src/rktio/rktio.h | 167 + racket/src/rktio/rktio_config.h.in | 21 + racket/src/rktio/rktio_error.c | 44 + racket/src/rktio/rktio_filesystem.c | 1964 ++++++++++ racket/src/rktio/rktio_poll_set.c | 779 ++++ racket/src/rktio/rktio_private.h | 86 + racket/src/rktio/rktio_read_write.c | 1168 ++++++ 13 files changed, 9569 insertions(+), 2 deletions(-) create mode 100644 racket/src/rktio/Makefile.in create mode 100755 racket/src/rktio/configure create mode 100644 racket/src/rktio/configure.ac create mode 100644 racket/src/rktio/rktio.h create mode 100644 racket/src/rktio/rktio_config.h.in create mode 100644 racket/src/rktio/rktio_error.c create mode 100644 racket/src/rktio/rktio_filesystem.c create mode 100644 racket/src/rktio/rktio_poll_set.c create mode 100644 racket/src/rktio/rktio_private.h create mode 100644 racket/src/rktio/rktio_read_write.c diff --git a/racket/src/configure b/racket/src/configure index fe2c906383..164fe5ca1c 100755 --- a/racket/src/configure +++ b/racket/src/configure @@ -838,7 +838,8 @@ LDFLAGS LIBS CPPFLAGS CPP' -ac_subdirs_all='foreign/libffi ' +ac_subdirs_all='foreign/libffi +rktio ' # Initialize some variables set by options. ac_init_help= @@ -7150,6 +7151,9 @@ else fi makefiles="$makefiles foreign/Makefile" +subdirs="$subdirs rktio" + + # Remove any --enable or --disable arguments from `ac_configure_args': new_configure_args= fixup_prev= diff --git a/racket/src/racket/configure.ac b/racket/src/racket/configure.ac index d62a42ad3d..0fe411d03e 100644 --- a/racket/src/racket/configure.ac +++ b/racket/src/racket/configure.ac @@ -1,7 +1,7 @@ ################################################################# # This is the source for the `configure' script, to be compiled # -# by autoconf (use make-configure in this directory). # +# by autoconf (use `make-configure` in this directory). # ################################################################# # Remember: @@ -1938,6 +1938,8 @@ else fi makefiles="$makefiles foreign/Makefile" +AC_CONFIG_SUBDIRS( rktio ) + # Remove any --enable or --disable arguments from `ac_configure_args': new_configure_args= fixup_prev= diff --git a/racket/src/racket/make-configure b/racket/src/racket/make-configure index c593b1c144..99aede84ae 100755 --- a/racket/src/racket/make-configure +++ b/racket/src/racket/make-configure @@ -10,6 +10,11 @@ if [ -e "$tgt" ]; then fi autoconf "$src" | racket "$0" > "$tgt" chmod +x "$tgt" +src="../rktio/configure.ac" +tgt="../rktio/configure" +echo "Creating $tgt from $src" +autoconf "$src" > "$tgt" +chmod +x "$tgt" exit 0 |# #lang racket/base diff --git a/racket/src/rktio/Makefile.in b/racket/src/rktio/Makefile.in new file mode 100644 index 0000000000..846e7f5fb6 --- /dev/null +++ b/racket/src/rktio/Makefile.in @@ -0,0 +1,21 @@ + +srcdir = @srcdir@ + +CC = @CC@ +CFLAGS = @CFLAGS@ @CPPFLAGS@ + +RKTIO_HEADERS = $(srcdir)/rktio.h $(srcdir)/rktio_private.h rktio_config.h + +all: rktio_filesystem.o rktio_read_write.o rktio_poll_set.o rktio_error.o + +rktio_filesystem.o: $(srcdir)/rktio_filesystem.c $(RKTIO_HEADERS) + $(CC) $(CFLAGS) -I$(srcdir) -I. -o rktio_filesystem.o -c $(srcdir)/rktio_filesystem.c + +rktio_read_write.o: $(srcdir)/rktio_read_write.c $(RKTIO_HEADERS) + $(CC) $(CFLAGS) -I$(srcdir) -I. -o rktio_read_write.o -c $(srcdir)/rktio_read_write.c + +rktio_poll_set.o: $(srcdir)/rktio_poll_set.c $(RKTIO_HEADERS) + $(CC) $(CFLAGS) -I$(srcdir) -I. -o rktio_poll_set.o -c $(srcdir)/rktio_poll_set.c + +rktio_error.o: $(srcdir)/rktio_error.c $(RKTIO_HEADERS) + $(CC) $(CFLAGS) -I$(srcdir) -I. -o rktio_error.o -c $(srcdir)/rktio_error.c diff --git a/racket/src/rktio/configure b/racket/src/rktio/configure new file mode 100755 index 0000000000..e4231d8330 --- /dev/null +++ b/racket/src/rktio/configure @@ -0,0 +1,5110 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69. +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= +PACKAGE_URL= + +ac_unique_file="rktio.h" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='LTLIBOBJS +LIBOBJS +EGREP +GREP +CPP +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +target_os +target_vendor +target_cpu +target +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] + --target=TARGET configure for building compilers for TARGET [HOST] +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to the package provider. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +configure +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_config_headers="$ac_config_headers rktio_config.h" + + +ac_aux_dir= +for ac_dir in ../lt "$srcdir"/../lt; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in ../lt \"$srcdir\"/../lt" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 +$as_echo_n "checking target system type... " >&6; } +if ${ac_cv_target+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$target_alias" = x; then + ac_cv_target=$ac_cv_host +else + ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 +$as_echo "$ac_cv_target" >&6; } +case $ac_cv_target in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; +esac +target=$ac_cv_target +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_target +shift +target_cpu=$1 +target_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +target_os=$* +IFS=$ac_save_IFS +case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac + + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +test -n "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + + +###### Autoconfigure ####### + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBDL 1 +_ACEOF + + LIBS="-ldl $LIBS" + +fi + + +############## platform tests ################ + +case "$host_os" in + *) + ;; +esac + +############## C flags ################ + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "$ac_includes_default" +if test "x$ac_cv_type_intptr_t" = xyes; then : + +$as_echo "#define HAVE_INTPTR_T 1" >>confdefs.h + +else + for ac_type in 'int' 'long int' 'long long int'; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($ac_type))]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +cat >>confdefs.h <<_ACEOF +#define intptr_t $ac_type +_ACEOF + + ac_type= +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test -z "$ac_type" && break + done +fi + + + + ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default" +if test "x$ac_cv_type_uintptr_t" = xyes; then : + +$as_echo "#define HAVE_UINTPTR_T 1" >>confdefs.h + +else + for ac_type in 'unsigned int' 'unsigned long int' \ + 'unsigned long long int'; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($ac_type))]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +cat >>confdefs.h <<_ACEOF +#define uintptr_t $ac_type +_ACEOF + + ac_type= +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test -z "$ac_type" && break + done +fi + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo" >&5 +$as_echo_n "checking for getaddrinfo... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +int +main () +{ +getaddrinfo(0, 0, 0, 0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +$as_echo "#define HAVE_GETADDRINFO 1" >>confdefs.h + + have_getaddrinfo=yes +else + have_getaddrinfo=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_getaddrinfo" >&5 +$as_echo "$have_getaddrinfo" >&6; } + +iconv_lib_flag="" +if test "${skip_iconv_check}" = "no" ; then + if test "${enable_iconv}" = "yes" ; then + ac_fn_c_check_header_mongrel "$LINENO" "iconv.h" "ac_cv_header_iconv_h" "$ac_includes_default" +if test "x$ac_cv_header_iconv_h" = xyes; then : + enable_iconv=yes +else + enable_iconv=no +fi + + + if test "${enable_iconv}" = "yes" ; then + # Does it all work, now? + if test "$cross_compiling" = yes; then : + enable_iconv=yes +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + #include + #include + int main() { + iconv_open("UTF-8", "UTF-8"); + return 0; + } +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + enable_iconv=yes +else + enable_iconv=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + if test "${enable_iconv}" = "no" ; then + # Try adding -liconv ? + # We did not use AC_CHECK_LIB because iconv is sometimes macro-renamed + ORIG_LIBS="$LIBS" + LIBS="$LIBS -liconv" + if test "$cross_compiling" = yes; then : + enable_iconv=yes +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + #include + #include + int main() { + iconv_open("UTF-8", "UTF-8"); + return 0; + } +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + enable_iconv=yes +else + enable_iconv=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + if test "${enable_iconv}" = "no" ; then + LIBS="$ORIG_LIBS" + else + iconv_lib_flag=" -liconv" + fi + fi + fi + fi + msg="iconv is usable" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking $msg" >&5 +$as_echo_n "checking $msg... " >&6; } + iconv_usage_result="$enable_iconv$iconv_lib_flag" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $iconv_usage_result" >&5 +$as_echo "$iconv_usage_result" >&6; } + if test "${enable_iconv}" = "no" ; then + CFLAGS="$CFLAGS -DRKTIO_NO_ICONV" + fi +fi + + msg="for mbsrtowcs" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $msg" >&5 +$as_echo_n "checking $msg... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include + int main() { + mbstate_t state; + char *src = "X"; + bzero(&state, sizeof(mbstate_t)); + mbsrtowcs(0, &src, 0, &state); + return 0; + } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + mbsrtowcs=yes +else + mbsrtowcs=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test "$mbsrtowcs" = "no" ; then + CFLAGS="$CFLAGS -DNO_MBTOWC_FUNCTIONS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $mbsrtowcs" >&5 +$as_echo "$mbsrtowcs" >&6; } + +if test "${try_poll_syscall}" = "yes" ; then + msg="for poll" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking $msg" >&5 +$as_echo_n "checking $msg... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + int main() { + struct pollfd pfd; + int r; + pfd.fd = 0; + pfd.events = POLLIN; + r = poll(&pfd, 1, 0); + return 0; + } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + use_poll=yes +else + use_poll=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $use_poll" >&5 +$as_echo "$use_poll" >&6; } + if test "${use_poll}" = "yes" ; then + +$as_echo "#define HAVE_POLL_SYSCALL 1" >>confdefs.h + + fi +fi + +if test "${try_epoll_syscall}" = "yes" ; then + msg="for epoll" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking $msg" >&5 +$as_echo_n "checking $msg... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + int main() { + int fd; + struct epoll_event ev; + fd = epoll_create(5); + ev.events = EPOLLIN | EPOLLONESHOT; + epoll_ctl(fd, EPOLL_CTL_ADD, 0, &ev); + return 0; + } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + use_epoll=yes +else + use_epoll=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $use_epoll" >&5 +$as_echo "$use_epoll" >&6; } + if test "${use_epoll}" = "yes" ; then + +$as_echo "#define HAVE_EPOLL_SYSCALL 1" >>confdefs.h + + fi +fi + +if test "${try_inotify_syscall}" = "yes" ; then + msg="for inotify" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking $msg" >&5 +$as_echo_n "checking $msg... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + int main() { + int fd; + int wd; + fd = inotify_init(); + wd = inotify_add_watch(fd, "/tmp", + (IN_CREATE | IN_DELETE | IN_DELETE_SELF + | IN_MODIFY | IN_MOVE_SELF | IN_MOVED_TO)); + return 0; + } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + use_inotify=yes +else + use_inotify=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $use_inotify" >&5 +$as_echo "$use_inotify" >&6; } + if test "${use_inotify}" = "yes" ; then + +$as_echo "#define HAVE_INOTIFY_SYSCALL 1" >>confdefs.h + + fi +fi + +if test "${try_kqueue_syscall}" = "yes" ; then + msg="for kqueue" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking $msg" >&5 +$as_echo_n "checking $msg... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include + #include + int main() { + int kq; + struct kevent kev; + struct timespec timeout = {0, 0}; + kq = kqueue(); + EV_SET(&kev, 0, EVFILT_READ, EV_ADD, 0, 0, NULL); + kevent(kq, &kev, 1, NULL, 0, &timeout); + return 0; + } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + use_kqueue=yes +else + use_kqueue=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $use_kqueue" >&5 +$as_echo "$use_kqueue" >&6; } + if test "${use_kqueue}" = "yes" ; then + +$as_echo "#define HAVE_KQUEUE_SYSCALL 1" >>confdefs.h + + fi +fi + +LFS_CFLAGS=`getconf LFS_CFLAGS 2> /dev/null` +if test "${LFS_CFLAGS}" != "" && test "${LFS_CFLAGS}" != "undefined"; then + echo "Large-file support: ${LFS_CFLAGS}" + CFLAGS="${CFLAGS} ${LFS_CFLAGS}" +fi + +############## final output ################ + + + + + +makefiles="Makefile" + +ac_config_files="$ac_config_files $makefiles" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Report bugs to the package provider." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "rktio_config.h") CONFIG_HEADERS="$CONFIG_HEADERS rktio_config.h" ;; + "$makefiles") CONFIG_FILES="$CONFIG_FILES $makefiles" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi + ;; + + + esac + +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/racket/src/rktio/configure.ac b/racket/src/rktio/configure.ac new file mode 100644 index 0000000000..bbfb58e625 --- /dev/null +++ b/racket/src/rktio/configure.ac @@ -0,0 +1,196 @@ + +################################################################# +# This is the source for the `configure` script, to be compiled # +# by autoconf (use `make-configure` in "../racket"). # +################################################################# + +AC_INIT([rktio.h]) +AC_CONFIG_HEADERS([rktio_config.h]) + +AC_CONFIG_AUX_DIR(../lt) +AC_CANONICAL_SYSTEM + +###### Autoconfigure ####### + +AC_PROG_CC + +AC_CHECK_LIB(dl, dlopen) + +############## platform tests ################ + +case "$host_os" in + *) + ;; +esac + +############## C flags ################ + +AC_LANG_C + +AC_TYPE_INTPTR_T +AC_TYPE_UINTPTR_T + +AC_MSG_CHECKING([for getaddrinfo]) +AC_TRY_LINK([#include +#include +#include ], + [getaddrinfo(0, 0, 0, 0);], + AC_DEFINE(HAVE_GETADDRINFO,1,[Have getaddrinfo]) + have_getaddrinfo=yes, + have_getaddrinfo=no) +AC_MSG_RESULT($have_getaddrinfo) + +iconv_lib_flag="" +if test "${skip_iconv_check}" = "no" ; then + if test "${enable_iconv}" = "yes" ; then + AC_CHECK_HEADER(iconv.h, enable_iconv=yes, enable_iconv=no) + if test "${enable_iconv}" = "yes" ; then + # Does it all work, now? + AC_TRY_RUN( +[ #include ] +[ #include ] + int main() { +[ iconv_open("UTF-8", "UTF-8");] + return 0; + }, enable_iconv=yes, enable_iconv=no, enable_iconv=yes) + if test "${enable_iconv}" = "no" ; then + # Try adding -liconv ? + # We did not use AC_CHECK_LIB because iconv is sometimes macro-renamed + ORIG_LIBS="$LIBS" + LIBS="$LIBS -liconv" + AC_TRY_RUN( +[ #include ] +[ #include ] + int main() { +[ iconv_open("UTF-8", "UTF-8");] + return 0; + }, enable_iconv=yes, enable_iconv=no, enable_iconv=yes) + if test "${enable_iconv}" = "no" ; then + LIBS="$ORIG_LIBS" + else + iconv_lib_flag=" -liconv" + fi + fi + fi + fi + [ msg="iconv is usable" ] + AC_MSG_CHECKING($msg) + iconv_usage_result="$enable_iconv$iconv_lib_flag" + AC_MSG_RESULT($iconv_usage_result) + if test "${enable_iconv}" = "no" ; then + CFLAGS="$CFLAGS -DRKTIO_NO_ICONV" + fi +fi + +[ msg="for mbsrtowcs" ] +AC_MSG_CHECKING($msg) +AC_LINK_IFELSE([AC_LANG_SOURCE([ + #include + #include + int main() { + mbstate_t state; + char *src = "X"; + bzero(&state, sizeof(mbstate_t)); + mbsrtowcs(0, &src, 0, &state); + return 0; + }])], mbsrtowcs=yes, mbsrtowcs=no) +if test "$mbsrtowcs" = "no" ; then + CFLAGS="$CFLAGS -DNO_MBTOWC_FUNCTIONS" +fi +AC_MSG_RESULT($mbsrtowcs) + +if test "${try_poll_syscall}" = "yes" ; then + [ msg="for poll" ] + AC_MSG_CHECKING($msg) + AC_LINK_IFELSE([AC_LANG_SOURCE([ + #include + int main() { + struct pollfd pfd; + int r; + pfd.fd = 0; + pfd.events = POLLIN; + r = poll(&pfd, 1, 0); + return 0; + }])], use_poll=yes, use_poll=no) + AC_MSG_RESULT($use_poll) + if test "${use_poll}" = "yes" ; then + AC_DEFINE(HAVE_POLL_SYSCALL,1,[Have poll]) + fi +fi + +if test "${try_epoll_syscall}" = "yes" ; then + [ msg="for epoll" ] + AC_MSG_CHECKING($msg) + AC_LINK_IFELSE([AC_LANG_SOURCE([ + #include + int main() { + int fd; + struct epoll_event ev; + fd = epoll_create(5); + ev.events = EPOLLIN | EPOLLONESHOT; + epoll_ctl(fd, EPOLL_CTL_ADD, 0, &ev); + return 0; + }])], use_epoll=yes, use_epoll=no) + AC_MSG_RESULT($use_epoll) + if test "${use_epoll}" = "yes" ; then + AC_DEFINE(HAVE_EPOLL_SYSCALL,1,[Have epoll]) + fi +fi + +if test "${try_inotify_syscall}" = "yes" ; then + [ msg="for inotify" ] + AC_MSG_CHECKING($msg) + AC_LINK_IFELSE([AC_LANG_SOURCE([ + #include + int main() { + int fd; + int wd; + fd = inotify_init(); + wd = inotify_add_watch(fd, "/tmp", + (IN_CREATE | IN_DELETE | IN_DELETE_SELF + | IN_MODIFY | IN_MOVE_SELF | IN_MOVED_TO)); + return 0; + }])], use_inotify=yes, use_inotify=no) + AC_MSG_RESULT($use_inotify) + if test "${use_inotify}" = "yes" ; then + AC_DEFINE(HAVE_INOTIFY_SYSCALL,1,[Have inotify]) + fi +fi + +if test "${try_kqueue_syscall}" = "yes" ; then + [ msg="for kqueue" ] + AC_MSG_CHECKING($msg) + AC_LINK_IFELSE([AC_LANG_SOURCE([ + #include + #include + #include + int main() { + int kq; + struct kevent kev; + struct timespec timeout = {0, 0}; + kq = kqueue(); + EV_SET(&kev, 0, EVFILT_READ, EV_ADD, 0, 0, NULL); + kevent(kq, &kev, 1, NULL, 0, &timeout); + return 0; + }])], use_kqueue=yes, use_kqueue=no) + AC_MSG_RESULT($use_kqueue) + if test "${use_kqueue}" = "yes" ; then + AC_DEFINE(HAVE_KQUEUE_SYSCALL,1,[Have kqueue]) + fi +fi + +LFS_CFLAGS=`getconf LFS_CFLAGS 2> /dev/null` +if test "${LFS_CFLAGS}" != "" && test "${LFS_CFLAGS}" != "undefined"; then + echo "Large-file support: ${LFS_CFLAGS}" + CFLAGS="${CFLAGS} ${LFS_CFLAGS}" +fi + +############## final output ################ + +AC_SUBST(CC) +AC_SUBST(CFLAGS) +AC_SUBST(LDFLAGS) + +makefiles="Makefile" + +AC_OUTPUT($makefiles) diff --git a/racket/src/rktio/rktio.h b/racket/src/rktio/rktio.h new file mode 100644 index 0000000000..84e1f10a20 --- /dev/null +++ b/racket/src/rktio/rktio.h @@ -0,0 +1,167 @@ +#ifndef __RKTIO_H__ +#define __RKTIO_H__ + +#include "rktio_config.h" + +/*************************************************/ +/* Reading and writing files */ + +typedef struct rktio_fd_t rktio_fd_t; + +#define RKTIO_OPEN_READ (1<<0) +#define RKTIO_OPEN_WRITE (1<<1) +#define RKTIO_OPEN_TRUNCATE (1<<2) +#define RKTIO_OPEN_APPEND (1<<3) +#define RKTIO_OPEN_REPLACE (1<<4) +#define RKTIO_OPEN_MUST_EXIST (1<<5) +#define RKTIO_OPEN_CAN_EXIST (1<<6) + +rktio_fd_t *rktio_fd(intptr_t system_fd, int modes); + +rktio_fd_t *rktio_open(char *src, int modes); +int rktio_close(rktio_fd_t *fd); + +#define RKTIO_READ_EOF (-1) +#define RKTIO_READ_ERROR (-2) +#define RKTIO_WRITE_ERROR (-2) +#define RKTIO_POLL_ERROR (-2) + +intptr_t rktio_read(rktio_fd_t *fd, char *buffer, intptr_t len); +intptr_t rktio_write(rktio_fd_t *fd, char *buffer, intptr_t len); + +int rktio_poll_read_ready(rktio_fd_t *rfd); +int rktio_poll_write_ready(rktio_fd_t *rfd); +int rktio_poll_write_flushed(rktio_fd_t *rfd); + +/*************************************************/ +/* File-descriptor sets */ + +typedef struct rktio_poll_set_t rktio_poll_set_t; + +#define RKTIO_POLL_READ RKTIO_OPEN_READ +#define RKTIO_POLL_WRITE RKTIO_OPEN_WRITE + +void rktio_poll_add(rktio_fd_t *rfd, rktio_poll_set_t *fds, int modes); + +/*************************************************/ +/* Files, directories, and links */ + +int rktio_file_exists(char *filename); +int rktio_directory_exists(char *dirname); +int rktio_link_exists(char *filename); +int rktio_is_regular_file(char *filename); + +int rktio_delete_file(char *fn, int enable_write_on_fail); +int rktio_rename_file(char *dest, char *src, int exists_ok); + +char *rktio_get_current_directory(); +int rktio_set_current_directory(char *expanded); +int rktio_make_directory(char *filename); +int rktio_delete_directory(char *filename, char *current_directory, int enable_write_on_fail); + +char *rktio_readlink(char *fullfilename); +int rktio_make_link(char *src, char *dest, int dest_is_directory); + +/*************************************************/ +/* File attributes */ + +typedef struct { + unsigned lo, hi; +} rktio_size_t; + +typedef intptr_t rktio_timestamp_t; + +typedef struct { + uintptr_t a, b, c; +} rktio_identity_t; + +rktio_size_t *rktio_file_size(char *filename); + +rktio_timestamp_t *rktio_get_file_modify_seconds(char *file); +int rktio_set_file_modify_seconds(char *file, rktio_timestamp_t secs); + +rktio_identity_t *rktio_get_fd_identity(intptr_t fd, char *path); + +/*************************************************/ +/* Permissions */ + +/* Must match OS bits: */ +#define RKTIO_PERMISSION_READ 0x1 +#define RKTIO_PERMISSION_WRITE 0x2 +#define RKTIO_PERMISSION_EXEC 0x4 + +int rktio_get_file_or_directory_permissions(char *filename, int all_bits); +int rktio_set_file_or_directory_permissions(char *filename, int new_bits); + +/*************************************************/ +/* Directory listing */ + +typedef struct rktio_directory_list_t rktio_directory_list_t; + +rktio_directory_list_t *rktio_directory_list_start(char *filename, int is_drive); +char *rktio_directory_list_step(rktio_directory_list_t *dl); + +char **rktio_filesystem_root_list(); + +/*************************************************/ +/* File copying */ + +typedef struct rktio_file_copy_t rktio_file_copy_t; + +rktio_file_copy_t *rktio_copy_file_start(char *dest, char *src, int exists_ok); +int rktio_copy_file_is_done(rktio_file_copy_t *fc); +int rktio_copy_file_step(rktio_file_copy_t *fc); +void rktio_copy_file_stop(rktio_file_copy_t *fc); + +/*************************************************/ +/* System paths */ + +enum { + RKTIO_PATH_SYS_DIR, + RKTIO_PATH_TEMP_DIR, + RKTIO_PATH_PREF_DIR, + RKTIO_PATH_PREF_FILE, + RKTIO_PATH_ADDON_DIR, + RKTIO_PATH_HOME_DIR, + RKTIO_PATH_DESK_DIR, + RKTIO_PATH_DOC_DIR, + RKTIO_PATH_INIT_DIR, + RKTIO_PATH_INIT_FILE +}; + +char *rktio_system_path(int which); +char *rktio_expand_user_tilde(char *filename); + +/*************************************************/ +/* Errors */ + +/* Kinds of error values: */ +enum { + RKTIO_ERROR_KIND_POSIX, + RKTIO_ERROR_KIND_WINDOWS, + RKTIO_ERROR_KIND_GAI, + RKTIO_ERROR_KIND_RACKET +}; + +/* Error IDs of kind RKTIO_ERROR_KIND_RACKET */ +enum { + RKTIO_ERROR_UNSUPPORTED, + RKTIO_ERROR_EXISTS, + RKTIO_ERROR_LINK_FAILED, + RKTIO_ERROR_NOT_A_LINK, + RKTIO_ERROR_BAD_PERMISSION, + RKTIO_ERROR_IS_A_DIRECTORY, + RKTIO_ERROR_NOT_A_DIRECTORY, + RKTIO_ERROR_NO_TILDE, + RKTIO_ERROR_ILL_FORMED_USER, + RKTIO_ERROR_UNKNOWN_USER +}; + +int rktio_get_last_error(void); +int rktio_get_last_error_kind(void); + +char *rktio_get_error_string(int kind, int errid); + +/*************************************************/ + +#endif diff --git a/racket/src/rktio/rktio_config.h.in b/racket/src/rktio/rktio_config.h.in new file mode 100644 index 0000000000..659d3f1fc2 --- /dev/null +++ b/racket/src/rktio/rktio_config.h.in @@ -0,0 +1,21 @@ +/* Whether `intptr_t' is available. */ +#undef HAVE_INTPTR_T + +/* Whether `uintptr_t' is available. */ +#undef HAVE_UINTPTR_T + +#ifdef HAVE_INTPTR_T +# include +#endif +#ifndef HAVE_INTPTR_T +typedef long intptr_t; +#endif +#ifndef HAVE_UINTPTR_T +typedef unsigned long uintptr_t; +#endif + +/* When poll(), epoll(), kqueue(), etc. is available: */ +#undef HAVE_POLL_SYSCALL +#undef HAVE_EPOLL_SYSCALL +#undef HAVE_INOTIFY_SYSCALL +#undef HAVE_KQUEUE_SYSCALL diff --git a/racket/src/rktio/rktio_error.c b/racket/src/rktio/rktio_error.c new file mode 100644 index 0000000000..f673ef3d8c --- /dev/null +++ b/racket/src/rktio/rktio_error.c @@ -0,0 +1,44 @@ +#include "rktio.h" +#include "rktio_private.h" +#ifdef RKTIO_SYSTEM_WINDOWS +# include +#endif +#include + +THREAD_LOCAL_DECL(static intptr_t errid); +THREAD_LOCAL_DECL(static int errkind); + +void rktio_get_posix_error(void) +{ + errid = errno; + errkind = RKTIO_ERROR_KIND_POSIX; +} + +void rktio_set_racket_error(int new_errid) +{ + errid = new_errid; + errkind = RKTIO_ERROR_KIND_RACKET; +} + +#ifdef RKTIO_SYSTEM_WINDOWS +void rktio_get_windows_error(void) +{ + errid = GetLastError(); + errkind = RKTIO_ERROR_KIND_WINDOWS; +} +#endif + +int rktio_get_last_error(void) +{ + return errid; +} + +int rktio_get_last_error_kind(void) +{ + return errkind; +} + +char *rktio_get_error_string(int kind, int errid) +{ + return "???"; +} diff --git a/racket/src/rktio/rktio_filesystem.c b/racket/src/rktio/rktio_filesystem.c new file mode 100644 index 0000000000..60f1d50455 --- /dev/null +++ b/racket/src/rktio/rktio_filesystem.c @@ -0,0 +1,1964 @@ +#include "rktio.h" +#include "rktio_private.h" +#include +#include +#include +#include +#include +#include +#include +#ifdef RKTIO_SYSTEM_UNIX +# include +#include +#include +#include +#include +#endif +#ifdef RKTIO_SYSTEM_WINDOWS +# include +#endif + +#ifdef RKTIO_SYSTEM_UNIX +# define A_PATH_SEP '/' +#endif +#ifdef RKTIO_SYSTEM_WINDOWS +# define A_PATH_SEP '\\' +# define IS_A_DOS_SEP(c) IS_A_SEP(c) +#endif +#define IS_A_SEP(c) ((c) == A_PATH_SEP) + +#ifdef USE_TRANSITIONAL_64_FILE_OPS +# define BIG_OFF_T_IZE(n) n ## 64 +#else +# define BIG_OFF_T_IZE(n) n +#endif + +#if defined(RKTIO_SYSTEM_UNIX) && !defined(NO_UNIX_USERS) +static int have_user_ids = 0; +static uid_t uid; +static uid_t euid; +static gid_t gid; +static gid_t egid; + +#define GROUP_MEMBER_CACHE_STATE_UNUSED 0 +#define GROUP_MEMBER_CACHE_STATE_IN 1 +#define GROUP_MEMBER_CACHE_STATE_NOT_IN 2 +typedef struct { + int state; + gid_t gid; + uid_t uid; +} group_member_cache_entry_t; +THREAD_LOCAL_DECL(static group_member_cache_entry_t *group_member_cache); +# define GROUP_CACHE_SIZE 10 +#endif + +#ifdef RKTIO_SYSTEM_WINDOWS +static int procs_initied = 0; +typedef BOOLEAN (WINAPI*CreateSymbolicLinkProc_t)(wchar_t *dest, wchar_t *src, DWORD flags); +static CreateSymbolicLinkProc_t CreateSymbolicLinkProc = NULL; + +typedef BOOL (WINAPI*DeviceIoControlProc_t)(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, + DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, + LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped); +static DeviceIoControlProc_t DeviceIoControlProc; +#endif + +#ifdef RKTIO_SYSTEM_WINDOWS +static void init_procs() +{ + if (!procs_inited) { + HMODULE hm; + + procs_inited = 1; + + hm = LoadLibrary("kernel32.dll"); + + CreateSymbolicLinkProc = (CreateSymbolicLinkProc_t)GetProcAddress(hm, "CreateSymbolicLinkW"); + DeviceIoControlProc = (DeviceIoControlProc_t)GetProcAddress(hm, "DeviceIoControl"); + + FreeLibrary(hm); + } +} +#endif + +#ifdef RKTIO_SYSTEM_WINDOWS +# define MZ_UNC_READ RKTIO_PERMISSION_READ +# define MZ_UNC_WRITE RKTIO_PERMISSION_WRITE +# define MZ_UNC_EXEC RKTIO_PERMISSION_EXEC + +# define FIND_FIRST FindFirstFileW +# define FIND_NEXT FindNextFileW +# define FIND_CLOSE FindClose +# define FF_TYPE WIN32_FIND_DATAW +# define FF_HANDLE_TYPE HANDLE +# define FIND_FAILED(h) (h == INVALID_HANDLE_VALUE) +# define FF_A_RDONLY FILE_ATTRIBUTE_READONLY +# define FF_A_DIR FILE_ATTRIBUTE_DIRECTORY +# define FF_A_LINK 0x400 +# define GET_FF_ATTRIBS(fd) (fd.dwFileAttributes) +# define GET_FF_MODDATE(fd) convert_date(&fd.ftLastWriteTime) +# define GET_FF_NAME(fd) fd.cFileName + +static time_t convert_date(const FILETIME *ft) +{ + LONGLONG l, delta; + FILETIME ft2; + SYSTEMTIME st; + TIME_ZONE_INFORMATION tz; + + /* FindFirstFile incorrectly shifts for daylight saving. It + subtracts an hour to get to UTC when daylight saving is in effect + now, even when daylight saving was not in effect when the file + was saved. Counteract the difference. There's a race condition + here, because we might cross the daylight-saving boundary between + the time that FindFirstFile runs and GetTimeZoneInformation + runs. Cross your fingers... */ + FileTimeToLocalFileTime(ft, &ft2); + FileTimeToSystemTime(&ft2, &st); + + delta = 0; + if (GetTimeZoneInformation(&tz) == TIME_ZONE_ID_DAYLIGHT) { + /* Daylight saving is in effect now, so there may be a bad + shift. Check the file's date. */ + int start_day_of_month, end_day_of_month, first_day_of_week, diff, end_shift; + + /* Valid only when the months match: */ + first_day_of_week = (st.wDayOfWeek - (st.wDay - 1 - (((st.wDay - 1) / 7) * 7))); + if (first_day_of_week < 0) + first_day_of_week += 7; + + diff = (tz.DaylightDate.wDayOfWeek - first_day_of_week); + if (diff < 0) + diff += 7; + start_day_of_month = 1 + (((tz.DaylightDate.wDay - 1) * 7) + + diff); + + diff = (tz.StandardDate.wDayOfWeek - first_day_of_week); + if (diff < 0) + diff += 7; + end_day_of_month = 1 + (((tz.StandardDate.wDay - 1) * 7) + + diff); + + /* Count ambigious range (when the clock goes back) as + in standard time. We assume that subtracting the + ambiguous range does not go back into the previous day, + and that the shift is a multiple of an hour. */ + end_shift = ((tz.StandardBias - tz.DaylightBias) / 60); + + if ((st.wMonth < tz.DaylightDate.wMonth) + || ((st.wMonth == tz.DaylightDate.wMonth) + && ((st.wDay < start_day_of_month) + || ((st.wDay == start_day_of_month) + && (st.wHour < tz.DaylightDate.wHour))))) { + /* Daylight saving had not yet started. */ + delta = ((tz.StandardBias - tz.DaylightBias) * 60); + } else if ((st.wMonth > tz.StandardDate.wMonth) + || ((st.wMonth == tz.StandardDate.wMonth) + && ((st.wDay > end_day_of_month) + || ((st.wDay == end_day_of_month) + && (st.wHour >= (tz.StandardDate.wHour + - end_shift)))))) { + /* Daylight saving was already over. */ + delta = ((tz.StandardBias - tz.DaylightBias) * 60); + } + } + + l = ((((LONGLONG)ft->dwHighDateTime << 32) | ft->dwLowDateTime) + - (((LONGLONG)0x019DB1DE << 32) | 0xD53E8000)); + l /= 10000000; + l += delta; + + return (time_t)l; +} + +typedef struct mz_REPARSE_DATA_BUFFER { + ULONG ReparseTag; + USHORT ReparseDataLength; + USHORT Reserved; + union { + struct { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + ULONG Flags; + WCHAR PathBuffer[1]; + } SymbolicLinkReparseBuffer; + struct { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + WCHAR PathBuffer[1]; + } MountPointReparseBuffer; + struct { + UCHAR DataBuffer[1]; + } GenericReparseBuffer; + } u; +} mz_REPARSE_DATA_BUFFER; + +#define mzFILE_FLAG_OPEN_REPARSE_POINT 0x200000 +#define mzFSCTL_GET_REPARSE_POINT 0x900A8 + +static char *UNC_readlink(const char *fn) +{ + HANDLE h; + DWORD got; + char *buffer; + int size = 1024; + mz_REPARSE_DATA_BUFFER *rp; + int len, off; + wchar_t *lk; + + init_procs(); + + if (!DeviceIoControlProc) return NULL; + + h = CreateFileW(WIDE_PATH_temp(fn), FILE_READ_ATTRIBUTES, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS | mzFILE_FLAG_OPEN_REPARSE_POINT, + NULL); + + if (h == INVALID_HANDLE_VALUE) { + get_windows_error(); + return NULL; + } + + while (1) { + buffer = (char *)malloc(size); + if (DeviceIoControlProc(h, mzFSCTL_GET_REPARSE_POINT, NULL, 0, buffer, size, + &got, NULL)) + break; + else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + size *= 2; + free(buffer); + buffer = (char *)malloc(size); + } else { + get_windows_error(); + CloseHandle(h); + free(buffer); + return NULL; + } + } + + CloseHandle(h); + + rp = (mz_REPARSE_DATA_BUFFER *)buffer; + if ((rp->ReparseTag != IO_REPARSE_TAG_SYMLINK) + && (rp->ReparseTag != IO_REPARSE_TAG_MOUNT_POINT)) { + free(buffer); + set_racket_error(RKTIO_ERROR_LINK_FAILED); + return NULL; + } + + if (rp->ReparseTag == IO_REPARSE_TAG_SYMLINK) { + off = rp->u.SymbolicLinkReparseBuffer.SubstituteNameOffset; + len = rp->u.SymbolicLinkReparseBuffer.SubstituteNameLength; + if (!len) { + off = rp->u.SymbolicLinkReparseBuffer.PrintNameOffset; + len = rp->u.SymbolicLinkReparseBuffer.PrintNameLength; + } + } else { + off = rp->u.MountPointReparseBuffer.SubstituteNameOffset; + len = rp->u.MountPointReparseBuffer.SubstituteNameLength; + if (!len) { + off = rp->u.MountPointReparseBuffer.PrintNameOffset; + len = rp->u.MountPointReparseBuffer.PrintNameLength; + } + } + + lk = (wchar_t *)malloc(len + 2); + + if (rp->ReparseTag == IO_REPARSE_TAG_SYMLINK) + memcpy(lk, (char *)rp->u.SymbolicLinkReparseBuffer.PathBuffer + off, len); + else + memcpy(lk, (char *)rp->u.MountPointReparseBuffer.PathBuffer + off, len); + + lk[len>>1] = 0; + + if ((lk[0] == '\\') && (lk[1] == '?') && (lk[2] == '?') && (lk[3] == '\\')) { + /* "?\\" is a prefix that means "unparsed", or something like that */ + memmove(lk, lk+4, len - 8); + len -= 8; + lk[len>>1] = 0; + + if ((lk[0] == 'U') && (lk[1] == 'N') && (lk[2] == 'C') && (lk[3] == '\\')) { + /* "UNC\" is a further prefix that means "UNC"; replace "UNC" with "\" */ + memmove(lk, lk+2, len - 4); + lk[0] = '\\'; + len -= 4; + lk[len>>1] = 0; + } + } + + free(buffer); + + /* Make sure it's not empty, because that would form a bad path: */ + if (!lk[0]) { + free(lk); + set_racket_error(RKTIO_ERROR_LINK_FAILED); + return NULL; + } + + buffer = NARROW_PATH_copy(lk); + free(lk); + + return buffer; +} + +static int UNC_stat(const char *dirname, int *flags, int *isdir, int *islink, + rktio_timestamp_t **date, rktio_file_size_t *filesize, + const char **resolved_path, int set_flags) +/* dirname must be absolute */ +{ + /* Note: stat() doesn't work with UNC "drive" names or \\?\ paths. + Also, stat() doesn't distinguish between the ability to + list a directory's content and whether the directory exists. + So, we use GetFileAttributesExW(). */ + char *copy; + WIN32_FILE_ATTRIBUTE_DATA fad; + int len, must_be_dir = 0; + + if (resolved_path) + *resolved_path = NULL; + + retry: + + if (islink) + *islink = 0; + if (isdir) + *isdir = 0; + if (date) + *date = NULL; + + len = strlen(dirname); + + copy = malloc(len+1); + memcpy(copy, dirname, len+1); + + if (!rktio_windows_nt_or_later() + || ((len >= 4) + && (copy[0] == '\\') + && (copy[1] == '\\') + && (copy[2] == '?') + && (copy[3] == '\\'))) { + /* Keep `copy` as-is */ + } else { + /* Strip trailing separators */ + while (IS_A_DOS_SEP(copy[len - 1])) { + --len; + copy[len] = 0; + must_be_dir = 1; + } + } + + /* If we ended up with "\\?\X:" (and nothing after), then drop the "\\?\" */ + if ((copy[0] == '\\')&& (copy[1] == '\\') && (copy[2] == '?') && (copy[3] == '\\') + && is_drive_letter(copy[4]) && (copy[5] == ':') && !copy[6]) { + memmove(copy, copy + 4, len - 4); + len -= 4; + copy[len] = 0; + } + /* If we ended up with "\\?\\X:" (and nothing after), then drop the "\\?\\" */ + if ((copy[0] == '\\') && (copy[1] == '\\') && (copy[2] == '?') && (copy[3] == '\\') + && (copy[4] == '\\') && is_drive_letter(copy[5]) && (copy[6] == ':') && !copy[7]) { + memmove(copy, copy + 5, len - 5); + len -= 5; + copy[len] = 0; + } + /* If we ended up with "X:[/]", then add a "." at the end so that we get information + for the drive, not the current directory of the drive: */ + if (is_drive_letter(copy[0]) && (copy[1] == ':') + && (!copy[2] + || (IS_A_DOS_SEP(copy[2]) && !copy[3]))) { + copy[2] = '\\'; + copy[3] = '.'; + copy[4] = 0; + } + + if (!GetFileAttributesExW(WIDE_PATH_temp(copy), GetFileExInfoStandard, &fad)) { + get_windows_error(); + free(copy); + return 0; + } else { + if (GET_FF_ATTRIBS(fad) & FF_A_LINK) { + if (islink) { + *islink = 1; + return 1; + } else { + /* Resolve a link by opening the link and then getting + the path from the handle. */ + HANDLE h; + wchar_t *dest = NULL; + DWORD len = 255; + + h = CreateFileW(WIDE_PATH_temp(copy), FILE_READ_ATTRIBUTES, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + NULL); + + if (!h) { + get_windows_error(); + free(copy); + return 0; + } + + do { + if (dest) free(dest); + dest_len = len + 1; + dest = malloc(dest_len); + len = GetFinalPathNameByHandleW(h, dest, dest_len, FILE_NAME_NORMALIZED); + } while (len > dest_len); + + if (!len) { + get_windows_error(); + CloseHandle(h); + free(copy); + free(dest); + return 0; + } + + CloseHandle(h); + + dirname = NARROW_PATH_copy(dest); + if (resolved_path) + *resolved_path = dirname; + + free(dest); + free(copy); + + goto retry; + } + } + + if (set_flags != -1) { + DWORD attrs = GET_FF_ATTRIBS(fad); + + if (!(set_flags & MZ_UNC_WRITE)) + attrs |= FF_A_RDONLY; + else if (attrs & FF_A_RDONLY) + attrs -= FF_A_RDONLY; + + if (!SetFileAttributesW(WIDE_PATH_temp(copy), attrs)) { + get_windows_error(); + free(copy); + return 0; + } + } else { + if (must_be_dir && !(GET_FF_ATTRIBS(fad) & FF_A_DIR)) { + set_racket_error(RKTIO_ERROR_NOT_A_DIRECTORY); + free(copy); + return 0; + } + if (flags) + *flags = MZ_UNC_READ | MZ_UNC_EXEC | ((GET_FF_ATTRIBS(fad) & FF_A_RDONLY) ? 0 : MZ_UNC_WRITE); + if (date) { + rktio_timestamp_t *dt; + time_t mdt; + mdt = GET_FF_MODDATE(fad); + dt = malloc(sizeof(rktio_timestamp_t)); + *dt = mdt; + *date = dt; + } + if (isdir) { + *isdir = (GET_FF_ATTRIBS(fad) & FF_A_DIR); + } + if (filesize) { + rktio_size_t *fsz; + fsz = malloc(sizeof(rktio_size_t)); + fsz->lo = fad.nFileSizeLow; + fsz->hi = fad.nFileSizeHigh; + } + } + free(copy); + return 1; + } +} +#endif + +int rktio_file_exists(char *filename) +/* Windows: check for special filenames before calling */ +{ +# ifdef NO_STAT_PROC + int fd; + + fd = open(filename, O_RDONLY); + if (fd != -1) { + fclose(fd); + return 1; + } else + return 0; +# else +# ifdef RKTIO_SYSTEM_WINDOWS + { + int isdir; + return (UNC_stat(filename, NULL, &isdir, NULL, NULL, NULL, NULL, -1) + && !isdir); + } +# else + struct MSC_IZE(stat) buf; + int ok; + + do { + ok = MSC_W_IZE(stat)(MSC_WIDE_PATH_temp(filename), &buf); + } while ((ok == -1) && (errno == EINTR)); + + return !ok && !S_ISDIR(buf.st_mode); +# endif +# endif +} + +int rktio_directory_exists(char *dirname) +{ +# ifdef NO_STAT_PROC + return 0; +# else +# ifdef RKTIO_SYSTEM_WINDOWS + int isdir; + + return (UNC_stat(dirname, NULL, &isdir, NULL, NULL, NULL, NULL, -1) + && isdir); +# else + struct MSC_IZE(stat) buf; + + while (1) { + if (!MSC_IZE(stat)(dirname, &buf)) + break; + else if (errno != EINTR) + return 0; + } + + return S_ISDIR(buf.st_mode); +# endif +# endif +} + +int rktio_is_regular_file(char *filename) +/* Windows: check for special filenames before calling */ +{ +# ifdef NO_STAT_PROC + return 0; +# else + struct MSC_IZE(stat) buf; + + while (1) { + if (!MSC_W_IZE(stat)(MSC_WIDE_PATH_temp(filename), &buf)) + break; + else if (errno != EINTR) + return 0; + } + + return S_ISREG(buf.st_mode); +# endif +} + +int rktio_link_exists(char *filename) +{ +#ifdef RKTIO_SYSTEM_WINDOWS + { + int islink; + if (UNC_stat(filename, NULL, NULL, &islink, NULL, NULL, NULL, -1) + && islink) + return 1; + else + return 0; + } +#else + { + struct MSC_IZE(stat) buf; + while (1) { + if (!MSC_W_IZE(lstat)(MSC_WIDE_PATH_temp(filename), &buf)) + break; + else if (errno != EINTR) + return 0; + } + + if (S_ISLNK(buf.st_mode)) + return 1; + else + return 0; + } +#endif +} + +char *rktio_get_current_directory() +{ +#ifdef RKTIO_SYSTEM_WINDOWS + int need_l, bl = 256; + wchar_t *wbuf; + char *r; + + wbuf = malloc(bl); + while (1) { + need_l = GetCurrentDirectoryW(bl, wbuf); + if (need_l > bl) { + free(wbuf); + wbuf = malloc(need_l * sizeof(wchar_t)); + bl = need_l; + } else + break; + } + + if (!need_l) { + get_windows_error(); + return NULL; + } + + r = NARROW_PATH_copy_then_free(wbuf); + + return r; +#else + char *r, *s; + int len = 256; + + s = malloc(len); + while (1) { + r = MSC_IZE(getcwd)(s, len); + if (r) + break; + if (errno == ERANGE) { + free(s); + len *= 2; + s = malloc(len); + } else + break; + } + if (!r) + get_posix_error(); + return r; +#endif +} + +int rktio_set_current_directory(char *expanded) +{ + int err; + + while (1) { + err = MSC_W_IZE(chdir)(MSC_WIDE_PATH_temp(expanded)); + if (!err || (errno != EINTR)) + break; + } + + get_posix_error(); + + return !err; +} + +rktio_identity_t *rktio_get_fd_identity(intptr_t fd, char *path) +/* If path is supplied, then fd is 0 for stat, 1 for lstat */ +{ + uintptr_t devi = 0, inoi = 0, inoi2 = 0; + +#ifdef FILES_HAVE_FDS + int errid = 0; + struct MSC_IZE(stat) buf; + + while (1) { + if (!path && !MSC_IZE(fstat)(fd, &buf)) + break; + else if (path && !fd && !MSC_IZE(stat)(path, &buf)) + break; + else if (path && fd && !MSC_IZE(lstat)(path, &buf)) + break; + else if (errno != EINTR) { + errid = errno; + break; + } + } + + if (errid) { + get_posix_error(); + return NULL; + } else { + /* Warning: we assume that dev_t and ino_t fit in a pointer-sized integer. */ + devi = (uintptr_t)buf.st_dev; + inoi = (uintptr_t)buf.st_ino; + } +#endif +#ifdef WINDOWS_FILE_HANDLES + BY_HANDLE_FILE_INFORMATION info; + HANDLE fdh = (HANDLE)fd; + + init_procs(); + + if (path) { + fdh = CreateFileW(WIDE_PATH_temp(path), + 0, /* not even read access => just get info */ + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS + | ((fd && CreateSymbolicLinkProc) + ? mzFILE_FLAG_OPEN_REPARSE_POINT + : 0), + NULL); + if (fdh == INVALID_HANDLE_VALUE) { + get_windows_error(); + return NULL; + } + } + + if (!GetFileInformationByHandle(fdh, &info)) { + get_windows_error(); + if (path) CloseHandle(fdh); + return NULL; + } + + if (path) CloseHandle(fdh); + + devi = info.dwVolumeSerialNumber; + inoi = info.nFileIndexLow; + inoi2 = info.nFileIndexHigh; +#endif + + { + rktio_identity_t *id; + + id = malloc(sizeof(rktio_identity_t)); + + id->a = devi; + id->b = inoi; + id->c = inoi2; + + return id; + } +} + +#ifdef RKTIO_SYSTEM_WINDOWS +static int enable_write_permission(const char *fn) +{ + int flags; + + return UNC_stat(fn, &flags, NULL, NULL, NULL, NULL, NULL, MZ_UNC_WRITE); +} +#endif + +int rktio_delete_file(char *fn, int enable_write_on_fail) +{ + int errid; + +#ifdef RKTIO_SYSTEM_WINDOWS + if (DeleteFileW(WIDE_PATH_temp(fn))) + return 1; + errid = GetLastError(); + if ((errid == ERROR_ACCESS_DENIED) && enable_write_on_fail) { + /* Maybe it's just that the file has no write permission. Provide a more + Unix-like experience by attempting to change the file's permission. */ + if (enable_write_permission(fn)) { + if (DeleteFileW(WIDE_PATH_temp(fn))) + return 1; + } + } + + get_windows_error(); + return 0; +#else + while (1) { + if (!MSC_W_IZE(unlink)(MSC_WIDE_PATH_temp(fn))) + return 1; + else if (errno != EINTR) + break; + } + + get_posix_error(); + return 0; +#endif +} + +int rktio_rename_file(char *dest, char *src, int exists_ok) +{ +# ifdef RKTIO_SYSTEM_WINDOWS + int errid; + wchar_t *src_w = WIDE_PATH_copy(src); + + if (MoveFileExW(src_w, WIDE_PATH_temp(dest), (exists_ok ? MOVEFILE_REPLACE_EXISTING : 0))) { + free(src_w); + return 1; + } + + errid = GetLastError(); + + if (errid == ERROR_CALL_NOT_IMPLEMENTED) { + /* Then we have the great misfortune of running in Windows 9x. If + exists_ok, then do something no less stupid than the OS + itself: */ + int errid; + if (exists_ok) + MSC_W_IZE(unlink)(MSC_WIDE_PATH_temp(dest)); + if (MoveFileW(src_w, WIDE_PATH_temp(dest))) { + free(src_w); + return 1; + } + get_windows_error(); + } else + get_windows_error(); + + free(src_w); + return 0; +# else + if (!exists_ok && (rktio_file_exists(dest) || rktio_directory_exists(dest))) { + /* We use a specialized error here, because it's not + a system error (e.g., setting `errval` to `EEXIST` would + be a lie). */ + set_racket_error(RKTIO_ERROR_EXISTS); + return 0; + } + + while (1) { + if (!rename(src, dest)) + return 1; + else if (errno != EINTR) + break; + } + + get_posix_error(); + return 0; +# endif +} + +char *rktio_readlink(char *fullfilename) +{ +#ifdef RKTIO_SYSTEM_WINDOWS + if (UNC_stat(fullfilename, NULL, NULL, &is_link, NULL, NULL, NULL, -1) + && is_link) { + return UNC_readlink(fullfilename); + } else { + set_racket_error(RKTIO_ERROR_NOT_A_LINK); + return NULL; + } +#else + int len, buf_len = 256; + char *buffer = malloc(buf_len); + + while (1) { + len = readlink(fullfilename, buffer, buf_len); + if (len == -1) { + if (errno != EINTR) { + get_posix_error(); + return NULL; + } + } else if (len == buf_len) { + /* maybe too small */ + free(buffer); + buf_len *= 2; + buffer = malloc(buf_len); + } else + break; + } + buffer[len] = 0; + return buffer; +#endif +} + +int rktio_make_directory(char *filename) +{ +#ifdef NO_MKDIR + set_racket_error(RKTIO_ERROR_UNSUPPORTED); + return 0; +#else + int exists_already = 0; + int len, copied = 0; + + /* Make sure path doesn't have trailing separator: */ + len = strlen(filename); + while (len && IS_A_SEP(filename[len - 1])) { + if (!copied) { + filename = strdup(filename); + copied = 1; + } + filename[--len] = 0; + } + + while (1) { + if (!MSC_W_IZE(mkdir)(MSC_WIDE_PATH_temp(filename) +# ifndef MKDIR_NO_MODE_FLAG + , 0777 +# endif + )) { + if (copied) free(filename); + return 1; + } else if (errno != EINTR) + break; + } + + if (errno == EEXIST) + set_racket_error(RKTIO_ERROR_EXISTS); + else + get_posix_error(); + + if (copied) free(filename); + + return 0; +} + +int rktio_delete_directory(char *filename, char *current_directory, int enable_write_on_fail) +{ +#ifdef RKTIO_SYSTEM_WINDOWS + int tried_cwd = 0, tried_perm = 0; +#endif + + while (1) { + if (!MSC_W_IZE(rmdir)(MSC_WIDE_PATH_temp(filename))) + return 1; +# ifdef RKTIO_SYSTEM_WINDOWS + else if ((errno == EACCES) && !tried_cwd) { + /* Maybe we're using the target directory. Try a real setcwd. */ + (void)rktio_set_current_directory(current_directory); + tried_cwd = 1; + } else if ((errno == EACCES) && !tried_perm && enable_write_on_fail) { + /* Maybe the directory doesn't have write permission. */ + (void)enable_write_permission(filename); + tried_perm = 1; + } +# endif + else if (errno != EINTR) + break; + } + + get_posix_error(); + return 0; +#endif +} + +int rktio_make_link(char *src, char *dest, int dest_is_directory) +/* `src` is the file that is written, and `dest` is written to that + file */ +{ +#if defined(RKTIO_SYSTEM_WINDOWS) + init_procs(); + + if (CreateSymbolicLinkProc) { + int flags; + wchar_t *src_w = WIDE_PATH_COPY(src); + + if (dest_is_directory) + flags = 0x1; /* directory */ + else + flags = 0; /* file */ + + if (CreateSymbolicLinkProc(src_w, WIDE_PATH_temp(dest), flags)) { + free(src_w); + return 1; + } + get_windows_error(); + free(src_w); + } else + set_racket_error(RKTIO_ERROR_UNSUPPORTED); + + return 0; +#else + while (1) { + if (!symlink(dest, src)) + return 1; + else if (errno != EINTR) + break; + } + get_posix_error(); + return 0; +#endif +} + +rktio_timestamp_t *rktio_get_file_modify_seconds(char *file) +{ +#ifdef RKTIO_SYSTEM_WINDOWS + rktio_timestamp_t *secs; + + if (UNC_stat(file, NULL, NULL, NULL, &secs, NULL, NULL, -1)) + return secs; + return NULL; +#else + struct MSC_IZE(stat) buf; + + while (1) { + if (!MSC_W_IZE(stat)(MSC_WIDE_PATH_temp(file), &buf)){ + rktio_timestamp_t *ts = malloc(sizeof(rktio_timestamp_t)); + *ts = buf.st_mtime; + return ts; + } + if (errno != EINTR) + break; + } + + get_posix_error(); + return NULL; +#endif +} + +int rktio_set_file_modify_seconds(char *file, rktio_timestamp_t secs) +{ + while (1) { + struct MSC_IZE(utimbuf) ut; + ut.actime = secs; + ut.modtime = secs; + if (!MSC_W_IZE(utime)(MSC_WIDE_PATH_temp(file), &ut)) + return 1; + if (errno != EINTR) + break; + } + + get_posix_error(); + return 0; +} + +#if defined(RKTIO_SYSTEM_UNIX) && !defined(NO_UNIX_USERS) +static int user_in_group(uid_t uid, gid_t gid) +{ + struct group *g; + struct passwd *pw; + int i, in; + + if (!group_member_cache) + group_member_cache = calloc(GROUP_CACHE_SIZE, sizeof(group_member_cache_entry_t)); + + for (i = 0; i < GROUP_CACHE_SIZE; i++) { + if ((group_member_cache[i].state != GROUP_MEMBER_CACHE_STATE_UNUSED) + && (group_member_cache[i].gid == gid) + && (group_member_cache[i].uid == uid)) + return (group_member_cache[i].state == GROUP_MEMBER_CACHE_STATE_IN); + } + + pw = getpwuid(uid); + if (!pw) + return 0; + + g = getgrgid(gid); + if (!g) + return 0; + + for (i = 0; g->gr_mem[i]; i++) { + if (!strcmp(g->gr_mem[i], pw->pw_name)) + break; + } + + in = !!(g->gr_mem[i]); + + for (i = 0; i < GROUP_CACHE_SIZE; i++) { + if (group_member_cache[i].state == GROUP_MEMBER_CACHE_STATE_UNUSED) { + group_member_cache[i].gid = gid; + group_member_cache[i].uid = uid; + group_member_cache[i].state = (in + ? GROUP_MEMBER_CACHE_STATE_IN + : GROUP_MEMBER_CACHE_STATE_NOT_IN); + break; + } + } + + return in; +} +#endif + +int rktio_get_file_or_directory_permissions(char *filename, int all_bits) +/* -1 result indicates an error */ +{ +# ifdef NO_STAT_PROC + set_racket_error(RKTIO_ERROR_UNSUPPORTED); + return -1; +# else +# ifdef RKTIO_SYSTEM_UNIX + /* General strategy for permissions (to deal with setuid) + taken from euidaccess() in coreutils... */ +# ifndef NO_UNIX_USERS + if (have_user_ids == 0) { + have_user_ids = 1; + uid = getuid(); + gid = getgid(); + euid = geteuid(); + egid = getegid(); + } + + if (!all_bits && (uid == euid) && (gid == egid)) { + /* Not setuid; use access() */ + int read, write, execute, ok; + + do { + ok = access(filename, R_OK); + } while ((ok == -1) && (errno == EINTR)); + read = !ok; + + if (ok && (errno != EACCES)) { + get_posix_error(); + return -1; + } else { + do { + ok = access(filename, W_OK); + } while ((ok == -1) && (errno == EINTR)); + write = !ok; + + /* Don't fail at the exec step if errno is EPERM; under Mac OS + X, at least, such a failure seems to mean that the file is + not writable. (We assume it's not a directory-access issue, + since the read test succeeded.) */ + if (ok && (errno != EACCES) && (errno != EPERM) && (errno != EROFS)) { + get_posix_error(); + return -1; + } else { + do { + ok = access(filename, X_OK); + } while ((ok == -1) && (errno == EINTR)); + execute = !ok; + + /* Don't fail at the exec step if errno is EPERM; under Mac OS + X, at least, such a failure simply means that the file is + not executable. */ + if (ok && (errno != EACCES) && (errno != EPERM)) { + get_posix_error(); + return -1; + } else { + return ((read ? S_IRUSR : 0) + | (write ? S_IWUSR : 0) + | (execute ? S_IXUSR : 0)); + } + } + } + } +# endif + { + /* Use stat, because setuid, or because or no user info available */ + struct stat buf; + int ok, read, write, execute; + + do { + ok = stat(filename, &buf); + } while ((ok == -1) && (errno == EINTR)); + + if (ok) { + get_posix_error(); + return -1; + } else { + if (all_bits) { + int bits = buf.st_mode; +# ifdef S_IFMT + bits -= (bits & S_IFMT); +# endif + return bits; + } else { +# ifndef NO_UNIX_USERS + if (euid == 0) { + /* Super-user can read/write anything, and can + execute anything that someone can execute */ + read = 1; + write = 1; + execute = !!(buf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)); + } else if (buf.st_uid == euid) { + read = !!(buf.st_mode & S_IRUSR); + write = !!(buf.st_mode & S_IWUSR); + execute = !!(buf.st_mode & S_IXUSR); + } else if ((egid == buf.st_gid) || user_in_group(euid, buf.st_gid)) { + read = !!(buf.st_mode & S_IRGRP); + write = !!(buf.st_mode & S_IWGRP); + execute = !!(buf.st_mode & S_IXGRP); + } else { + read = !!(buf.st_mode & S_IROTH); + write = !!(buf.st_mode & S_IWOTH); + execute = !!(buf.st_mode & S_IXOTH); + } +# else + read = !!(buf.st_mode & (S_IRUSR | S_IRGRP | S_IROTH)); + write = !!(buf.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)); + execute = !!(buf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)); +# endif + + return ((read ? S_IRUSR : 0) + | (write ? S_IWUSR : 0) + | (execute ? S_IXUSR : 0)); + } + } + } +# endif +# ifdef RKTIO_SYSTEM_WINDOWS + { + int flags; + + if (UNC_stat(filename, &flags, NULL, NULL, NULL, NULL, NULL, -1)) { + if (as_bits) + return (flags | (flags << 3) | (flags << 6)); + else { + return ((read ? MZ_UNC_READ : 0) + | (write ? MZ_UNC_WRITE : 0) + | (execute ? MZ_UNC_EXEC : 0)); + } + } else { + return -1; + } + } +# endif +# endif +} + +int rktio_set_file_or_directory_permissions(char *filename, int new_bits) +{ +# ifdef NO_STAT_PROC + set_racket_error(RKTIO_ERROR_UNSUPPORTED); + return -1; +# else +# ifdef RKTIO_SYSTEM_UNIX + { + int r; + + do { + r = chmod(filename, new_bits); + } while ((r == -1) && (errno == EINTR)); + if (r) { + get_posix_error(); + return 0; + } else + return 1; + } +# endif +# ifdef RKTIO_SYSTEM_WINDOWS + { + int len = strlen(filename); + int ALWAYS_SET_BITS = ((MZ_UNC_READ | MZ_UNC_EXEC) + | ((MZ_UNC_READ | MZ_UNC_EXEC) << 3) + | ((MZ_UNC_READ | MZ_UNC_EXEC) << 6)); + if (((new_bits & ALWAYS_SET_BITS) != ALWAYS_SET_BITS) + || ((new_bits & MZ_UNC_WRITE) != ((new_bits & (MZ_UNC_WRITE << 3)) >> 3)) + || ((new_bits & MZ_UNC_WRITE) != ((new_bits & (MZ_UNC_WRITE << 6)) >> 6)) + || (new_bits >= (1 << 9))) { + set_racket_error(RKTIO_ERROR_BAD_PERMISSION); + return 0; + } + + if (UNC_stat(filename, NULL, NULL, NULL, NULL, NULL, NULL, new_bits)) + return 1; + + return 0; + } +# endif +# endif +} + +rktio_size_t *rktio_file_size(char *filename) +{ + rktio_size_t *sz = NULL; +#ifdef RKTIO_SYSTEM_WINDOWS + { + if (UNC_stat(filename, NULL, NULL, NULL, NULL, &sz, NULL, -1)) { + return sz; + } + return NULL; + } +#else + { + struct BIG_OFF_T_IZE(stat) buf; + + while (1) { + if (!BIG_OFF_T_IZE(stat)(MSC_WIDE_PATH_temp(filename), &buf)) + break; + else if (errno != EINTR) { + get_posix_error(); + return NULL; + } + } + + if (S_ISDIR(buf.st_mode)) { + set_racket_error(RKTIO_ERROR_IS_A_DIRECTORY); + return NULL; + } + + sz = malloc(sizeof(rktio_size_t)); + sz->lo = ((unsigned)buf.st_size & 0xFFFFFFFF); + if (sizeof(buf.st_size) > 4) + sz->hi = (buf.st_size >> 32); + else + sz->hi = 0; + + return sz; + } +#endif +} + +/*************************************************************/ +/* directory list */ +/*************************************************************/ + +#ifdef USE_FINDFIRST + +struct rktio_directory_list_t { + FF_HANDLE_TYPE hfile; + FF_TYPE info; +}; + +rktio_directory_list_t *rktio_directory_list_start(char *filename, int is_drive) +/* path must be normalized */ +{ + char *pattern; + int len; + FF_HANDLE_TYPE hfile; + FF_TYPE info; + rktio_directory_list_t *dl; + + retry: + + { + char *nf; + int is_ssq = 0, is_unc = 0, d, nd; + len = strlen(filename); + pattern = malloc(len + 14); + + if (IS_A_DOS_SEP(filename[0]) + && IS_A_DOS_SEP(filename[1])) { + if (filename[2] == '?') + is_ssq = 1; + else + is_unc = 1; + } + + if (is_ssq) { + d = 0; + nd = 0; + } else { + pattern[0] = '\\'; + pattern[1] = '\\'; + pattern[2] = '?'; + pattern[3] = '\\'; + if (is_unc) { + pattern[4] = 'U'; + pattern[5] = 'N'; + pattern[6] = 'C'; + pattern[7] = '\\'; + d = 8; + nd = 2; + } else { + d = 4; + nd = 0; + } + } + memcpy(pattern + d, nf + nd, len - nd); + len += (d - nd); + if (len && !IS_A_DOS_SEP(pattern[len - 1])) + pattern[len++] = '\\'; + memcpy(pattern + len, "*.*", 4); + } + + hfile = FIND_FIRST(WIDE_PATH_temp(pattern), &info); + if (FIND_FAILED(hfile)) { + int err_val; + err_val = GetLastError(); + if ((err_val == ERROR_DIRECTORY) && CreateSymbolicLinkProc) { + /* check for symbolic link */ + const char *resolved; + if (UNC_stat(filename, NULL, NULL, NULL, NULL, NULL, &resolved, -1)) { + if (resolved) { + filename = (char *)resolved; + goto retry; + } + } + } + get_windows_error(); + return NULL; + } + + dl = malloc(sizeof(rktio_directory_list_t)); + memcpy(&dl->info, &info); + dl->hfile = hfile; + + return dl; +} + +char *rktio_directory_list_step(rktio_directory_list_t *dl) +/* empty-strng result (don't deallocate) means done */ +{ + while (dl->first_ready || FIND_NEXT(dl->hfile, &dl->info)) { + dl->first_ready = 0; + if ((GET_FF_NAME(dl->info)[0] == '.') + && (!GET_FF_NAME(dl->info)[1] || ((GET_FF_NAME(dl->info)[1] == '.') + && !GET_FF_NAME(dl->info)[2]))) { + /* skip . and .. */ + } else { + return NARROW_PATH_copy(info.cFileName); + } + } + + FIND_CLOSE(dl->hfile); + + free(dl); + + return ""; +} + +# elif !defined(NO_READDIR) + +struct rktio_directory_list_t { + DIR *dir; +}; + +rktio_directory_list_t *rktio_directory_list_start(char *filename, int is_drive) +{ + rktio_directory_list_t *dl; + DIR *dir; + int nlen; + + dir = opendir(filename ? filename : "."); + if (!dir) { + get_posix_error(); + return NULL; + } + + dl = malloc(sizeof(rktio_directory_list_t)); + dl->dir = dir; + + return dl; +} + +char *rktio_directory_list_step(rktio_directory_list_t *dl) +/* empty-strng result (don't deallocate) means done */ +{ + struct dirent *e; + + while ((e = readdir(dl->dir))) { + int nlen; + +# ifdef DIRENT_NO_NAMLEN + nlen = strlen(e->d_name); +# elif defined(__QNX__) || defined(__QNXNTO__) + nlen = e->d_namelen; +# else + nlen = e->d_namlen; +# endif + +# if defined(RKTIO_SYSTEM_UNIX) || defined(RKTIO_SYSTEM_WINDOWS) + if (nlen == 1 && e->d_name[0] == '.') + continue; + if (nlen == 2 && e->d_name[0] == '.' && e->d_name[1] == '.') + continue; +# endif + + return strndup(e->d_name, nlen); + } + + closedir(dl->dir); + free(dl); + + return ""; +} + +#else + +rktio_directory_list_t *rktio_directory_list_start(char *filename, int is_drive) +{ + set_racket_error(RKTIO_ERROR_UNSUPPORTED); + return NULL; +} + +char *rktio_directory_list_step(rktio_directory_list_t *dl) +{ + set_racket_error(RKTIO_ERROR_UNSUPPORTED); + return NULL; +} + +#endif + +/*************************************************************/ +/* copy file */ +/*************************************************************/ + +struct rktio_file_copy_t { + int done; + rktio_fd_t *src_fd, *dest_fd; +}; + +rktio_file_copy_t *rktio_copy_file_start(char *dest, char *src, int exists_ok) +{ +#ifdef RKTIO_SYSTEM_UNIX + { +# define COPY_BUFFER_SIZE 2048 + int ok; + struct stat buf; + rktio_fd_t *src_fd, *dest_fd; + + src_fd = rktio_open(src, RKTIO_OPEN_READ); + if (!src_fd) + return NULL; + + do { + ok = fstat(rktio_fd_value(src_fd), &buf); + } while ((ok == -1) && (errno == EINTR)); + + if (ok || S_ISDIR(buf.st_mode)) { + if (ok) + get_posix_error(); + else + set_racket_error(RKTIO_ERROR_IS_A_DIRECTORY); + rktio_close(src_fd); + return NULL; + } + + dest_fd = rktio_open(dest, (RKTIO_OPEN_WRITE + | (exists_ok ? RKTIO_OPEN_TRUNCATE : 0))); + if (!dest_fd) { + rktio_close(src_fd); + return NULL; + } + + { + rktio_file_copy_t *fc; + + fc = malloc(sizeof(rktio_file_copy_t)); + + fc->done = 0; + fc->src_fd = src_fd; + fc->dest_fd = dest_fd; + + return fc; + } + } +#endif +#ifdef RKTIO_SYSTEM_WINDOWS + int err_val = 0; + wchar_t *src_w = WIDE_PATH_copy(src); + + if (CopyFileW(src_w, WIDE_PATH_temp(dest), !exists_ok)) { + rktio_file_copy_t *fc; + free(src_w); + /* Return a pointer to indicate success: */ + fc = malloc(sizeof(rktio_file_copy_t)); + fc->done = 1; + return fc; + } + + err_val = GetLastError(); + if ((err_val == ERROR_FILE_EXISTS) + || (err_val == ERROR_ALREADY_EXISTS)) + set_racket_error(RKTIO_ERROR_EXISTS); + else + get_windows_error(); + + free(src_w); + + return NULL; +#endif +} + +int rktio_copy_file_is_done(rktio_file_copy_t *fc) +{ + return fc->done; +} + +int rktio_copy_file_step(rktio_file_copy_t *fc) +{ +#ifdef RKTIO_SYSTEM_UNIX + char buffer[4096]; + intptr_t len; + + if (fc->done) + return 1; + + len = rktio_read(fc->src_fd, buffer, sizeof(buffer)); + if (len == RKTIO_READ_EOF) { + fc->done = 1; + return 1; + } else if (len == RKTIO_READ_ERROR) { + return 0; + } else { + intptr_t done = 0, amt; + + while (done < len) { + amt = rktio_write(fc->dest_fd, buffer + done, len - done); + if (amt < 0) + return 0; + done += amt; + } + return 1; + } +#endif +#ifdef RKTIO_SYSTEM_WINDOWS + return 1; +#endif +} + +void rktio_copy_file_stop(rktio_file_copy_t *fc) +{ +#ifdef RKTIO_SYSTEM_UNIX + rktio_close(fc->src_fd); + rktio_close(fc->dest_fd); +#endif + free(fc); +} + +/*************************************************************/ +/* filesystem root list */ +/*************************************************************/ + +char **rktio_filesystem_root_list(void) +/* returns a NULL-terminated array of strings */ +{ +#ifdef RKTIO_SYSTEM_WINDOWS + { +# define DRIVE_BUF_SIZE 1024 + char drives[DRIVE_BUF_SIZE], *s; + intptr_t len, ds, ss_len, ss_count = 0; + UINT oldmode; + char **ss, *new_ss; + + len = GetLogicalDriveStrings(DRIVE_BUF_SIZE, drives); + if (len <= DRIVE_BUF_SIZE) + s = drives; + else { + s = malloc(len + 1); + GetLogicalDriveStrings(len + 1, s); + } + + ss_len = 8; + ss = malloc(sizeof(char*) * ss_len); + + ds = 0; + oldmode = SetErrorMode(SEM_FAILCRITICALERRORS); + while (s[ds]) { + DWORD a, b, c, d; + /* GetDiskFreeSpace effectively checks whether we can read the disk: */ + if (GetDiskFreeSpace(s XFORM_OK_PLUS ds, &a, &b, &c, &d)) { + if ((ss_count + 1) == ss_len) { + new_ss = malloc(sizeof(char*) * ss_len * 2); + mempcy(ss, new_ss, ss_count * sizeof(char*)); + ss = new_ss; + ss_len *= 2; + } + + ss[ss_count++] = strdup(s + ds); + } + ds += strlen(s XFORM_OK_PLUS ds) + 1; + } + SetErrorMode(oldmode); + + if (s != drived) + free(s); + + ss[ss_count] = 0; + + return ss; + } +#else + char **ss; + + ss = malloc(sizeof(char*) * 2); + ss[1] = strdup("/"); + ss[0] = NULL; + + return ss; +#endif +} + +/*************************************************************/ +/* expand user tilde & system paths */ +/*************************************************************/ + +char *rktio_expand_user_tilde(char *filename) { +#ifdef RKTIO_SYSTEM_WINDOWS + set_racket_error(RKTIO_ERROR_UNSUPPORTED); + return NULL; +#else + char user[256], *home = NULL, *naya; + struct passwd *who = NULL; + intptr_t u, f, len, flen, ilen; + + if (filename[0] != '~') { + set_racket_error(RKTIO_ERROR_NO_TILDE); + return NULL; + } + + for (u = 0, f = 1; + u < 255 && filename[f] && filename[f] != '/'; + u++, f++) { + user[u] = filename[f]; + } + + if (filename[f] && filename[f] != '/') { + set_racket_error(RKTIO_ERROR_ILL_FORMED_USER); + return NULL; + } + user[u] = 0; + + if (!user[0]) { + if (!(home = getenv("HOME"))) { + char *ptr; + + ptr = getenv("USER"); + if (!ptr) + ptr = getenv("LOGNAME"); + + who = ptr ? getpwnam(ptr) : NULL; + + if (!who) + who = getpwuid(getuid()); + } + } else + who = getpwnam(user); + + if (!home && who) + home = who->pw_dir; + + if (!home) { + set_racket_error(RKTIO_ERROR_UNKNOWN_USER); + return NULL; + } + + ilen = strlen(filename); + len = strlen(home); + if (f < ilen) + flen = ilen - f - 1; + else + flen = 0; + naya = (char *)malloc(len + flen + 2); + memcpy(naya, home, len); + naya[len] = '/'; + memcpy(naya + len + 1, filename + f + 1, flen); + naya[len + flen + 1] = 0; + + filename = naya; + + return filename; +#endif +} + +static char *append_paths(char *a, char *b, int free_a, int free_b) +{ + int alen = strlen(a); + int blen = strlen(b); + int sep_len = 0; + char *s; + + if (!IS_A_SEP(a[alen])) + sep_len = 1; + + s = malloc(alen + sep_len + blen + 1); + + memcpy(s, a, alen); + if (sep_len) + s[alen] = A_PATH_SEP; + memcpy(s+alen+sep_len, b, blen); + s[alen + blen] = 0; + + if (free_a) free(a); + if (free_b) free(b); + + return s; +} + +char *rktio_system_path(int which) +{ +#ifdef RKTIO_SYSTEM_UNIX + if (which == RKTIO_PATH_SYS_DIR) { + return strdup("/"); + } + + if (which == RKTIO_PATH_TEMP_DIR) { + char *p; + + if ((p = getenv("TMPDIR"))) { + if (rktio_directory_exists(p)) + return strdup(p); + } + + if (rktio_directory_exists("/var/tmp")) + return strdup("/var/tmp"); + + if (rktio_directory_exists("/usr/tmp")) + return strdup("/usr/tmp"); + + if (rktio_directory_exists("/tmp")) + return strdup("/tmp"); + + return rktio_get_current_directory(); + } + + { + /* Everything else is in ~: */ + char *home_str, *ex_home, *alt_home, *home; + + /* cast here avoids a clang warning: */ +# define mz_STR_OFFSET(s, d) ((const char *)s XFORM_OK_PLUS d) + + if ((which == RKTIO_PATH_PREF_DIR) + || (which == RKTIO_PATH_PREF_FILE) + || (which == RKTIO_PATH_ADDON_DIR)) { +#if defined(OS_X) && !defined(XONX) + if (which == RKTIO_PATH_ADDON_DIR) + home_str = "~/Library/Racket/"; + else + home_str = "~/Library/Preferences/"; +#else + home_str = "~/.racket/"; +#endif + } else { +#if defined(OS_X) && !defined(XONX) + if (which == RKTIO_PATH_DESK_DIR) + home_str = "~/Desktop/"; + else if (which == RKTIO_PATH_DOC_DIR) + home_str = "~/Documents/"; + else +#endif + home_str = "~/"; + } + + alt_home = getenv("PLTUSERHOME"); + if (alt_home) + home = append_paths(alt_home, home_str + 2, 0, 0); + else { + home = rktio_expand_user_tilde(home_str); + + if (!home) { + /* Something went wrong with the user lookup. Just drop "~'. */ + int h_len = strlen(home_str); + home = (char *)malloc(h_len - 2 + 1); + strcpy(home, home_str+2); + } + } + + if ((which == RKTIO_PATH_PREF_DIR) || (which == RKTIO_PATH_INIT_DIR) + || (which == RKTIO_PATH_HOME_DIR) || (which == RKTIO_PATH_ADDON_DIR) + || (which == RKTIO_PATH_DESK_DIR) || (which == RKTIO_PATH_DOC_DIR)) + return home; + + if (which == RKTIO_PATH_INIT_FILE) + return append_paths(home, ".racketrc", 1, 0); + if (which == RKTIO_PATH_PREF_FILE) { +#if defined(OS_X) && !defined(XONX) + return append_paths(home, "org.racket-lang.prefs.rktd", 1, 0); +#else + return append_paths(home, "racket-prefs.rktd", 1, 0); +#endif + } else + return strdup("/"); + } +#endif + +#ifdef RKTIO_SYSTEM_WINDOWS + if (which == RKTIO_PATH_SYS_DIR) { + int size; + wchar_t *s; + size = GetSystemDirectoryW(NULL, 0); + s = (wchar_t *)malloc((size + 1) * sizeof(wchar_t)); + GetSystemDirectoryW(s, size + 1); + return NARROW_PATH_copy_then_free(s); + } + + { + char *d, *p; + Scheme_Object *home; + + if (which == RKTIO_PATH_TEMP_DIR) { + if ((p = getenv("TMP")) || (p = getenv("TEMP"))) { + if (p && rktio_directory_exists(p)) + return strdup(p); + } + + return rktio_current_drectory(); + } + + home = NULL; + + p = getenv("PLTUSERHOME"); + if (p) + home = strdup(p); + + if (!home) { + /* Try to get Application Data directory: */ + LPITEMIDLIST items; + int which_folder; + + if ((which == RKTIO_PATH_ADDON_DIR) + || (which == RKTIO_PATH_PREF_DIR) + || (which == RKTIO_PATH_PREF_FILE)) + which_folder = CSIDL_APPDATA; + else if (which == RKTIO_PATH_DOC_DIR) { +# ifndef CSIDL_PERSONAL +# define CSIDL_PERSONAL 0x0005 +# endif + which_folder = CSIDL_PERSONAL; + } else if (which == RKTIO_PATH_DESK_DIR) + which_folder = CSIDL_DESKTOPDIRECTORY; + else { +# ifndef CSIDL_PROFILE +# define CSIDL_PROFILE 0x0028 +# endif + which_folder = CSIDL_PROFILE; + } + + if (SHGetSpecialFolderLocation(NULL, which_folder, &items) == S_OK) { + int ok; + IMalloc *mi; + wchar_t *buf; + + buf = (wchar_t *)malloc(MAX_PATH * sizeof(wchar_t)); + ok = SHGetPathFromIDListW(items, buf); + + SHGetMalloc(&mi); + mi->lpVtbl->Free(mi, items); + mi->lpVtbl->Release(mi); + + home = NARROW_PATH_copy_then_free(buf); + } + } + + if (!home) { + /* Back-up: try USERPROFILE environment variable */ + d = getenv("USERPROFILE"); + if (d && rktio_directory_exists(d)) + return strdup(d); + } + + if (!home) { + /* Last-ditch effort: try HOMEDRIVE+HOMEPATH */ + d = getenv("HOMEDRIVE"); + p = getenv("HOMEPATH"); + + if (d && p) { + home = append_paths(d, p); + + if (rktio_directory_exists(home)) + return home; + else { + free(home); + home = NULL; + } + } else + home = NULL; + + if (!home) { + wchar_t name[1024]; + + if (!GetModuleFileNameW(NULL, name, 1024)) { + /* Disaster. Use CWD. */ + home = rktio_current_drectory(); + if (!home) + return NULL; + } else { + int i; + wchar_t *s; + + s = name; + + i = wc_strlen(s) - 1; + + while (i && (s[i] != '\\')) { + --i; + } + s[i] = 0; + home = NARROW_PATH_copy(s); + } + } + } + + if ((which == RKTIO_PATH_INIT_DIR) + || (which == RKTIO_PATH_HOME_DIR) + || (which == RKTIO_PATH_DOC_DIR) + || (which == RKTIO_PATH_DESK_DIR)) + return home; + + if ((which == RKTIO_PATH_ADDON_DIR) + || (which == RKTIO_PATH_PREF_DIR) + || (which == RKTIO_PATH_PREF_FILE)) { + home = append_paths(home, "Racket", 1, 0); + } + + if (which == RKTIO_PATH_INIT_FILE) + return append_paths(home, "racketrc.rktl", 1, 0); + if (which == RKTIO_PATH_PREF_FILE) + return append_paths(home, "racket-prefs.rktd", 1, 0); + return home; + } +#endif +} diff --git a/racket/src/rktio/rktio_poll_set.c b/racket/src/rktio/rktio_poll_set.c new file mode 100644 index 0000000000..a1c8649503 --- /dev/null +++ b/racket/src/rktio/rktio_poll_set.c @@ -0,0 +1,779 @@ +#include "rktio.h" +#include "rktio_private.h" +#ifdef RKTIO_SYSTEM_UNIX +# include +# include +#endif +#ifdef RKTIO_SYSTEM_WINDOWS +# include +#endif +#include + +/* Generalize fd arrays (FD_SET, etc) with a runtime-determined size, + special hooks for Windows "descriptors" like even queues and + semaphores, etc. */ + +#ifdef USE_FAR_RKTIO_FDCALLS +THREAD_LOCAL_DECL(rktio_poll_set_t *rktio_global_poll_set); +#endif + +void rktio_alloc_global_poll_set() { +#ifdef USE_FAR_RKTIO_FDCALLS + rktio_global_poll_set = rktio_alloc_fdset_array(3); +#endif +} + +/************************************************************/ +/* Poll variant */ +/************************************************************/ + +#ifdef HAVE_POLL_SYSCALL + +# define PFD_EXTRA_SPACE 1 + +struct rktio_poll_set_t { + struct rktio_fd_set_data_t *data; + rktio_poll_set_t *w; + rktio_poll_set_t *e; + int flags; +}; + +struct rktio_fd_set_data_t { + struct pollfd *pfd; + intptr_t size, count; +}; + +rktio_poll_set_t *rktio_alloc_fdset_array(int count) +{ + struct rktio_fd_set_data_t *data; + rktio_poll_set_t *r, *w, *e; + struct pollfd *pfd; + + data = malloc(sizeof(struct rktio_fd_set_data_t)); + r = malloc(sizeof(struct rktio_poll_set_t)); + w = malloc(sizeof(struct rktio_poll_set_t)); + e = malloc(sizeof(struct rktio_poll_set_t)); + + r->w = w; + r->e = e; + r->data = data; + w->data = data; + e->data = data; + + r->flags = POLLIN; + w->flags = POLLOUT; + e->flags = 0; + + data->size = 32; + data->count = 0; + + pfd = malloc(sizeof(struct pollfd) * (32 + PFD_EXTRA_SPACE)); + data->pfd = pfd; + + return data; +} + +rktio_poll_set_t *rktio_init_fdset_array(rktio_poll_set_t *fdarray, int count) +{ + ((struct rktio_fd_set *)fdarray)->data->count = 0; + return fdarray; +} + +rktio_poll_set_t *rktio_get_fdset(rktio_poll_set_t *fdarray, int pos) +{ + switch (pos) { + case 0: + return fdarray; + case 1: + return fdarray->w; + case 2: + default: + return fdarray->e; + } +} + +void rktio_fdzero(rktio_poll_set_t *fd) +{ + fd->data->count = 0; +} + +static int find_fd_pos(struct rktio_fd_set_data_t *data, int n) +{ + intptr_t count = data->count; + intptr_t i; + + /* This linear search probably isn't good enough for hundreds or + thousands of descriptors, but epoll()/kqueue() mode should handle + that case, anyway. */ + for (i = 0; i < count; i++) { + if (data->pfd[i].fd == n) { + return i; + } + } + + return -1; +} + +void rktio_fdclr(rktio_poll_set_t *fd, int n) +{ + struct rktio_fd_set_data_t *data = fd->data; + intptr_t flag = fd->flags; + intptr_t pos; + + if (!flag) return; + + pos = find_fd_pos(data, n); + if (pos >= 0) { + data->pfd[pos].events -= (data->pfd[pos].events & flag); + } +} + +void rktio_fdset(rktio_poll_set_t *fd, int n) +{ + struct rktio_fd_set_data_t *data = fd->data; + intptr_t flag = fd->flags; + intptr_t count, size, pos; + struct pollfd *pfd; + + if (!flag) return; + + pos = find_fd_pos(data, n); + if (pos >= 0) { + data->pfd[pos].events |= flag; + return; + } + + count = data->count; + size = data->size; + if (count >= size) { + size = size * 2; + pfd = malloc(sizeof(struct pollfd) * (size + PFD_EXTRA_SPACE)); + memcpy(pfd, data->pfd, sizeof(struct pollfd) * count); + free(data->pfd); + data->pfd = pfd; + data->size = size; + } + + data->pfd[count].fd = n; + data->pfd[count].events = flag; + count++; + data->count = count; +} + +int rktio_fdisset(rktio_poll_set_t *fd, int n) +{ + struct rktio_fd_set_data_t *data = data->data; + intptr_t flag = fd->flags; + intptr_t pos; + + if (!flag) flag = (POLLERR | POLLHUP); + + pos = find_fd_pos(data, n); + if (pos >= 0) { + if (data->pfd[pos].revents & flag) + return 1; + else + return 0; + } + + return 0; +} + +static int cmp_fd(const void *_a, const void *_b) +{ + struct pollfd *a = (struct pollfd *)_a; + struct pollfd *b = (struct pollfd *)_b; + return a->fd - b->fd; +} + +rktio_poll_set_t *rktio_merge_fd_sets(rktio_poll_set_t *fds, rktio_poll_set_t *src_fds) +{ + struct rktio_fd_set_data_t *data = fds->data; + struct rktio_fd_set_data_t *src_data = src_fds->data; + int i, si, c, sc, j, nc; + struct pollfd *pfds; + + rktio_clean_fd_set(fds); + rktio_clean_fd_set(src_fds); + + c = data->count; + sc = src_data->count; + + if (!c) + return src_fds; + if (!sc) + return fds; + + qsort(data->pfd, c, sizeof(struct pollfd), cmp_fd); + qsort(src_data->pfd, sc, sizeof(struct pollfd), cmp_fd); + + nc = c + sc; + pfds = (struct pollfd *)rktio_malloc_atomic(sizeof(struct pollfd) * (nc + PFD_EXTRA_SPACE)); + j = 0; + for (i = 0, si = 0; (i < c) && (si < sc); ) { + if (data->pfd[i].fd == src_data->pfd[si].fd) { + pfds[j].fd = data->pfd[i].fd; + pfds[j].events = (data->pfd[i].events | src_data->pfd[si].events); + i++; + si++; + } else if (data->pfd[i].fd < src_data->pfd[si].fd) { + pfds[j].fd = data->pfd[i].fd; + pfds[j].events = data->pfd[i].events; + i++; + } else { + pfds[j].fd = src_data->pfd[si].fd; + pfds[j].events = src_data->pfd[si].events; + si++; + } + j++; + } + for ( ; i < c; i++, j++) { + pfds[j].fd = data->pfd[i].fd; + pfds[j].events = data->pfd[i].events; + } + for ( ; si < sc; si++, j++) { + pfds[j].fd = src_data->pfd[si].fd; + pfds[j].events = src_data->pfd[si].events; + } + + if (nc > RKTIO_INT_VAL(data->size)) { + data->pfd = pfds; + data->size = rktio_make_integer(nc); + } else + memcpy(data->pfd, pfds, j * sizeof(struct pollfd)); + data->count = rktio_make_integer(j); + + return fds; +} + +void rktio_clean_fd_set(rktio_poll_set_t *fds) +{ + struct rktio_fd_set_data_t *data = fds->data; + intptr_t count = data->count; + intptr_t i, j = 0; + + for (i = 0; i < count; i++) { + if (data->pfd[i].events) { + if (j < i) { + data->pfd[j].fd = data->pfd[i].fd; + data->pfd[j].events = data->pfd[i].events; + } + j++; + } + } + + count = j; + data->count = count; +} + +int rktio_get_fd_limit(rktio_poll_set_t *fds) +{ + return 0; +} + +#elif defined(USE_DYNAMIC_FDSET_SIZE) + +/************************************************************/ +/* Variant with run-time determined fd_set length */ +/************************************************************/ + +struct rktio_poll_set_t { + fd_set data; +}; + +/* initialized early via rktio_alloc_global_poll_set */ +static int dynamic_fd_size; + +# define STORED_ACTUAL_FDSET_LIMIT +# define FDSET_LIMIT(fd) (*(int *)((char *)fd + dynamic_fd_size)) + +rktio_poll_set_t *rktio_alloc_fdset_array(int count) +{ + if (!dynamic_fd_size) { +# ifdef USE_ULIMIT + dynamic_fd_size = ulimit(4, 0); +# else + dynamic_fd_size = getdtablesize(); +# endif + /* divide by bits-per-byte: */ + dynamic_fd_size = (dynamic_fd_size + 7) >> 3; + /* word-align: */ + if (dynamic_fd_size % sizeof(void*)) + dynamic_fd_size += sizeof(void*) - (dynamic_fd_size % sizeof(void*)); + } + + return malloc(count * (dynamic_fd_size + sizeof(intptr_t))); +} + +rktio_poll_set_t *rktio_init_fdset_array(rktio_poll_set_t *fdarray, int count) +{ + return fdarray; +} + +rktio_poll_set_t *rktio_get_fdset(rktio_poll_set_t *fdarray, int pos) +{ + return (rktio_poll_set_t *)(((char *)fdarray) + (pos * (dynamic_fd_size + sizeof(intptr_t)))); +} + +void rktio_fdzero(rktio_poll_set_t *fd) +{ + memset(fd, 0, dynamic_fd_size + sizeof(intptr_t)); +} + +#elif defined (RKTIO_SYSTEM_WINDOWS) + +/************************************************************/ +/* Windows variant */ +/************************************************************/ + +typedef struct { + SOCKET *sockets; + + intptr_t added, alloc, last_alloc; + + intptr_t num_handles, alloc_handles, last_alloc_handles; + OS_SEMAPHORE_TYPE *handles; + + int *repost_sema; + + int no_sleep; /* boolean */ + + intptr_t wait_event_mask; + + HANDLE *wait_array; + + HANDLE *combined_wait_array; + intptr_t combined_len; +} rktio_poll_set_t; + +rktio_poll_set_t *rktio_alloc_fdset_array(int count) +{ + rktio_poll_set_t *fdarray; + if (count) { + fdarray = calloc(count, sizeof(rktio_poll_set_t)); + rktio_init_fdset_array(fdarray, count); + } else + fdarray = NULL; + + return fdarray; +} + +static void reset_wait_array(rktio_poll_set_t *efd) +{ + /* Allocate an array that may be big enough to hold all events + when we eventually call WaitForMultipleObjects. One of the three + arrays will be big enough. */ + int sz = (3 * (efd->alloc + efd->alloc_handles)) + 2; + HANDLE *wa; + if (efd->wait_array) free(efd->wait_array); + wa = calloc(sz, sizeof(HANDLE)); + efd->wait_array = wa; +} + +rktio_poll_set_t *rktio_init_fdset_array(rktio_poll_set_t *fdarray, int count) +{ + if (count) { + int i; + rktio_poll_set_t *fd; + for (i = 0; i < count; i++) { + int reset = 0; + fd = rktio_get_fdset(fdarray, i); + fd->added = 0; + if (RKTIO_INT_VAL(fd->alloc) > (2 * RKTIO_INT_VAL(fd->last_alloc))) { + fd->alloc = 0; + if (fd->sockets) free(fd->sockets); + fd->sockets = NULL; + reset = 1; + } + fd->last_alloc = 0; + fd->num_handles = 0; + if (RKTIO_INT_VAL(fd->alloc_handles) > (2 * RKTIO_INT_VAL(fd->last_alloc_handles))) { + fd->alloc_handles = 0; + if (fd->handles) free(fd->handles); + if (fd->repost_sema) free(fd->repost_sema); + fd->handles = NULL; + fd->repost_sema = NULL; + reset = 1; + } + fd->last_alloc_handles = 0; + fd->no_sleep = 0; + fd->wait_event_mask = 0; + if (reset) + reset_wait_array(fdarray); + } + } +} + +rktio_poll_set_t *rktio_get_fdset(rktio_poll_set_t *fdarray, int pos) +{ + return fdarray + pos; +} + +void rktio_fdzero(rktio_poll_set_t *fd) +{ + rktio_init_fdset_array(fd, 1); +} + +void rktio_fdclr(rktio_poll_set_t *fd, int n) +{ + int i; + for (i = fd->added; i--; ) { + if (fd->sockets[i] == n) + fd->sockets[i] = INVALID_SOCKET; + } +} + +static int next_size(int v) { return (v ? (2 * v) : 10); } + +void rktio_fdset(rktio_poll_set_t *fd, int n) +{ + if (fd->added >= fd->last_alloc) { + int na; + na = next_size(fd->last_alloc); + efd->last_alloc = na; + } + if (fd->added >= fd->alloc) { + SOCKET *naya; + int na; + na = next_size(fd->alloc); + naya = malloc(na * sizeof(SOCKET)); + memcpy(naya, fd->sockets, RKTIO_INT_VAL(fd->alloc) * sizeof(SOCKET)); + if (fd->sockets) free(fd->sockets); + fd->sockets = naya; + fd->alloc = na; + reset_wait_array(fd); + } + fd->sockets[fd->added++] = n; +} + +int rktio_fdisset(rktio_poll_set_t *fd, int n) +{ + int i; + for (i = fd->added; i--; ) { + if (fd->sockets[i] == n) + return 1; + } + return 0; +} + +rktio_poll_set_t *rktio_merge_fd_sets(rktio_poll_set_t *fds, rktio_poll_set_t *src_fds) +{ + int i; + for (i = src_fd->added; i--; ) { + if (stv_fd->sockets[i] != INVALID_SOCKET) + rktio_fdset(fds, src_fd->sockets[i]); + } + return fds; +} + +void rktio_clean_fd_set(rktio_poll_set_t *fds) +{ +} + +int rktio_get_fd_limit(rktio_poll_set_t *fds) +{ + return 0; +} + +void rktio_fdset_add_handle(HANDLE h, rktio_poll_set_t *fds, int repost) +{ + rktio_poll_set_t *efd = fds; + OS_SEMAPHORE_TYPE *hs; + int i, new_i, *rps; + + if (efd->num_handles == efd->last_alloc_handles) { + i = next_size(efd->last_alloc_handles); + efd->last_alloc_handles = 1; + } + if (efd->num_handles == efd->alloc_handles) { + i = efd->alloc_handles; + new_i = next_size(i); + hs = malloc(sizeof(HANDLE) * new_i); + rps = malloc(sizeof(int) * new_i); + memcpy(hs, efd->handles, sizeof(HANDLE)*i); + memcpy(rps, efd->repost_sema, sizeof(int)*i); + if (efd->handles) free(efd->handles); + if (efd->repost_sema) free(efd->repost_sema); + efd->handles = hs; + efd->repost_sema = rps; + efd->alloc_handles = new_i; + reset_wait_array(efd); + } + i = efd->num_handles; + efd->handles[i] = h; + efd->repost_sema[i] = repost; + efd->num_handles++; +} + +void rktio_add_fd_nosleep(rktio_poll_set_t *fds) +{ + fds->no_sleep = 1; +} + +void rktio_fdset_add_eventmask(rktio_poll_set_t *fds, int mask) +{ + fds->wait_event_mask |= mask; +} + +void WSAEventSelect_plus_check(SOCKET s, WSAEVENT e, long mask) +{ + fd_set rd[1], wr[1], ex[1]; + struct timeval t = {0, 0}; + + WSAEventSelect(s, e, mask); + + /* double-check with select(), because WSAEventSelect only + handles new activity (I think) */ + FD_ZERO(rd); + FD_ZERO(wr); + FD_ZERO(ex); + + if (mask & FD_READ) + FD_SET(s, rd); + if (mask & FD_WRITE) + FD_SET(s, wr); + if (mask & FD_OOB) + FD_SET(s, ex); + + if (select(1, rd, wr, ex, &t)) { + /* already ready */ + WSAEventSelect(s, NULL, 0); + SetEvent(e); + } +} + +void rktio_collapse_win_fd(rktio_poll_set_t *fds) +{ + rktio_poll_set_t *rfd, *wfd, *efd; + HANDLE *wa, e; + int i, p = 0, mask, j; + SOCKET s; + + rfd = fds; + wfd = rktio_get_fdset(fds, 1); + efd = rktio_get_fdset(fds, 2); + + if (rfd->combined_wait_array) { + /* clean up */ + for (i = rfd->added; i--; ) { + if (rfd->sockets[i] != INVALID_SOCKET) + WSAEventSelect(rfd->sockets[i], NULL, 0); + } + for (i = wfd->added; i--; ) { + if (wfd->sockets[i] != INVALID_SOCKET) + WSAEventSelect(wfd->sockets[i], NULL, 0); + } + for (i = efd->added; i--; ) { + if (efd->sockets[i] != INVALID_SOCKET) + WSAEventSelect(efd->sockets[i], NULL, 0); + } + p = rfd->num_handles; + for (i = rfd->combined_len; i-- > p; ) { + WSACloseEvent(rfd->combined_wait_array[i]); + } + rfd->combined_wait_array = NULL; + } else { + /* merge */ + if (rfd->alloc < RKTIO_INT_VAL(wfd->alloc)) { + if (wfd->alloc < efd->alloc) + wa = efd->wait_array; + else + wa = wfd->wait_array; + } else { + if (rfd->alloc < efd->alloc) + wa = efd->wait_array; + else + wa = rfd->wait_array; + } + + rfd->combined_wait_array = wa; + + p = rfd->num_handles; + for (i = 0; i < p; i++) { + wa[i] = rfd->handles[i]; + } + + for (i = rfd->added; i--; ) { + s = rfd->sockets[i]; + if (s != INVALID_SOCKET) { + mask = FD_READ | FD_ACCEPT | FD_CLOSE; + + for (j = wfd->added; j--; ) { + if (wfd->sockets[j] == s) { + mask |= FD_WRITE; + break; + } + } + + for (j = efd->added; j--; ) { + if (efd->sockets[j] == s) { + mask |= FD_OOB; + break; + } + } + + e = WSACreateEvent(); + wa[p++] = e; + WSAEventSelect_plus_check(s, e, mask); + } + } + + for (i = wfd->added; i--; ) { + s = wfd->sockets[i]; + if (s != INVALID_SOCKET) { + mask = FD_WRITE | FD_CONNECT | FD_CLOSE; + + for (j = rfd->added; j--; ) { + if (rfd->sockets[j] == s) { + mask = 0; + break; + } + } + + if (mask) { + for (j = efd->added; j--; ) { + if (efd->sockets[j] == s) { + mask |= FD_OOB; + break; + } + } + + e = WSACreateEvent(); + wa[p++] = e; + WSAEventSelect_plus_check(s, e, mask); + } + } + } + + for (i = efd->added; i--; ) { + s = efd->sockets[i]; + if (s != INVALID_SOCKET) { + mask = FD_OOB | FD_CLOSE; + + for (j = rfd->added; j--; ) { + if (rfd->sockets[j] == s) { + mask = 0; + break; + } + } + + if (mask) { + for (j = wfd->added; j--; ) { + if (wfd->sockets[j] == s) { + mask = 0; + break; + } + } + + if (mask) { + e = WSACreateEvent(); + wa[p++] = e; + WSAEventSelect_plus_check(s, e, mask); + } + } + } + } + + rfd->combined_len = p; + } +} + +#else + +/************************************************************/ +/* Plain fd_set variant */ +/************************************************************/ + +rktio_poll_set_t *rktio_alloc_fdset_array(int count) +{ + return malloc(count * sizeof(fd_set)); +} + +rktio_poll_set_t *rktio_init_fdset_array(rktio_poll_set_t *fdarray, int count) +{ + return fdarray; +} + +rktio_poll_set_t *rktio_get_fdset(rktio_poll_set_t *fdarray, int pos) +{ + return fdarray + pos; +} + +void rktio_fdzero(rktio_poll_set_t *fd) +{ + FD_ZERO(&(fd)->data); +} + +void rktio_fdclr(rktio_poll_set_t *fd, int n) +{ + FD_CLR(n, &(fd)->data); +} + +void rktio_fdset(rktio_poll_set_t *fd, int n) +{ +# ifdef STORED_ACTUAL_FDSET_LIMIT + int mx; + mx = FDSET_LIMIT(fd); + if (n > mx) + FDSET_LIMIT(fd) = n; +# endif + FD_SET(n, &(fd)->data); +} + +int rktio_fdisset(rktio_poll_set_t *fd, int n) +{ + return FD_ISSET(n, &(fd)->data); +} + +rktio_poll_set_t *rktio_merge_fd_sets(rktio_poll_set_t *fds, rktio_poll_set_t *src_fds) +{ + int i, j; + unsigned char *p, *sp; + for (j = 0; j < 3; j++) { + p = (unsigned char *)rktio_get_fdset(fds, j); + sp = (unsigned char *)rktio_get_fdset(src_fds, j); +# ifdef STORED_ACTUAL_FDSET_LIMIT + if (FDSET_LIMIT(sp) > FDSET_LIMIT(p)) { + i = FDSET_LIMIT(sp); + FDSET_LIMIT(p) = i; + } +# endif +# if defined(USE_DYNAMIC_FDSET_SIZE) + i = dynamic_fd_size; +# else + i = sizeof(fd_set); +# endif + for (; i--; p++, sp++) { + *p |= *sp; + } + } + return fds; +} + +void rktio_clean_fd_set(rktio_poll_set_t *fds) +{ +} + +int rktio_get_fd_limit(rktio_poll_set_t *fds) +{ + int actual_limit; + +# ifdef STORED_ACTUAL_FDSET_LIMIT + actual_limit = FDSET_LIMIT(rd); + if (FDSET_LIMIT(wr) > actual_limit) + actual_limit = FDSET_LIMIT(wr); + if (FDSET_LIMIT(ex) > actual_limit) + actual_limit = FDSET_LIMIT(ex); + actual_limit++; +# elif defined (USE_ULIMIT) + actual_limit = ulimit(4, 0); +#elif defined(FIXED_FD_LIMIT) + actual_limit = FIXED_FD_LIMIT; +#else + actual_limit = getdtablesize(); +# endif + + return actual_limit; +} + +#endif diff --git a/racket/src/rktio/rktio_private.h b/racket/src/rktio/rktio_private.h new file mode 100644 index 0000000000..5463121634 --- /dev/null +++ b/racket/src/rktio/rktio_private.h @@ -0,0 +1,86 @@ +#if ((defined(_MSC_VER) || defined(__MINGW32__)) \ + && (defined(__WIN32__) || defined(WIN32) || defined(_WIN32))) +# define RKTIO_SYSTEM_WINDOWS +# define MSC_IZE(n) _ ## n +# define MSC_W_IZE(n) _w ## n +# define MSC_WIDE_PATH_temp(n) WIDE_PATH_temp(n) +#else +# define RKTIO_SYSTEM_UNIX +# define MSC_IZE(n) n +# define MSC_W_IZE(n) MSC_IZE(n) +# define MSC_WIDE_PATH_temp(n) n +#endif + +#define THREAD_LOCAL_DECL(decl) decl + +void rktio_get_posix_error(void); +#define get_posix_error() rktio_get_posix_error() + +void rktio_set_racket_error(int errid); +#define set_racket_error(e) rktio_set_racket_error(e) + +#ifdef RKTIO_SYSTEM_WINDOWS +void rktio_get_windows_error(void); +# define get_windows_error() rktio_get_windows_error() +#endif + +intptr_t rktio_fd_value(rktio_fd_t *fd); + +/*******************************************************************/ + +typedef struct rktio_poll_set_t rktio_poll_set_t; + +#if RKTIO_SYSTEM_WINDOWS +# define USE_FAR_RKTIO_FDCALLS +#endif +#ifdef USE_DYNAMIC_FDSET_SIZE +# define USE_FAR_RKTIO_FDCALLS +#endif +#ifdef HAVE_POLL_SYSCALL +# define USE_FAR_RKTIO_FDCALLS +#endif + +#ifdef USE_FAR_RKTIO_FDCALLS +/* A single fdset that can be reused for immediate actions: */ +THREAD_LOCAL_DECL(extern rktio_poll_set_t *rktio_global_fd_set); + +# define DECL_FDSET(n, c) fd_set *n +# define INIT_DECL_FDSET(r, w, e) { \ + r = RKTIO_GET_FDSET(rktio_global_poll_set, 0 ); \ + w = RKTIO_GET_FDSET(rktio_global_poll_set, 1 ); \ + e = RKTIO_GET_FDSET(rktio_global_poll_set, 2 ); \ + } +# define INIT_DECL_RD_FDSET(r) r = RKTIO_GET_FDSET(rktio_global_poll_set, 0 ) +# define INIT_DECL_WR_FDSET(r) r = RKTIO_GET_FDSET(rktio_global_poll_set, 1 ) +# define INIT_DECL_ER_FDSET(r) r = RKTIO_GET_FDSET(rktio_global_poll_set, 2 ) + +# define RKTIO_GET_FDSET(p, n) rktio_get_fdset(p, n) +# define RKTIO_FD_ZERO(p) rktio_fdzero(p) +# define RKTIO_FD_SET(n, p) rktio_fdset(p, n) +# define RKTIO_FD_CLR(n, p) rktio_fdclr(p, n) +# define RKTIO_FD_ISSET(n, p) rktio_fdisset(p, n) + +#else + +#include +struct rktio_poll_set_t { fd_set data; }; + +# define DECL_FDSET(n, c) rktio_poll_set_t n[c] +# define INIT_DECL_FDSET(r, w, e) /* empty */ +# define INIT_DECL_RD_FDSET(r) /* empty */ +# define INIT_DECL_WR_FDSET(r) /* empty */ +# define INIT_DECL_ER_FDSET(r) /* empty */ + +# define RKTIO_FDS(p) (&(p)->data) + +# define RKTIO_GET_FDSET(p, n) ((p)+(n)) +# define RKTIO_FD_ZERO(p) FD_ZERO(RKTIO_FDS(p)) +# define RKTIO_FD_SET(n, p) FD_SET(n, RKTIO_FDS(p)) +# define RKTIO_FD_CLR(n, p) FD_CLR(n, RKTIO_FDS(p)) +# define RKTIO_FD_ISSET(n, p) FD_ISSET(n, RKTIO_FDS(p)) + +#endif + +rktio_poll_set_t *rktio_merge_fd_sets(rktio_poll_set_t *fds, rktio_poll_set_t *src_fds); +void rktio_clean_fd_set(rktio_poll_set_t *fds); +int rktio_get_fd_limit(rktio_poll_set_t *fds); diff --git a/racket/src/rktio/rktio_read_write.c b/racket/src/rktio/rktio_read_write.c new file mode 100644 index 0000000000..60d3a37b99 --- /dev/null +++ b/racket/src/rktio/rktio_read_write.c @@ -0,0 +1,1168 @@ +#include "rktio.h" +#include "rktio_private.h" +#include +#include +#ifdef RKTIO_SYSTEM_UNIX +# include +# include +# include +# include +#endif +#ifdef RKTIO_SYSTEM_WINDOWS +# include +#endif + +#if defined(USE_FCNTL_O_NONBLOCK) +# define RKTIO_NONBLOCKING O_NONBLOCK +#else +# define RKTIO_NONBLOCKING FNDELAY +#endif + +#ifndef RKTIO_BINARY +# define RKTIO_BINARY 0 +#endif + +struct rktio_fd_t { + int modes; + +#ifdef RKTIO_SYSTEM_UNIX + intptr_t fd; +# ifdef SOME_FDS_ARE_NOT_SELECTABLE + int bufcount; + char buffer[1]; +# endif +#endif + +#ifdef RKTIO_SYSTEM_WINDOWS + HANDLE fd; + Win_FD_Input_Thread *th; /* input mode */ + Win_FD_Output_Thread *oth; /* output mode */ +#endif + + int regfile; +}; + +/*************************************************************/ +/* creating an fd */ +/*************************************************************/ + +static void init_read_fd(rktio_fd_t *rfd) +{ +#ifdef RKTIO_SYSTEM_UNIX +# ifdef SOME_FDS_ARE_NOT_SELECTABLE + rfd->bufcount = 0; +# endif +#endif +#ifdef RKTIO_SYSTEM_WINDOWS + if (!rfd->regfile) { + /* To get non-blocking I/O for anything that can block, we create + a separate reader thread. + + Yes, Windows NT pipes support non-blocking reads, but there + doesn't seem to be any way to use WaitForSingleObject to sleep + until characters are ready. PeekNamedPipe can be used for + polling, but not sleeping. */ + + Win_FD_Input_Thread *th; + DWORD id; + HANDLE h; + OS_SEMAPHORE_TYPE sm; + + th = malloc(sizeof(Win_FD_Input_Thread)); + rfd->th = th; + + /* Replace buffer with a malloced one: */ + bfr = malloc(MZPORT_FD_BUFFSIZE); + fip->buffer = bfr; + th->buffer = bfr; + + th->fd = (HANDLE)fd; + th->avail = 0; + th->err = 0; + th->eof = NULL; + th->checking = 0; + + sm = CreateSemaphore(NULL, 0, 1, NULL); + th->checking_sema = sm; + sm = CreateSemaphore(NULL, 0, 1, NULL); + th->ready_sema = sm; + sm = CreateSemaphore(NULL, 1, 1, NULL); + th->you_clean_up_sema = sm; + th->refcount = refcount; + + h = CreateThread(NULL, 4096, (LPTHREAD_START_ROUTINE)WindowsFDReader, th, 0, &id); + + th->thread = h; + } +#endif +} + +rktio_fd_t *rktio_fd(intptr_t system_fd, int modes) +{ + rktio_fd_t *rfd; + + rfd = malloc(sizeof(rktio_fd_t)); + rfd->modes = modes; + + +#ifdef RKTIO_SYSTEM_UNIX + rfd->fd = system_fd; + { + struct stat buf; + int cr; + do { + cr = fstat(rfd->fd, &buf); + } while ((cr == -1) && (errno == EINTR)); + rfd->regfile = S_ISREG(buf.st_mode); + } +#endif + +#ifdef RKTIO_SYSTEM_WINDOWS + rfd->fd = (HANDLE)system_fd; + rfd->regfile = (GetFileType(rfd->fd) == FILE_TYPE_DISK); +#endif + + if (modes & RKTIO_OPEN_READ) + init_read_fd(rfd); + + return rfd; +} + +/*************************************************************/ +/* opening a file fd */ +/*************************************************************/ + +static rktio_fd_t *open_read(char *filename) +{ +#ifdef RKTIO_SYSTEM_UNIX + int fd; + struct stat buf; + rktio_fd_t *rfd; + + do { + fd = open(filename, O_RDONLY | RKTIO_NONBLOCKING | RKTIO_BINARY); + } while ((fd == -1) && (errno == EINTR)); + + if (fd == -1) { + get_posix_error(); + return NULL; + } else { + int cr; + + do { + cr = fstat(fd, &buf); + } while ((cr == -1) && (errno == EINTR)); + + if (cr) { + get_posix_error(); + do { + cr = close(fd); + } while ((cr == -1) && (errno == EINTR)); + return NULL; + } + + if (S_ISDIR(buf.st_mode)) { + do { + cr = close(fd); + } while ((cr == -1) && (errno == EINTR)); + set_racket_error(RKTIO_ERROR_IS_A_DIRECTORY); + return NULL; + } else { + rfd = malloc(sizeof(rktio_fd_t)); + rfd->modes = RKTIO_OPEN_READ; + rfd->fd = fd; + rfd->regfile = S_ISREG(buf.st_mode); + + init_read_fd(rfd); + + return rfd; + } + } +#endif +#ifdef RKTIO_SYSTEM_WINDOWS + HANDLE fd; + rktio_fd_t *rfd; + + fd = CreateFileW(WIDE_PATH(filename), + GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, + OPEN_EXISTING, + 0, + NULL); + + if (fd == INVALID_HANDLE_VALUE) { + get_windows_error(); + return NULL; + } + + rfd = malloc(sizeof(rktio_fd_t)); + rfd->modes = RKTIO_OPEN_READ; + rfd->fd = fd; + rfd->regfile = (GetFileType(fd) == FILE_TYPE_DISK); + + init_read_fd(rfd); + + return rfd; +#endif +} + +static rktio_fd_t *open_write(char *filename, int modes) +{ +#ifdef RKTIO_SYSTEM_UNIX + int fd; + int flags; + struct stat buf; + int cr; + rktio_fd_t *rfd; + + flags = (((modes & RKTIO_OPEN_READ) ? O_RDWR : O_WRONLY) + | ((modes & RKTIO_OPEN_MUST_EXIST ? 0 : O_CREAT))); + + if (modes & RKTIO_OPEN_APPEND) + flags |= O_APPEND; + else if (modes & RKTIO_OPEN_TRUNCATE) + flags |= O_TRUNC; + else if (!(modes & RKTIO_OPEN_CAN_EXIST)) + flags |= O_EXCL; + + do { + fd = open(filename, flags | RKTIO_NONBLOCKING | RKTIO_BINARY, 0666); + } while ((fd == -1) && (errno == EINTR)); + + if (errno == ENXIO) { + /* FIFO with no reader? Try opening in RW mode: */ + flags -= O_WRONLY; + flags |= O_RDWR; + do { + fd = open(filename, flags | RKTIO_NONBLOCKING | RKTIO_BINARY, 0666); + } while ((fd == -1) && (errno == EINTR)); + } + + if (fd == -1) { + if (errno == EISDIR) { + set_racket_error(RKTIO_ERROR_IS_A_DIRECTORY); + return NULL; + } else if (errno == EEXIST) { + if (!(modes & RKTIO_OPEN_REPLACE)) { + set_racket_error(RKTIO_ERROR_EXISTS); + return NULL; + } else { + do { + cr = unlink(filename); + } while ((cr == -1) && (errno == EINTR)); + + if (cr) { + get_posix_error(); + return NULL; + } + + do { + fd = open(filename, flags | RKTIO_BINARY, 0666); + } while ((fd == -1) && (errno == EINTR)); + } + } + + if (fd == -1) { + get_posix_error(); + return NULL; + } + } + + do { + cr = fstat(fd, &buf); + } while ((cr == -1) && (errno == EINTR)); + + if (cr) { + get_posix_error(); + do { + cr = close(fd); + } while ((cr == -1) && (errno == EINTR)); + return NULL; + } + + rfd = malloc(sizeof(rktio_fd_t)); + rfd->modes = modes; + rfd->fd = fd; + rfd->regfile = S_ISREG(buf.st_mode); + return rfd; +#endif +#ifdef RKTIO_SYSTEM_WINDOWS + HANDLE fd; + int hmode, regfile; + BY_HANDLE_FILE_INFORMATION info; + rktio_fd_t *rfd; + + if (modes & RKTIO_OPEN_MUST_EXIST) { + if (modes & RKTIO_OPEN_TRUNNCATE) + hmode = TRUNCATE_EXISTING; + else + hmode = OPEN_EXISTING; + } else if (modes & RKTIO_OPEN_CAN_EXIST) + hmode = OPEN_ALWAYS; + else + hmode = CREATE_NEW; + + fd = CreateFileW(WIDE_PATH_temp(filename), + GENERIC_WRITE | ((modes & RKTIO_OPEN_READ) ? GENERIC_READ : 0), + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, + hmode, + FILE_FLAG_BACKUP_SEMANTICS, /* lets us detect directories in NT */ + NULL); + + if (fd == INVALID_HANDLE_VALUE) { + int errv; + errv = GetLastError(); + if ((errv == ERROR_ACCESS_DENIED) && (existsok < -1)) { + /* Delete and try again... */ + if (DeleteFileW(WIDE_PATH_temp(filename))) { + fd = CreateFileW(WIDE_PATH_temp(filename), + GENERIC_WRITE | ((modes & RKTIO_OPEN_READ) ? GENERIC_READ : 0), + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, + hmode, + 0, + NULL); + if (fd == INVALID_HANDLE_VALUE) { + get_windows_error(); + return NULL; + } + } else { + get_windows_error(); + return NULL; + } + } else if (errv == ERROR_FILE_EXISTS) { + set_racket_error(RKTIO_ERROR_EXISTS); + return NULL; + } + + if (fd == INVALID_HANDLE_VALUE) { + get_windows_error(); + return NULL; + } + } + + if (GetFileInformationByHandle(fd, &info)) { + if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + CloseHandle(fd); + set_racket_error(RKTIO_ERROR_IS_A_DIRECTORY); + return NULL; + } + } + + rfd = malloc(sizeof(rktio_fd_t)); + rfd->modes = modes; + rfd->fd = fd; + rfd->regfile = (GetFileType(fd) == FILE_TYPE_DISK); + + if (rfd->regfile && (modes & RKTIO_OPEN_APPEND)) { + SetFilePointer(fd, 0, NULL, FILE_END); + } + + return rfd; +#endif +} + +rktio_fd_t *rktio_open(char *filename, int modes) +{ + if (modes & RKTIO_OPEN_WRITE) + return open_write(filename, modes); + else + return open_read(filename); +} + +/*************************************************************/ +/* closing */ +/*************************************************************/ + +int rktio_close(rktio_fd_t *rfd) +{ +#ifdef RKTIO_SYSTEM_UNIX + int cr; + +# ifdef USE_FCNTL_AND_FORK_FOR_FILE_LOCKS + release_lockf(rfd->fd); +# endif + + do { + cr = close(rfd->fd); + } while ((cr == -1) && (errno == EINTR)); +#endif +#ifdef RKTIO_SYSTEM_WINDOWS + if (rfd->th) { + CSI_proc csi; + + /* -1 for checking means "shut down" */ + rfd->th->checking = -1; + ReleaseSemaphore(rfd->th->checking_sema, 1, NULL); + + if (rfd->th->eof && (rfd->th->eof != INVALID_HANDLE_VALUE)) { + ReleaseSemaphore(rfd->th->eof, 1, NULL); + rfd->th->eof = NULL; + } + + csi = get_csi(); + if (csi) { + /* Helps thread wake up. Otherwise, it's possible for the + thread to stay stuck trying to read, in which case the + file handle (probably a pipe) doesn't get closed. */ + csi(rfd->th->thread); + } + + /* Try to get out of cleaning up the records (since they can't be + cleaned until the thread is also done: */ + if (WaitForSingleObject(rfd->th->you_clean_up_sema, 0) != WAIT_OBJECT_0) { + /* The other thread exited and left us with clean-up: */ + WindowsFDICleanup(rfd->th); + } /* otherwise, thread is responsible for clean-up */ + } + if (rfd->oth) { + CSI_proc csi; + + csi = get_csi(); + + if (csi) { + /* See also call to csi in fd_close_input */ + csi(rfd->oth->thread); + } + CloseHandle(rfd->oth->thread); + rfd->oth->done = 1; + ReleaseSemaphore(rfd->oth->work_sema, 1, NULL); + + /* Try to leave clean-up to the other thread: */ + if (WaitForSingleObject(rfd->oth->you_clean_up_sema, 0) != WAIT_OBJECT_0) { + /* Other thread is already done, so we're stuck with clean-up: */ + WindowsFDOCleanup(rfd->oth); + } /* otherwise, thread is responsible for clean-up */ + } + if (!rfp->th && !rfp->oth) { + CloseHandle(rfd->fd); + } +#endif + + free(rfd); + + return 1; +} + +/*************************************************************/ +/* polling */ +/*************************************************************/ + +#ifdef SOME_FDS_ARE_NOT_SELECTABLE +static int try_get_fd_char(int fd, int *ready) +{ + int old_flags, c; + unsigned char buf[1]; + + old_flags = fcntl(fd, F_GETFL, 0); + if (!(old_flags & RKTIO_NONBLOCKING)) + fcntl(fd, F_SETFL, old_flags | RKTIO_NONBLOCKING); + do { + c = read(fd, buf, 1); + } while ((c == -1) && errno == EINTR); + if (!(old_flags & RKTIO_NONBLOCKING)) + fcntl(fd, F_SETFL, old_flags); + + if (c < 0) { + *ready = 0; + return 0; + } else { + *ready = 1; + if (!c) + return EOF; + else + return buf[0]; + } +} +#endif + +int rktio_poll_read_ready(rktio_fd_t *rfd) +{ + if (rfd->regfile) + return 1; + +#ifdef RKTIO_SYSTEM_UNIX + { + int r; + +# ifdef SOME_FDS_ARE_NOT_SELECTABLE + if (rfd->bufcount) + return 1; +# endif + +# ifdef HAVE_POLL_SYSCALL + struct pollfd pfd[1]; + pfd[0].fd = rfd->fd; + pfd[0].events = POLLIN; + do { + r = poll(pfd, 1, 0); + } while ((r == -1) && (errno == EINTR)); +# else + DECL_FDSET(readfds, 1); + DECL_FDSET(exnfds, 1); + struct timeval time = {0, 0}; + + INIT_DECL_RD_FDSET(readfds); + INIT_DECL_ER_FDSET(exnfds); + + RKTIO_FD_ZERO(readfds); + RKTIO_FD_ZERO(exnfds); + RKTIO_FD_SET(rfd->fd, readfds); + RKTIO_FD_SET(rfd->fd, exnfds); + + do { + r = select(rfd->fd + 1, RKTIO_FDS(readfds), NULL, RKTIO_FDS(exnfds), &time); + } while ((r == -1) && (errno == EINTR)); +# endif + +# ifdef SOME_FDS_ARE_NOT_SELECTABLE + /* Try a non-blocking read: */ + if (!r && !rfd->textmode) { + int c, ready; + + c = try_get_fd_char(rfd->fd, &ready); + if (ready) { + if (c != EOF) { + rfd->buffpos = 0; + rfd->buffer[0] = (unsigned char)c; + rfd->bufcount = 1; + } + r = 1; + } + } +# endif + + return r != 0; + } +#endif +#ifdef RKTIO_SYSTEM_WINDOWS + if (!rfd->th) { + /* No thread -- so wait works. This case isn't actually used + right now, because wait doesn't seem to work reliably for + anything that we can recognize other than regfiles, which are + handled above. */ + if (WaitForSingleObject(rfd->fd, 0) == WAIT_OBJECT_0) + return 1; + } else { + /* Has the reader thread pulled in data? */ + if (rfd->th->checking) { + /* The thread is still trying, last we knew. Check the + data-is-ready sema: */ + if (WaitForSingleObject(rfd->th->ready_sema, 0) == WAIT_OBJECT_0) { + rfd->th->checking = 0; + return 1; + } + } else if (rfd->th->avail || rfd->th->err || rfd->th->eof) + return 1; /* other thread found data */ + else { + /* Doesn't have anything, and it's not even looking. Tell it + to look: */ + rfd->th->checking = 1; + ReleaseSemaphore(rfd->th->checking_sema, 1, NULL); + } + } + + return 0; +#endif +} + +int poll_write_ready_or_flushed(rktio_fd_t *rfd, int check_flushed) +{ +#ifdef RKTIO_SYSTEM_UNIX + if (check_flushed) + return 1; + else { + int sr; +# ifdef HAVE_POLL_SYSCALL + GC_CAN_IGNORE struct pollfd pfd[1]; + pfd[0].fd = rfd->fd; + pfd[0].events = POLLOUT; + do { + sr = poll(pfd, 1, 0); + } while ((sr == -1) && (errno == EINTR)); +# else + DECL_FDSET(writefds, 1); + DECL_FDSET(exnfds, 1); + struct timeval time = {0, 0}; + + INIT_DECL_WR_FDSET(writefds); + INIT_DECL_ER_FDSET(exnfds); + + RKTIO_FD_ZERO(writefds); + RKTIO_FD_ZERO(exnfds); + RKTIO_FD_SET(rfd->fd, writefds); + RKTIO_FD_SET(rfd->fd, exnfds); + + do { + /* Mac OS X 10.8 and 10.9: select() seems to claim that a pipe + is always ready for output. To work around that problem, + kqueue() support is enabled for pipes, so we shouldn't get + here much for pipes. */ + sr = select(rfd->fd + 1, NULL, RKTIO_FDS(writefds), RKTIO_FDS(exnfds), &time); + } while ((sr == -1) && (errno == EINTR)); +# endif + + if (sr == -1) { + get_posix_error(); + return RKTIO_POLL_ERROR; + } else + return (sr != 0); + } +#endif +#ifdef RKTIO_SYSTEM_WINDOWS + if (rfd->oth) { + /* Pipe output that can block... */ + int retval; + Win_FD_Output_Thread *oth = rfd->oth; + + WaitForSingleObject(oth->lock_sema, INFINITE); + if (oth->nonblocking) { + if (oth->needflush) { + oth->needflush = 0; + oth->flushed = 0; + ReleaseSemaphore(oth->work_sema, 1, NULL); /* start trying to flush */ + retval = 0; + } else + retval = oth->flushed; + } else + retval = (oth->err_no || (check_flushed + ? !oth->buflen + : (oth->buflen < MZPORT_FD_BUFFSIZE))); + if (!retval && !check_flushed) + WaitForSingleObject(oth->ready_sema, 0); /* clear any leftover state */ + ReleaseSemaphore(oth->lock_sema, 1, NULL); + + return retval; + } else + return 1; /* non-blocking output, such as a console, or haven't written yet */ +#endif +} + +int rktio_poll_write_ready(rktio_fd_t *rfd) +{ + return poll_write_ready_or_flushed(rfd, 0); +} + +int rktio_poll_write_flushed(rktio_fd_t *rfd) +{ + return poll_write_ready_or_flushed(rfd, 1); +} + +void rktio_poll_add(rktio_fd_t *rfd, rktio_poll_set_t *fds, int modes) +{ +#ifdef RKTIO_SYSTEM_UNIX + rktio_poll_set_t *fds2; + + if (modes & RKTIO_POLL_READ) { + RKTIO_FD_SET(rfd->fd, fds); + } + if (modes & RKTIO_POLL_WRITE) { + fds2 = RKTIO_GET_FDSET(fds, 1); + RKTIO_FD_SET(rfd->fd, fds2); + } + fds2 = RKTIO_GET_FDSET(fds, 2); + RKTIO_FD_SET(rfd->fd, fds2); +#endif +#ifdef RKTIO_SYSTEM_WINDOWS + if (modes & RKTIO_POLL_READ) { + if (rfd->th) { + /* See fd_byte_ready */ + if (!rfd->th->checking) { + if (rfd->th->avail || rfd->th->err || rfd->th->eof) { + /* Data is ready. We shouldn't be trying to sleep, so force an + immediate wake-up: */ + rktio_fdset_add_nosleep(fds); + } else { + rfd->th->checking = 1; + ReleaseSemaphore(rfd->th->checking_sema, 1, NULL); + rktio_fdset_add_handle(rfd->th->ready_sema, fds, 1); + } + } else + rktio_fdset_add_handle(rfd->th->ready_sema, fds, 1); + } else if (rfd->regfile) { + /* regular files never block */ + rktio_fdset_add_nosleep(fds); + } else { + /* This case is not currently used. See fd_byte_ready. */ + rktio_fdset_add_handle(rfd->fd, fds, 0); + } + } + + if (modes & RKTIO_POLL_WRITE) { + if (rfp->oth && !fd_write_ready(port)) + rktio_fdset_add_handle(rfp->oth->ready_sema, fds, 1); + else + rktio_fdset_nosleep(fds); + } +#endif +} + +/*************************************************************/ +/* reading */ +/*************************************************************/ + +intptr_t rktio_read(rktio_fd_t *rfd, char *buffer, intptr_t len) +{ +#ifdef RKTIO_SYSTEM_UNIX + intptr_t bc; + + if (rfd->regfile) { + /* Reading regular file never blocks */ + do { + bc = read(rfd->fd, buffer, len); + } while ((bc == -1) && (errno == EINTR)); + + if (bc == -1) { + get_posix_error(); + return RKTIO_READ_ERROR; + } else if (bc == 0) + return RKTIO_READ_EOF; + else + return bc; + } else { + /* We use a non-blocking read here, even though we've waited + for input above, because an external process might have + gobbled the characters that we expected to get. */ + int old_flags; + + old_flags = fcntl(rfd->fd, F_GETFL, 0); + if (!(old_flags & RKTIO_NONBLOCKING)) + fcntl(rfd->fd, F_SETFL, old_flags | RKTIO_NONBLOCKING); + + do { + bc = read(rfd->fd, buffer, len); + } while ((bc == -1) && errno == EINTR); + + if ((bc == -1) && (errno != EAGAIN)) + get_posix_error(); + + if (!(old_flags & RKTIO_NONBLOCKING)) + fcntl(rfd->fd, F_SETFL, old_flags); + + if (bc == -1) { + if (errno == EAGAIN) + return 0; /* no bytes from a non-blocking read */ + else + return RKTIO_READ_ERROR; + } else if (bc == 0) + return RKTIO_READ_EOF; + else + return bc; + } +#endif +#ifdef RKTIO_SYSTEM_WINDOWS + if (!rfd->th) { + /* We can read directly. This must be a regular file, where + reading never blocks. */ + DWORD rgot, delta; + + if (!ReadFile((HANDLE)rfd->fd, buffer, len, &rgot, NULL)) { + get_windows_error(); + return RKTIO_READ_ERROR; + } + + if (!rgot) + return RKTIO_READ_EOF; + else + return rgot; + } else { + if (!rktio_poll_read(rfd)) + return 0; + + /* If we get this far, there's definitely data available. + Extract data made available by the reader thread. */ + if (rfd->th->eof) { + if (rfd->th->eof != INVALID_HANDLE_VALUE) { + ReleaseSemaphore(rfd->th->eof, 1, NULL); + rfd->th->eof = NULL; + } + return RKTIO_READ_EOF; + } else if (rfd->th->err) { + set_windows_error(rfd->th->err); + return RKTIO_READ_ERROR; + } else { + intptr_t bc = rfd->th->avail; + rfd->th->avail = 0; + FIXME read the data; + return bc; + } + } +#endif +} + +#ifdef RKTIO_SYSTEM_WINDOWS + +static long WINAPI WindowsFDReader(Win_FD_Input_Thread *th) +{ + DWORD toget, got; + int perma_eof = 0; + HANDLE eof_wait = NULL; + + if (GetFileType((HANDLE)th->fd) == FILE_TYPE_PIPE) { + /* Reading from a pipe will return early when data is available. */ + toget = MZPORT_FD_BUFFSIZE; + } else { + /* Non-pipe: get one char at a time: */ + toget = 1; + } + + while (!perma_eof && !th->err) { + /* Wait until we're supposed to look for input: */ + WaitForSingleObject(th->checking_sema, INFINITE); + + if (th->checking < 0) + break; + + if (ReadFile(th->fd, th->buffer, toget, &got, NULL)) { + th->avail = got; + if (!got) { + /* We interpret a send of 0 bytes as a mid-stream EOF. */ + eof_wait = CreateSemaphore(NULL, 0, 1, NULL); + th->eof = eof_wait; + } + } else { + int err; + err = GetLastError(); + if (err == ERROR_BROKEN_PIPE) { + th->eof = INVALID_HANDLE_VALUE; + perma_eof = 1; + } else + th->err = err; + } + + /* Notify main program that we found something: */ + ReleaseSemaphore(th->ready_sema, 1, NULL); + + if (eof_wait) { + WaitForSingleObject(eof_wait, INFINITE); + eof_wait = NULL; + } + } + + /* We have to clean up if the main program has abandoned us: */ + if (WaitForSingleObject(th->you_clean_up_sema, 0) != WAIT_OBJECT_0) { + WindowsFDICleanup(th); + } /* otherwise, main program is responsible for clean-up */ + + return 0; +} + +static void WindowsFDICleanup(Win_FD_Input_Thread *th) +{ + int rc; + + CloseHandle(th->checking_sema); + CloseHandle(th->ready_sema); + CloseHandle(th->you_clean_up_sema); + + rc = adj_refcount(th->refcount, -1); + if (!rc) CloseHandle(th->fd); + + free(th->buffer); + free(th); +} + +#endif + +/*************************************************************/ +/* writing */ +/*************************************************************/ + +intptr_t rktio_write(rktio_fd_t *rfd, char *buffer, intptr_t len) +{ +#ifdef RKTIO_SYSTEM_UNIX + int flags; + intptr_t amt; + + flags = fcntl(rfd->fd, F_GETFL, 0); + if (!(flags & RKTIO_NONBLOCKING)) + fcntl(rfd->fd, F_SETFL, flags | RKTIO_NONBLOCKING); + + amt = len; + + do { + do { + len = write(rfd->fd, buffer, amt); + } while ((len == -1) && (errno == EINTR)); + + /* If there was no room to write `amt` bytes, then it's + possible that writing fewer bytes will succeed. That seems + to be the case with FIFOs on Mac OS X, for example. */ + amt = amt >> 1; + } while ((len == -1) && (errno == EAGAIN) && (amt > 0)); + + if (len == -1) + get_posix_error(); + + if (!(flags & RKTIO_NONBLOCKING)) + fcntl(rfd->fd, F_SETFL, flags); + + if (len == -1) + return RKTIO_WRITE_ERROR; + else + return len; +#endif +#ifdef RKTIO_SYSTEM_WINDOWS + DWORD winwrote; + + if (rfd->regfile) { + /* Regular files never block, so this code looks like the Unix + code. We've cheated in the make_fd proc and called + consoles regular files, because they cannot block, either. */ + + /* If we try to write too much at once, the result + is ERROR_NOT_ENOUGH_MEMORY (as opposed to a partial write). */ + int ok; + intptr_t towrite = len; + + while (1) { + ok = WriteFile((HANDLE)rfd->fd, buffer, towrite, &winwrote, NULL); + if (!ok) + errsaved = GetLastError(); + + if (!ok && (errsaved == ERROR_NOT_ENOUGH_MEMORY)) { + towrite = towrite >> 1; + if (!towrite) + break; + } else + break; + } + + if (!ok) { + get_windows_error(); + return RKTIO_WRITE_ERROR; + } + + return winwrote; + } else { + /* If we don't have a thread yet, we'll need to start it. If + we have a non-blocking pipe, we can try the write (and + we'll still need the thread to determine when the data is + flushed). */ + intptr_t out_len = 0; + int ok, errsaved; + + if (!rfd->oth || rfd->oth->nonblocking) { + int nonblocking; + + /* If we don't have a thread, this is our first write attempt. + Determine whether this is a non-blocking pipe: */ + if (!rfd->oth) { + /* The FILE_TYPE_PIPE test is currently redundant, I think, + but better safe than sorry. */ + nonblocking = (rktio_windows_nt_or_later() + && (GetFileType((HANDLE)rfd->fd) == FILE_TYPE_PIPE)); + } else + nonblocking = 1; /* must be, or we would not have gotten here */ + + if (nonblocking) { + /* Unless we're still trying to flush old data, write to the + pipe and have the other thread start flushing it. */ + DWORD nonblock = PIPE_NOWAIT; + int flushed; + + if (rfd->oth) { + if (rfd->oth->needflush) { + /* Not flushed, but we haven't promised not to block: */ + flushed = 1; + } else { + WaitForSingleObject(rfd->oth->lock_sema, INFINITE); + flushed = rfd->oth->flushed; + ReleaseSemaphore(rfd->oth->lock_sema, 1, NULL); + } + } else + flushed = 1; /* haven't written anything before */ + + if (flushed) { + /* Put the pipe in non-blocking mode and write. */ + int towrite; + + towrite = len; + + /* Apparently, the semantics of non-blocking pipe writes + is not partial writes, but giving up entirely when + the other end isn't being read. In other words, if we + try to write too much and nothing is being pulled + from the pipe, winwrote will be set to 0. Also, if + we try to write too much at once, the result is a + ERROR_NOT_ENOUGH_MEMORY error. Account for these + behaviors by trying to write less each iteration when the + write fails. (Yuck.) */ + while (1) { + if (!rfd->unblocked) { + ok = SetNamedPipeHandleState((HANDLE)rfd->fd, &nonblock, NULL, NULL); + if (ok) + rfd->unblocked = 1; + else + errsaved = GetLastError(); + } else + ok = 1; + if (ok) { + ok = WriteFile((HANDLE)rfd->fd, buffer, towrite, &winwrote, NULL); + if (!ok) + errsaved = GetLastError(); + } + + if ((ok && !winwrote) + || (!ok && (errsaved == ERROR_NOT_ENOUGH_MEMORY))) { + towrite = towrite >> 1; + if (!towrite) { + set_windows_error(); + return RKTIO_WRITE_ERROR; + } + } else + break; + } + } else { + /* Don't try to write while flushing. */ + ok = 1; + winwrote = 0; + } + + if (ok) + out_len = winwrote; + } + /* and create the writer thread... */ + + if (!rfd->oth) { + /* We create a thread even for pipes that can be put in + non-blocking mode, because that seems to be the only + way to get evt behavior. */ + Win_FD_Output_Thread *oth; + HANDLE h; + DWORD id; + unsigned char *bfr; + OS_SEMAPHORE_TYPE sm; + + oth = malloc(sizeof(Win_FD_Output_Thread)); + rfd->oth = oth; + + oth->nonblocking = nonblocking; + + if (!nonblocking) { + bfr = malloc(MZPORT_FD_BUFFSIZE); + oth->buffer = bfr; + oth->flushed = 0; + oth->needflush = 0; + } else { + oth->buffer = NULL; + oth->flushed = 1; + oth->needflush = 1; + } + + oth->buflen = 0; + oth->bufstart = 0; + oth->bufend = 0; + + oth->fd = (HANDLE)rfd->fd; + oth->err_no = 0; + oth->done = 0; + sm = CreateSemaphore(NULL, 1, 1, NULL); + oth->lock_sema = sm; + sm = CreateSemaphore(NULL, 0, 1, NULL); + oth->work_sema = sm; + sm = CreateSemaphore(NULL, 1, 1, NULL); + oth->ready_sema = sm; + sm = CreateSemaphore(NULL, 1, 1, NULL); + oth->you_clean_up_sema = sm; + oth->refcount = rfd->refcount; + + h = CreateThread(NULL, 4096, (LPTHREAD_START_ROUTINE)WindowsFDWriter, oth, 0, &id); + + oth->thread = h; + } + } + + /* We have a thread, if only to watch when the flush is + done... */ + + if (!rfd->oth->nonblocking) { + /* This case is for Win 95/98/Me anonymous pipes and + character devices. We haven't written anything yet! We + write to a buffer read by the other thread, and return -- + the other thread takes care of writing. Thus, as long as + there's room in the buffer, we don't block, and we can + tell whether there's room. Technical problem: if multiple + ports are attched to the same underlying pipe (different + handle, same "device"), the port writes can get out of + order. We try to avoid the problem by sleeping. */ + + Win_FD_Output_Thread *oth = rfd->oth; + + WaitForSingleObject(oth->lock_sema, INFINITE); + if (oth->err_no) { + errsaved = oth->err_no; + ok = 0; + } else if (oth->buflen == MZPORT_FD_BUFFSIZE) { + WaitForSingleObject(oth->ready_sema, 0); /* clear any leftover state */ + ok = 1; + } else { + intptr_t topp; + int was_pre; + + if (!oth->buflen) { + /* Avoid fragmenting in circular buffer: */ + oth->bufstart = 0; + oth->bufend = 0; + } + + /* Write to top part of circular buffer, then bottom part + if anything's left. */ + + if (oth->bufstart <= oth->bufend) { + was_pre = 1; + topp = MZPORT_FD_BUFFSIZE; + } else { + was_pre = 0; + topp = oth->bufstart; + } + + winwrote = topp - oth->bufend; + if (winwrote > len) + winwrote = len; + + memcpy(oth->buffer + oth->bufend, buffer, winwrote); + oth->buflen += winwrote; + out_len = winwrote; + + oth->bufend += winwrote; + if (oth->bufend == MZPORT_FD_BUFFSIZE) + oth->bufend = 0; + + if (was_pre) { + if (winwrote < len) { + /* Try continuing with a wrap-around: */ + winwrote = oth->bufstart - oth->bufend; + if (winwrote > len - out_len) + winwrote = len - out_len; + + memcpy(oth->buffer + oth->bufend, buffer + out_len, winwrote); + oth->buflen += winwrote; + oth->bufend += winwrote; + out_len += winwrote; + } + } + /* Let the other thread know that it should start trying + to write, if it isn't already: */ + ReleaseSemaphore(oth->work_sema, 1, NULL); + Sleep(0); /* to decrease the chance of re-ordering flushes */ + + ok = 1; + } + ReleaseSemaphore(oth->lock_sema, 1, NULL); + } else if (out_len > 0) { + /* We've already written, which implies that no flush is + in progress. We'll need a flush check in the future. */ + rfd->oth->needflush = 1; + } + + if (ok) + return out_len; + + set_windows_error(errsaved); + return RKTIO_WRITE_ERROR; + } +#endif +}