I’m trying to implement named PIPE based inter-process communication between a running java program and console. Contents of java program (Test.java) are:
import java.io.*; public class Test { public static void main(String[] args) throws Exception { // starts pipe server InputStreamReader isReader = new InputStreamReader(System.in); BufferedReader bufReader = new BufferedReader(isReader); boolean shutdown = false; while(!shutdown) { String inputStr = bufReader.readLine(); if(inputStr != null) { System.out.println("PONG: "+inputStr); } Thread.sleep(1000); } } }
Program was compiled using:
javac Test.java
A named pipe was created:
mkfifo testing
Then program was ran as consumer of pipe STDOUT:
java Test < testing
Then, using console, I’m sending a ping to pipe STDIN:
echo PING > testing
Which is captured by java program, outputting:
PONG: PING
Now the strange issue: whenever java program is ran, until a message is sent to pipe, its process is untrackable using ps eaux or even in /proc/.
This reproduces both on ubuntu (work computer) and rhel (production server) OS. Does anyone have any idea why that happens?
Advertisement
Answer
That has nothing to do with your java program, but with the shell you’re starting it from, and with the behavior of named pipes.
In a command like program <file
, the shell will first fork()
a separate process, then perform the redirection by open()
ing file
, and finally execve()
the program
.
If the file
is a named pipe/fifo, open()
ing it will block until its other end is opened too. Thence the behavior you’re observing, where your java program isn’t started until you open()
the other end of the fifo.
You can easily work around that by opening the fifo in read/write mode, which will not block, but that means giving up on the ability to detect when the reader has closed its end of the pipe — your program will never get an EOF
on its stdin:
mkfifo testing java Test 0<>testing