bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

lseek test on Windows


From: Bruno Haible
Subject: lseek test on Windows
Date: Sun, 15 Apr 2012 18:35:28 +0200
User-agent: KMail/4.7.4 (Linux/3.1.0-1.2-desktop; KDE/4.7.4; x86_64; ; )

For me, the configure test "checking whether lseek detects pipes..." reports
  - "no" on mingw2009 and MSVC9,
  - "yes" on mingw2011 and mingw64
for no immediately apparent reason: The function 'lseek' comes from MSVCRT
in all cases.

The reason is that I run the mingw2009 and MSVC9 environments from within
a Cygwin 1.5 environment, while the mingw2011 and mingw64 builds are done
within a Cygwin 1.7.9 environment. When I run "echo hi | ./foo.exe"
then the standard input handle that the program foo.exe gets apparently
depends on the environment.

Most characteristics are the same:
  GetFileType(handle) = FILE_TYPE_PIPE in either case,
  GetNamedPipeInfo(handle, NULL, NULL, NULL, NULL) succeeds in either case,
  PeekNamedPipe(handle, NULL, 0, NULL, NULL, NULL) succeeds in either case.
But SetFilePointer(handle, 0, NULL, FILE_CURRENT)
succeeds on Cygwin 1.5 but fails with ERROR_INVALID_PARAMETER on Cygwin 1.7.

As a consequence, lseek (0, (off_t)0, SEEK_CUR)
succeeds on Cygwin 1.5 but fails with EINVAL on Cygwin 1.7.

Therefore the "checking whether lseek detects pipes" test
reports no on Cygwin 1.5 but yes on Cygwin 1.7 - and if lseek does not
get replaced for other reasons, we then get a unit test failure:
  test-lseek.c:73: assertion failed
  FAIL: test-lseek.sh
because the unit test expects an error code ESPIPE, not EINVAL.

I don't like autoconf test results that depend on the environment, therefore
the fix is to make the test consistently report "no". Either by hardcoding
the result to "no", or by checking that errno == ESPIPE. Since I don't know
how Windows binaries in Wine behave (one more possible environment...) I'm
going for the hardcoding approach.


2012-04-15  Bruno Haible  <address@hidden>

        lseek: Make configure test independent of environment.
        * m4/lseek.m4 (gl_FUNC_LSEEK): Require AC_CANONICAL_HOST. On native
        Windows, we know that lseek() on pipes is broken; skip the runtime
        test.

--- m4/lseek.m4.orig    Sun Apr 15 18:33:02 2012
+++ m4/lseek.m4 Sun Apr 15 18:21:40 2012
@@ -1,4 +1,4 @@
-# lseek.m4 serial 8
+# lseek.m4 serial 9
 dnl Copyright (C) 2007, 2009-2012 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -7,11 +7,23 @@
 AC_DEFUN([gl_FUNC_LSEEK],
 [
   AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+  AC_REQUIRE([AC_CANONICAL_HOST])
   AC_REQUIRE([AC_PROG_CC])
   AC_CHECK_HEADERS_ONCE([unistd.h])
   AC_CACHE_CHECK([whether lseek detects pipes], [gl_cv_func_lseek_pipe],
-    [if test $cross_compiling = no; then
-       AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+    [case "$host_os" in
+       mingw*)
+         dnl Native Windows.
+         dnl The result of lseek (fd, (off_t)0, SEEK_CUR) or
+         dnl SetFilePointer(handle, 0, NULL, FILE_CURRENT)
+         dnl for a pipe depends on the environment: In a Cygwin 1.5
+         dnl environment it succeeds (wrong); in a Cygwin 1.7 environment
+         dnl it fails with a wrong errno value.
+         gl_cv_func_lseek_pipe=no
+         ;;
+       *)
+         if test $cross_compiling = no; then
+           AC_LINK_IFELSE([AC_LANG_PROGRAM([[
 #include <sys/types.h> /* for off_t */
 #include <stdio.h> /* for SEEK_CUR */
 #if HAVE_UNISTD_H
@@ -23,23 +35,28 @@
   /* Exit with success only if stdin is seekable.  */
   return lseek (0, (off_t)0, SEEK_CUR) < 0;
 ]])],
-         [if test -s conftest$ac_exeext \
-             && ./conftest$ac_exeext < conftest.$ac_ext \
-             && test 1 = "`echo hi \
-               | { ./conftest$ac_exeext; echo $?; cat >/dev/null; }`"; then
-            gl_cv_func_lseek_pipe=yes
-          else
-            gl_cv_func_lseek_pipe=no
-          fi],
-         [gl_cv_func_lseek_pipe=no])
-     else
-       AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
-#if ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) || defined 
__BEOS__
-/* mingw and BeOS mistakenly return 0 when trying to seek on pipes.  */
+             [if test -s conftest$ac_exeext \
+                 && ./conftest$ac_exeext < conftest.$ac_ext \
+                 && test 1 = "`echo hi \
+                   | { ./conftest$ac_exeext; echo $?; cat >/dev/null; }`"; then
+                gl_cv_func_lseek_pipe=yes
+              else
+                gl_cv_func_lseek_pipe=no
+              fi
+             ],
+             [gl_cv_func_lseek_pipe=no])
+         else
+           AC_COMPILE_IFELSE(
+             [AC_LANG_SOURCE([[
+#if defined __BEOS__
+/* BeOS mistakenly return 0 when trying to seek on pipes.  */
   Choke me.
 #endif]])],
-         [gl_cv_func_lseek_pipe=yes], [gl_cv_func_lseek_pipe=no])
-     fi])
+             [gl_cv_func_lseek_pipe=yes], [gl_cv_func_lseek_pipe=no])
+         fi
+         ;;
+     esac
+    ])
   if test $gl_cv_func_lseek_pipe = no; then
     REPLACE_LSEEK=1
     AC_DEFINE([LSEEK_PIPE_BROKEN], [1],




reply via email to

[Prev in Thread] Current Thread [Next in Thread]