/*
 * Copyright 2002 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 4763384
 * @summary Ensure that piped input always works with exec'd processes
 */

import java.io.*;


/**
 * This class demonstrates a regression in java1.4.1 in the handling of the
 * Process OutputStream (exec'd process stdin).  The subprocess completes 100%
 * of the time in 1.4, but about only about 50% of the time under 1.4.1.  Issue
 * exists for client JVM, Linux Redhat 6.2 not sure about other variants of
 * Linux or other OSes, or server JVM.
 */

public class ExecWithInput {

    private static final String CAT = "/bin/cat";
    private static final int N = 200;

    static int go(int i) throws Exception {
        /*
         * Execute /bin/cat supplying two lines of input. cat should
         * read the input lines and copy them to stdout. On completion,
         * p.waitFor should return and the exit status is printed and this
         * program exits. Under 1.4.1, cat sometimes gets stuck on a pipe
         * read and never terminates.
         */
        //Process p = Runtime.getRuntime().exec(new String[] { CAT } );
        Process p = Runtime.getRuntime().exec(CAT);

        String input = i + ": line 1\n" + i + ": line 2\n";
        StringBufferInputStream in = new StringBufferInputStream(input);
        // create threads to handle I/O streams
        IO ioIn = new IO("stdin", in, p.getOutputStream());
        IO ioOut = new IO("stdout", p.getInputStream(), System.out);
        IO ioErr = new IO("stderr", p.getErrorStream(), System.err);

        // wait for process to exit
        return p.waitFor();
    }

    public static void main(String[] args) throws Exception {
        if (!System.getProperty("os.name").equals("Linux"))
            return;
        if (File.separatorChar == '\\') {
            // no /bin/cat on windows
            return;
        }
        for (int i = 0; i < N; i++)
            go(i);
    }

    /**
     * Handle IO. Thread is started in constructor.
     */
    static class IO extends Thread {

        private InputStream in;
        private OutputStream out;

        IO(String name, InputStream in, OutputStream out)
        {
            this.in = in;
            this.out = out;
            setName(name);
            start();
        }

        public void run() {
            try {
                int c;
                byte[] buf = new byte[8192];
                int n;
                while ((n = in.read(buf)) != -1) {
                    out.write(buf, 0, n);
                    out.flush();
                }
                /*
                while ((c = in.read()) != -1) {
                    out.write(c);
                    if (c == '\n')
                        out.flush();
                }
                out.flush();
                */
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (!System.out.equals(out) && !System.err.equals(out)) {
                    // Note: in order to get an exec'd java process to
                    // see EOF on input, it is necessary to close stdin
                    if (out != null) {
                        try { out.close(); } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

}
