2

I need to implement non-blocking reading and writing from windows named pipes using Python (ctypes). I am able to achieve this if the pipe is opened in server mode. But I fail to do it when opening the pipe with client, using CreateFile.

ReadFile blocks, no matter that the pipe was created with PIPE_NOWAIT by the server process. I'm trying to use windll.kernel32.SetNamedPipeHandleState on the handle returned by windll.kernel32.CreateFileW, but get an error ERROR_ACCESS_DENIED

The description for SetNamedPipeHandleState says that it must have GENERIC_READ and FILE_WRITE_ATTRIBUTES access for a read-only pipe.

How do I set these flags when opening a file? And will it actually help to resolve my problem?

Ray P.
  • 875
  • 1
  • 9
  • 24
  • you need use `FILE_FLAG_OVERLAPPED` option in `CreateFile` (in `dwFlagsAndAttributes`) – RbMm Apr 24 '18 at 10:54
  • and *Nonblocking mode* != *asynchronous I/O* - this is different things. i suggest use not *Nonblocking mode* but exactly *asynchronous I/O* - so use `PIPE_WAIT` flag in `CreateNamedPipe` and `FILE_FLAG_OVERLAPPED` in both calls to `CreateNamedPipe` and `CreateFile` – RbMm Apr 24 '18 at 10:59
  • 1
    Does that mean using callbacks? This might imply serious changes to my code. – Ray P. Apr 24 '18 at 11:02
  • yes, asynchronous i/o usually use callbacks. or another completion way. this is different from nonblocking io which just return result (success or fail). asynchronous io usual return `STATUS_PENDING` and operation complete some late (with success or fail). if you not want/can do this - you in this case really need `SetNamedPipeHandleState` – RbMm Apr 24 '18 at 11:06
  • 1
    Yes, I really can't change it. So I just need to understand how to set GENERIC_READ and FILE_WRITE_ATTRIBUTES. – Ray P. Apr 24 '18 at 11:12
  • you really need have `FILE_WRITE_ATTRIBUTES` on file handle. you need set this in call `CreateFile` – RbMm Apr 24 '18 at 11:12
  • so you need `CreateFile("your pipe name", FILE_GENERIC_READ|FILE_GENERIC_WRITE, ..)` – RbMm Apr 24 '18 at 11:14
  • You could offload onto another thread and use `Queue.read_no_wait` to read, and adapt the technique for writes. Check out [this answer](https://stackoverflow.com/a/4896288/5240004) for an example. Or you could just use/adapt the [python-nonblock](https://pypi.org/project/python-nonblock/) module from PyPi, which implements async reads and writes in pure python. – theB Apr 24 '18 at 12:13

0 Answers0