# HG changeset patch # User jlahoda # Date 1550657498 -3600 # Node ID 9a0fd1f82406dba89f3adb77cf8bc1f76db2c373 # Parent 31dde2f0ddf11798358dc6c562fe4ffc2aaa4a64 8218287: jshell tool: input behavior unstable after 12-ea+24 on Windows Summary: Ensure correct wrapping of input on Windows. Reviewed-by: rfield diff -r 31dde2f0ddf1 -r 9a0fd1f82406 src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractWindowsTerminal.java --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractWindowsTerminal.java Wed Feb 20 10:48:36 2019 +0100 +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractWindowsTerminal.java Wed Feb 20 11:11:38 2019 +0100 @@ -86,8 +86,8 @@ super(name, type, selectCharset(encoding, codepage), signalHandler); NonBlockingPumpReader reader = NonBlocking.nonBlockingPumpReader(); this.slaveInputPipe = reader.getWriter(); - this.reader = reader; this.input = inputStreamWrapper.apply(NonBlocking.nonBlockingStream(reader, encoding())); + this.reader = NonBlocking.nonBlocking(name, input, encoding()); this.writer = new PrintWriter(writer); this.output = new WriterOutputStream(writer, encoding()); parseInfoCmp(); diff -r 31dde2f0ddf1 -r 9a0fd1f82406 src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlocking.java --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlocking.java Wed Feb 20 10:48:36 2019 +0100 +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlocking.java Wed Feb 20 11:11:38 2019 +0100 @@ -123,9 +123,9 @@ } if (bytes.hasRemaining()) { if (isPeek) { - return bytes.get(bytes.position()); + return Byte.toUnsignedInt(bytes.get(bytes.position())); } else { - return bytes.get(); + return Byte.toUnsignedInt(bytes.get()); } } else { return READ_EXPIRED; diff -r 31dde2f0ddf1 -r 9a0fd1f82406 src/jdk.internal.le/windows/native/lible/Kernel32.cpp --- a/src/jdk.internal.le/windows/native/lible/Kernel32.cpp Wed Feb 20 10:48:36 2019 +0100 +++ b/src/jdk.internal.le/windows/native/lible/Kernel32.cpp Wed Feb 20 11:11:38 2019 +0100 @@ -460,7 +460,7 @@ HANDLE h = GetStdHandle((jint) env->GetLongField(in_hConsoleOutput, pointerValue)); INPUT_RECORD *buffer = new INPUT_RECORD[in_nLength]; DWORD numberOfEventsRead; - if (!ReadConsoleInput(h, buffer, in_nLength, &numberOfEventsRead)) { + if (!ReadConsoleInputW(h, buffer, in_nLength, &numberOfEventsRead)) { delete buffer; DWORD error = GetLastError(); jobject exc = env->NewObject(lastErrorExceptionClass, diff -r 31dde2f0ddf1 -r 9a0fd1f82406 test/jdk/jdk/internal/jline/AbstractWindowsTerminalTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/jdk/internal/jline/AbstractWindowsTerminalTest.java Wed Feb 20 11:11:38 2019 +0100 @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8218287 + * @summary Verify the wrapper input stream is used when using Terminal.reader() + * @modules jdk.internal.le/jdk.internal.org.jline.terminal + * jdk.internal.le/jdk.internal.org.jline.terminal.impl + * jdk.internal.le/jdk.internal.org.jline.utils + */ + +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Function; + +import jdk.internal.org.jline.terminal.Size; +import jdk.internal.org.jline.terminal.Terminal.SignalHandler; +import jdk.internal.org.jline.terminal.impl.AbstractWindowsTerminal; + + +public class AbstractWindowsTerminalTest { + public static void main(String... args) throws IOException { + new AbstractWindowsTerminalTest().run(); + } + + void run() throws IOException { + var out = new StringWriter(); + AtomicBoolean called = new AtomicBoolean(); + Function isWrapper = is -> new InputStream() { + @Override + public int read() throws IOException { + called.set(true); + return is.read(); + } + }; + var t = new AbstractWindowsTerminal(out, "test", "vt100", null, -1, false, SignalHandler.SIG_DFL, isWrapper) { + @Override + protected int getConsoleOutputCP() { + throw new UnsupportedOperationException("unexpected."); + } + + @Override + protected int getConsoleMode() { + return -1; + } + + @Override + protected void setConsoleMode(int mode) { + throw new UnsupportedOperationException("unexpected."); + } + + @Override + protected boolean processConsoleInput() throws IOException { + throw new UnsupportedOperationException("unexpected."); + } + + @Override + public Size getSize() { + throw new UnsupportedOperationException("unexpected."); + } + }; + t.processInputChar(' '); + if (t.reader().read() != ' ') { + throw new AssertionError("Unexpected input!"); + } + if (!called.get()) { + throw new AssertionError("The wrapper was not called!"); + } + } +}