1290001Sglebius/* 2290001Sglebius * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") 3290001Sglebius * Copyright (C) 2000, 2001 Internet Software Consortium. 4290001Sglebius * 5290001Sglebius * Permission to use, copy, modify, and/or distribute this software for any 6290001Sglebius * purpose with or without fee is hereby granted, provided that the above 7290001Sglebius * copyright notice and this permission notice appear in all copies. 8290001Sglebius * 9290001Sglebius * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10290001Sglebius * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11290001Sglebius * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12290001Sglebius * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13290001Sglebius * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14290001Sglebius * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15290001Sglebius * PERFORMANCE OF THIS SOFTWARE. 16290001Sglebius */ 17290001Sglebius 18290001Sglebius/* $Id: keyboard.c,v 1.13 2007/06/19 23:47:18 tbox Exp $ */ 19290001Sglebius 20290001Sglebius#include <config.h> 21290001Sglebius 22290001Sglebius#include <sys/param.h> 23290001Sglebius#include <sys/types.h> 24290001Sglebius#include <sys/time.h> 25290001Sglebius#include <sys/uio.h> 26290001Sglebius 27290001Sglebius#include <errno.h> 28290001Sglebius#include <stdlib.h> 29290001Sglebius#include <string.h> 30290001Sglebius#include <termios.h> 31290001Sglebius#include <unistd.h> 32290001Sglebius#include <fcntl.h> 33290001Sglebius 34290001Sglebius#include <isc/keyboard.h> 35290001Sglebius#include <isc/util.h> 36290001Sglebius 37290001Sglebiusisc_result_t 38290001Sglebiusisc_keyboard_open(isc_keyboard_t *keyboard) { 39290001Sglebius int fd; 40290001Sglebius isc_result_t ret; 41290001Sglebius struct termios current_mode; 42290001Sglebius 43290001Sglebius REQUIRE(keyboard != NULL); 44290001Sglebius 45290001Sglebius fd = open("/dev/tty", O_RDONLY, 0); 46290001Sglebius if (fd < 0) 47290001Sglebius return (ISC_R_IOERROR); 48290001Sglebius 49290001Sglebius keyboard->fd = fd; 50290001Sglebius 51290001Sglebius if (tcgetattr(fd, &keyboard->saved_mode) < 0) { 52290001Sglebius ret = ISC_R_IOERROR; 53290001Sglebius goto errout; 54290001Sglebius } 55290001Sglebius 56290001Sglebius current_mode = keyboard->saved_mode; 57290001Sglebius 58290001Sglebius current_mode.c_iflag &= 59290001Sglebius ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); 60290001Sglebius current_mode.c_oflag &= ~OPOST; 61290001Sglebius current_mode.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); 62290001Sglebius current_mode.c_cflag &= ~(CSIZE|PARENB); 63290001Sglebius current_mode.c_cflag |= CS8; 64290001Sglebius 65290001Sglebius current_mode.c_cc[VMIN] = 1; 66290001Sglebius current_mode.c_cc[VTIME] = 0; 67290001Sglebius if (tcsetattr(fd, TCSAFLUSH, ¤t_mode) < 0) { 68290001Sglebius ret = ISC_R_IOERROR; 69290001Sglebius goto errout; 70290001Sglebius } 71290001Sglebius 72290001Sglebius keyboard->result = ISC_R_SUCCESS; 73290001Sglebius 74290001Sglebius return (ISC_R_SUCCESS); 75290001Sglebius 76290001Sglebius errout: 77290001Sglebius close (fd); 78290001Sglebius 79290001Sglebius return (ret); 80290001Sglebius} 81290001Sglebius 82290001Sglebiusisc_result_t 83290001Sglebiusisc_keyboard_close(isc_keyboard_t *keyboard, unsigned int sleeptime) { 84290001Sglebius REQUIRE(keyboard != NULL); 85290001Sglebius 86290001Sglebius if (sleeptime > 0 && keyboard->result != ISC_R_CANCELED) 87290001Sglebius (void)sleep(sleeptime); 88290001Sglebius 89290001Sglebius (void)tcsetattr(keyboard->fd, TCSAFLUSH, &keyboard->saved_mode); 90290001Sglebius (void)close(keyboard->fd); 91290001Sglebius 92290001Sglebius keyboard->fd = -1; 93290001Sglebius 94290001Sglebius return (ISC_R_SUCCESS); 95290001Sglebius} 96290001Sglebius 97290001Sglebiusisc_result_t 98290001Sglebiusisc_keyboard_getchar(isc_keyboard_t *keyboard, unsigned char *cp) { 99290001Sglebius ssize_t cc; 100290001Sglebius unsigned char c; 101290001Sglebius cc_t *controlchars; 102290001Sglebius 103290001Sglebius REQUIRE(keyboard != NULL); 104290001Sglebius REQUIRE(cp != NULL); 105290001Sglebius 106290001Sglebius cc = read(keyboard->fd, &c, 1); 107290001Sglebius if (cc < 0) { 108290001Sglebius keyboard->result = ISC_R_IOERROR; 109290001Sglebius return (keyboard->result); 110290001Sglebius } 111290001Sglebius 112290001Sglebius controlchars = keyboard->saved_mode.c_cc; 113290001Sglebius if (c == controlchars[VINTR] || c == controlchars[VQUIT]) { 114290001Sglebius keyboard->result = ISC_R_CANCELED; 115290001Sglebius return (keyboard->result); 116290001Sglebius } 117290001Sglebius 118290001Sglebius *cp = c; 119290001Sglebius 120290001Sglebius return (ISC_R_SUCCESS); 121290001Sglebius} 122290001Sglebius 123290001Sglebiusisc_boolean_t 124290001Sglebiusisc_keyboard_canceled(isc_keyboard_t *keyboard) { 125290001Sglebius return (ISC_TF(keyboard->result == ISC_R_CANCELED)); 126290001Sglebius} 127