Annotation of 43BSDTahoe/new/notes/src/miscio.c, revision 1.1.1.1

1.1       root        1: #include       "parms.h"
                      2: #include       "structs.h"
                      3: 
                      4: #ifdef RCSIDENT
                      5: static char rcsid[] = "$Header: miscio.c,v 1.7.0.1 85/09/28 11:23:51 notes Rel $";
                      6: #endif RCSIDENT
                      7: 
                      8: 
                      9: /*  miscio stuff:
                     10:  *
                     11:  * ttystrt/ttystop switch back and forth to character-at-a-time mode
                     12:  *
                     13:  * catchem makes our program ignore kills and coredumps.
                     14:  *
                     15:  * getnum is a char at a time input routine
                     16:  *
                     17:  * gchar sucks in 1 character. masks off parity. Uses raw mode to do this
                     18:  *
                     19:  */
                     20: 
                     21: 
                     22: #include <signal.h>
                     23: #include <errno.h>
                     24: 
                     25: 
                     26: #ifdef USG                                             /* Bell's Sys III and V */
                     27: #include <termio.h>
                     28: struct termio   tty,
                     29:                 otty;
                     30: #endif defined(USG)
                     31: 
                     32: #if    defined(V7) || defined(BSD4x)
                     33:                                                        /* Standard Bell V7 and Berkeley too */
                     34: #include <sgtty.h>
                     35: int     oldmode;                                       /* prev mode bits */
                     36: long    oldlocalbits;                                  /* prev local bits */
                     37: struct sgttyb   tty;
                     38: #endif defined(V7) || defined(BSD4x)
                     39: 
                     40: #ifdef BSD2x                                           /* Berkeley PDP-11 Unix */
                     41: #include <sgtty.h>
                     42: int     oldmode;                                       /* prev mode bits */
                     43: int     oldlocalbits;                                  /* 2.8 Bsd uses 16 bits */
                     44: struct sgttyb   tty;
                     45: #endif defined(BSD2x)
                     46: 
                     47: char    ttyerase,                                      /* user's chosen erase character */
                     48:         ttykill;                                       /* and his line kill character */
                     49: int     modeset = 0;                                   /* == 1 if ttyflags messed with */
                     50: short   ospeed;                                                /* for tputs padding */
                     51: 
                     52: 
                     53: 
                     54: ttystrt ()
                     55: {
                     56: #if    defined(BSD2x)
                     57:     int     localbits;                                 /* 2.8 Bsd uses 16 bits */
                     58: #endif defined(BSD2x)
                     59: 
                     60: #if    defined(BSD4x)
                     61:     long    localbits;                                 /* for ctlecho and tildes */
                     62: #endif defined(BSD4x)
                     63: 
                     64: 
                     65: /*
                     66:  *     Grab the current tty state
                     67:  */
                     68: 
                     69: #ifdef V7                                              /* V7 has simple tty controls */
                     70:     if (gtty (0, &tty) < 0)                            /* failure to grab */
                     71:     {
                     72:        fprintf (stderr, "%s: Unable to gtty\n", Invokedas);
                     73:        exit (1);
                     74:     }
                     75: #endif defined(V7)
                     76: 
                     77: #ifdef USG                                             /* BTL SYS III & V  */
                     78:     if (ioctl (0, TCGETA, &tty) < 0 ||
                     79:            ioctl (0, TCGETA, &otty) < 0)               /* one failed */
                     80:     {
                     81:        fprintf (stderr, "%s: Unable to get tty state\n", Invokedas);
                     82:        exit (1);
                     83:     }
                     84: #endif defined(USG)
                     85: 
                     86: #if    defined(BSD4x) || defined(BSD2x)
                     87:                                                        /* Berkeley Unices */
                     88:     if (ioctl (0, TIOCGETP, &tty) < 0 ||
                     89:            ioctl (0, TIOCLGET, &oldlocalbits) < 0)
                     90:     {
                     91:        fprintf (stderr, "%s: Unable to get tty states\n");
                     92:        exit (1);
                     93:     }
                     94: #endif defined(BSD4x) || defined(BSD2x)
                     95: 
                     96: /*
                     97:  *     Modify the state to what we want:  cbreak, fix tildes for cursor
                     98:  *     and disable "control-echo" (berkeley)
                     99:  */
                    100: 
                    101: #if    defined(USG)
                    102:     tty.c_lflag &= NOT ICANON;
                    103:     tty.c_cc[VEOF] = 1;
                    104:     tty.c_cc[VEOL] = 1;
                    105:     ospeed = tty.c_cflag & CBAUD;
                    106:     ttyerase = tty.c_cc[VERASE];                       /* grab erase char */
                    107:     ttykill = tty.c_cc[VKILL];                         /* and kill char */
                    108: #endif defined(USG)
                    109: 
                    110: #if    defined(BSD4x) || defined(BSD2x) || defined(V7)
                    111:     oldmode = tty.sg_flags;
                    112:     tty.sg_flags |= CBREAK;
                    113:     ospeed = tty.sg_ospeed;                            /* speed of terminal */
                    114:     ttyerase = tty.sg_erase;                           /* grab erase character */
                    115:     ttykill = tty.sg_kill;                             /* and kill character */
                    116: #endif defined(BSD4x) || defined(BSD2x) || defined(V7)
                    117: 
                    118: 
                    119: /*
                    120:  *     Now actually tell the system that we want it this way
                    121:  */
                    122: 
                    123: #if    defined(V7)
                    124:     if (stty (0, &tty) < 0)                            /* failed */
                    125:     {
                    126:        fprintf (stderr, "%s: Unable to stty\n", Invokedas);
                    127:        exit (1);
                    128:     }
                    129: #endif defined(V7)
                    130: 
                    131: #if    defined(USG)
                    132:     if (ioctl (0, TCSETA, &tty) < 0)
                    133:     {
                    134:        fprintf (stderr, "%s: Unable to set tty state\n", Invokedas);
                    135:        exit (1);
                    136:     }
                    137: #endif defined(USG)
                    138: 
                    139: #if    defined(BSD4x) || defined(BSD2x)
                    140:     localbits = LTILDE | LCTLECH;                      /* zap tildes (hazeltines) and ctlecho */
                    141:     if (ioctl (0, TIOCSETN, &tty) < 0 ||
                    142:            ioctl (0, TIOCLBIC, &localbits) < 0)
                    143:     {
                    144:        fprintf (stderr, "%s: Unable to set tty state\n", Invokedas);
                    145:        exit (1);
                    146:     }
                    147: #endif defined(BSD4x) || defined(BSD2x)
                    148: 
                    149:     modeset = 1;
                    150:     cmstart ();                                                /* so can cursor address reliably */
                    151: }
                    152: 
                    153: ttystop ()
                    154: {
                    155:     if (modeset)
                    156:     {
                    157: #if    defined(V7) || defined(BSD4x) || defined(BSD2x)
                    158:        tty.sg_flags = oldmode;
                    159: #endif defined(V7) || defined(BSD4x) || defined(BSD2x)
                    160: 
                    161: #if    defined(V7)
                    162:        if (stty (0, &tty) < 0)                         /* vanilla Version 7 */
                    163:            printf ("ttystop: stty");                   /* cant use x cause he calls us */
                    164: #endif defined(V7)
                    165: 
                    166: #if    defined(USG)
                    167:        if (ioctl (0, TCSETA, &otty) < 0)               /* Unix 4.0 */
                    168:            printf ("ttystop: stty");                   /* cant use x cause he calls us */
                    169: #endif defined(USG)
                    170: 
                    171: #if    defined(BSD4x) || defined(BSD2x)
                    172:        if ((ioctl (0, TIOCSETN, &tty) < 0) ||
                    173:                (ioctl (0, TIOCLSET, &oldlocalbits) < 0))
                    174:            printf ("ttystop: stty");                   /* cant use x cause he calls us */
                    175: #endif defined(BSD4x) || defined(BSD2x)
                    176:     }
                    177:     cmstop ();                                         /* get out of cursor addressing mode */
                    178:     modeset = 0;
                    179: }
                    180: 
                    181: 
                    182: static int  (*osigint) (),
                    183:             (*osigquit) ();                            /* hold signal status */
                    184: #if     defined(SIGTSTP)
                    185: static int  (*osigtstp) ();                            /* control-z job stop */
                    186: #endif defined(SIGTSTP)
                    187: 
                    188: catchint ()
                    189: {
                    190:     intflag = 1;
                    191:     signal (SIGINT, catchint);                         /* fix em up again */
                    192: #ifndef        DEBUG
                    193:     signal (SIGQUIT, catchint);
                    194: #endif DEBUG
                    195: }
                    196: 
                    197: #if    defined(SIGTSTP)
                    198: catchz ()                                              /* handle ^Z gracefully */
                    199: {
                    200:     int     wasset;                                    /* tty mode flag */
                    201: 
                    202:     if (ignoresigs)                                    /* if in critical section */
                    203:     {
                    204:        signal (SIGTSTP, catchz);                       /* re-catch */
                    205:        return;                                         /* and ignore */
                    206:     }
                    207:     if ((wasset = modeset) != 0)                       /* want assignment */
                    208:     {
                    209:        at (0, 1);                                      /* go to bottom corner */
                    210:        fflush (stdout);
                    211:        ttystop ();                                     /* fix tty modes */
                    212:     }
                    213: 
                    214:     signal (SIGTSTP, SIG_DFL);                         /* make sure it nabs us */
                    215: #if    defined(BSD42)
                    216: /*
                    217:  *     since 4.2 Bsd blocks signals while we are handling them, we
                    218:  *     have to explicitly tell the kernel that we want the signals
                    219:  *     to come through.
                    220:  *     It would probably be more correct to only let some signals
                    221:  *     through instead of all.
                    222:  */
                    223:     (void) sigsetmask (0);                             /* pass signals */
                    224: #endif BSD42
                    225:     kill (0, SIGTSTP);                                 /* halt myself */
                    226:     signal (SIGTSTP, catchz);                          /* ready to catch again */
                    227:     if (wasset)
                    228:        ttystrt ();                                     /* fix his tty */
                    229: }
                    230: #endif defined(SIGTSTP)
                    231: 
                    232: catchem ()
                    233: {
                    234:     osigint = signal (SIGINT, catchint);               /* interrupts */
                    235: #ifndef        DEBUG
                    236:     osigquit = signal (SIGQUIT, catchint);             /* quits */
                    237: #endif DEBUG
                    238: #if    defined(SIGTSTP)
                    239:     osigtstp = signal (SIGTSTP, catchz);               /* control Z */
                    240: #endif
                    241: }
                    242: 
                    243: uncatchem ()                                           /* restore signal status */
                    244: {
                    245:     signal (SIGINT, osigint);
                    246: #ifndef        DEBUG
                    247:     signal (SIGQUIT, osigquit);
                    248: #endif DEBUG
                    249: #if    defined(SIGTSTP)
                    250:     signal (SIGTSTP, osigtstp);
                    251: #endif
                    252: }
                    253: 
                    254: gchar ()
                    255: /*
                    256:  *     Return next character from tty.
                    257:  *     this is all done in cbreak mode of course
                    258:  */
                    259: {
                    260:     char    c;
                    261:     register int    retcode;
                    262:     fflush (stdout);                                   /* get rid of what's there */
                    263:     while ((retcode = read (0, &c, 1)) <= 0)           /* try reading */
                    264:        if (retcode == 0 || errno != EINTR)             /* if bizarre */
                    265:        {
                    266:            fprintf (stderr, "%s: Bad tty read\n", Invokedas);
                    267:            exit (1);
                    268:        }
                    269:     intflag = 0;                                       /* remove any pending */
                    270: 
                    271:     return (c & 0177);
                    272: }
                    273: 
                    274: /*
                    275:  *     getnum (c) 
                    276:  *     grab a number from the terminal. "c" is the first digit o 
                    277:  *     the number. 
                    278:  *     
                    279:  *     Originally coded:       Rob Kolstad     Fall 1980
                    280:  *     Modified:               Ray Essick (with help from Malcolm Slaney)
                    281:  *                                             July 1982
                    282:  *                             to handle user defined erase and kill
                    283:  *                             characters.
                    284:  */
                    285: 
                    286: getnum (c)                                             /* c is the initial character! */
                    287: char    c;
                    288: {
                    289:     int     num,
                    290:             numin;
                    291:     num = c - '0';
                    292:     numin = 1;
                    293:     putc (c, stdout);
                    294:     while (1)
                    295:     {
                    296:        c = gchar ();                                   /* get next digit */
                    297:        if (c == ttyerase)                              /* want to erase? */
                    298:        {
                    299:            if (numin > 0)                              /* if have some */
                    300:            {
                    301:                if (c != '\10')                         /* Assumes physically */
                    302:                    printf ("\10\10  \10\10");          /* backspaces on ^H */
                    303:                else
                    304:                    printf (" \10");
                    305:                numin--;
                    306:                num /= 10;                              /* drop that digit */
                    307:            }
                    308:            else
                    309:            {                                           /* nothing to zap */
                    310:                if (c != '\10')                         /* non-backspace char */
                    311:                    printf ("\10\10 ");
                    312:                else
                    313:                    putchar (' ');                      /* backspace */
                    314:            }
                    315:        }
                    316:        else
                    317:            if (c == ttykill)
                    318:            {
                    319:                num = 0;                                /* blast it away */
                    320:                numin++;
                    321:                while (numin > 0)                       /* erase the screen */
                    322:                {
                    323:                    numin--;
                    324:                    printf ("\10 \10");
                    325:                }
                    326:                numin = 0;                              /* in case */
                    327:            }
                    328:            else
                    329:                switch (c)
                    330:                {
                    331:                    case '\n': 
                    332:                    case '\r': 
                    333:                        return num;                     /* done */
                    334: 
                    335:                    default: 
                    336:                        if (c < '0' || c > '9')
                    337:                        {
                    338:                            printf ("\10 \10\07");
                    339:                            continue;
                    340:                        }
                    341:                        numin++;
                    342:                        num = 10 * num + (c - '0');
                    343:                        break;
                    344:                }
                    345:     }
                    346: }
                    347: 
                    348: /*
                    349:  *     gline( p, i) - suck a maximum of i characters from the tty.
                    350:  *     do erase and kill processing.
                    351:  *     The line is terminated by the user typing a <cr> or <nl>. This
                    352:  *     character is converted to null and left on the end of the
                    353:  *     string returned. The count of characters (including the null
                    354:  *     terminator) is returned.
                    355:  *     The array passed in is assumed to have i+1 elements
                    356:  *     (enough for the characters plus the terminator)
                    357:  *
                    358:  *     Original Coding:        Ray Essick      December 1981
                    359:  *     Repaired to use user's erase and kill characters
                    360:  *                             Malcolm Slaney  July 1982
                    361:  *
                    362:  */
                    363: 
                    364: gline (p, max)
                    365: char   *p;
                    366: {
                    367:     register int    numin;
                    368:     register char  *q;                                 /* pointer to buffer */
                    369:     register char   c;                                 /* hold the input character */
                    370: 
                    371:     q = p;                                             /* get base */
                    372:     numin = 0;
                    373:     while (1)
                    374:     {
                    375:        c = gchar ();                                   /* flushes stdout also */
                    376:        if (c == ttyerase)
                    377:        {
                    378:            if (numin > 0)
                    379:            {
                    380:                if (c != '\10')                         /* Assumes TTY physically */
                    381:                    printf ("\10\10  \10\10");          /* backspaces on ^H */
                    382:                else
                    383:                    printf (" \10");
                    384:                numin--;
                    385:                q--;                                    /* back up in buffer also */
                    386:            }
                    387:            else
                    388:            {
                    389:                if (c != '\10')
                    390:                    printf ("\10 \10");
                    391:                else
                    392:                    printf (" ");
                    393:            }
                    394:        }
                    395:        else
                    396:            if (c == ttykill)
                    397:            {
                    398:                numin++;
                    399:                while (numin > 0)                       /* erase the screen */
                    400:                {
                    401:                    numin--;
                    402:                    printf ("\10 \10");
                    403:                }
                    404:                q = p;                                  /* reset pointer */
                    405:                numin = 0;                              /* in case .. */
                    406:            }
                    407:            else
                    408:                switch (c)
                    409:                {
                    410:                    case '\n': 
                    411:                    case '\r': 
                    412:                        if (numin >= max)               /* should only ever be = */
                    413:                        {
                    414:                            p[max] = '\0';              /* put a null at the end */
                    415:                            return max + 1;             /* which is how many we return */
                    416:                        }
                    417:                        *q = '\0';
                    418:                        numin++;
                    419:                        return numin;
                    420: 
                    421:                    case '\\':                          /* escape character */
                    422:                        printf ("\010");                /* back space to it */
                    423:                        c = gchar ();                   /* grab escaped character */
                    424:                                                        /* and fall through to default */
                    425: 
                    426:                    default:                            /* add character to buffer */
                    427:                        if (numin < max)
                    428:                        {
                    429:                            *q++ = c;
                    430:                            numin++;
                    431:                        }
                    432:                        else
                    433:                        {
                    434:                            printf ("\10 \10");         /* show him I ignored char */
                    435:                        }
                    436:                        break;
                    437:                }
                    438:     }
                    439: }
                    440: 
                    441: askyn (p) char *p;                                     /* returns y or n to the question */
                    442: {
                    443:     char    c;                                         /* return temp */
                    444:     printf ("%s", p);
                    445:     while (1)
                    446:     {
                    447:        c = gchar ();
                    448:        if (c == 'y' || c == 'n')
                    449:            break;
                    450:        printf ("\07 y or n please\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
                    451:     }
                    452:     return c;
                    453: }
                    454: 
                    455: /*
                    456:  * return 1 if there is input from the terminal,
                    457:  * 0 otherwise.  systems without the appropriate
                    458:  * call should always return 0.
                    459:  */
                    460: isinput ()
                    461: {
                    462: #ifdef FIONREAD                                        /* BSD 4.1, 4.1a, 4.2 */
                    463:     long    retval;
                    464:     if (ioctl (0, FIONREAD, &retval))
                    465:        return 0;                                       /* failed, say no input */
                    466:     return (retval != 0);                              /* count of characters */
                    467: #endif FIONREAD
                    468: 
                    469:     return 0;                                          /* for other systems */
                    470: }
                    471: 
                    472: /*
                    473:  *     mapch(c) char c;
                    474:  *
                    475:  *     prints control characters as ^x style. 
                    476:  *     others as normal.
                    477:  */
                    478: mapch (c)
                    479: char    c;
                    480: {
                    481:     if (c < 40)
                    482:     {
                    483:        putchar ('^');
                    484:        putchar (c | 0100);                             /* make visible */
                    485:     }
                    486:     else
                    487:        if (c == 0177)
                    488:        {
                    489:            putchar ('^');
                    490:            putchar ('?');
                    491:        }
                    492:        else
                    493:            putchar (c);
                    494: }

unix.superglobalmegacorp.com

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