home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Product / Product.zip / ISPSRC.ZIP / term.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-30  |  16.7 KB  |  676 lines

  1. /* -*- Mode:Text -*- */
  2. #ifndef lint
  3. static char Rcs_Id[] =
  4.     "$Id: term.c,v 1.37 1991/12/09 00:40:48 geoff Exp $";
  5. #endif
  6.  
  7. /*
  8.  * term.c - deal with termcap, and unix terminal mode settings
  9.  *
  10.  * Pace Willisson, 1983
  11.  *
  12.  * Copyright 1987, 1988, 1989, by Geoff Kuenning, Manhattan Beach, CA
  13.  * Permission for non-profit use is hereby granted.
  14.  * All other rights reserved.
  15.  * See "version.h" for a more complete copyright notice.
  16.  */
  17.  
  18. /*
  19.  * $Log: term.c,v $
  20.  * Revision 1.37  1991/12/09  00:40:48  geoff
  21.  * Don't unlink the tempfile on exit if it has a null name.
  22.  *
  23.  * Revision 1.36  91/09/04  18:00:57  geoff
  24.  * Move the include of config.h.  Since it now contains the definition of
  25.  * USG, it must precede any use of that option.
  26.  * 
  27.  * Revision 1.35  91/07/27  20:48:37  geoff
  28.  * Don't obey the screen size from TIOCGWINSZ if it's zero or negative.
  29.  * 
  30.  * Revision 1.34  91/07/11  19:52:24  geoff
  31.  * Remove the include of stdio.h, since ispell.h now does this.  Change
  32.  * the termination code to put out the te sequence, rather than ti.
  33.  * 
  34.  * Revision 1.33  91/07/05  19:51:55  geoff
  35.  * Fix some lint complaints, including getting rid of a couple of unused
  36.  * variables.
  37.  * 
  38.  * Revision 1.32  91/07/03  18:21:09  geoff
  39.  * Add code to support the "ti" and "te" termcap sequences, since the Sun
  40.  * cmdtool (or is it shelltool) needs it to function properly with ispell.
  41.  * 
  42.  * Revision 1.31  90/12/31  00:59:29  geoff
  43.  * Reformat to follow a consistent convention throughout ispell
  44.  * 
  45.  * Revision 1.30  90/04/26  22:44:25  geoff
  46.  * If it is available, use the TIOCGWINSZ ioctl to determine the dimensions
  47.  * of the terminal.  The enviroment variables LINES and COLUMNS can still
  48.  * be used to override this ioctl.
  49.  * 
  50.  * Revision 1.29  90/04/17  15:35:07  geoff
  51.  * Declare the signal-handling routines to be SIGNAL_TYPE
  52.  * 
  53.  * Revision 1.28  89/12/27  03:18:43  geoff
  54.  * Move all messages to msgs.h so they can be reconfigured
  55.  * 
  56.  * Revision 1.27  89/12/26  23:26:32  geoff
  57.  * Change the signal type to be definable (Israel Pinkas).
  58.  * 
  59.  * Revision 1.26  89/04/28  01:17:17  geoff
  60.  * Change Header to Id;  nobody cares about my pathnames.
  61.  * 
  62.  * Revision 1.25  89/04/03  01:58:34  geoff
  63.  * Fix a bunch of lint complaints.  Add code to let LINES and COLUMNS
  64.  * override the screen size given by the termcap entry.  Rearrange some
  65.  * code so that signal-catching and terminal setting is done only after
  66.  * we are sure the termcap entry is ok.
  67.  * 
  68.  * Revision 1.24  89/02/27  02:23:48  geoff
  69.  * Fix the interpretation of CONTEXTROUNDUP (it was inverted from what
  70.  * the comments in config.X said).
  71.  * 
  72.  * Revision 1.23  89/02/22  23:16:43  geoff
  73.  * Add support for calculating "contextsize" based on the terminal size.
  74.  * 
  75.  * Revision 1.22  89/01/06  00:14:47  geoff
  76.  * Add support for MAX_SCREEN_SIZE (Keith Cantrell).
  77.  * 
  78.  * Revision 1.21  88/12/26  02:32:39  geoff
  79.  * Add a copyright notice.
  80.  * 
  81.  * Revision 1.20  88/11/16  02:20:35  geoff
  82.  * Make sure "tpgrp" is defined if TIOCGPGRP is defined but not TIOCPGRP
  83.  * (a Locus-ism).
  84.  * 
  85.  * Revision 1.19  88/10/20  20:53:09  geoff
  86.  * If a shell escape fails, don't flush stdio buffers on exit from the child.
  87.  * (Ole Bjoern Hessen).
  88.  * 
  89.  * Revision 1.18  88/04/30  22:15:45  geoff
  90.  * Fix some lint complaints, and get rid of some unused variables found
  91.  * by lint.
  92.  * 
  93.  * Revision 1.17  88/03/27  01:05:19  geoff
  94.  * Fix the #ifdefs to handle USG-like systems that nevertheless have job
  95.  * control.
  96.  * 
  97.  * Revision 1.16  87/09/03  23:17:42  geoff
  98.  * Integrate George Sipe's latest changes:  make ^Z spawn a shell on USG.
  99.  * Add the shellescape() routine to handle simple shell commands faster.
  100.  * Also clean up signal handling a bit.
  101.  * 
  102.  * Revision 1.15  87/09/03  17:32:29  geoff
  103.  * Add ifdefs to make it compile on V7
  104.  * 
  105.  * Revision 1.14  87/09/03  17:09:09  geoff
  106.  * Catch signals on USG systems, too (imt3b2!imtsft)
  107.  * 
  108.  * Revision 1.13  87/06/27  12:20:54  geoff
  109.  * Get the sg termcap value for braindamaged terminals (Michael Wester).
  110.  * 
  111.  * Revision 1.12  87/06/07  14:31:12  geoff
  112.  * Integrate Joel Shprentz's changes into the main branch
  113.  * 
  114.  * Revision 1.11  87/05/25  21:24:34  geoff
  115.  * Integrate Mark Davies' changes, and improve some signal catching code.
  116.  * 
  117.  * Revision 1.10  87/04/21  23:29:20  geoff
  118.  * Only catch signals if they aren't ignored;  this makes background stuff
  119.  * work properly.
  120.  * 
  121.  * Revision 1.9  87/04/19  22:53:44  geoff
  122.  * Swap the includes of ispell.h and config.h so config.h can affect ispell.h.
  123.  * 
  124.  * Revision 1.8  87/04/02  12:26:10  geoff
  125.  * Make stdout buffered.
  126.  * 
  127.  * Revision 1.7  87/04/01  15:22:58  geoff
  128.  * Integrate Joe Orost's V7/register changes into the main branch
  129.  * 
  130.  * Revision 1.6  87/03/22  23:21:44  geoff
  131.  * Integrate Perry Smith's changes into the main branch
  132.  * 
  133.  * Revision 1.5  87/02/26  00:22:48  geoff
  134.  * Integrate McQueer's and McMahon's enhancements into the main branch
  135.  * 
  136.  * Revision 1.4  87/01/19  00:25:19  geoff
  137.  * Prohibit non-interactive use on USG systems too
  138.  * 
  139.  * Revision 1.3  87/01/19  00:07:00  geoff
  140.  * Modify to work on USG systems.
  141.  * 
  142.  * Revision 1.2  87/01/17  13:12:11  geoff
  143.  * Add RCS ID keywords
  144.  * 
  145.  */
  146.  
  147. #include "config.h"
  148. #ifdef USG
  149. #include <termio.h>
  150. #else
  151. #include <sgtty.h>
  152. #endif
  153. #include <signal.h>
  154. #include <stdio.h>
  155. #include "ispell.h"
  156. #include "msgs.h"
  157.  
  158. extern char *    tgoto ();
  159.  
  160. extern void    exit ();
  161. extern void    _exit ();
  162. extern char *    getenv ();
  163.  
  164. int putch();
  165.  
  166. erase ()
  167.     {
  168.  
  169.     if (cl)
  170.     tputs (cl, li, putch);
  171.     else
  172.     {
  173.     if (ho)
  174.         tputs (ho, 100, putch);
  175.     else if (cm)
  176.         tputs (tgoto (cm, 0, 0), 100, putch);
  177.     tputs (cd, li, putch);
  178.     }
  179.     }
  180.  
  181. move (row, col)
  182.     {
  183.     tputs (tgoto (cm, col, row), 100, putch);
  184.     }
  185.  
  186. inverse ()
  187.     {
  188.     tputs (so, 10, putch);
  189.     }
  190.  
  191. normal ()
  192.     {
  193.     tputs (se, 10, putch);
  194.     }
  195.  
  196. backup ()
  197.     {
  198.     if (BC)
  199.     tputs (BC, 1, putch);
  200.     else
  201.     (void) putchar ('\b');
  202.     }
  203.  
  204. putch (c)
  205.     {
  206.     (void) putchar (c);
  207.     }
  208.  
  209. #ifdef USG
  210. struct termio        sbuf;
  211. struct termio        osbuf;
  212. #else
  213. struct sgttyb        sbuf;
  214. struct sgttyb        osbuf;
  215. #ifdef TIOCSLTC
  216. struct ltchars        ltc;
  217. struct ltchars        oltc;
  218. #endif
  219. #endif
  220. static int        termchanged = 0;
  221. static SIGNAL_TYPE    (*oldint) ();
  222. static SIGNAL_TYPE    (*oldterm) ();
  223. #ifdef SIGTSTP
  224. static SIGNAL_TYPE    (*oldttin) ();
  225. static SIGNAL_TYPE    (*oldttou) ();
  226. static SIGNAL_TYPE    (*oldtstp) ();
  227. #endif
  228.  
  229. terminit ()
  230.     {
  231. #ifdef OS2
  232.     int            dst[2];
  233.     int                 tgstat;
  234. #endif  /* OS2 */ 
  235. #ifdef TIOCPGRP
  236.     int            tpgrp;
  237. #else
  238. #ifdef TIOCGPGRP
  239.     int            tpgrp;
  240. #endif
  241. #endif
  242. #ifdef SIGTSTP
  243.     SIGNAL_TYPE        onstop ();
  244. #endif
  245. #ifdef TIOCGWINSZ
  246.     struct winsize    wsize;
  247. #endif /* TIOCGWINSZ */
  248.  
  249. #ifdef OS2      /* check if termcap.dat is found and TERM is valid */
  250.     if ( (tgstat = tgetent (termcap, getenv ("TERM") ) ) == -1 )
  251.         {
  252.         (void) fprintf (stderr, TERM_C_NO_TERMCAP);
  253.         exit();
  254.         }
  255.     else if (tgstat == 0)
  256.         {
  257.         (void) fprintf (stderr, TERM_C_INVALID_TERM, getenv ("TERM"));
  258.         exit();
  259.         }
  260. #else
  261.     tgetent (termcap, getenv ("TERM"));
  262. #endif  /* OS2 */
  263.     termptr = termstr;
  264.     BC = tgetstr ("bc", &termptr);
  265.     cd = tgetstr ("cd", &termptr);
  266.     cl = tgetstr ("cl", &termptr);
  267.     cm = tgetstr ("cm", &termptr);
  268.     ho = tgetstr ("ho", &termptr);
  269.     nd = tgetstr ("nd", &termptr);
  270.     so = tgetstr ("so", &termptr);    /* inverse video on */
  271.     se = tgetstr ("se", &termptr);    /* inverse video off */
  272.     if ((sg = tgetnum ("sg")) < 0)    /* space taken by so/se */
  273.     sg = 0;
  274.     ti = tgetstr ("ti", &termptr);    /* terminal initialization */
  275.     te = tgetstr ("te", &termptr);    /* terminal termination */
  276.     co = tgetnum ("co");
  277.     li = tgetnum ("li");
  278. #ifdef TIOCGWINSZ
  279.     if (ioctl (0, TIOCGWINSZ, &wsize) >= 0)
  280.     {
  281.     if (wsize.ws_col > 0)
  282.         co = wsize.ws_col;
  283.     if (wsize.ws_row > 0)
  284.         li = wsize.ws_row;
  285.     }
  286. #endif /* TIOCGWINSZ */
  287.  
  288. #ifdef OS2      /* get the OS/2 window size */
  289.         _scrsize(dst);
  290.         co = dst[0];
  291.         li = dst[1];
  292. #endif  /* OS2 */
  293.  
  294.  
  295.     /*
  296.      * Let the variables "LINES" and "COLUMNS" override the termcap
  297.      * entry.  Technically, this is a terminfo-ism, but I think the
  298.      * vast majority of users will find it pretty handy.
  299.      */
  300.     if (getenv ("COLUMNS") != NULL)
  301.     co = atoi (getenv ("COLUMNS"));
  302.     if (getenv ("LINES") != NULL)
  303.     li = atoi (getenv ("LINES"));
  304. #if MAX_SCREEN_SIZE > 0
  305.     if (li > MAX_SCREEN_SIZE)
  306.     li = MAX_SCREEN_SIZE;
  307. #endif /* MAX_SCREEN_SIZE > 0 */
  308. #if MAXCONTEXT == MINCONTEXT
  309.     contextsize = MINCONTEXT;
  310. #else /* MAXCONTEXT == MINCONTEXT */
  311.     if (contextsize == 0)
  312. #ifdef CONTEXTROUNDUP
  313.     contextsize = (li * CONTEXTPCT + 99) / 100;
  314. #else /* CONTEXTROUNDUP */
  315.     contextsize = (li * CONTEXTPCT) / 100;
  316. #endif /* CONTEXTROUNDUP */
  317.     if (contextsize > MAXCONTEXT)
  318.     contextsize = MAXCONTEXT;
  319.     else if (contextsize < MINCONTEXT)
  320.     contextsize = MINCONTEXT;
  321. #endif /* MAX_CONTEXT == MIN_CONTEXT */
  322.     /*
  323.      * Insist on 2 lines for the screen header, 2 for blank lines
  324.      * separating areas of the screen, 2 for word choices, and 2 for
  325.      * the minimenu, plus however many are needed for context.  If
  326.      * possible, make the context smaller to fit on the screen.
  327.      */
  328.     if (li < contextsize + 8  &&  contextsize > MINCONTEXT)
  329.     {
  330.     contextsize = li - 8;
  331.     if (contextsize < MINCONTEXT)
  332.         contextsize = MINCONTEXT;
  333.     }
  334.     if (li < MINCONTEXT + 8)
  335.     (void) fprintf (stderr, TERM_C_SMALL_SCREEN, MINCONTEXT + 8);
  336.  
  337. #ifdef SIGTSTP
  338. #ifdef TIOCPGRP
  339. retry:
  340. #endif /* SIGTSTP */
  341. #endif /* TIOCPGRP */
  342.  
  343. #ifdef USG
  344.     if (!isatty (0))
  345.     {
  346.     (void) fprintf (stderr, TERM_C_NO_BATCH);
  347.     exit (1);
  348.     }
  349.     (void) ioctl (0, TCGETA, &osbuf);
  350.     termchanged = 1;
  351.  
  352.     sbuf = osbuf;
  353. #ifdef OS2      /* IDEFAULT added for os/2 -- jbh  8/15/92 */
  354.     sbuf.c_lflag &= ~(ECHO | ECHOK | ECHONL | ICANON | IDEFAULT);
  355. #else
  356.     sbuf.c_lflag &= ~(ECHO | ECHOK | ECHONL | ICANON);
  357. #endif  /* OS2 */
  358.  
  359.     sbuf.c_oflag &= ~(OPOST);
  360.     sbuf.c_iflag &= ~(INLCR | IGNCR | ICRNL);
  361.     sbuf.c_cc[VMIN] = 1;
  362.     sbuf.c_cc[VTIME] = 1;
  363.     (void) ioctl (0, TCSETAW, &sbuf);
  364.  
  365.     erasechar = osbuf.c_cc[VERASE];
  366.     killchar = osbuf.c_cc[VKILL];
  367.  
  368. #endif
  369.  
  370. #ifdef SIGTSTP
  371. #ifndef USG
  372.     (void) sigsetmask (1<<(SIGTSTP-1) | 1<<(SIGTTIN-1) | 1<<(SIGTTOU-1));
  373. #endif
  374. #endif
  375. #ifdef TIOCGPGRP
  376.     if (ioctl (0, TIOCGPGRP, &tpgrp) != 0)
  377.     {
  378.     (void) fprintf (stderr, TERM_C_NO_BATCH);
  379.     exit (1);
  380.     }
  381. #endif
  382. #ifdef SIGTSTP
  383. #ifdef TIOCPGRP
  384.     if (tpgrp != getpgrp(0)) /* not in foreground */
  385.     {
  386. #ifndef USG
  387.     (void) sigsetmask (1 << (SIGTSTP - 1) | 1 << (SIGTTIN - 1));
  388. #endif
  389.     (void) signal (SIGTTOU, SIG_DFL);
  390.     (void) kill (0, SIGTTOU);
  391.     /* job stops here waiting for SIGCONT */
  392.     goto retry;
  393.     }
  394. #endif
  395. #endif
  396.  
  397. #ifndef USG
  398.     (void) ioctl (0, TIOCGETP, &osbuf);
  399. #ifdef TIOCGLTC
  400.     (void) ioctl (0, TIOCGLTC, &oltc);
  401. #endif
  402.     termchanged = 1;
  403.  
  404.     sbuf = osbuf;
  405.     sbuf.sg_flags &= ~ECHO;
  406.     sbuf.sg_flags |= TERM_MODE;
  407.     (void) ioctl (0, TIOCSETP, &sbuf);
  408.  
  409.     erasechar = sbuf.sg_erase;
  410.     killchar = sbuf.sg_kill;
  411.  
  412. #ifdef TIOCSLTC
  413.     ltc = oltc;
  414.     ltc.t_suspc = -1;
  415.     (void) ioctl (0, TIOCSLTC, <c);
  416. #endif
  417.  
  418. #endif /* USG */
  419.  
  420.     if ((oldint = signal (SIGINT, SIG_IGN)) != SIG_IGN)
  421.     (void) signal (SIGINT, done);
  422.     if ((oldterm = signal (SIGTERM, SIG_IGN)) != SIG_IGN)
  423.     (void) signal (SIGTERM, done);
  424.  
  425. #ifdef SIGTSTP
  426. #ifndef USG
  427.     (void) sigsetmask (0);
  428. #endif
  429.     if ((oldttin = signal (SIGTTIN, SIG_IGN)) != SIG_IGN)
  430.     (void) signal (SIGTTIN, onstop);
  431.     if ((oldttou = signal (SIGTTOU, SIG_IGN)) != SIG_IGN)
  432.     (void) signal (SIGTTOU, onstop);
  433.     if ((oldtstp = signal (SIGTSTP, SIG_IGN)) != SIG_IGN)
  434.     (void) signal (SIGTSTP, onstop);
  435. #endif
  436.     if (ti)
  437.     tputs (ti, 1, putch);
  438.     }
  439.  
  440. SIGNAL_TYPE done ()
  441.     {
  442.     if (tempfile[0] != '\0')
  443. #ifdef OS2
  444.         {
  445.         fcloseall();    /* OS/2 won't unlink an open file */
  446.     (void) unlink (tempfile); 
  447.         }
  448. #else  /* OS2 */
  449.     (void) unlink (tempfile);
  450. #endif  /* OS2 */
  451.  
  452.     if (termchanged)
  453.     {
  454.     if (te)
  455.         tputs (te, 1, putch);
  456. #ifdef USG
  457.     (void) ioctl (0, TCSETAW, &osbuf);
  458. #else
  459.     (void) ioctl (0, TIOCSETP, &osbuf);
  460. #ifdef TIOCSLTC
  461.     (void) ioctl (0, TIOCSLTC, &oltc);
  462. #endif
  463. #endif
  464.     }
  465. #ifdef OS2      /* returns screen to the original color */
  466.     erase ();
  467. #endif  /* OS2 */
  468.     exit (0);
  469.     }
  470.  
  471. #ifdef SIGTSTP
  472. SIGNAL_TYPE onstop (signo)
  473.     int        signo;
  474.     {
  475. #ifdef USG
  476.     (void) ioctl (0, TCSETAW, &osbuf);
  477. #else
  478.     (void) ioctl (0, TIOCSETP, &osbuf);
  479. #ifdef TIOCSLTC
  480.     (void) ioctl (0, TIOCSLTC, &oltc);
  481. #endif
  482. #endif
  483.     (void) signal (signo, SIG_DFL);
  484. #ifndef USG
  485.     (void) sigsetmask (sigblock (0) & ~(1 << (signo - 1)));
  486. #endif
  487.     (void) kill (0, signo);
  488.     /* stop here until continued */
  489.     (void) signal (signo, onstop);
  490. #ifdef USG
  491.     (void) ioctl (0, TCSETAW, &sbuf);
  492. #else
  493.     (void) ioctl (0, TIOCSETP, &sbuf);
  494. #ifdef TIOCSLTC
  495.     (void) ioctl (0, TIOCSLTC, <c);
  496. #endif
  497. #endif
  498.     }
  499. #endif
  500.  
  501. stop ()
  502.     {
  503. #ifdef SIGTSTP
  504.     onstop (SIGTSTP);
  505. #else
  506.     /* for System V */
  507.     move (li - 1, 0);
  508.     (void) fflush (stdout);
  509.     if (getenv ("SHELL"))
  510.     (void) shellescape (getenv ("SHELL"));
  511.     else
  512.     (void) shellescape ("sh");
  513. #endif
  514.     }
  515.  
  516. /* Fork and exec a process.  Returns NZ if command found, regardless of
  517. ** command's return status.  Returns zero if command was not found.
  518. ** Doesn't use a shell.
  519. */
  520. int shellescape    (buf)
  521.     char *    buf;
  522.     {
  523.     char *    argv[100];
  524.     char *    cp = buf;
  525.     int        i = 0;
  526.     int        termstat;
  527.  
  528.     /* parse buf to args (destroying it in the process) */
  529.     while (*cp != '\0')
  530.     {
  531.     while (*cp == ' '  ||  *cp == '\t')
  532.         ++cp;
  533.     if (*cp == '\0')
  534.         break;
  535.     argv[i++] = cp;
  536.     while (*cp != ' '  &&  *cp != '\t'  &&  *cp != '\0')
  537.         ++cp;
  538.     if (*cp != '\0')
  539.         *cp++ = '\0';
  540.     }
  541.     argv[i] = NULL;
  542.  
  543. #ifdef USG
  544.     (void) ioctl (0, TCSETAW, &osbuf);
  545. #else
  546.     (void) ioctl (0, TIOCSETP, &osbuf);
  547.     (void) ioctl (0, TIOCSLTC, &oltc);
  548. #endif
  549.     (void) signal (SIGINT, oldint);
  550.     (void) signal (SIGTERM, oldterm);
  551. #ifdef SIGTSTP
  552.     (void) signal (SIGTTIN, oldttin);
  553.     (void) signal (SIGTTOU, oldttou);
  554.     (void) signal (SIGTSTP, oldtstp);
  555. #endif
  556.  
  557. /* ifdef OS2      no fork available under OS/2 - needs to be rewritted */
  558.     /* (void) printf(TERM_C_NO_FORK); */
  559. /* else */
  560.     if ((i = fork ()) == 0)
  561.     {
  562.     (void) execvp (argv[0], argv);
  563.     _exit (123);        /* Command not found */
  564.     }
  565.     else if (i > 0)
  566.     {
  567.     while (wait (&termstat) != i)
  568.         ;
  569.     termstat = (termstat == (123 << 8)) ? 0 : -1;
  570.     }
  571.     else
  572.     {
  573.     (void) printf (TERM_C_CANT_FORK);
  574.     termstat = -1;        /* Couldn't fork */
  575.     }
  576.  
  577. /* endif   OS2 */
  578.  
  579.  
  580.     if (oldint != SIG_IGN)
  581.     (void) signal (SIGINT, done);
  582.     if (oldterm != SIG_IGN)
  583.     (void) signal (SIGTERM, done);
  584.  
  585. #ifdef SIGTSTP
  586.     if (oldttin != SIG_IGN)
  587.     (void) signal (SIGTTIN, onstop);
  588.     if (oldttou != SIG_IGN)
  589.     (void) signal (SIGTTOU, onstop);
  590.     if (oldtstp != SIG_IGN)
  591.     (void) signal (SIGTSTP, onstop);
  592. #endif
  593.  
  594. #ifdef USG
  595.     (void) ioctl (0, TCSETAW, &sbuf);
  596. #else
  597.     (void) ioctl (0, TIOCSETP, &sbuf);
  598.     (void) ioctl (0, TIOCSLTC, <c);
  599. #endif
  600.     if (termstat)
  601.     {
  602.     (void) printf (TERM_C_TYPE_SPACE);
  603.     (void) fflush (stdout);
  604. #ifdef COMMANDFORSPACE
  605.     i = getchar ();
  606.     if (i != ' ' && i != '\n' && i != '\r')
  607.         ungetc (i, stdin);
  608. #else
  609.     while (getchar () != ' ')
  610.         ;
  611. #endif
  612.     }
  613.     return (termstat);
  614.     }
  615.  
  616. #ifdef    USESH
  617. shescape (buf)
  618.     char *    buf;
  619.     {
  620. #ifdef COMMANDFORSPACE
  621.     int        ch;
  622. #endif
  623.  
  624. #ifdef USG
  625.     (void) ioctl (0, TCSETAW, &osbuf);
  626. #else
  627.     (void) ioctl (0, TIOCSETP, &osbuf);
  628. #ifdef TIOCSLTC
  629.     (void) ioctl (0, TIOCSLTC, &oltc);
  630. #endif
  631. #endif
  632.     (void) signal (SIGINT, oldint);
  633.     (void) signal (SIGTERM, oldterm);
  634. #ifdef SIGTSTP
  635.     (void) signal (SIGTTIN, oldttin);
  636.     (void) signal (SIGTTOU, oldttou);
  637.     (void) signal (SIGTSTP, oldtstp);
  638. #endif
  639.  
  640.     (void) system (buf);
  641.  
  642.     if (oldint != SIG_IGN)
  643.     (void) signal (SIGINT, done);
  644.     if (oldterm != SIG_IGN)
  645.     (void) signal (SIGTERM, done);
  646.  
  647. #ifdef SIGTSTP
  648.     if (oldttin != SIG_IGN)
  649.     (void) signal (SIGTTIN, onstop);
  650.     if (oldttou != SIG_IGN)
  651.     (void) signal (SIGTTOU, onstop);
  652.     if (oldtstp != SIG_IGN)
  653.     (void) signal (SIGTSTP, onstop);
  654. #endif
  655.  
  656. #ifdef USG
  657.     (void) ioctl (0, TCSETAW, &sbuf);
  658. #else
  659.     (void) ioctl (0, TIOCSETP, &sbuf);
  660. #ifdef TIOCSLTC
  661.     (void) ioctl (0, TIOCSLTC, <c);
  662. #endif
  663. #endif
  664.     (void) printf (TERM_C_TYPE_SPACE);
  665.     (void) fflush (stdout);
  666. #ifdef COMMANDFORSPACE
  667.     ch = getchar ();
  668.     if (ch != ' '  &&  ch != '\n'  &&  ch != '\r')
  669.     ungetc (ch, stdin);
  670. #else
  671.     while (getchar () != ' ')
  672.     ;
  673. #endif
  674.     }
  675. #endif
  676.