# 2.11BSD#431 - /usr/src/new/notes/src/miscio.c

##### Functions

    askyn             X
    catchem           X
    catchint          X
    catchz            X
    gchar             X
    getnum            X
    gline             X
    isinput           X
    mapch             X
    ttystop           X
    ttystrt           X
    uncatchem         X
    widthch           X

##### Variables

    echoctl           X
    modeset           X
    oldlocalbits      X
    oldmode           X
    ospeed            X
    otty              X
    tty               X
    ttyerase          X
    ttykill           X

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

#### Defined functions

askyn defined in line 457; used 18 times

- in /usr/src/new/notes/src/adnote.c line 69-73(2), 83
- in /usr/src/new/notes/src/adresp.c line 51-55(2), 62
- in /usr/src/new/notes/src/control.c line 89, 102
- in /usr/src/new/notes/src/dropt.c line 176, 442, 477
- in /usr/src/new/notes/src/gtext.c line 86
- in /usr/src/new/notes/src/index.c line 69
- in /usr/src/new/notes/src/limindx.c line 159
- in /usr/src/new/notes/src/mailit.c line 141
- in /usr/src/new/notes/src/readem.c line 137, 281, 646

catchem defined in line 213; used 1 times

- in /usr/src/new/notes/src/main.c line 204

catchint defined in line 169; used 4 times

- in line 172-174(2), 215-217(2)

catchz defined in line 179; used 3 times

- in line 185, 207, 220

gchar defined in line 235; used 17 times

- in line 280, 375, 439, 463
- in /usr/src/new/notes/src/access.c line 82, 154, 223, 254, 297
- in /usr/src/new/notes/src/control.c line 111
- in /usr/src/new/notes/src/dropt.c line 87
- in /usr/src/new/notes/src/dsply.c line 359
- in /usr/src/new/notes/src/help.c line 43
- in /usr/src/new/notes/src/index.c line 52
- in /usr/src/new/notes/src/limindx.c line 40
- in /usr/src/new/notes/src/readem.c line 92
- in /usr/src/new/notes/src/talkto.c line 44

getnum defined in line 267; used 4 times

- in /usr/src/new/notes/src/access.c line 226, 257
- in /usr/src/new/notes/src/index.c line 222
- in /usr/src/new/notes/src/limindx.c line 118

gline defined in line 362; used 19 times

- in /usr/src/new/notes/src/access.c line 173
- in /usr/src/new/notes/src/adnote.c line 93
- in /usr/src/new/notes/src/asearch.c line 53
- in /usr/src/new/notes/src/dropt.c line 137, 207, 262, 410, 428, 473
- in /usr/src/new/notes/src/gdate.c line 47
- in /usr/src/new/notes/src/index.c line 145
- in /usr/src/new/notes/src/mailit.c line 90, 168
- in /usr/src/new/notes/src/readem.c line 522, 624, 695, 763, 785
- in /usr/src/new/notes/src/tsearch.c line 33

isinput defined in line 476; used 2 times

- in /usr/src/new/notes/src/dsply.c line 318
- in /usr/src/new/notes/src/prtind.c line 101

mapch defined in line 494; never used
ttystop defined in line 134; used 9 times

- in line 192
- in /usr/src/new/notes/src/cursor.c line 166, 174
- in /usr/src/new/notes/src/main.c line 226, 235
- in /usr/src/new/notes/src/misc.c line 65, 199, 298, 370

ttystrt defined in line 48; used 3 times

- in line 209
- in /usr/src/new/notes/src/main.c line 205
- in /usr/src/new/notes/src/misc.c line 146

uncatchem defined in line 224; used 1 times

- in /usr/src/new/notes/src/misc.c line 72

widthch defined in line 519; used 8 times

- in line 291, 307, 317, 388(2), 402, 412-417(2)

#### Defined variables

echoctl defined in line 42; used 8 times

- in line 54, 85, 288, 304, 385, 399, 523-525(2)

modeset defined in line 43; used 4 times

- in line 130, 136, 159, 188

oldlocalbits defined in line 36; used 3 times

- in line 79-84(2), 154

oldmode defined in line 35; used 2 times

- in line 102, 139

ospeed defined in line 44; used 2 times

- in line 96, 104

otty defined in line 29; used 2 times

- in line 69, 148

rcsid defined in line 5; never used
tty defined in line 37; used 19 times

- in line 60, 68, 78, 93-106(11), 115, 123, 139-143(2), 153

ttyerase defined in line 40; used 4 times

- in line 97, 105, 281, 376

ttykill defined in line 41; used 4 times

- in line 98, 106, 314, 410

Last modified: 1996-03-22 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1272 |