/*
 * Copyright 2003 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

/* @test
 * @bug 4820217
 * @summary Ensure that pending reads on stdout and stderr streams
 *          return -1 when the process is destroyed
 */

import java.io.*;


public class StreamsSurviveDestroy {

    private static class Copier extends Thread {

        String name;
        InputStream in;
        OutputStream out;
        boolean wantInterrupt;
        boolean acceptException;
        Exception exc = null;

        Copier(String name, InputStream in, OutputStream out,
               boolean ae, boolean wi)
        {
            this.name = name;
            this.in = in;
            this.out = out;
            this.acceptException = ae;
            this.wantInterrupt = wi;
            setName(name);
            start();
        }

        private void log(String s) {
            System.err.println("  " + name + ": " + s);
        }

        public void run() {
            byte[] buf = new byte[4242];
            for (;;) {
                try {
                    int n = in.read(buf);
                    if (n < 0) {
                        System.err.println("  EOF");
                        break;
                    }
                    out.write(buf, 0, n);
                } catch (IOException x) {
                    if (wantInterrupt) {
                        if (x instanceof InterruptedIOException) {
                            log("Interrupted as expected");
                            return;
                        }
                        exc = new Exception(name
                                            + ": Not interrupted as expected");
                        return;
                    }
                    exc = x;
                    if (acceptException) {
                        log("Thrown, but okay: " + x);
                        return;
                    }
                    return;
                }
            }
        }

        public void check() throws Exception {
            if (!acceptException && exc != null)
                throw new Exception(name + ": Exception thrown", exc);
        }

    }

    static void test() throws Exception {
        System.err.println("test");
        Process p = Runtime.getRuntime().exec("/bin/cat");
        Copier cp1 = new Copier("out", p.getInputStream(), System.err,
                               false, false);
        Copier cp2 = new Copier("err", p.getErrorStream(), System.err,
                               false, false);
        Thread.sleep(100);
        p.destroy();
        System.err.println("  exit: " + p.waitFor());
        cp1.join();
        cp1.check();
        cp2.join();
        cp2.check();
    }

    static void testCloseBeforeDestroy() throws Exception {
        System.err.println("testCloseBeforeDestroy");
        Process p = Runtime.getRuntime().exec("/bin/cat");
        Copier cp1 = new Copier("out", p.getInputStream(), System.err,
                                true, false);
        Copier cp2 = new Copier("err", p.getErrorStream(), System.err,
                                true, false);
        Thread.sleep(100);
        p.getInputStream().close();
        p.getErrorStream().close();
        p.destroy();
        System.err.println("  exit: " + p.waitFor());
        cp1.join();
        cp1.check();
        cp2.join();
        cp2.check();
    }

    static void testCloseAfterDestroy() throws Exception {
        System.err.println("testCloseAfterDestroy");
        Process p = Runtime.getRuntime().exec("/bin/cat");
        Copier cp1 = new Copier("out", p.getInputStream(), System.err,
                                true, false);
        Copier cp2 = new Copier("err", p.getErrorStream(), System.err,
                                true, false);
        Thread.sleep(100);
        p.destroy();
        p.getInputStream().close();
        p.getErrorStream().close();
        System.err.println("  exit: " + p.waitFor());
        cp1.join();
        cp1.check();
        cp2.join();
        cp2.check();
    }

    static void testInterrupt() throws Exception {
        System.err.println("testInterrupt");
        Process p = Runtime.getRuntime().exec("/bin/cat");
        Copier cp1 = new Copier("out", p.getInputStream(), System.err,
                                false, true);
        Copier cp2 = new Copier("err", p.getErrorStream(), System.err,
                                false, true);
        Thread.sleep(100);
        cp1.interrupt();
        cp2.interrupt();
        Thread.sleep(100);
        p.destroy();
        System.err.println("  exit: " + p.waitFor());
        cp1.join();
        cp1.check();
        cp2.join();
        cp2.check();
    }

    public static void main(String[] args) throws Exception {

        // Applies only to Solaris; Linux and Windows
        // behave a little differently
        if (!System.getProperty("os.name").equals("SunOS"))
            return;

        test();
        testCloseBeforeDestroy();
        testCloseAfterDestroy();
        testInterrupt();

    }

}
