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

From: Peter Rosin <[email-masked]>
Date: Mon, 16 Jan 2012 12:40:14 +0100

Sorry for the delay.

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).
>>
> So I guess even something like this would fail:
> 
>   int main (void)
>   {
>     return (system("echo bazbazbaz >&9") == 0);
>   }
> 
> right?

Yes, system() fails as well:

+ cat foo.log
+ cat bar.log
+ cat baz.log
The handle could not be duplicated
during redirection of handle 1.
+ cat qux.log
The handle could not be duplicated
during redirection of handle 1.

In a MinGW program, system() invokes the Windows command interpreter
(cmd) and not /bin/sh, and it suffers the same redirection troubles
as the original C code.  However, I think fd 9 is lost already when
the MinGW program is fork()/exec()ed from the MSYS environment and
adding system() to the mix simply added another non-MSYS layer. I
believe anything you try to do, short of being an MSYS program, is
going to fail.  Since the whole point of MSYS in its normal mode is
building MinGW programs with the MinGW compiler (and not MSYS
programs), this redirection just won't work.  This is one of the
costs of the trickery MSYS is guilty of by masquerading as MinGW,
when the reality is that the environment is a cross from MSYS to
MinGW, and not MinGW native.  In a plain old cross enviroment,
nobody is surprised when executing generated executables fail in
spectacular ways...

>         If yes, the solution might be splitting p'arallel-tests-fd-redirect.test'
> into two tests, and make the one testing the redirection from C skip on MinGW/MSYS.

Maybe, but XFAIL would be better if that can be specified for an
individual system (I don't think so, but I forget). Also,
mentioning it in the documentation would be nice if there is any
previous mention of the use of fd 9 from test cases (I'm ignorant
here, and haven't bothered to check).

>> Also, including unistd.h will not work for non-ANSI systems,
>> MinGW provides a half-baked unistd.h but MSVC does not.
>> MSVC has its write() in io.h, but it will probably suffer
>> from the same problem with a dysfunctional fd 9.
> 
>> With this diff:
>>
>> diff --git a/tests/parallel-tests-fd-redirect.test b/tests/parallel-tests-fd-red
>> index 73a134e..5728014 100755
>> --- a/tests/parallel-tests-fd-redirect.test
>> +++ b/tests/parallel-tests-fd-redirect.test
>> @@ -65,20 +65,26 @@ END
>>  chmod a+x foo.sh bar
>>
>>  cat > baz.c <<'END'
>> +#include <stdio.h>
>>  #include <unistd.h>
>>  int main (void)
>>  {
>> -  write (9, " bazbazbaz\n", 11);
>> -  return 0;
>> +  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)
>>  {
>> -  write (9, " quxquxqux\n", 11);
>> -  return 0;
>> +  ssize_t res = write (9, " quxquxqux\n", 11);
>> +  if (res < 0)
>> +    perror("write failed");
>> +  return res != 11;
>>  }
>>  END
>>
> BTW, this change might be independently useful in catching other potential
> unexpected write failures; would you feel like cooking it in a proper patch?

I'm swamped with work for a week or so, go right ahead if you like to
and can't wait.

Cheers,
Peter