1135446Strhodes/* 2193149Sdougb * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") 3135446Strhodes * Copyright (C) 2000, 2001 Internet Software Consortium. 4135446Strhodes * 5193149Sdougb * Permission to use, copy, modify, and/or distribute this software for any 6135446Strhodes * purpose with or without fee is hereby granted, provided that the above 7135446Strhodes * copyright notice and this permission notice appear in all copies. 8135446Strhodes * 9135446Strhodes * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10135446Strhodes * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11135446Strhodes * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12135446Strhodes * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13135446Strhodes * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14135446Strhodes * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15135446Strhodes * PERFORMANCE OF THIS SOFTWARE. 16135446Strhodes */ 17135446Strhodes 18234010Sdougb/* $Id: keyboard.c,v 1.13 2007/06/19 23:47:18 tbox Exp $ */ 19135446Strhodes 20135446Strhodes#include <config.h> 21135446Strhodes 22135446Strhodes#include <sys/param.h> 23135446Strhodes#include <sys/types.h> 24135446Strhodes#include <sys/time.h> 25135446Strhodes#include <sys/uio.h> 26135446Strhodes 27135446Strhodes#include <errno.h> 28135446Strhodes#include <stdlib.h> 29135446Strhodes#include <string.h> 30135446Strhodes#include <termios.h> 31135446Strhodes#include <unistd.h> 32135446Strhodes#include <fcntl.h> 33135446Strhodes 34135446Strhodes#include <isc/keyboard.h> 35135446Strhodes#include <isc/util.h> 36135446Strhodes 37135446Strhodesisc_result_t 38135446Strhodesisc_keyboard_open(isc_keyboard_t *keyboard) { 39135446Strhodes int fd; 40135446Strhodes isc_result_t ret; 41135446Strhodes struct termios current_mode; 42135446Strhodes 43135446Strhodes REQUIRE(keyboard != NULL); 44135446Strhodes 45135446Strhodes fd = open("/dev/tty", O_RDONLY, 0); 46135446Strhodes if (fd < 0) 47135446Strhodes return (ISC_R_IOERROR); 48135446Strhodes 49135446Strhodes keyboard->fd = fd; 50135446Strhodes 51135446Strhodes if (tcgetattr(fd, &keyboard->saved_mode) < 0) { 52135446Strhodes ret = ISC_R_IOERROR; 53135446Strhodes goto errout; 54135446Strhodes } 55135446Strhodes 56135446Strhodes current_mode = keyboard->saved_mode; 57135446Strhodes 58135446Strhodes current_mode.c_iflag &= 59135446Strhodes ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); 60135446Strhodes current_mode.c_oflag &= ~OPOST; 61135446Strhodes current_mode.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); 62135446Strhodes current_mode.c_cflag &= ~(CSIZE|PARENB); 63135446Strhodes current_mode.c_cflag |= CS8; 64135446Strhodes 65135446Strhodes current_mode.c_cc[VMIN] = 1; 66135446Strhodes current_mode.c_cc[VTIME] = 0; 67135446Strhodes if (tcsetattr(fd, TCSAFLUSH, ¤t_mode) < 0) { 68135446Strhodes ret = ISC_R_IOERROR; 69135446Strhodes goto errout; 70135446Strhodes } 71135446Strhodes 72135446Strhodes keyboard->result = ISC_R_SUCCESS; 73135446Strhodes 74135446Strhodes return (ISC_R_SUCCESS); 75135446Strhodes 76135446Strhodes errout: 77135446Strhodes close (fd); 78135446Strhodes 79135446Strhodes return (ret); 80135446Strhodes} 81135446Strhodes 82135446Strhodesisc_result_t 83135446Strhodesisc_keyboard_close(isc_keyboard_t *keyboard, unsigned int sleeptime) { 84135446Strhodes REQUIRE(keyboard != NULL); 85135446Strhodes 86135446Strhodes if (sleeptime > 0 && keyboard->result != ISC_R_CANCELED) 87135446Strhodes (void)sleep(sleeptime); 88135446Strhodes 89135446Strhodes (void)tcsetattr(keyboard->fd, TCSAFLUSH, &keyboard->saved_mode); 90135446Strhodes (void)close(keyboard->fd); 91135446Strhodes 92135446Strhodes keyboard->fd = -1; 93135446Strhodes 94135446Strhodes return (ISC_R_SUCCESS); 95135446Strhodes} 96135446Strhodes 97135446Strhodesisc_result_t 98135446Strhodesisc_keyboard_getchar(isc_keyboard_t *keyboard, unsigned char *cp) { 99135446Strhodes ssize_t cc; 100135446Strhodes unsigned char c; 101135446Strhodes cc_t *controlchars; 102135446Strhodes 103135446Strhodes REQUIRE(keyboard != NULL); 104135446Strhodes REQUIRE(cp != NULL); 105135446Strhodes 106135446Strhodes cc = read(keyboard->fd, &c, 1); 107135446Strhodes if (cc < 0) { 108135446Strhodes keyboard->result = ISC_R_IOERROR; 109135446Strhodes return (keyboard->result); 110135446Strhodes } 111135446Strhodes 112135446Strhodes controlchars = keyboard->saved_mode.c_cc; 113135446Strhodes if (c == controlchars[VINTR] || c == controlchars[VQUIT]) { 114135446Strhodes keyboard->result = ISC_R_CANCELED; 115135446Strhodes return (keyboard->result); 116135446Strhodes } 117135446Strhodes 118135446Strhodes *cp = c; 119135446Strhodes 120135446Strhodes return (ISC_R_SUCCESS); 121135446Strhodes} 122135446Strhodes 123135446Strhodesisc_boolean_t 124135446Strhodesisc_keyboard_canceled(isc_keyboard_t *keyboard) { 125135446Strhodes return (ISC_TF(keyboard->result == ISC_R_CANCELED)); 126135446Strhodes} 127