Skip to content

Commit f8633eb

Browse files
committed
8358552: EndOfFileException in System.in.read() and IO.readln() etc. in JShell
1 parent 2b94b70 commit f8633eb

File tree

3 files changed

+34
-2
lines changed

3 files changed

+34
-2
lines changed

src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1041,6 +1041,8 @@ private synchronized String doReadUserLine(String prompt, Character mask) throws
10411041
return in.readLine(prompt.replace("%", "%%"), mask);
10421042
} catch (UserInterruptException ex) {
10431043
throw new InterruptedIOException();
1044+
} catch (EndOfFileException ex) {
1045+
return null; // Signal that Ctrl+D or similar happened
10441046
} finally {
10451047
in.setParser(prevParser);
10461048
in.setHistory(prevHistory);
@@ -1051,7 +1053,11 @@ private synchronized String doReadUserLine(String prompt, Character mask) throws
10511053

10521054
public char[] readPassword(String prompt) throws IOException {
10531055
//TODO: correct behavior w.r.t. pre-read stuff?
1054-
return doReadUserLine(prompt, '\0').toCharArray();
1056+
String line = doReadUserLine(prompt, '\0');
1057+
if (line == null) {
1058+
throw new UserInterruptException("");
1059+
}
1060+
return line.toCharArray();
10551061
}
10561062

10571063
@Override

test/langtools/jdk/jshell/InputUITest.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
/*
2525
* @test
26-
* @bug 8356165
26+
* @bug 8356165 8358552
2727
* @summary Check user input works properly
2828
* @modules
2929
* jdk.compiler/com.sun.tools.javac.api
@@ -38,6 +38,7 @@
3838
* @run testng/othervm -Dstderr.encoding=UTF-8 -Dstdin.encoding=UTF-8 -Dstdout.encoding=UTF-8 InputUITest
3939
*/
4040

41+
import java.util.Map;
4142
import java.util.function.Function;
4243
import org.testng.annotations.Test;
4344

@@ -67,4 +68,21 @@ public void testUserInputWithSurrogates() throws Exception {
6768
}, false);
6869
}
6970

71+
public void testCloseInputSinkWhileReadingUserInputSimulatingCtrlD() throws Exception {
72+
var snippets = Map.of(
73+
"System.in.read()", " ==> 110",
74+
"System.console().reader().read()", " ==> 110",
75+
"System.console().readLine()", " ==> null",
76+
"System.console().readPassword()", " ==> null",
77+
"IO.readln()", " ==> \"null\""
78+
// TODO , "System.in.readAllBytes()", " ==> " // ... hangs forever
79+
);
80+
for (var snippet : snippets.entrySet()) {
81+
doRunTest((inputSink, out) -> {
82+
inputSink.write(snippet.getKey() + "\n");
83+
inputSink.close(); // Does not work: inputSink.write("\u0004"); // CTRL + D
84+
waitOutput(out, patternQuote(snippet.getValue()), patternQuote("EndOfFileException"));
85+
}, false);
86+
}
87+
}
7088
}

test/langtools/jdk/jshell/UITesting.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,19 @@ protected void doRunTest(Test test, boolean setUserInput) throws Exception {
106106
});
107107

108108
Writer inputSink = new OutputStreamWriter(input.createOutput(), StandardCharsets.UTF_8) {
109+
boolean closed = false;
109110
@Override
110111
public void write(String str) throws IOException {
112+
if (closed) return; // prevents exception thrown due to closed writer
111113
super.write(str);
112114
flush();
113115
}
116+
117+
@Override
118+
public void close() throws IOException {
119+
super.close();
120+
closed = true;
121+
}
114122
};
115123

116124
runner.start();

0 commit comments

Comments
 (0)