Annotation of 43BSDTahoe/new/notes/src/miscio.c, revision 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.