Annotation of sbbs/sbbs3/conwrap.c, revision 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.