|
|
1.1 ! root 1: /* conwrap.c */ ! 2: ! 3: /* DOS's kbhit and getch functions for Unix - Casey Martin 2000 */ ! 4: ! 5: /* $Id: conwrap.c,v 1.11 2004/11/02 22:48:50 deuce Exp $ */ ! 6: ! 7: /**************************************************************************** ! 8: * @format.tab-size 4 (Plain Text/Source Code File Header) * ! 9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * ! 10: * * ! 11: * Copyright 2004 Rob Swindell - http://www.synchro.net/copyright.html * ! 12: * * ! 13: * This library is free software; you can redistribute it and/or * ! 14: * modify it under the terms of the GNU Lesser General Public License * ! 15: * as published by the Free Software Foundation; either version 2 * ! 16: * of the License, or (at your option) any later version. * ! 17: * See the GNU Lesser General Public License for more details: lgpl.txt or * ! 18: * http://www.fsf.org/copyleft/lesser.html * ! 19: * * ! 20: * Anonymous FTP access to the most recent released source is available at * ! 21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * ! 22: * * ! 23: * Anonymous CVS access to the development source and modification history * ! 24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: * ! 25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login * ! 26: * (just hit return, no password is necessary) * ! 27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src * ! 28: * * ! 29: * For Synchronet coding style and modification guidelines, see * ! 30: * http://www.synchro.net/source.html * ! 31: * * ! 32: * You are encouraged to submit any modifications (preferably in Unix diff * ! 33: * format) via e-mail to [email protected] * ! 34: * * ! 35: * Note: If this box doesn't appear square, then you need to fix your tabs. * ! 36: ****************************************************************************/ ! 37: ! 38: #if defined(__unix__) ! 39: ! 40: #include <stdlib.h> ! 41: #include <string.h> /* memcpy */ ! 42: #include <unistd.h> ! 43: #include <termios.h> ! 44: ! 45: #if defined(__FreeBSD__) ! 46: #include <sys/kbio.h> ! 47: #elif defined(__linux__) ! 48: #include <sys/kd.h> ! 49: #endif ! 50: ! 51: #include <sys/time.h> ! 52: #include <sys/types.h> ! 53: #include <signal.h> ! 54: ! 55: #include "conwrap.h" /* Verify prototypes */ ! 56: ! 57: static struct termios current; /* our current term settings */ ! 58: static struct termios original; /* old termios settings */ ! 59: static int beensetup = 0; /* has _termios_setup() been called? */ ! 60: static int istty = 0; /* is stdin a tty? */ ! 61: ! 62: /* Resets the termios to its previous state */ ! 63: void _termios_reset(void) ! 64: { ! 65: tcsetattr(STDIN_FILENO, TCSANOW, &original); ! 66: } ! 67: ! 68: /************************************************ ! 69: This pair of functions handles Ctrl-Z presses ! 70: ************************************************/ ! 71: #if defined(__BORLANDC__) ! 72: #pragma argsused ! 73: #endif ! 74: void _sighandler_stop(int sig) ! 75: { ! 76: /* clean up the terminal */ ! 77: _termios_reset(); ! 78: ! 79: /* ... and stop */ ! 80: kill(getpid(), SIGSTOP); ! 81: } ! 82: #if defined(__BORLANDC__) ! 83: #pragma argsused ! 84: #endif ! 85: void _sighandler_cont(int sig) ! 86: { ! 87: /* restore terminal */ ! 88: tcsetattr(STDIN_FILENO, TCSANOW, ¤t); ! 89: } ! 90: ! 91: ! 92: /* Prepares termios for non-blocking action */ ! 93: void _termios_setup(void) ! 94: { ! 95: beensetup = 1; ! 96: ! 97: tcgetattr(STDIN_FILENO, &original); ! 98: ! 99: memcpy(¤t, &original, sizeof(struct termios)); ! 100: current.c_cc[VMIN] = 1; /* read() will return with one char */ ! 101: current.c_cc[VTIME] = 0; /* read() blocks forever */ ! 102: current.c_lflag &= ~ICANON; /* character mode */ ! 103: current.c_lflag &= ~ECHO; /* turn off echoing */ ! 104: tcsetattr(STDIN_FILENO, TCSANOW, ¤t); ! 105: ! 106: /* Let's install an exit function, also. This way, we can reset ! 107: * the termios silently ! 108: */ ! 109: atexit(_termios_reset); ! 110: ! 111: /* install the Ctrl-Z handler */ ! 112: signal(SIGTSTP, _sighandler_stop); ! 113: signal(SIGCONT, _sighandler_cont); ! 114: } ! 115: ! 116: ! 117: int kbhit(void) ! 118: { ! 119: fd_set inp; ! 120: struct timeval timeout = {0, 0}; ! 121: ! 122: if(!istty) { ! 123: istty = isatty(STDIN_FILENO); ! 124: if(!istty) ! 125: return 0; ! 126: } ! 127: ! 128: if(!beensetup) ! 129: _termios_setup(); ! 130: ! 131: /* set up select() args */ ! 132: FD_ZERO(&inp); ! 133: FD_SET(STDIN_FILENO, &inp); ! 134: ! 135: if(select(STDIN_FILENO+1, &inp, NULL, NULL, &timeout)<1) ! 136: return 0; ! 137: return 1; ! 138: } ! 139: ! 140: int getch(void) ! 141: { ! 142: char c; ! 143: ! 144: if(!beensetup) ! 145: _termios_setup(); ! 146: ! 147: /* get a char out of stdin */ ! 148: read(STDIN_FILENO, &c, 1); ! 149: ! 150: return c; ! 151: } ! 152: ! 153: #endif /* __unix__ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.