Skip to content

Commit

Permalink
Input stream supplied to TerminalBuilder.streams() is consumed when a…
Browse files Browse the repository at this point in the history
… terminal instance gets created, fixes #266
  • Loading branch information
gnodet committed May 13, 2018
1 parent f8894f3 commit a67d60f
Show file tree
Hide file tree
Showing 10 changed files with 77 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

public class ExternalTerminalTest {
Expand Down Expand Up @@ -137,6 +138,14 @@ public void testCursorPosition() throws IOException {
assertEquals('f', console.reader().read());
}

@Test
public void testPaused() throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ByteArrayInputStream bais = new ByteArrayInputStream("abcdefghijklmnopqrstuvwxyz".getBytes());
Terminal term = TerminalBuilder.builder().system(false).streams(bais, baos).paused(true).build();
assertTrue(term.paused());
}

@Test
public void testExceptionOnInputStream() throws IOException, InterruptedException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,13 @@ else if (osName.startsWith("FreeBSD")) {

@Override
public Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, Terminal.SignalHandler signalHandler) throws IOException {
return winSysTerminal(name, type, ansiPassThrough, encoding, codepage, nativeSignals, signalHandler, false);
}

@Override
public Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused) throws IOException {
if (JANSI_MAJOR_VERSION > 1 || JANSI_MAJOR_VERSION == 1 && JANSI_MINOR_VERSION >= 12) {
JansiWinSysTerminal terminal = new JansiWinSysTerminal(name, type, ansiPassThrough, encoding, codepage, nativeSignals, signalHandler);
JansiWinSysTerminal terminal = new JansiWinSysTerminal(name, type, ansiPassThrough, encoding, codepage, nativeSignals, signalHandler, paused);
if (JANSI_MAJOR_VERSION == 1 && JANSI_MINOR_VERSION < 16) {
terminal.disableScrolling();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ public JansiWinSysTerminal(String name, boolean nativeSignals) throws IOExceptio
}

public JansiWinSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, SignalHandler signalHandler) throws IOException {
this(name, TYPE_WINDOWS, false, null, 0, nativeSignals, signalHandler, false);
}

public JansiWinSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, SignalHandler signalHandler, boolean paused) throws IOException {
super(ansiPassThrough
? new JansiWinConsoleWriter()
: new WindowsAnsiWriter(new BufferedWriter(new JansiWinConsoleWriter())),
Expand All @@ -46,7 +50,9 @@ public JansiWinSysTerminal(String name, String type, boolean ansiPassThrough, Ch
signalHandler);

// Start input pump thread
resume();
if (!paused) {
resume();
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,9 @@ public Pty open(Attributes attributes, Size size) throws IOException {
public Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, Terminal.SignalHandler signalHandler) throws IOException {
return new JnaWinSysTerminal(name, type, ansiPassThrough, encoding, codepage, nativeSignals, signalHandler);
}

@Override
public Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused) throws IOException {
return new JnaWinSysTerminal(name, type, ansiPassThrough, encoding, codepage, nativeSignals, signalHandler, paused);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,20 @@ public JnaWinSysTerminal(String name, boolean nativeSignals) throws IOException
}

public JnaWinSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, SignalHandler signalHandler) throws IOException {
this(name, TYPE_WINDOWS, false, null, 0, nativeSignals, signalHandler, false);
}

public JnaWinSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, SignalHandler signalHandler, boolean paused) throws IOException {
super(ansiPassThrough
? new JnaWinConsoleWriter(consoleOut)
: new WindowsAnsiWriter(new BufferedWriter(new JnaWinConsoleWriter(consoleOut)), consoleOut),
name, type, encoding, codepage, nativeSignals, signalHandler);
strings.put(InfoCmp.Capability.key_mouse, "\\E[M");

// Start input pump thread
resume();
if (!paused) {
resume();
}
}

@Override
Expand Down
25 changes: 20 additions & 5 deletions terminal/src/main/java/org/jline/terminal/TerminalBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ public static TerminalBuilder builder() {
private Size size;
private boolean nativeSignals = false;
private Terminal.SignalHandler signalHandler = Terminal.SignalHandler.SIG_DFL;
private boolean paused = false;

private TerminalBuilder() {
}
Expand Down Expand Up @@ -229,6 +230,20 @@ public TerminalBuilder signalHandler(Terminal.SignalHandler signalHandler) {
return this;
}

/**
* Initial paused state of the terminal (defaults to false).
* By default, the terminal is started, but in some cases,
* one might want to make sure the input stream is not consumed
* before needed, in which case the terminal needs to be created
* in a paused state.
* @param paused
* @see Terminal#pause()
*/
public TerminalBuilder paused(boolean paused) {
this.paused = paused;
return this;
}

public Terminal build() throws IOException {
Terminal terminal = doBuild();
Log.debug(() -> "Using terminal " + terminal.getClass().getSimpleName());
Expand Down Expand Up @@ -311,15 +326,15 @@ private Terminal doBuild() throws IOException {
}
if (jna) {
try {
return load(JnaSupport.class).winSysTerminal(name, type, ansiPassThrough, encoding, codepage, nativeSignals, signalHandler);
return load(JnaSupport.class).winSysTerminal(name, type, ansiPassThrough, encoding, codepage, nativeSignals, signalHandler, paused);
} catch (Throwable t) {
Log.debug("Error creating JNA based terminal: ", t.getMessage(), t);
exception.addSuppressed(t);
}
}
if (jansi) {
try {
return load(JansiSupport.class).winSysTerminal(name, type, ansiPassThrough, encoding, codepage, nativeSignals, signalHandler);
return load(JansiSupport.class).winSysTerminal(name, type, ansiPassThrough, encoding, codepage, nativeSignals, signalHandler, paused);
} catch (Throwable t) {
Log.debug("Error creating JANSI based terminal: ", t.getMessage(), t);
exception.addSuppressed(t);
Expand Down Expand Up @@ -386,20 +401,20 @@ private Terminal doBuild() throws IOException {
if (jna) {
try {
Pty pty = load(JnaSupport.class).open(attributes, size);
return new PosixPtyTerminal(name, type, pty, in, out, encoding, signalHandler);
return new PosixPtyTerminal(name, type, pty, in, out, encoding, signalHandler, paused);
} catch (Throwable t) {
Log.debug("Error creating JNA based terminal: ", t.getMessage(), t);
}
}
if (jansi) {
try {
Pty pty = load(JansiSupport.class).open(attributes, size);
return new PosixPtyTerminal(name, type, pty, in, out, encoding, signalHandler);
return new PosixPtyTerminal(name, type, pty, in, out, encoding, signalHandler, paused);
} catch (Throwable t) {
Log.debug("Error creating JANSI based terminal: ", t.getMessage(), t);
}
}
Terminal terminal = new ExternalTerminal(name, type, in, out, encoding, signalHandler);
Terminal terminal = new ExternalTerminal(name, type, in, out, encoding, signalHandler, paused);
if (attributes != null) {
terminal.setAttributes(attributes);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,20 @@ public ExternalTerminal(String name, String type,
OutputStream masterOutput,
Charset encoding,
SignalHandler signalHandler) throws IOException {
this(name, type, masterInput, masterOutput, encoding, signalHandler, false);
}

public ExternalTerminal(String name, String type,
InputStream masterInput,
OutputStream masterOutput,
Charset encoding,
SignalHandler signalHandler,
boolean paused) throws IOException {
super(name, type, masterOutput, encoding, signalHandler);
this.masterInput = masterInput;
resume();
if (!paused) {
resume();
}
}

public void close() throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ public PosixPtyTerminal(String name, String type, Pty pty, InputStream in, Outpu
}

public PosixPtyTerminal(String name, String type, Pty pty, InputStream in, OutputStream out, Charset encoding, SignalHandler signalHandler) throws IOException {
this(name, type, pty, in, out, encoding, signalHandler, false);
}

public PosixPtyTerminal(String name, String type, Pty pty, InputStream in, OutputStream out, Charset encoding, SignalHandler signalHandler, boolean paused) throws IOException {
super(name, type, pty, encoding, signalHandler);
this.in = Objects.requireNonNull(in);
this.out = Objects.requireNonNull(out);
Expand All @@ -54,7 +58,9 @@ public PosixPtyTerminal(String name, String type, Pty pty, InputStream in, Outpu
this.reader = NonBlocking.nonBlocking(name, input, encoding());
this.writer = new PrintWriter(new OutputStreamWriter(output, encoding()));
parseInfoCmp();
resume();
if (!paused) {
resume();
}
}

public InputStream input() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ public interface JansiSupport {

Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, Terminal.SignalHandler signalHandler) throws IOException;

Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused) throws IOException;

}
2 changes: 2 additions & 0 deletions terminal/src/main/java/org/jline/terminal/spi/JnaSupport.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ public interface JnaSupport {

Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, Terminal.SignalHandler signalHandler) throws IOException;

Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused) throws IOException;

}

0 comments on commit a67d60f

Please sign in to comment.