8202105: Console echo is disabled when exiting jshell
Summary: Preserving original terminal echo state when Console.readPassword finishes.
Reviewed-by: sherman, martin
--- a/src/java.base/share/classes/java/io/Console.java Mon Apr 30 12:19:55 2018 +0200
+++ b/src/java.base/share/classes/java/io/Console.java Mon Apr 30 15:03:08 2018 +0200
@@ -311,9 +311,9 @@
char[] passwd = null;
synchronized (writeLock) {
synchronized(readLock) {
- boolean echoWasOn;
+ installShutdownHook();
try {
- echoWasOn = echo(false);
+ restoreEcho = echo(false);
} catch (IOException x) {
throw new IOError(x);
}
@@ -326,7 +326,8 @@
ioe = new IOError(x);
} finally {
try {
- echo(echoWasOn);
+ if (restoreEcho)
+ restoreEcho = echo(true);
} catch (IOException x) {
if (ioe == null)
ioe = new IOError(x);
@@ -342,6 +343,31 @@
return passwd;
}
+ private void installShutdownHook() {
+ if (shutdownHookInstalled)
+ return;
+ try {
+ // Add a shutdown hook to restore console's echo state should
+ // it be necessary.
+ SharedSecrets.getJavaLangAccess()
+ .registerShutdownHook(0 /* shutdown hook invocation order */,
+ false /* only register if shutdown is not in progress */,
+ new Runnable() {
+ public void run() {
+ try {
+ if (restoreEcho) {
+ echo(true);
+ }
+ } catch (IOException x) { }
+ }
+ });
+ } catch (IllegalStateException e) {
+ // shutdown is already in progress and readPassword is first used
+ // by a shutdown hook
+ }
+ shutdownHookInstalled = true;
+ }
+
/**
* Reads a password or passphrase from the console with echoing disabled
*
@@ -372,6 +398,8 @@
private Formatter formatter;
private Charset cs;
private char[] rcb;
+ private boolean restoreEcho;
+ private boolean shutdownHookInstalled;
private static native String encoding();
/*
* Sets the console echo status to {@code on} and returns the previous
@@ -381,12 +409,6 @@
* @return true if the previous console echo status is on
*/
private static native boolean echo(boolean on) throws IOException;
- /*
- * Returns the current console echo on/off status.
- * @return true if the cosole echo is on
- */
- private static native boolean echo0() throws IOException;
- private static boolean echoOn;
private char[] readline(boolean zeroOut) throws IOException {
int len = reader.read(rcb, 0, rcb.length);
@@ -531,25 +553,6 @@
// Set up JavaIOAccess in SharedSecrets
static {
- try {
- // Add a shutdown hook to restore console's echo state should
- // it be necessary.
- SharedSecrets.getJavaLangAccess()
- .registerShutdownHook(0 /* shutdown hook invocation order */,
- false /* only register if shutdown is not in progress */,
- new Runnable() {
- public void run() {
- try {
- if (cons != null)
- echo(echoOn);
- } catch (IOException x) { }
- }
- });
- } catch (IllegalStateException e) {
- // shutdown is already in progress and console is first used
- // by a shutdown hook
- }
-
SharedSecrets.setJavaIOAccess(new JavaIOAccess() {
public Console console() {
if (istty()) {
@@ -591,10 +594,5 @@
readLock,
cs));
rcb = new char[1024];
- try {
- echoOn = echo0();
- } catch (IOException x) {
- echoOn = true;
- }
}
}
--- a/src/java.base/unix/native/libjava/Console_md.c Mon Apr 30 12:19:55 2018 +0200
+++ b/src/java.base/unix/native/libjava/Console_md.c Mon Apr 30 15:03:08 2018 +0200
@@ -67,14 +67,3 @@
}
return old;
}
-
-JNIEXPORT jboolean JNICALL
-Java_java_io_Console_echo0(JNIEnv *env, jclass cls) {
- struct termios tio;
- int tty = fileno(stdin);
- if (tcgetattr(tty, &tio) == -1) {
- JNU_ThrowIOExceptionWithLastError(env, "tcgetattr failed");
- return JNI_TRUE;
- }
- return (tio.c_lflag & ECHO) != 0;
-}
--- a/src/java.base/windows/native/libjava/Console_md.c Mon Apr 30 12:19:55 2018 +0200
+++ b/src/java.base/windows/native/libjava/Console_md.c Mon Apr 30 15:03:08 2018 +0200
@@ -82,14 +82,3 @@
}
return old;
}
-
-JNIEXPORT jboolean JNICALL
-Java_java_io_Console_echo0(JNIEnv *env, jclass cls)
-{
- DWORD fdwMode;
- if (! GetConsoleMode(hStdIn, &fdwMode)) {
- JNU_ThrowIOExceptionWithLastError(env, "GetConsoleMode failed");
- return JNI_TRUE;
- }
- return (fdwMode & ENABLE_ECHO_INPUT) != 0;
-}