Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/io/Console.java
38829 views
1
/*
2
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package java.io;
27
28
import java.util.*;
29
import java.nio.charset.Charset;
30
import sun.nio.cs.StreamDecoder;
31
import sun.nio.cs.StreamEncoder;
32
33
/**
34
* Methods to access the character-based console device, if any, associated
35
* with the current Java virtual machine.
36
*
37
* <p> Whether a virtual machine has a console is dependent upon the
38
* underlying platform and also upon the manner in which the virtual
39
* machine is invoked. If the virtual machine is started from an
40
* interactive command line without redirecting the standard input and
41
* output streams then its console will exist and will typically be
42
* connected to the keyboard and display from which the virtual machine
43
* was launched. If the virtual machine is started automatically, for
44
* example by a background job scheduler, then it will typically not
45
* have a console.
46
* <p>
47
* If this virtual machine has a console then it is represented by a
48
* unique instance of this class which can be obtained by invoking the
49
* {@link java.lang.System#console()} method. If no console device is
50
* available then an invocation of that method will return <tt>null</tt>.
51
* <p>
52
* Read and write operations are synchronized to guarantee the atomic
53
* completion of critical operations; therefore invoking methods
54
* {@link #readLine()}, {@link #readPassword()}, {@link #format format()},
55
* {@link #printf printf()} as well as the read, format and write operations
56
* on the objects returned by {@link #reader()} and {@link #writer()} may
57
* block in multithreaded scenarios.
58
* <p>
59
* Invoking <tt>close()</tt> on the objects returned by the {@link #reader()}
60
* and the {@link #writer()} will not close the underlying stream of those
61
* objects.
62
* <p>
63
* The console-read methods return <tt>null</tt> when the end of the
64
* console input stream is reached, for example by typing control-D on
65
* Unix or control-Z on Windows. Subsequent read operations will succeed
66
* if additional characters are later entered on the console's input
67
* device.
68
* <p>
69
* Unless otherwise specified, passing a <tt>null</tt> argument to any method
70
* in this class will cause a {@link NullPointerException} to be thrown.
71
* <p>
72
* <b>Security note:</b>
73
* If an application needs to read a password or other secure data, it should
74
* use {@link #readPassword()} or {@link #readPassword(String, Object...)} and
75
* manually zero the returned character array after processing to minimize the
76
* lifetime of sensitive data in memory.
77
*
78
* <blockquote><pre>{@code
79
* Console cons;
80
* char[] passwd;
81
* if ((cons = System.console()) != null &&
82
* (passwd = cons.readPassword("[%s]", "Password:")) != null) {
83
* ...
84
* java.util.Arrays.fill(passwd, ' ');
85
* }
86
* }</pre></blockquote>
87
*
88
* @author Xueming Shen
89
* @since 1.6
90
*/
91
92
public final class Console implements Flushable
93
{
94
/**
95
* Retrieves the unique {@link java.io.PrintWriter PrintWriter} object
96
* associated with this console.
97
*
98
* @return The printwriter associated with this console
99
*/
100
public PrintWriter writer() {
101
return pw;
102
}
103
104
/**
105
* Retrieves the unique {@link java.io.Reader Reader} object associated
106
* with this console.
107
* <p>
108
* This method is intended to be used by sophisticated applications, for
109
* example, a {@link java.util.Scanner} object which utilizes the rich
110
* parsing/scanning functionality provided by the <tt>Scanner</tt>:
111
* <blockquote><pre>
112
* Console con = System.console();
113
* if (con != null) {
114
* Scanner sc = new Scanner(con.reader());
115
* ...
116
* }
117
* </pre></blockquote>
118
* <p>
119
* For simple applications requiring only line-oriented reading, use
120
* <tt>{@link #readLine}</tt>.
121
* <p>
122
* The bulk read operations {@link java.io.Reader#read(char[]) read(char[]) },
123
* {@link java.io.Reader#read(char[], int, int) read(char[], int, int) } and
124
* {@link java.io.Reader#read(java.nio.CharBuffer) read(java.nio.CharBuffer)}
125
* on the returned object will not read in characters beyond the line
126
* bound for each invocation, even if the destination buffer has space for
127
* more characters. The {@code Reader}'s {@code read} methods may block if a
128
* line bound has not been entered or reached on the console's input device.
129
* A line bound is considered to be any one of a line feed (<tt>'\n'</tt>),
130
* a carriage return (<tt>'\r'</tt>), a carriage return followed immediately
131
* by a linefeed, or an end of stream.
132
*
133
* @return The reader associated with this console
134
*/
135
public Reader reader() {
136
return reader;
137
}
138
139
/**
140
* Writes a formatted string to this console's output stream using
141
* the specified format string and arguments.
142
*
143
* @param fmt
144
* A format string as described in <a
145
* href="../util/Formatter.html#syntax">Format string syntax</a>
146
*
147
* @param args
148
* Arguments referenced by the format specifiers in the format
149
* string. If there are more arguments than format specifiers, the
150
* extra arguments are ignored. The number of arguments is
151
* variable and may be zero. The maximum number of arguments is
152
* limited by the maximum dimension of a Java array as defined by
153
* <cite>The Java&trade; Virtual Machine Specification</cite>.
154
* The behaviour on a
155
* <tt>null</tt> argument depends on the <a
156
* href="../util/Formatter.html#syntax">conversion</a>.
157
*
158
* @throws IllegalFormatException
159
* If a format string contains an illegal syntax, a format
160
* specifier that is incompatible with the given arguments,
161
* insufficient arguments given the format string, or other
162
* illegal conditions. For specification of all possible
163
* formatting errors, see the <a
164
* href="../util/Formatter.html#detail">Details</a> section
165
* of the formatter class specification.
166
*
167
* @return This console
168
*/
169
public Console format(String fmt, Object ...args) {
170
formatter.format(fmt, args).flush();
171
return this;
172
}
173
174
/**
175
* A convenience method to write a formatted string to this console's
176
* output stream using the specified format string and arguments.
177
*
178
* <p> An invocation of this method of the form <tt>con.printf(format,
179
* args)</tt> behaves in exactly the same way as the invocation of
180
* <pre>con.format(format, args)</pre>.
181
*
182
* @param format
183
* A format string as described in <a
184
* href="../util/Formatter.html#syntax">Format string syntax</a>.
185
*
186
* @param args
187
* Arguments referenced by the format specifiers in the format
188
* string. If there are more arguments than format specifiers, the
189
* extra arguments are ignored. The number of arguments is
190
* variable and may be zero. The maximum number of arguments is
191
* limited by the maximum dimension of a Java array as defined by
192
* <cite>The Java&trade; Virtual Machine Specification</cite>.
193
* The behaviour on a
194
* <tt>null</tt> argument depends on the <a
195
* href="../util/Formatter.html#syntax">conversion</a>.
196
*
197
* @throws IllegalFormatException
198
* If a format string contains an illegal syntax, a format
199
* specifier that is incompatible with the given arguments,
200
* insufficient arguments given the format string, or other
201
* illegal conditions. For specification of all possible
202
* formatting errors, see the <a
203
* href="../util/Formatter.html#detail">Details</a> section of the
204
* formatter class specification.
205
*
206
* @return This console
207
*/
208
public Console printf(String format, Object ... args) {
209
return format(format, args);
210
}
211
212
/**
213
* Provides a formatted prompt, then reads a single line of text from the
214
* console.
215
*
216
* @param fmt
217
* A format string as described in <a
218
* href="../util/Formatter.html#syntax">Format string syntax</a>.
219
*
220
* @param args
221
* Arguments referenced by the format specifiers in the format
222
* string. If there are more arguments than format specifiers, the
223
* extra arguments are ignored. The maximum number of arguments is
224
* limited by the maximum dimension of a Java array as defined by
225
* <cite>The Java&trade; Virtual Machine Specification</cite>.
226
*
227
* @throws IllegalFormatException
228
* If a format string contains an illegal syntax, a format
229
* specifier that is incompatible with the given arguments,
230
* insufficient arguments given the format string, or other
231
* illegal conditions. For specification of all possible
232
* formatting errors, see the <a
233
* href="../util/Formatter.html#detail">Details</a> section
234
* of the formatter class specification.
235
*
236
* @throws IOError
237
* If an I/O error occurs.
238
*
239
* @return A string containing the line read from the console, not
240
* including any line-termination characters, or <tt>null</tt>
241
* if an end of stream has been reached.
242
*/
243
public String readLine(String fmt, Object ... args) {
244
String line = null;
245
synchronized (writeLock) {
246
synchronized(readLock) {
247
if (fmt.length() != 0)
248
pw.format(fmt, args);
249
try {
250
char[] ca = readline(false);
251
if (ca != null)
252
line = new String(ca);
253
} catch (IOException x) {
254
throw new IOError(x);
255
}
256
}
257
}
258
return line;
259
}
260
261
/**
262
* Reads a single line of text from the console.
263
*
264
* @throws IOError
265
* If an I/O error occurs.
266
*
267
* @return A string containing the line read from the console, not
268
* including any line-termination characters, or <tt>null</tt>
269
* if an end of stream has been reached.
270
*/
271
public String readLine() {
272
return readLine("");
273
}
274
275
/**
276
* Provides a formatted prompt, then reads a password or passphrase from
277
* the console with echoing disabled.
278
*
279
* @param fmt
280
* A format string as described in <a
281
* href="../util/Formatter.html#syntax">Format string syntax</a>
282
* for the prompt text.
283
*
284
* @param args
285
* Arguments referenced by the format specifiers in the format
286
* string. If there are more arguments than format specifiers, the
287
* extra arguments are ignored. The maximum number of arguments is
288
* limited by the maximum dimension of a Java array as defined by
289
* <cite>The Java&trade; Virtual Machine Specification</cite>.
290
*
291
* @throws IllegalFormatException
292
* If a format string contains an illegal syntax, a format
293
* specifier that is incompatible with the given arguments,
294
* insufficient arguments given the format string, or other
295
* illegal conditions. For specification of all possible
296
* formatting errors, see the <a
297
* href="../util/Formatter.html#detail">Details</a>
298
* section of the formatter class specification.
299
*
300
* @throws IOError
301
* If an I/O error occurs.
302
*
303
* @return A character array containing the password or passphrase read
304
* from the console, not including any line-termination characters,
305
* or <tt>null</tt> if an end of stream has been reached.
306
*/
307
public char[] readPassword(String fmt, Object ... args) {
308
char[] passwd = null;
309
synchronized (writeLock) {
310
synchronized(readLock) {
311
try {
312
echoOff = echo(false);
313
} catch (IOException x) {
314
throw new IOError(x);
315
}
316
IOError ioe = null;
317
try {
318
if (fmt.length() != 0)
319
pw.format(fmt, args);
320
passwd = readline(true);
321
} catch (IOException x) {
322
ioe = new IOError(x);
323
} finally {
324
try {
325
echoOff = echo(true);
326
} catch (IOException x) {
327
if (ioe == null)
328
ioe = new IOError(x);
329
else
330
ioe.addSuppressed(x);
331
}
332
if (ioe != null)
333
throw ioe;
334
}
335
pw.println();
336
}
337
}
338
return passwd;
339
}
340
341
/**
342
* Reads a password or passphrase from the console with echoing disabled
343
*
344
* @throws IOError
345
* If an I/O error occurs.
346
*
347
* @return A character array containing the password or passphrase read
348
* from the console, not including any line-termination characters,
349
* or <tt>null</tt> if an end of stream has been reached.
350
*/
351
public char[] readPassword() {
352
return readPassword("");
353
}
354
355
/**
356
* Flushes the console and forces any buffered output to be written
357
* immediately .
358
*/
359
public void flush() {
360
pw.flush();
361
}
362
363
private Object readLock;
364
private Object writeLock;
365
private Reader reader;
366
private Writer out;
367
private PrintWriter pw;
368
private Formatter formatter;
369
private Charset cs;
370
private char[] rcb;
371
private static native String encoding();
372
private static native boolean echo(boolean on) throws IOException;
373
private static boolean echoOff;
374
375
private char[] readline(boolean zeroOut) throws IOException {
376
int len = reader.read(rcb, 0, rcb.length);
377
if (len < 0)
378
return null; //EOL
379
if (rcb[len-1] == '\r')
380
len--; //remove CR at end;
381
else if (rcb[len-1] == '\n') {
382
len--; //remove LF at end;
383
if (len > 0 && rcb[len-1] == '\r')
384
len--; //remove the CR, if there is one
385
}
386
char[] b = new char[len];
387
if (len > 0) {
388
System.arraycopy(rcb, 0, b, 0, len);
389
if (zeroOut) {
390
Arrays.fill(rcb, 0, len, ' ');
391
}
392
}
393
return b;
394
}
395
396
private char[] grow() {
397
assert Thread.holdsLock(readLock);
398
char[] t = new char[rcb.length * 2];
399
System.arraycopy(rcb, 0, t, 0, rcb.length);
400
rcb = t;
401
return rcb;
402
}
403
404
class LineReader extends Reader {
405
private Reader in;
406
private char[] cb;
407
private int nChars, nextChar;
408
boolean leftoverLF;
409
LineReader(Reader in) {
410
this.in = in;
411
cb = new char[1024];
412
nextChar = nChars = 0;
413
leftoverLF = false;
414
}
415
public void close () {}
416
public boolean ready() throws IOException {
417
//in.ready synchronizes on readLock already
418
return in.ready();
419
}
420
421
public int read(char cbuf[], int offset, int length)
422
throws IOException
423
{
424
int off = offset;
425
int end = offset + length;
426
if (offset < 0 || offset > cbuf.length || length < 0 ||
427
end < 0 || end > cbuf.length) {
428
throw new IndexOutOfBoundsException();
429
}
430
synchronized(readLock) {
431
boolean eof = false;
432
char c = 0;
433
for (;;) {
434
if (nextChar >= nChars) { //fill
435
int n = 0;
436
do {
437
n = in.read(cb, 0, cb.length);
438
} while (n == 0);
439
if (n > 0) {
440
nChars = n;
441
nextChar = 0;
442
if (n < cb.length &&
443
cb[n-1] != '\n' && cb[n-1] != '\r') {
444
/*
445
* we're in canonical mode so each "fill" should
446
* come back with an eol. if there no lf or nl at
447
* the end of returned bytes we reached an eof.
448
*/
449
eof = true;
450
}
451
} else { /*EOF*/
452
if (off - offset == 0)
453
return -1;
454
return off - offset;
455
}
456
}
457
if (leftoverLF && cbuf == rcb && cb[nextChar] == '\n') {
458
/*
459
* if invoked by our readline, skip the leftover, otherwise
460
* return the LF.
461
*/
462
nextChar++;
463
}
464
leftoverLF = false;
465
while (nextChar < nChars) {
466
c = cbuf[off++] = cb[nextChar];
467
cb[nextChar++] = 0;
468
if (c == '\n') {
469
return off - offset;
470
} else if (c == '\r') {
471
if (off == end) {
472
/* no space left even the next is LF, so return
473
* whatever we have if the invoker is not our
474
* readLine()
475
*/
476
if (cbuf == rcb) {
477
cbuf = grow();
478
end = cbuf.length;
479
} else {
480
leftoverLF = true;
481
return off - offset;
482
}
483
}
484
if (nextChar == nChars && in.ready()) {
485
/*
486
* we have a CR and we reached the end of
487
* the read in buffer, fill to make sure we
488
* don't miss a LF, if there is one, it's possible
489
* that it got cut off during last round reading
490
* simply because the read in buffer was full.
491
*/
492
nChars = in.read(cb, 0, cb.length);
493
nextChar = 0;
494
}
495
if (nextChar < nChars && cb[nextChar] == '\n') {
496
cbuf[off++] = '\n';
497
nextChar++;
498
}
499
return off - offset;
500
} else if (off == end) {
501
if (cbuf == rcb) {
502
cbuf = grow();
503
end = cbuf.length;
504
} else {
505
return off - offset;
506
}
507
}
508
}
509
if (eof)
510
return off - offset;
511
}
512
}
513
}
514
}
515
516
// Set up JavaIOAccess in SharedSecrets
517
static {
518
try {
519
// Add a shutdown hook to restore console's echo state should
520
// it be necessary.
521
sun.misc.SharedSecrets.getJavaLangAccess()
522
.registerShutdownHook(0 /* shutdown hook invocation order */,
523
false /* only register if shutdown is not in progress */,
524
new Runnable() {
525
public void run() {
526
try {
527
if (echoOff) {
528
echo(true);
529
}
530
} catch (IOException x) { }
531
}
532
});
533
} catch (IllegalStateException e) {
534
// shutdown is already in progress and console is first used
535
// by a shutdown hook
536
}
537
538
sun.misc.SharedSecrets.setJavaIOAccess(new sun.misc.JavaIOAccess() {
539
public Console console() {
540
if (istty()) {
541
if (cons == null)
542
cons = new Console();
543
return cons;
544
}
545
return null;
546
}
547
548
public Charset charset() {
549
// This method is called in sun.security.util.Password,
550
// cons already exists when this method is called
551
return cons.cs;
552
}
553
});
554
}
555
private static Console cons;
556
private native static boolean istty();
557
private Console() {
558
readLock = new Object();
559
writeLock = new Object();
560
String csname = encoding();
561
if (csname != null) {
562
try {
563
cs = Charset.forName(csname);
564
} catch (Exception x) {}
565
}
566
if (cs == null)
567
cs = Charset.defaultCharset();
568
out = StreamEncoder.forOutputStreamWriter(
569
new FileOutputStream(FileDescriptor.out),
570
writeLock,
571
cs);
572
pw = new PrintWriter(out, true) { public void close() {} };
573
formatter = new Formatter(out);
574
reader = new LineReader(StreamDecoder.forInputStreamReader(
575
new FileInputStream(FileDescriptor.in),
576
readLock,
577
cs));
578
rcb = new char[1024];
579
}
580
}
581
582