< prev index next >

src/java.base/share/classes/java/lang/ProcessBuilder.java

Print this page

        

*** 23,36 **** --- 23,39 ---- * questions. */ package java.lang; + import sun.nio.ch.SelChImpl; + import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; + import java.nio.channels.Pipe; import java.util.Arrays; import java.util.ArrayList; import java.util.List; import java.util.Map;
*** 457,476 **** --- 460,507 ---- * {@link Type Type}. * * @since 1.7 */ public static abstract class Redirect { + + private static final boolean PIPE_CHANNEL_SUPPORTED; + + static { + boolean supported = false; + try { + Pipe p = Pipe.open(); + supported = (p.sink() instanceof SelChImpl) && + (p.source() instanceof SelChImpl); + try { p.sink().close(); } catch (IOException e) {} + try { p.source().close(); } catch (IOException e) {} + } catch (IOException e) { + // ignore + } + PIPE_CHANNEL_SUPPORTED = supported; + } + + final void checkSupported() throws UnsupportedOperationException { + if (this == PIPE_CHANNEL && !PIPE_CHANNEL_SUPPORTED) { + throw new UnsupportedOperationException("Unsupported SelectorProvider"); + } + } + /** * The type of a {@link Redirect}. */ public enum Type { /** * The type of {@link Redirect#PIPE Redirect.PIPE}. */ PIPE, /** + * The type of {@link Redirect#PIPE_CHANNEL Redirect.PIPE_CHANNEL}. + */ + PIPE_CHANNEL, + + /** * The type of {@link Redirect#INHERIT Redirect.INHERIT}. */ INHERIT, /**
*** 513,522 **** --- 544,571 ---- public static final Redirect PIPE = new Redirect() { public Type type() { return Type.PIPE; } public String toString() { return type().toString(); }}; /** + * Indicates that subprocess I/O will be connected to the + * current Java process over a pipe and that the communication + * will be performed via {@link java.nio.channels.Pipe.SourceChannel} + * or {@link java.nio.channels.Pipe.SinkChannel}. + ** + * <p>It will always be true that + * <pre> {@code + * Redirect.PIPE_CHANNEL.file() == null && + * Redirect.PIPE_CHANNEL.type() == Redirect.Type.PIPE_CHANNEL + * }</pre> + * + * @since 1.9 + */ + public static final Redirect PIPE_CHANNEL = new Redirect() { + public Type type() { return Type.PIPE_CHANNEL; } + public String toString() { return type().toString(); }}; + + /** * Indicates that subprocess I/O source or destination will be the * same as those of the current process. This is the normal * behavior of most operating system command interpreters (shells). * * <p>It will always be true that
*** 685,708 **** --- 734,770 ---- * returned by {@link Process#getOutputStream()}. * If the source is set to any other value, then * {@link Process#getOutputStream()} will return a * <a href="#redirect-input">null output stream</a>. * + * <p>If the source is {@link Redirect#PIPE_CHANNEL Redirect.PIPE_CHANNEL}, + * then the standard input of a subprocess can be written to + * using the output channel returned by + * {@link Process#getOutputChannel()} which, unlike the output stream + * above, must be obtained and closed by the user. + * If the source is set to any other value, then + * {@link Process#getOutputChannel()} will return {@code null}. + * * @param source the new standard input source * @return this process builder * @throws IllegalArgumentException * if the redirect does not correspond to a valid source * of data, that is, has type * {@link Redirect.Type#WRITE WRITE} or * {@link Redirect.Type#APPEND APPEND} + * @throws UnsupportedOperationException if the redirect has type + * {@link Redirect.Type#PIPE_CHANNEL PIPE_CHANNEL} and the + * platform is configured with unsupported + * {@link java.nio.channels.spi.SelectorProvider} * @since 1.7 */ public ProcessBuilder redirectInput(Redirect source) { if (source.type() == Redirect.Type.WRITE || source.type() == Redirect.Type.APPEND) throw new IllegalArgumentException( "Redirect invalid for reading: " + source); + source.checkSupported(); redirects()[0] = source; return this; } /**
*** 717,738 **** --- 779,812 ---- * Process#getInputStream()}. * If the destination is set to any other value, then * {@link Process#getInputStream()} will return a * <a href="#redirect-output">null input stream</a>. * + * <p>If the destination is {@link Redirect#PIPE_CHANNEL Redirect.PIPE_CHANNEL}, + * then the standard output of a subprocess can be read using the input + * channel returned by {@link Process#getInputChannel()}. which, + * unlike the input stream above, must be obtained and closed by the user. + * If the destination is set to any other value, then + * {@link Process#getInputChannel()} will return {@code null}. + * * @param destination the new standard output destination * @return this process builder * @throws IllegalArgumentException * if the redirect does not correspond to a valid * destination of data, that is, has type * {@link Redirect.Type#READ READ} + * @throws UnsupportedOperationException if the redirect has type + * {@link Redirect.Type#PIPE_CHANNEL PIPE_CHANNEL} and the + * platform is configured with unsupported + * {@link java.nio.channels.spi.SelectorProvider} * @since 1.7 */ public ProcessBuilder redirectOutput(Redirect destination) { if (destination.type() == Redirect.Type.READ) throw new IllegalArgumentException( "Redirect invalid for writing: " + destination); + destination.checkSupported(); redirects()[1] = destination; return this; } /**
*** 757,772 **** --- 831,851 ---- * @return this process builder * @throws IllegalArgumentException * if the redirect does not correspond to a valid * destination of data, that is, has type * {@link Redirect.Type#READ READ} + * @throws UnsupportedOperationException if the redirect has type + * {@link Redirect.Type#PIPE_CHANNEL PIPE_CHANNEL} and the + * platform is configured with unsupported + * {@link java.nio.channels.spi.SelectorProvider} * @since 1.7 */ public ProcessBuilder redirectError(Redirect destination) { if (destination.type() == Redirect.Type.READ) throw new IllegalArgumentException( "Redirect invalid for writing: " + destination); + destination.checkSupported(); redirects()[2] = destination; return this; } /**
*** 895,905 **** * * <p>If this property is {@code true}, then any error output * generated by subprocesses subsequently started by this object's * {@link #start()} method will be merged with the standard * output, so that both can be read using the ! * {@link Process#getInputStream()} method. This makes it easier * to correlate error messages with the corresponding output. * The initial value is {@code false}. * * @return this process builder's {@code redirectErrorStream} property */ --- 974,985 ---- * * <p>If this property is {@code true}, then any error output * generated by subprocesses subsequently started by this object's * {@link #start()} method will be merged with the standard * output, so that both can be read using the ! * {@link Process#getInputStream()} or {@link Process#getInputChannel()} ! * methods. This makes it easier * to correlate error messages with the corresponding output. * The initial value is {@code false}. * * @return this process builder's {@code redirectErrorStream} property */
*** 912,922 **** * * <p>If this property is {@code true}, then any error output * generated by subprocesses subsequently started by this object's * {@link #start()} method will be merged with the standard * output, so that both can be read using the ! * {@link Process#getInputStream()} method. This makes it easier * to correlate error messages with the corresponding output. * The initial value is {@code false}. * * @param redirectErrorStream the new property value * @return this process builder --- 992,1003 ---- * * <p>If this property is {@code true}, then any error output * generated by subprocesses subsequently started by this object's * {@link #start()} method will be merged with the standard * output, so that both can be read using the ! * {@link Process#getInputStream()} or {@link Process#getInputChannel()} ! * methods. This makes it easier * to correlate error messages with the corresponding output. * The initial value is {@code false}. * * @param redirectErrorStream the new property value * @return this process builder
< prev index next >