# # patch "netxx_pipe.cc" # from [96d429f6144a46bb99537d27bcc580f55096a2a8] # to [68febc1da00beabc89c53f827280e095a2c7c5b8] # ======================================================================== --- netxx_pipe.cc 96d429f6144a46bb99537d27bcc580f55096a2a8 +++ netxx_pipe.cc 68febc1da00beabc89c53f827280e095a2c7c5b8 @@ -71,7 +71,7 @@ #include #include #define FAIL_IF(FUN,ARGS,CHECK) \ - E(!(FUN ARGS CHECK), F(#FUN " failed %d\n") % GetLastError()) + E(!((FUN ARGS) CHECK), F(#FUN " failed %d\n") % GetLastError()) #endif Netxx::PipeStream::PipeStream (const std::string &cmd, const std::vector &args) @@ -92,14 +92,24 @@ fd1[1]=-1; fd2[0]=-1; fd2[1]=-1; - E(_pipe(fd1,0,_O_BINARY)==0, F("first pipe failed")); - if (_pipe(fd2,0,_O_BINARY)) - { ::close(fd1[0]); - ::close(fd1[1]); - E(false,F("second pipe failed")); - } - // it looks like we have to use CreateNamedPipe and CreateFile (OPEN_EXISTING) - // if we do not want the pipe to block + E(_pipe(fd2,0,_O_BINARY)==0, F("first pipe failed")); + char pipename[256]; + static int serial; + // yes, since we have to use named pipes because of nonblocking read + // (so called overlapped I/O) we could as well use one bidirectional + // pipe. I prefer two pipes to resemble the unix case. + snprintf(pipename,sizeof pipename,"\\\\.\\pipe\\netxx_pipe_%d_%d", + GetCurrentProcessId(),++serial); + HANDLE readhandle=0,writehandle=0; + FAIL_IF(readhandle=CreateNamedPipe,(pipename, + PIPE_ACCESS_INBOUND|FILE_FLAG_OVERLAPPED, + PIPE_TYPE_BYTE | PIPE_WAIT, + 1,4096,4096,1000,0),==INVALID_HANDLE_VALUE); + FAIL_IF(writehandle=CreateFile,(pipename,GENERIC_WRITE,0,0,OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL,0),==INVALID_HANDLE_VALUE); + // MinGW defines this function to take a long, not a HANDLE :-( + FAIL_IF(fd1[0]=_open_osfhandle,(long(readhandle),O_BINARY|O_RDONLY),==-1); + FAIL_IF(fd1[1]=_open_osfhandle,(long(writehandle),O_BINARY|O_WRONLY),==-1); // mark these file handles as not inheritable SetHandleInformation( (HANDLE)_get_osfhandle(fd1[0]), HANDLE_FLAG_INHERIT, 0); @@ -125,12 +135,8 @@ readfd=fd1[0]; writefd=fd2[1]; - HANDLE h_nonblockwrite = ReOpenFile((HANDLE)_get_osfhandle(readfd),FILE_READ_DATA,0,FILE_FLAG_OVERLAPPED)); - ::close(readfd); - readfd=_open_osfhandle(h_nonblockwrite); - memset(&overlap,0,sizeof overlap); - overlap.hEvent=CreateEvent(0,FALSE,FALSE,0); + overlap.hEvent=CreateEvent(0,FALSE,FALSE,0); // or TRUE,TRUE? bytes_available=0; I(overlap.hEvent!=0); #else