// ExecBug // // This program demonstrates two bugs with the error stream of an // exec'd Process. // // What the program tries to do is exec a subprocess that writes something // to stderr; read that text from the subprocess's error stream and echo it // to System.err; and display the return value of the subprocess. // // What happens instead, when run using Solaris JDK 1.0.2: // - The first buffer read from the subprocess's error stream is "err = 1!". // This comes from src/solaris/java/green_threads/src/process_md.c, // java_lang_UNIXProcess_fork(). // - The second buffer is ok, and contains the first part of the subprocess's // error message. // - The third buffer comes back from read() with a length of -2, causing // an ArrayIndexOutOfBoundsException. // // Sample run: // % java ExecBug // len=9 // err = 1! // len=20 // cat: cannot open /felen=-2 // java.lang.ArrayIndexOutOfBoundsException // at java.io.BufferedOutputStream.write(BufferedOutputStream.java) // at java.io.PrintStream.write(PrintStream.java) // at ExecBug.main(ExecBug.java:37) // // This bug is fixed in JDK 1.1. // // Jef Poskanzer 17jul96 package Bugs; import java.io.*; import java.util.*; public class ExecBug { public static void main( String[] args ) { Runtime runtime = Runtime.getRuntime(); Process process1 = null; int r = 1234; try { String[] cmd = { "/bin/cat", "/feepyfoo" }; process1 = runtime.exec( cmd ); } catch ( IOException e ) { System.err.println( "exec: " + e ); System.exit( 1 ); } try { InputStream e = process1.getErrorStream(); byte[] buf = new byte[20]; int len; boolean eEof = false; while ( ! eEof ) { len = e.read( buf ); if ( len == -1 ) eEof = true; else if ( len != 0 ) { System.err.println( "len=" + len ); System.err.write( buf, 0, len ); } } e.close(); } catch ( IOException e ) { System.err.println( "read: " + e ); System.exit( 1 ); } try { r = process1.waitFor(); } catch ( InterruptedException e ) { System.err.println( "waitFor: " + e ); System.exit( 1 ); } System.out.println( "returned " + r ); } }