Annotation of coherent/g/usr/bin/vi/unix.c, revision 1.1

1.1     ! root        1: /* unix.c */
        !             2: 
        !             3: /* Author:
        !             4:  *     Steve Kirkendall
        !             5:  *     14407 SW Teal Blvd. #C
        !             6:  *     Beaverton, OR 97005
        !             7:  *     [email protected]
        !             8:  */
        !             9: 
        !            10: 
        !            11: /* This file contains the unix-specific versions the ttyread() functions.
        !            12:  * There are actually three versions of ttyread() defined here, because
        !            13:  * BSD, SysV, and V7 all need quite different implementations.
        !            14:  */
        !            15: 
        !            16: #include "config.h"
        !            17: #if ANY_UNIX
        !            18: # include "vi.h"
        !            19: 
        !            20: # if BSD
        !            21: /* For BSD, we use select() to wait for characters to become available,
        !            22:  * and then do a read() to actually get the characters.  We also try to
        !            23:  * handle SIGWINCH -- if the signal arrives during the select() call, then
        !            24:  * we adjust the o_columns and o_lines variables, and fake a control-L.
        !            25:  */
        !            26: #  include <sys/types.h>
        !            27: #  include <sys/time.h>
        !            28: int ttyread(buf, len, time)
        !            29:        char    *buf;   /* where to store the gotten characters */
        !            30:        int     len;    /* maximum number of characters to read */
        !            31:        int     time;   /* maximum time to allow for reading */
        !            32: {
        !            33:        fd_set  rd;     /* the file descriptors that we want to read from */
        !            34:        static  tty;    /* 'y' if reading from tty, or 'n' if not a tty */
        !            35:        int     i;
        !            36:        struct timeval t;
        !            37:        struct timeval *tp;
        !            38: 
        !            39: 
        !            40:        /* do we know whether this is a tty or not? */
        !            41:        if (!tty)
        !            42:        {
        !            43:                tty = (isatty(0) ? 'y' : 'n');
        !            44:        }
        !            45: 
        !            46:        /* compute the timeout value */
        !            47:        if (time)
        !            48:        {
        !            49:                t.tv_sec = time / 10;
        !            50:                t.tv_usec = (time % 10) * 100000L;
        !            51:                tp = &t;
        !            52:        }
        !            53:        else
        !            54:        {
        !            55:                tp = (struct timeval *)0;
        !            56:        }
        !            57: 
        !            58:        /* loop until we get characters or a definite EOF */
        !            59:        for (;;)
        !            60:        {
        !            61:                if (tty == 'y')
        !            62:                {
        !            63:                        /* wait until timeout or characters are available */
        !            64:                        FD_ZERO(&rd);
        !            65:                        FD_SET(0, &rd);
        !            66:                        i = select(1, &rd, (fd_set *)0, (fd_set *)0, tp);
        !            67:                }
        !            68:                else
        !            69:                {
        !            70:                        /* if reading from a file or pipe, never timeout!
        !            71:                         * (This also affects the way that EOF is detected)
        !            72:                         */
        !            73:                        i = 1;
        !            74:                }
        !            75:        
        !            76:                /* react accordingly... */
        !            77:                switch (i)
        !            78:                {
        !            79:                  case -1:      /* assume we got an EINTR because of SIGWINCH */
        !            80:                        if (*o_lines != LINES || *o_columns != COLS)
        !            81:                        {
        !            82: #ifndef CRUNCH
        !            83:                                *o_nearscroll = 
        !            84: #endif
        !            85:                                *o_lines = LINES;
        !            86:                                *o_columns = COLS;
        !            87: #ifndef CRUNCH
        !            88:                                if (!wset)
        !            89:                                {
        !            90:                                        *o_window = LINES - 1;
        !            91:                                }
        !            92: #endif
        !            93:                                if (mode != MODE_EX)
        !            94:                                {
        !            95:                                        /* pretend the user hit ^L */
        !            96:                                        *buf = ctrl('L');
        !            97:                                        return 1;
        !            98:                                }
        !            99:                        }
        !           100:                        break;
        !           101:        
        !           102:                  case 0:       /* timeout */
        !           103:                        return 0;
        !           104:        
        !           105:                  default:      /* characters available */
        !           106:                        return read(0, buf, len);
        !           107:                }
        !           108:        }
        !           109: }
        !           110: # else
        !           111: 
        !           112: # if M_SYSV || COHERENT
        !           113: /* For System-V or Coherent, we use VMIN/VTIME to implement the timeout.
        !           114:  * For no timeout, VMIN should be 1 and VTIME should be 0; for timeout,
        !           115:  * VMIN should be 0 and VTIME should be the timeout value.
        !           116:  */
        !           117: #  include <termio.h>
        !           118: int ttyread(buf, len, time)
        !           119:        char    *buf;   /* where to store the gotten characters */
        !           120:        unsigned len;   /* maximum number of characters to read */
        !           121:        int     time;   /* maximum time to allow for reading */
        !           122: {
        !           123:        struct termio tio;
        !           124:        int     bytes;  /* number of bytes actually read */
        !           125: 
        !           126:        /* arrange for timeout */
        !           127:        ioctl(0, TCGETA, &tio);
        !           128:        if (time)
        !           129:        {
        !           130:                tio.c_cc[VMIN] = 0;
        !           131:                tio.c_cc[VTIME] = time;
        !           132:        }
        !           133:        else
        !           134:        {
        !           135:                tio.c_cc[VMIN] = 1;
        !           136:                tio.c_cc[VTIME] = 0;
        !           137:        }
        !           138:        ioctl(0, TCSETA, &tio);
        !           139: 
        !           140:        /* Perform the read.  Loop if EINTR error happens */
        !           141:        while ((bytes = read(0, buf, len)) < 0)
        !           142:        {
        !           143:                /* probably EINTR error because a SIGWINCH was received */
        !           144:                if (*o_lines != LINES || *o_columns != COLS)
        !           145:                {
        !           146:                        *o_lines = LINES;
        !           147:                        *o_columns = COLS;
        !           148: #ifndef CRUNCH
        !           149:                        if (!wset)
        !           150:                        {
        !           151:                                *o_nearscroll = *o_window = LINES - 1;
        !           152:                        }
        !           153: #endif
        !           154:                        if (mode != MODE_EX)
        !           155:                        {
        !           156:                                /* pretend the user hit ^L */
        !           157:                                *buf = ctrl('L');
        !           158:                                return 1;
        !           159:                        }
        !           160:                }
        !           161:        }
        !           162: 
        !           163:        /* return the number of bytes read */
        !           164:        return bytes;
        !           165: 
        !           166:        /* NOTE: The terminal may be left in a timeout-mode after this function
        !           167:         * returns.  This shouldn't be a problem since Elvis *NEVER* tries to
        !           168:         * read from the keyboard except through this function.
        !           169:         */
        !           170: }
        !           171: 
        !           172: # else /* any other version of UNIX, assume it is V7 compatible */
        !           173: 
        !           174: /* For V7 UNIX (including Minix) we set an alarm() before doing a blocking
        !           175:  * read(), and assume that the SIGALRM signal will cause the read() function
        !           176:  * to give up.
        !           177:  */
        !           178: 
        !           179: #include <setjmp.h>
        !           180: 
        !           181: static jmp_buf env;
        !           182: 
        !           183: /*ARGSUSED*/
        !           184: int dummy(signo)
        !           185:        int     signo;
        !           186: {
        !           187:        longjmp(env, 1);
        !           188: }
        !           189: int ttyread(buf, len, time)
        !           190:        char    *buf;   /* where to store the gotten characters */
        !           191:        int     len;    /* maximum number of characters to read */
        !           192:        int     time;   /* maximum time to allow for reading */
        !           193: {
        !           194:        /* arrange for timeout */
        !           195: #if __GNUC__
        !           196:        signal(SIGALRM, (void (*)()) dummy);
        !           197: #else
        !           198:        signal(SIGALRM, dummy);
        !           199: #endif
        !           200:        alarm(time);
        !           201: 
        !           202:        /* perform the blocking read */
        !           203:        if (setjmp(env) == 0)
        !           204:        {
        !           205:                len = read(0, buf, len);
        !           206:        }
        !           207:        else /* I guess we timed out */
        !           208:        {
        !           209:                len = 0;
        !           210:        }
        !           211: 
        !           212:        /* cancel the alarm */
        !           213:        signal(SIGALRM, dummy); /* <-- to work around a bug in Minix */
        !           214:        alarm(0);
        !           215: 
        !           216:        /* return the number of bytes read */
        !           217:        if (len < 0)
        !           218:                len = 0;
        !           219:        return len;
        !           220: }
        !           221: 
        !           222: # endif /* !(M_SYSV || COHERENT) */
        !           223: # endif /* !BSD */
        !           224: 
        !           225: #endif /* ANY_UNIX */

unix.superglobalmegacorp.com

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