Skip to content
Advertisement

Running process that feeds on pipe STDOUT is untrackable until something is fed to pipe STDIN

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
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement