src/solaris/classes/java/lang/UNIXProcess.java.solaris

Print this page




 148     }
 149 
 150     public InputStream getErrorStream() {
 151         return stderr_stream;
 152     }
 153 
 154     public synchronized int waitFor() throws InterruptedException {
 155         while (!hasExited) {
 156             wait();
 157         }
 158         return exitcode;
 159     }
 160 
 161     public synchronized int exitValue() {
 162         if (!hasExited) {
 163             throw new IllegalThreadStateException("process hasn't exited");
 164         }
 165         return exitcode;
 166     }
 167 
 168     private static native void destroyProcess(int pid);
 169     public synchronized void destroy() {
 170         // There is a risk that pid will be recycled, causing us to
 171         // kill the wrong process!  So we only terminate processes
 172         // that appear to still be running.  Even with this check,
 173         // there is an unavoidable race condition here, but the window
 174         // is very small, and OSes try hard to not recycle pids too
 175         // soon, so this is quite safe.
 176         if (!hasExited)
 177             destroyProcess(pid);
 178         try {
 179             stdin_stream.close();
 180             if (stdout_inner_stream != null)
 181                 stdout_inner_stream.closeDeferred(stdout_stream);
 182             if (stderr_stream instanceof DeferredCloseInputStream)
 183                 ((DeferredCloseInputStream) stderr_stream)
 184                     .closeDeferred(stderr_stream);
 185         } catch (IOException e) {
 186             // ignore
 187         }
 188     }
















 189 
 190     // A FileInputStream that supports the deferment of the actual close
 191     // operation until the last pending I/O operation on the stream has
 192     // finished.  This is required on Solaris because we must close the stdin
 193     // and stdout streams in the destroy method in order to reclaim the
 194     // underlying file descriptors.  Doing so, however, causes any thread
 195     // currently blocked in a read on one of those streams to receive an
 196     // IOException("Bad file number"), which is incompatible with historical
 197     // behavior.  By deferring the close we allow any pending reads to see -1
 198     // (EOF) as they did before.
 199     //
 200     private static class DeferredCloseInputStream
 201         extends FileInputStream
 202     {
 203 
 204         private DeferredCloseInputStream(FileDescriptor fd) {
 205             super(fd);
 206         }
 207 
 208         private Object lock = new Object();     // For the following fields




 148     }
 149 
 150     public InputStream getErrorStream() {
 151         return stderr_stream;
 152     }
 153 
 154     public synchronized int waitFor() throws InterruptedException {
 155         while (!hasExited) {
 156             wait();
 157         }
 158         return exitcode;
 159     }
 160 
 161     public synchronized int exitValue() {
 162         if (!hasExited) {
 163             throw new IllegalThreadStateException("process hasn't exited");
 164         }
 165         return exitcode;
 166     }
 167 
 168     private static native void destroyProcess(int pid, boolean force);
 169     private synchronized void destroy(boolean force) {
 170         // There is a risk that pid will be recycled, causing us to
 171         // kill the wrong process!  So we only terminate processes
 172         // that appear to still be running.  Even with this check,
 173         // there is an unavoidable race condition here, but the window
 174         // is very small, and OSes try hard to not recycle pids too
 175         // soon, so this is quite safe.
 176         if (!hasExited)
 177             destroyProcess(pid, force);
 178         try {
 179             stdin_stream.close();
 180             if (stdout_inner_stream != null)
 181                 stdout_inner_stream.closeDeferred(stdout_stream);
 182             if (stderr_stream instanceof DeferredCloseInputStream)
 183                 ((DeferredCloseInputStream) stderr_stream)
 184                     .closeDeferred(stderr_stream);
 185         } catch (IOException e) {
 186             // ignore
 187         }
 188     }
 189 
 190     public void destroy() {
 191         destroy(false);
 192     }
 193 
 194     public Process destroyForcibly() {
 195         destroy(true);
 196         return this;
 197     }
 198 
 199     @Override
 200     public boolean isAlive() {
 201         synchronized (this) {
 202             return !hasExited;
 203         }
 204     }
 205 
 206     // A FileInputStream that supports the deferment of the actual close
 207     // operation until the last pending I/O operation on the stream has
 208     // finished.  This is required on Solaris because we must close the stdin
 209     // and stdout streams in the destroy method in order to reclaim the
 210     // underlying file descriptors.  Doing so, however, causes any thread
 211     // currently blocked in a read on one of those streams to receive an
 212     // IOException("Bad file number"), which is incompatible with historical
 213     // behavior.  By deferring the close we allow any pending reads to see -1
 214     // (EOF) as they did before.
 215     //
 216     private static class DeferredCloseInputStream
 217         extends FileInputStream
 218     {
 219 
 220         private DeferredCloseInputStream(FileDescriptor fd) {
 221             super(fd);
 222         }
 223 
 224         private Object lock = new Object();     // For the following fields