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: }

Defined functions

catchem defined in line 232; used 1 times
catchint defined in line 188; used 4 times
catchz defined in line 198; used 3 times
isinput defined in line 460; used 2 times
mapch defined in line 478; never used
ttystrt defined in line 54; used 3 times
uncatchem defined in line 243; used 1 times

Defined variables

modeset defined in line 49; used 4 times
oldlocalbits defined in line 43; used 2 times
oldmode defined in line 42; used 2 times
ospeed defined in line 50; used 2 times
otty defined in line 29; used 2 times
rcsid defined in line 5; never used
tty defined in line 44; used 20 times
ttyerase defined in line 47; used 4 times
ttykill defined in line 48; used 4 times
Last modified: 1985-10-30
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1733
Valid CSS Valid XHTML 1.0 Strict