Annotation of sbbs/sbbs3/conwrap.c, revision 1.1.1.1

1.1       root        1: /*
                      2:        conwrap.c -- To give DOS's getch() function to Linux for use in Synchronet
                      3:     Casey Martin 2000
                      4: */
                      5: 
                      6: /* $Id: conwrap.c,v 1.2 2000/11/02 13:21:24 rswindell Exp $ */
                      7: 
                      8: /* @format.tab-size 4, @format.use-tabs true */
                      9: 
                     10: #ifdef __unix__
                     11: 
                     12: #include <stdlib.h>
                     13: #include <unistd.h>
                     14: #include <termios.h>
                     15: #include <sys/kd.h>
                     16: #include <sys/time.h>
                     17: #include <sys/types.h>
                     18: #include <signal.h>
                     19: 
                     20: #include "conwrap.h"   // Verify prototypes
                     21: 
                     22: struct termios current;            // our current term settings
                     23: struct termios original;           // old termios settings
                     24: struct timeval timeout = {0, 0};   // passed in select() call
                     25: fd_set inp;                        // ditto
                     26: int beensetup = 0;                 // has _termios_setup() been called?
                     27: 
                     28: /*
                     29:        I'm using a variable function here simply for the sake of speed.  The
                     30:     termios functions must be called before a kbhit() can be successful, so
                     31:     on the first call, we just set up the terminal, point to variable function
                     32:     to kbhit_norm(), and then call the new function.  Otherwise, testing would
                     33:        be required on every call to determine if termios has already been setup.
                     34: 
                     35:     Maybe I'm being way too anal, though.
                     36: */
                     37: 
                     38: /* Resets the termios to its previous state */
                     39: void _termios_reset(void)
                     40: {
                     41:        tcsetattr(0, TCSANOW, &original);
                     42: }
                     43: 
                     44: /************************************************
                     45:   This pair of functions handles Ctrl-Z presses
                     46: ************************************************/
                     47: 
                     48: void _sighandler_stop(int sig)
                     49: {
                     50:     // clean up the terminal
                     51:     _termios_reset();
                     52: 
                     53:     // ... and stop
                     54:        kill(getpid(), SIGSTOP);
                     55: }
                     56: 
                     57: void _sighandler_cont(int sig)
                     58: {
                     59:     // restore terminal
                     60:        tcsetattr(0, TCSANOW, &current);
                     61: }
                     62: 
                     63: 
                     64: /* Prepares termios for non-blocking action */
                     65: void _termios_setup(void)
                     66: {
                     67:        beensetup = 1;
                     68:     
                     69:        tcgetattr(0, &original);
                     70:   
                     71:        memcpy(&current, &original, sizeof(struct termios));
                     72:        current.c_cc[VMIN] = 1;           // read() will return with one char
                     73:        current.c_cc[VTIME] = 0;          // read() blocks forever
                     74:        current.c_lflag &= ~ICANON;       // character mode
                     75:     current.c_lflag &= ~ECHO;         // turn off echoing
                     76:        tcsetattr(0, TCSANOW, &current);
                     77: 
                     78:     // Let's install an exit function, also.  This way, we can reset
                     79:     // the termios silently
                     80:     atexit(_termios_reset);
                     81: 
                     82:     // install the Ctrl-Z handler
                     83:     signal(SIGSTOP, _sighandler_stop);
                     84:     signal(SIGCONT, _sighandler_cont);
                     85: }
                     86: 
                     87: 
                     88: int kbhit(void)
                     89: {
                     90:        // set up select() args
                     91:        FD_ZERO(&inp);
                     92:        FD_SET(0, &inp);
                     93: 
                     94:        return select(1, &inp, NULL, NULL, &timeout);
                     95: }
                     96: 
                     97: int getch(void)
                     98: {
                     99:        char c;
                    100: 
                    101:     if (!beensetup)
                    102:        // I hate to test for this every time, but this shouldn't be
                    103:         // called that often anyway...
                    104:        _termios_setup();
                    105: 
                    106:     // get a char out of stdin
                    107:     read(0, &c, 1);
                    108: 
                    109:     return c;
                    110: }
                    111: 
                    112: #endif // __unix__

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.