diff --git a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java index 6fbc5cb523..fb39bdb146 100644 --- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java +++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java @@ -59,6 +59,7 @@ import jdk.internal.misc.Signal.Handler; import jdk.internal.org.jline.keymap.KeyMap; import jdk.internal.org.jline.reader.Binding; import jdk.internal.org.jline.reader.EOFError; +import jdk.internal.org.jline.reader.EndOfFileException; import jdk.internal.org.jline.reader.History; import jdk.internal.org.jline.reader.LineReader; import jdk.internal.org.jline.reader.LineReader.Option; @@ -200,6 +201,8 @@ class ConsoleIOContext extends IOContext { return in.readLine(firstLinePrompt); } catch (UserInterruptException ex) { throw (InputInterruptedException) new InputInterruptedException().initCause(ex); + } catch (EndOfFileException ex) { + return null; } } @@ -1212,6 +1215,7 @@ class ConsoleIOContext extends IOContext { while ((r = input.read()) != (-1)) { processInputByte(r); } + slaveInput.close(); } catch (IOException ex) { throw new IllegalStateException(ex); } diff --git a/test/langtools/jdk/jshell/ReplToolTesting.java b/test/langtools/jdk/jshell/ReplToolTesting.java index f3f88fc590..5ef4dc2990 100644 --- a/test/langtools/jdk/jshell/ReplToolTesting.java +++ b/test/langtools/jdk/jshell/ReplToolTesting.java @@ -22,6 +22,7 @@ */ import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.util.ArrayList; @@ -126,6 +127,14 @@ public class ReplToolTesting { cmdin.setInput(s); } + public void closeCommandInput() { + try { + cmdin.close(); + } catch (IOException ex) { + throw new IllegalStateException(ex); + } + } + public final static Pattern idPattern = Pattern.compile("^\\s+(\\d+)"); public Consumer assertList() { return s -> { @@ -755,6 +764,8 @@ public class ReplToolTesting { class WaitingTestingInputStream extends TestingInputStream { + private boolean closed; + @Override synchronized void setInput(String s) { super.setInput(s); @@ -764,7 +775,7 @@ public class ReplToolTesting { synchronized void waitForInput() { boolean interrupted = false; try { - while (available() == 0) { + while (available() == 0 && !closed) { try { wait(); } catch (InterruptedException e) { @@ -790,6 +801,12 @@ public class ReplToolTesting { waitForInput(); return super.read(b, off, len); } + + @Override + public synchronized void close() throws IOException { + closed = true; + notify(); + } } class PromptedCommandOutputStream extends OutputStream { diff --git a/test/langtools/jdk/jshell/ToolBasicTest.java b/test/langtools/jdk/jshell/ToolBasicTest.java index 75ba06611b..12a3b6650f 100644 --- a/test/langtools/jdk/jshell/ToolBasicTest.java +++ b/test/langtools/jdk/jshell/ToolBasicTest.java @@ -130,6 +130,18 @@ public class ToolBasicTest extends ReplToolTesting { } } + public void testCtrlD() { + test(false, new String[]{"--no-startup"}, + a -> { + if (!a) { + closeCommandInput(); + } else { + throw new IllegalStateException(); + } + } + ); + } + private final Object lock = new Object(); private PrintWriter out; private boolean isStopped;