Skip to content

Commit

Permalink
Allow java classes to close stdout/stderr
Browse files Browse the repository at this point in the history
When the client calls a class, where either stdout or stderr is closed
the socket connection to the client is closed and no further data is
sent. This includes data transmitted over the other stream and exit
codes.
  • Loading branch information
vhristov committed Feb 10, 2014
1 parent 4cac9ae commit 36733dd
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ public static void main (String[] args) {
exitCode = Integer.parseInt(args[0]);
} catch (Exception e) {}
}
// Close stdout to test the exit code is returned properly
// even in such case
System.out.close();
System.exit(exitCode);
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class NGOutputStream extends java.io.DataOutputStream {

private final Object lock;
private byte streamCode;
private boolean closed = false;

/**
* Creates a new NGOutputStream wrapping the specified
Expand All @@ -52,13 +53,15 @@ public NGOutputStream(java.io.OutputStream out, byte streamCode) {
* @see java.io.OutputStream.write(byte[])
*/
public void write(byte[] b) throws IOException {
throwIfClosed();
write(b, 0, b.length);
}

/**
* @see java.io.OutputStream.write(int)
*/
public void write(int b) throws IOException {
throwIfClosed();
byte[] b2 = {(byte) b};
write(b2, 0, 1);
}
Expand All @@ -67,11 +70,44 @@ public void write(int b) throws IOException {
* @see java.io.OutputStream.write(byte[],int,int)
*/
public void write(byte[] b, int offset, int len) throws IOException {
throwIfClosed();
synchronized(lock) {
writeInt(len);
writeByte(streamCode);
out.write(b, offset, len);
}
flush();
}

/**
* @see java.io.OutputStream.close()
*
* Implement an empty close function, to allow the client to close
* the stdout and/or stderr, without this closing the connection
* socket to the client.
*/
public void close() throws IOException {
throwIfClosed();
closed = true;
}

/**
* @see java.io.OutputStream.flush()
*/
public void flush() throws IOException {
throwIfClosed();
super.flush();
}

/**
* Check if stream is closed and throw an IOException if yes.
*
* In the case of a public operation is being performed while the stream
* is already closed throws an IOException.
*/
private void throwIfClosed() throws IOException {
if(closed) {
throw new IOException();
}
}
}

0 comments on commit 36733dd

Please sign in to comment.