Given a pair of named pipes (FIFOs, one for reading, one for writing) which are used to communicate with another process, I want to open both pipes in a way that is interruptible.
I have tested Files.newInputStream(), Files.newByteChannel() and new RandomAccessFile().
The problem I get is that when I open the pipes read-only (resp. write-only), the open() call will block, and thus the thread doing Files.newInputStream() etc will block until the other process has opened its end of the pipe.
This means that it is impossible for me to interrupt the opening process, e.g. when I decide to shut down a module or connect to a different set of pipes. That close() call will have to wait for the pipe to be open.
A workaround I have found is to use modes rw (or StandardOpenOption.READ, StandardOpenOption.WRITE) to open my files. This makes sure that there is somebody opening "the other end" (myself), so that open() does not block, but read() blocks as expected.
However, that breaks the ability to detect the other process closing the pipe. Normally, I would get a Broken Pipe exception on the writing end, and an EOF / ClosedByInterruptException on the other end. This happens only when I'm the last reader/writer on the pipe, which will never happen if I have both pipes open R+W.
Thread.interrupt() will interrupt a NIO read (f.ex. stream.getChannel().read(x), but not an open().
Now: Is there a possibility of getting a ByteChannel or InputStream from an open(O_NONBLOCK) call in Java?
All call paths I have found and traced give no possibility of passing that flag. open(3p) tells me that this would return successfully for reading (and hopefully block on the read()), and the writing end will error ENXIO, so that I can retry in a bit (but still have a chance to interrupt my retries if I choose).
Even AsynchronousFileChannel seems to call open() before opening its thread pool, so that would have the same problem.