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 }