1 /*
2 * Copyright (c) 2002-2012, the original author or authors.
3 *
4 * This software is distributable under the BSD license. See the terms of the
5 * BSD license in the documentation provided with this software.
6 *
7 * http://www.opensource.org/licenses/bsd-license.php
8 */
9 package jline;
10
11 import jline.internal.Log;
12 import jline.internal.TerminalLineSettings;
13
14 /**
15 * Terminal that is used for unix platforms. Terminal initialization
16 * is handled by issuing the <em>stty</em> command against the
17 * <em>/dev/tty</em> file to disable character echoing and enable
18 * character input. All known unix systems (including
19 * Linux and Macintosh OS X) support the <em>stty</em>), so this
20 * implementation should work for an reasonable POSIX system.
21 *
22 * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
23 * @author <a href="mailto:dwkemp@gmail.com">Dale Kemp</a>
24 * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
25 * @author <a href="mailto:jbonofre@apache.org">Jean-Baptiste Onofré</a>
26 * @since 2.0
27 */
28 public class UnixTerminal
29 extends TerminalSupport
30 {
31 private final TerminalLineSettings settings = new TerminalLineSettings();
32
33 public UnixTerminal() throws Exception {
34 super(true);
35 }
36
37 protected TerminalLineSettings getSettings() {
38 return settings;
39 }
40
41 /**
42 * Remove line-buffered input by invoking "stty -icanon min 1"
43 * against the current terminal.
44 */
45 @Override
46 public void init() throws Exception {
47 super.init();
48
49 setAnsiSupported(true);
50
51 // Set the console to be character-buffered instead of line-buffered.
52 // Make sure we're distinguishing carriage return from newline.
53 // Allow ctrl-s keypress to be used (as forward search)
54 settings.set("-icanon min 1 -icrnl -inlcr -ixon");
55 settings.set("dsusp undef");
56
57 setEchoEnabled(false);
58 }
59
60 /**
61 * Restore the original terminal configuration, which can be used when
62 * shutting down the console reader. The ConsoleReader cannot be
63 * used after calling this method.
64 */
65 @Override
66 public void restore() throws Exception {
67 settings.restore();
68 super.restore();
69 }
70
71 /**
72 * Returns the value of <tt>stty columns</tt> param.
73 */
74 @Override
75 public int getWidth() {
76 int w = settings.getProperty("columns");
77 return w < 1 ? DEFAULT_WIDTH : w;
78 }
79
80 /**
81 * Returns the value of <tt>stty rows>/tt> param.
82 */
83 @Override
84 public int getHeight() {
85 int h = settings.getProperty("rows");
86 return h < 1 ? DEFAULT_HEIGHT : h;
87 }
88
89 @Override
90 public synchronized void setEchoEnabled(final boolean enabled) {
91 try {
92 if (enabled) {
93 settings.set("echo");
94 }
95 else {
96 settings.set("-echo");
97 }
98 super.setEchoEnabled(enabled);
99 }
100 catch (Exception e) {
101 if (e instanceof InterruptedException) {
102 Thread.currentThread().interrupt();
103 }
104 Log.error("Failed to ", (enabled ? "enable" : "disable"), " echo", e);
105 }
106 }
107
108 public void disableInterruptCharacter()
109 {
110 try {
111 settings.set("intr undef");
112 }
113 catch (Exception e) {
114 if (e instanceof InterruptedException) {
115 Thread.currentThread().interrupt();
116 }
117 Log.error("Failed to disable interrupt character", e);
118 }
119 }
120
121 public void enableInterruptCharacter()
122 {
123 try {
124 settings.set("intr ^C");
125 }
126 catch (Exception e) {
127 if (e instanceof InterruptedException) {
128 Thread.currentThread().interrupt();
129 }
130 Log.error("Failed to enable interrupt character", e);
131 }
132 }
133 }