https://bugs.winehq.org/show_bug.cgi?id=43036
Bug ID: 43036 Summary: SetNamedPipeHandleState returns ERROR_ACCESS_DENIED when setting PIPE_NOWAIT Product: Wine Version: 2.7 Hardware: x86 OS: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: -unknown Assignee: wine-bugs@winehq.org Reporter: dan-wine@berrange.com Distribution: ---
In GNULIB, there is code which tries to create an implementation of the POSIX pipe() method for Windows, using the methods _pipe, _get_osfhandle and SetNamedPipeHandleState. This code works when run on real windows systems (i've tried Win2k8 myself), but fails when run under Wine (I've tested versions 2.5 and 2.7 in Fedora), with ERROR_ACCESS_DENIED from the SetNamedPipeHandleState method
Since GNULIB code is fairly complex to follow I created this short demo program:
$ cat > demo.c <<EOF #include <sys/unistd.h> #include <stdio.h> #include <windows.h>
int nonblock(int fd) { HANDLE h = (HANDLE)_get_osfhandle(fd); char errbuf[1024]; DWORD state;
if (GetNamedPipeHandleState (h, &state, NULL, NULL, NULL, NULL, 0) == 0) { FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), errbuf, 1024, NULL);
fprintf(stderr, "Failed GetNamedPipeHandleState (%lu) %s", GetLastError(), errbuf); return -1; }
if ((state & PIPE_NOWAIT) != 0) { return 0; }
state |= PIPE_NOWAIT;
if (SetNamedPipeHandleState (h, &state, NULL, NULL) == 0) { FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), errbuf, 1024, NULL);
fprintf(stderr, "Failed SetNamedPipeHandleState (%lu) %s", GetLastError(), errbuf); return -1; } return 0; }
int main(int argc, char **argv) { int fd[2];
if (_pipe(fd, 4096, 0) < 0) { fprintf(stderr, "Failed to create pipe\n"); return -1; }
if (nonblock(fd[0]) < 0){ fprintf(stderr, "Could not set non-blocking on fd[0]\n"); return -1; } if (nonblock(fd[1]) < 0){ fprintf(stderr, "Could not set non-blocking on fd[1]\n"); return -1; }
fprintf(stderr, "Created non-blocking pipe pair\n"); }
EOF
$ i686-w64-mingw32-gcc -Wall -mconsole -o pipe.exe pipe.c
$ ./pipe.exe fixme:winediag:start_process Wine Staging 2.7 is a testing version containing experimental patches. fixme:winediag:start_process Please mention your exact version when filing bug reports on winehq.org. fixme:sync:GetNamedPipeHandleStateW 0x2c 0x61f8f8 (nil) (nil) (nil) (nil) 0: semi-stub Failed SetNamedPipeHandleState (5) Access denied. Could not set non-blocking on fd[0]
Strangely, this only seems to fail on fd[0] - if I let it run on fd[1] it will work.
The original GNULIB code I hit the problem on is here:
http://git.savannah.gnu.org/cgit/gnulib.git/tree/lib/pipe2.c http://git.savannah.gnu.org/cgit/gnulib.git/tree/lib/nonblocking.c
The Fedora Wine 2.7 package I tested on was built with these sources:
SHA512 (wine-2.7.tar.xz) = 1e61b9a4aa1f5f42fb27d11d5254a9ba90f348ad9c4d1ddd4b5da47cd7de638290a20accf7447db9c0e4ced4c2144497cdf5fc906a5eac60e923dabb61f65d3a SHA512 (wine-2.7.tar.xz.sign) = b03f4376b10bd8ea66e5e6fc0862a4f948e009862a374677c326744b31c9d9fdcf1efd3b789149fcb6fe617f9c75b1b47d61f884e06e8c0fe16633a99911b667 SHA512 (wine-staging-2.7.tar.gz) = 0abc89af701ae1b95c0eb08e72894c7bc40bdfe792e05b8af9282eab8407bb90b7dfcd4eb3a193a88759ce5d6ea6c2aa9696cac2d744f543c92529bb0d2636ee