简体   繁体   中英

JVM not killed on SIGPIPE

What is the reason for the JVM handling SIGPIPE the way it does?

I would've expected for

java foo | head -10

with

public class Foo {
    public static void main(String[] args){
        Stream.iterate(0, n -> n + 1).forEach(System.out::println);
    }
}

to cause the process to be killed when writing the 11th line, however that is not the case. Instead, it seems that only a trouble flag is being set at the PrintStream, which can be checked through System.out.checkError() .

What happens is that the SIGPIPE exception results in an IOException.

For most OutputStream and Writer classes, this exception propagates through the "write" method, and has to be handled by the caller.

However, when you are writing to System.out, you are using a PrintStream , and that class by design takes care of the IOException of you. As the javadoc says:

A PrintStream adds functionality to another output stream, namely the ability to print representations of various data values conveniently. Two other features are provided as well. Unlike other output streams, a PrintStream never throws an IOException ; instead, exceptional situations merely set an internal flag that can be tested via the checkError method.

What is the reason for the JVM handling SIGPIPE the way it does?

The above explains what is happening. The "why" is... I guess... that the designers wanted to make PrintStream easy to use for typical use cases of System.out where the caller doesn't want to deal with a possible IOException on every call.

Unfortunately, there is no elegant solution to this:

  • You could just call checkError ...
  • You should be able get hold of the FileDescriptor.out object, and wrap it in a new FileOutputStream object... and use that instead of System.out .

Note that there are no strong guarantees that the Java app will only write 10 lines of output in java foo | head -1 java foo | head -1 . It is quite possible for the app to write-ahead many lines, and to only "see" the pipe closed after head has gotten around to reading the first 10 of them. This applies with System.out (and checkError ) or if you wrap FileDescriptor .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM