001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   https://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019
020package org.apache.commons.exec;
021
022import java.io.InputStream;
023import java.io.OutputStream;
024
025import org.apache.commons.exec.util.DebugUtils;
026
027/**
028 * Copies all data from a {@code System.input} stream to an output stream of the executed process.
029 */
030public class InputStreamPumper implements Runnable {
031
032    /**
033     * Sleep time in milliseconds.
034     */
035    public static final int SLEEPING_TIME = 100;
036
037    /** The input stream to pump from. */
038    private final InputStream is;
039
040    /** The output stream to pmp into. */
041    private final OutputStream os;
042
043    /** Flag to stop the stream pumping. */
044    private volatile boolean stop;
045
046    /**
047     * Create a new stream pumper.
048     *
049     * @param is input stream to read data from.
050     * @param os output stream to write data to.
051     */
052    public InputStreamPumper(final InputStream is, final OutputStream os) {
053        this.is = is;
054        this.os = os;
055        this.stop = false;
056    }
057
058    /**
059     * Copies data from the input stream to the output stream. Terminates as soon as the input stream is closed or an error occurs.
060     */
061    @Override
062    public void run() {
063        try {
064            while (!stop) {
065                while (is.available() > 0 && !stop) {
066                    os.write(is.read());
067                }
068                os.flush();
069                Thread.sleep(SLEEPING_TIME);
070            }
071        } catch (final Exception e) {
072            final String msg = "Got exception while reading/writing the stream";
073            DebugUtils.handleException(msg, e);
074        }
075    }
076
077    /**
078     * Requests processing to stop.
079     */
080    public void stopProcessing() {
081        stop = true;
082    }
083
084}