Subject: Re: bug#10466: MSYS problem with redirects

From: Stefano Lattarini <[email-masked]>
Date: Fri, 27 Jan 2012 13:20:49 +0100

tags 10466 + patch
severity 10466 minor
thanks

On 01/16/2012 12:40 PM, Peter Rosin wrote:
> Sorry for the delay.
Ditto here :-)

> Stefano Lattarini skrev 2012-01-09 20:32:
>> On 01/09/2012 12:29 PM, Peter Rosin wrote:
>>> Hi!
>>>
>>> parallel-tests-fd-redirect.test fails on MSYS, and I think
>>> the cause is that the write (9, ...) simply doesn't work for
>>> MinGW programs (baz.exe and qux.test.exe).  It works for the
>>> shell scripts (foo.sh and bar) since /bin/sh is an MSYS
>>> program and thus is a lot more POSIXy.  But redirecting from
>>> the MinGW world to the MSYS world in this manner is simply
>>> not possible, I think.  I think that will only work for
>>> fd 0,1 and 2 (but I'm not 100% sure).
>>>
The attached patch should take care of the issue.  Can you confirm
this is actually the case, before I push it?

Thanks,
  Stefano
>From 53339f86ceb32ff98b1ccfb05539645cb7e641fe Mon Sep 17 00:00:00 2001
Message-Id: <53339f86c[email-masked]>
From: Stefano Lattarini <[email-masked]>
Date: Tue, 10 Jan 2012 20:27:08 +0100
Subject: [PATCH] tests: work around MinGW/MSYS issue in fd redirections

Some checks on $(AM_TESTS_FD_REDIRECT) were failing on MSYS, likely
because system calls like "write(9, ...)" simply doesn't work for
MinGW-compiled programs.  Similar usages work for the shell scripts
though, since /bin/sh is an MSYS program and thus is a lot more
POSIX-ish than most MinGW-compiled programs.

The best fix for this issue is to separate the checks using shell
scripts as dummy test cases from the checks using compiled programs
for the same purpose, and skip these latter checks on MinGW.

This change fixes automake bug#10466.  Report by Peter Rosin.

* tests/parallel-tests-fd-redirect.test: Move checks using compiled
C programs as test cases to ...
* tests/parallel-tests-fd-redirect-exeext.test: ... this new test.
* tests/list-of-tests.mk: Update.
---
 tests/list-of-tests.mk                       |    1 +
 tests/parallel-tests-fd-redirect-exeext.test |  114 ++++++++++++++++++++++++++
 tests/parallel-tests-fd-redirect.test        |   59 ++------------
 3 files changed, 122 insertions(+), 52 deletions(-)
 create mode 100755 tests/parallel-tests-fd-redirect-exeext.test

diff --git a/tests/list-of-tests.mk b/tests/list-of-tests.mk
index 31d70a7..8bc0ef0 100644
--- a/tests/list-of-tests.mk
+++ b/tests/list-of-tests.mk
@@ -702,6 +702,7 @@ parallel-tests-log-compiler-2.test \
 parallel-tests-dry-run-1.test \
 parallel-tests-dry-run-2.test \
 parallel-tests-fd-redirect.test \
+parallel-tests-fd-redirect-exeext.test \
 parallel-tests-extra-programs.test \
 parallel-tests-unreadable.test \
 parallel-tests-subdir.test \
diff --git a/tests/parallel-tests-fd-redirect-exeext.test b/tests/parallel-tests-fd-redirect-exeext.test
new file mode 100755
index 0000000..0f9d6da
--- /dev/null
+++ b/tests/parallel-tests-fd-redirect-exeext.test
@@ -0,0 +1,114 @@
+#! /bin/sh
+# Copyright (C) 2011, 2012 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# parallel-tests support: redirection of file descriptors with
+# AM_TESTS_FD_REDIRECT, for tests which are binary executables
+# We use some tricks to ensure that all code paths in `lib/am/check2.am'
+# are covered, even on platforms where $(EXEEXT) would be naturally empty.
+# See also the more generic test 'check-fd-redirect.test', and
+# sister test 'parallel-tests-fd-redirect.test'.
+
+required='cc native'
+am_parallel_tests=yes
+. ./defs || Exit 1
+
+cat >> configure.in << 'END'
+AC_PROG_CC
+# Calls like "write(9, ...)" are unlikely to work for MinGW-compiled
+# programs.  We must skip this test if this is the case.
+am__ok=no
+AC_LINK_IFELSE(
+    [AC_LANG_PROGRAM([[#include <unistd.h>]],
+                     [[write (9, "foobar\n", 7); return 0;]])],
+    [AM_RUN_LOG([./conftest$EXEEXT 9>&1]) \
+       && AM_RUN_LOG([(./conftest$EXEEXT 9>&1) | grep "^foobar"]) \
+       && am__ok=yes])
+test $am__ok = yes || AS_EXIT([63])
+AM_CONDITIONAL([real_EXEEXT], [test -n "$EXEEXT"])
+test -n "$EXEEXT" || EXEEXT=.bin
+AC_OUTPUT
+END
+
+cat > Makefile.am << 'END'
+AM_TESTS_FD_REDIRECT = 9>&1
+TESTS = $(check_PROGRAMS)
+check_PROGRAMS = baz qux.test
+qux_test_SOURCES = zardoz.c
+
+## Sanity check.
+if !real_EXEEXT
+check-local:
+	test -f baz.bin
+	test -f qux.test.bin
+endif
+END
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE -a
+
+cat > baz.c <<'END'
+#include <stdio.h>
+#include <unistd.h>
+int main (void)
+{
+  ssize_t res = write (9, " bazbazbaz\n", 11);
+  if (res < 0)
+    perror("write failed");
+  return res != 11;
+}
+END
+
+cat > zardoz.c <<'END'
+#include <stdio.h>
+#include <unistd.h>
+int main (void)
+{
+  ssize_t res = write (9, " quxquxqux\n", 11);
+  if (res < 0)
+    perror("write failed");
+  return res != 11;
+}
+END
+
+st=0; ./configure || st=$?
+cat config.log # For debugging, as we do tricky checks in configure.
+if test $st -eq 63; then
+  skip_ "fd redirect in compiled program unsupported"
+elif test $st -eq 0; then
+  : Continue.
+else
+  fatal_ "unexpected error in ./configure"
+fi
+
+# Sanity checks.
+st=0
+grep '^baz\.log:.*baz\$(EXEEXT)' Makefile || st=1
+grep '^\.test\$(EXEEXT)\.log:' Makefile || st=1
+grep '^qux\.log:' Makefile && st=1
+test $st -eq 0 || fatal_ "doesn't cover expected code paths"
+
+st=0
+$MAKE check >stdout || st=1
+cat stdout
+cat baz.log
+cat qux.log
+test $st -eq 0
+grep "^ bazbazbaz$" stdout
+grep "^ quxquxqux$" stdout
+$EGREP '(bazbazbaz|quxquxqux)' *.log && Exit 1
+
+:
diff --git a/tests/parallel-tests-fd-redirect.test b/tests/parallel-tests-fd-redirect.test
index 8b16378..f22b31a 100755
--- a/tests/parallel-tests-fd-redirect.test
+++ b/tests/parallel-tests-fd-redirect.test
@@ -15,36 +15,22 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 # parallel-tests support: redirection of file descriptors with
-# AM_TESTS_FD_REDIRECT, even when using tests without suffix, or
-# which are binary executables.
-# We use some tricks to ensure that all code paths in `lib/am/check2.am'
-# are covered, even on platforms where $(EXEEXT) would be naturally empty.
+# AM_TESTS_FD_REDIRECT, even when using tests without suffix.
+# The sister `parallel-tests-fd-redirect-exeext.test' do a similar
+# check for tests that are binary executables.
 # See also the more generic test 'check-fd-redirect.test'.
 
-required='cc native'
 am_parallel_tests=yes
 . ./defs || Exit 1
 
 cat >> configure.in << 'END'
-AC_PROG_CC
-AM_CONDITIONAL([real_EXEEXT], [test -n "$EXEEXT"])
-test -n "$EXEEXT" || EXEEXT=.bin
 AC_OUTPUT
 END
 
 cat > Makefile.am << 'END'
 AM_TESTS_FD_REDIRECT = 9>&1
 TEST_EXTENSIONS = .test .sh
-TESTS = foo.sh bar $(check_PROGRAMS)
-check_PROGRAMS = baz qux.test
-qux_test_SOURCES = zardoz.c
-
-## Sanity check.
-if !real_EXEEXT
-check-local:
-	test -f baz.bin
-	test -f qux.test.bin
-endif
+TESTS = foo.sh bar
 END
 
 $ACLOCAL
@@ -64,52 +50,21 @@ END
 
 chmod a+x foo.sh bar
 
-cat > baz.c <<'END'
-#include <stdio.h>
-#include <unistd.h>
-int main (void)
-{
-  ssize_t res = write (9, " bazbazbaz\n", 11);
-  if (res < 0)
-    perror("write failed");
-  return res != 11;
-}
-END
-
-cat > zardoz.c <<'END'
-#include <stdio.h>
-#include <unistd.h>
-int main (void)
-{
-  ssize_t res = write (9, " quxquxqux\n", 11);
-  if (res < 0)
-    perror("write failed");
-  return res != 11;
-}
-END
-
 ./configure
 
 # Sanity checks.
 st=0
 grep '^bar\.log:.*bar' Makefile || st=1
-grep '^baz\.log:.*baz\$(EXEEXT)' Makefile || st=1
-grep '^\.test\$(EXEEXT)\.log:' Makefile || st=1
-$EGREP '^(foo|qux)\.log:' Makefile && st=1
+grep '^foo\.log:' Makefile && st=1
 test $st -eq 0 || fatal_ "doesn't cover expected code paths"
 
-st=0
-$MAKE check >stdout || st=1
+st=0; $MAKE check >stdout || st=1
 cat stdout
 cat foo.log
 cat bar.log
-cat baz.log
-cat qux.log
 test $st -eq 0
 grep "^ foofoofoo$" stdout
 grep "^ barbarbar$" stdout
-grep "^ bazbazbaz$" stdout
-grep "^ quxquxqux$" stdout
-$EGREP '(foofoofoo|barbarbar|bazbazbaz|quxquxqux)' *.log && Exit 1
+$EGREP '(foofoofoo|barbarbar)' *.log && Exit 1
 
 :
-- 
1.7.7.3