8202105: Console echo is disabled when exiting jshell

Preserving original terminal echo state when Console.readPassword finishes.

Reviewed-by: sherman, martin
This commit is contained in:
Jan Lahoda 2018-04-30 15:03:08 +02:00
parent b9490e5760
commit f7afa8ff53
3 changed files with 31 additions and 55 deletions

View file

@ -311,9 +311,9 @@ public final class Console implements Flushable
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 @@ public final class Console implements Flushable
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 @@ public final class Console implements Flushable
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 @@ public final class Console implements Flushable
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 @@ public final class Console implements Flushable
* @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 @@ public final class Console implements Flushable
// 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 @@ public final class Console implements Flushable
readLock,
cs));
rcb = new char[1024];
try {
echoOn = echo0();
} catch (IOException x) {
echoOn = true;
}
}
}

View file

@ -67,14 +67,3 @@ Java_java_io_Console_echo(JNIEnv *env,
}
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;
}

View file

@ -82,14 +82,3 @@ Java_java_io_Console_echo(JNIEnv *env, jclass cls, jboolean on)
}
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;
}