1/* 2 * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (C) 2000, 2001 Internet Software Consortium. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 * PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18/* $Id: keyboard.c,v 1.13 2007/06/19 23:47:18 tbox Exp $ */ 19 20#include <config.h> 21 22#include <sys/param.h> 23#include <sys/types.h> 24#include <sys/time.h> 25#include <sys/uio.h> 26 27#include <errno.h> 28#include <stdlib.h> 29#include <string.h> 30#include <termios.h> 31#include <unistd.h> 32#include <fcntl.h> 33 34#include <isc/keyboard.h> 35#include <isc/util.h> 36 37isc_result_t 38isc_keyboard_open(isc_keyboard_t *keyboard) { 39 int fd; 40 isc_result_t ret; 41 struct termios current_mode; 42 43 REQUIRE(keyboard != NULL); 44 45 fd = open("/dev/tty", O_RDONLY, 0); 46 if (fd < 0) 47 return (ISC_R_IOERROR); 48 49 keyboard->fd = fd; 50 51 if (tcgetattr(fd, &keyboard->saved_mode) < 0) { 52 ret = ISC_R_IOERROR; 53 goto errout; 54 } 55 56 current_mode = keyboard->saved_mode; 57 58 current_mode.c_iflag &= 59 ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); 60 current_mode.c_oflag &= ~OPOST; 61 current_mode.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); 62 current_mode.c_cflag &= ~(CSIZE|PARENB); 63 current_mode.c_cflag |= CS8; 64 65 current_mode.c_cc[VMIN] = 1; 66 current_mode.c_cc[VTIME] = 0; 67 if (tcsetattr(fd, TCSAFLUSH, ¤t_mode) < 0) { 68 ret = ISC_R_IOERROR; 69 goto errout; 70 } 71 72 keyboard->result = ISC_R_SUCCESS; 73 74 return (ISC_R_SUCCESS); 75 76 errout: 77 close (fd); 78 79 return (ret); 80} 81 82isc_result_t 83isc_keyboard_close(isc_keyboard_t *keyboard, unsigned int sleeptime) { 84 REQUIRE(keyboard != NULL); 85 86 if (sleeptime > 0 && keyboard->result != ISC_R_CANCELED) 87 (void)sleep(sleeptime); 88 89 (void)tcsetattr(keyboard->fd, TCSAFLUSH, &keyboard->saved_mode); 90 (void)close(keyboard->fd); 91 92 keyboard->fd = -1; 93 94 return (ISC_R_SUCCESS); 95} 96 97isc_result_t 98isc_keyboard_getchar(isc_keyboard_t *keyboard, unsigned char *cp) { 99 ssize_t cc; 100 unsigned char c; 101 cc_t *controlchars; 102 103 REQUIRE(keyboard != NULL); 104 REQUIRE(cp != NULL); 105 106 cc = read(keyboard->fd, &c, 1); 107 if (cc < 0) { 108 keyboard->result = ISC_R_IOERROR; 109 return (keyboard->result); 110 } 111 112 controlchars = keyboard->saved_mode.c_cc; 113 if (c == controlchars[VINTR] || c == controlchars[VQUIT]) { 114 keyboard->result = ISC_R_CANCELED; 115 return (keyboard->result); 116 } 117 118 *cp = c; 119 120 return (ISC_R_SUCCESS); 121} 122 123isc_boolean_t 124isc_keyboard_canceled(isc_keyboard_t *keyboard) { 125 return (ISC_TF(keyboard->result == ISC_R_CANCELED)); 126} 127