home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / ile-2.01 / tty.c < prev   
Encoding:
C/C++ Source or Header  |  1995-06-30  |  10.7 KB  |  573 lines

  1. /*
  2.  *  tty.c   - ile - Hops 07.06.94 *
  3.  */
  4.  
  5. #include    <sys/types.h>
  6. #include    <sys/stat.h>
  7. #include    <fcntl.h>
  8. #include    <signal.h>
  9. #include    <stdio.h>
  10.  
  11.  
  12. #ifdef HAVE_TERMIO_H
  13. #include <termio.h>
  14. #else
  15. #include <sys/ioctl.h>
  16. #endif  /* HAVE_TERMIO_H */
  17.  
  18. /* Include the local include file after all the system includes */
  19. #include    "ile.h"
  20.  
  21.  
  22. /* These are the terminal manipulation routines. :)  Fun!  */
  23.  
  24.  
  25. #ifdef SIGWINCH         /* Starting window structure */
  26.  
  27. /* I am using struct winsize here, but redefining it, because
  28.    Each system seems to define it in a different place, or not
  29.    at all.  The actual structure never seems to change though. :)
  30.  */
  31.  
  32. struct winstats {
  33.     unsigned short    ws_row;        /* rows, in characters */
  34.     unsigned short    ws_col;        /* columns, in characters */
  35.     unsigned short    ws_xpixel;    /* horizontal size, pixels - not used */
  36.     unsigned short    ws_ypixel;    /* vertical size, pixels - not used */
  37.     } tty_win;
  38.  
  39.  
  40. /* The window size has changed, let the pty know.  Used as a signal handler */
  41.  
  42.  
  43.  
  44. /*------------------------------------------------------------------*/
  45.  
  46. /*
  47.  * If the window changes size, tell the slave_tty about it.
  48. */
  49. void
  50. change_window()
  51. {
  52.     int pgrp;
  53.  
  54. #ifdef TIOCGWINSZ
  55.     (void) ioctl(0, TIOCGWINSZ, &tty_win);
  56.     (void) ioctl(slave_tty, TIOCSWINSZ, &tty_win);
  57. #endif /* TIOCGWINSZ */
  58.  
  59.     (void) ioctl(slave_tty, TIOCGPGRP, (char *) &pgrp);
  60.     if ( pgrp > 1 ) /* ?? */
  61.         (void) killpg(pgrp, SIGWINCH);
  62.  
  63.     /* note the change so that we don't die after select */
  64.  
  65.     windowchanged = TRUE;
  66. }
  67.  
  68. #if 0
  69. void updatewin()
  70. {
  71. #ifdef TIOCGWINSZ
  72.         (void) ioctl(ttyfd, TIOCGWINSZ, &tty_win);
  73.         (void) ioctl(masterfd, TIOCSWINSZ, &tty_win);
  74. #endif /* TIOCGWINSZ */
  75.  
  76.        /* An interesting note...
  77.         I had code here to send a SIGWINCH to the pty
  78.         process, but it turns out the kernel does when
  79.         the pty recieves the TIOCSWINSZ ioctl.  */
  80. }
  81. #endif /* 0 */
  82.  
  83.  
  84. #endif /* SIGWINCH */
  85.     
  86.  
  87. #ifdef HAVE_TERMIO_H
  88.  
  89. /* Get the modes of the contorlling tty and save them.  Saves
  90.    ttymodes in tty_mode and returns -1 if ioctl fails. */
  91.  
  92. struct termio tty_mode;  /* Save tty mode here */
  93. int tty_init=0;
  94.  
  95.  
  96. int tty_getmode(fd)
  97. int fd;
  98. {
  99.     tty_init=1;    /* Flag: we have initialized the tty_mode struct */
  100.     d_zero((char *)&tty_mode, sizeof(struct termio));
  101.  
  102.     if ( ! isatty(fd) )
  103.         return(0);
  104.  
  105.     if (ioctl(fd, TCGETA, (char *) &tty_mode) < 0)
  106.         return(-1);  
  107.  
  108. #if defined(SIGWINCH) && defined(TIOCGWINSZ)
  109.     d_zero((char *)&tty_win, sizeof(struct winstats));
  110.  
  111.        (void) ioctl(fd, TIOCGWINSZ, &tty_win);
  112. #endif /* SIGWINCH */
  113.  
  114.     return(0);
  115. }
  116.  
  117.  
  118. /* Restore terminal's mode to whatever it was on the most
  119.    recent call to the tty_getmode() function. */
  120.  
  121. int tty_reset(fd)
  122. int fd;
  123. {
  124.     if ( ! tty_init )
  125.         return(-1);
  126.  
  127.     if ( ! isatty(fd) )
  128.         return(0);
  129.  
  130.     if (ioctl(fd, TCSETA, (char *) &tty_mode) < 0)
  131.         return(-1);
  132.  
  133. #if defined(SIGWINCH) && defined(TIOCSWINSZ)
  134.     (void) ioctl(fd, TIOCSWINSZ, &tty_win);
  135. #endif /* SIGWINCH */
  136.  
  137.     return(0);
  138. }
  139.  
  140.  
  141. /* Set a tty to a sane mode */
  142.  
  143. int tty_sane(fd)
  144. int fd;
  145. {
  146.     struct termio temp_mode;
  147.  
  148.     if ( ! isatty(fd) )
  149.         return(0);
  150.  
  151. #ifdef DEBUG
  152.     fprintf(stderr, "tty_init: %d\r\n", tty_init);
  153. #endif
  154.  
  155.     temp_mode.c_lflag=(ISIG|ICANON|ECHO|ECHOE);
  156.     temp_mode.c_iflag=(BRKINT|IGNPAR|ISTRIP|ICRNL|IXON);
  157.     temp_mode.c_oflag=(OPOST|ONLCR);
  158.     temp_mode.c_cflag=(CS7|PARENB|CREAD);
  159.     temp_mode.c_cc[VERASE]=('H'^64);
  160.     temp_mode.c_cc[VKILL]=('U'^64);
  161.     temp_mode.c_cc[VQUIT]=('\\'^64);
  162.     temp_mode.c_cc[VINTR]=('C'^64);
  163.     temp_mode.c_cc[VEOF]=('D'^64);
  164.     
  165.     if (ioctl(fd, TCSETA, (char *) &temp_mode) < 0)
  166.         return(-1);
  167.  
  168.     return(0);
  169. }
  170.  
  171.  
  172. /* Set a terminal in raw mode */
  173.  
  174. int tty_raw(fd)
  175. int fd;         /* file descriptor of tty device */
  176. {
  177.     struct termio temp_mode;
  178.  
  179.     if ( ! isatty(fd) )
  180.         return(0);
  181.  
  182.     if ( ioctl(fd, TCGETA, (char *)&temp_mode) < 0 )
  183.         return(-1);
  184.  
  185.     temp_mode.c_iflag=(IGNBRK | ISTRIP);   /* turn off all input control */
  186.     temp_mode.c_oflag &= ~(OLCUC | ONLCR | OCRNL | ONLRET);
  187.                     /* disable output post-processing */
  188.     temp_mode.c_lflag = 0;
  189.     temp_mode.c_cc[VMIN]=1;        /* 1 or more chars satisfy read */
  190.     temp_mode.c_cc[VTIME]=0;    /* 10'ths of seconds between chars */
  191.  
  192.     if (ioctl(fd, TCSETA, (char *) &temp_mode) < 0)
  193.         return(-1);
  194.     return(0);
  195. }
  196.  
  197.  
  198. /* Function to set a tty echo or no echo */
  199.  
  200. int tty_echo(fd, echo)
  201. int fd;
  202. int echo;
  203. {
  204.     struct termio temp_mode;
  205.  
  206.     if ( ! isatty(fd) )
  207.         return(0);
  208.  
  209.     if ( ioctl(fd, TCGETA, &temp_mode) < 0 )
  210.         return(-1);
  211.  
  212.     if ( echo )
  213.         temp_mode.c_lflag|=ECHO;
  214.     else
  215.         temp_mode.c_lflag&=(~ECHO);
  216.  
  217.     if ( ioctl(fd, TCSETA, &temp_mode) < 0 )
  218.         return(-1);
  219.     return(0);
  220. }
  221.  
  222. /* one level stack for pushing or popping echo status
  223.  * must push first ( turns echo off )
  224.  * pop to restore orig modes
  225.  */
  226. int tty_noecho(fd, op)
  227. int fd;
  228. int op; /* PUSH or POP */
  229. {
  230. static struct termio orig_mode;
  231. struct termio temp_mode;
  232.  
  233.     if ( ! isatty(fd) )
  234.         return(0);
  235.  
  236.     if ( op == PUSH )
  237.     {
  238.             
  239.         if ( ioctl(fd, TCGETA, &temp_mode) < 0 )
  240.         {
  241.             fprintf(stderr, "tty_noecho TCGETA failed \n");
  242.         return(-1);
  243.     }
  244.  
  245.         orig_mode = temp_mode ;        
  246.         temp_mode.c_lflag &= (~ECHO);
  247.     }
  248.     else if (op == POP )
  249.         temp_mode = orig_mode;
  250.     else
  251.     {
  252.         fprintf(stderr, "tty_noecho() bad OP \n");
  253.         return -1;
  254.     }
  255.  
  256.     if ( ioctl(fd, TCSETA, &temp_mode) < 0 )
  257.     {
  258.         fprintf(stderr, "tty_noecho TCSETA failed \n");
  259.         return(-1);
  260.     }
  261.     return(0);
  262. }
  263.  
  264.  
  265. /* return TRUE if the fd has echo off */
  266. int tty_silentmode( fd )
  267. int fd;
  268. {
  269. struct termio params;
  270.  
  271.     if ( ! isatty(fd) )
  272.     return(0);
  273.  
  274.  
  275.     (void) ioctl(fd, TCGETA, ¶ms);
  276.  
  277.     return (( params.c_lflag & ECHO) == 0);
  278. }
  279.  
  280. /* replicate master tty modes into slave */
  281. void tty_replic( mfd, sfd )
  282. int mfd;
  283. int sfd;
  284. {
  285. struct termio temp_mode;
  286.  
  287.     if ( !isatty(mfd) || !isatty(sfd)  )
  288.     return;
  289.  
  290.  
  291.     ioctl(mfd, TCGETA, (char *) &temp_mode);
  292.  
  293.     ioctl(sfd, TCSETA, (char *)&temp_mode) ;
  294.  
  295. }
  296.  
  297. #else  /* ---------------- no /usr/include/termio.h ---------------- */
  298.  
  299.  
  300. /* Get the modes of the controlling tty and save them.  Saves
  301.    ttymodes in tty_mode and returns 1 if ioctl fails. */
  302.  
  303. static struct sgttyb    tty_mode;    /* save tty mode here */
  304. int tty_init=0;
  305.  
  306. int tty_getmode(fd)
  307. int fd;
  308. {
  309.     if ( ! isatty(fd) )
  310.         return(0);
  311.  
  312.     tty_init=1;    /* Flag: we have initialized the tty_mode struct */
  313.  
  314.     if (ioctl(fd, TIOCGETP, (char *) &tty_mode) < 0)
  315.         return(-1);
  316.  
  317. #ifdef SIGWINCH
  318.     if ( ioctl(fd, TIOCGWINSZ, &tty_win) < 0 )
  319.         perror("ioctl TIOCGWINSZ error");
  320. #endif /* SIGWINCH */
  321.  
  322.     return(0);
  323. }
  324.  
  325.  
  326. /*
  327.  * Restore a terminal's mode to whatever it was on the most
  328.  * recent call to the tty_getmode() function above.
  329.  */
  330.  
  331. int tty_reset(fd)
  332. int    fd;        /* of terminal device */
  333. {
  334.     if ( ! tty_init )    /* Have we been initialized? */
  335.         return(-1);
  336.  
  337.     if ( ! isatty(fd) )
  338.         return(0);
  339.  
  340.     if (ioctl(fd, TIOCSETP, (char *) &tty_mode) < 0)
  341.         return(-1);
  342.  
  343. #ifdef SIGWINCH
  344.         (void) ioctl(fd, TIOCSWINSZ, &tty_win);
  345. #endif /* SIGWINCH */
  346.  
  347.     return(0);
  348. }
  349. /* Set a tty to a sane mode */
  350.  
  351. int tty_sane(fd)
  352. int fd;
  353. {
  354.     struct sgttyb temp_mode;
  355.  
  356.     if ( ! isatty(fd) )
  357.         return(0);
  358.  
  359.     if (ioctl(fd, TIOCGETP, (char *) &temp_mode) < 0)
  360.         return(-1);
  361.  
  362.     temp_mode.sg_flags &= ~RAW;    /* turn RAW mode off */
  363.     temp_mode.sg_flags |= ECHO;    /* turn ECHO on */
  364.     
  365.     if (ioctl(fd, TIOCSETP, (char *) &temp_mode) < 0)
  366.         return(-1);
  367.  
  368.     return(0);
  369. }
  370.  
  371. /*
  372.  * Put a terminal device into RAW mode with ECHO off.
  373.  */
  374.  
  375. int tty_raw(fd)
  376. int    fd;        /* of terminal device */
  377. {
  378.     struct sgttyb    temp_mode;
  379.  
  380.     if ( ! isatty(fd) )
  381.         return(0);
  382.  
  383.     if (ioctl(fd, TIOCGETP, (char *) &temp_mode) < 0)
  384.         return(-1);
  385.  
  386.     temp_mode.sg_flags |= RAW;    /* turn RAW mode on */
  387.     temp_mode.sg_flags &= ~ECHO;    /* turn ECHO off */
  388.  
  389.     if (ioctl(fd, TIOCSETP, (char *) &temp_mode) < 0)
  390.         return(-1);
  391.  
  392.     return(0);
  393. }
  394.  
  395.  
  396. /* Set a terminal echo or no echo, as requested.  */
  397.  
  398. int tty_echo(fd, echo)
  399. int fd;
  400. int echo;
  401. {
  402.     struct sgttyb temp_mode;
  403.  
  404.     if ( ! isatty(fd) )
  405.         return(0);
  406.  
  407.     if (ioctl(fd, TIOCGETP, (char *) &temp_mode) < 0)
  408.         return(-1);
  409.  
  410.     if ( echo )
  411.         temp_mode.sg_flags |= ECHO;    /* turn ECHO on */
  412.     else
  413.         temp_mode.sg_flags &= ~ECHO;    /* turn ECHO off */
  414.     
  415.     if (ioctl(fd, TIOCSETP, (char *) &temp_mode) < 0)
  416.         return(-1);
  417.  
  418.     return(0);
  419. }
  420.  
  421.  
  422. /* one level stack for pushing or popping echo status
  423.  * must push first ( turns echo off )
  424.  * pop to restore orig modes
  425.  */
  426. int tty_noecho(fd, op)
  427. int fd;
  428. int op; /* PUSH or POP */
  429. {
  430. static struct termio orig_mode;
  431. struct termio temp_mode;
  432.  
  433.     if ( ! isatty(fd) )
  434.         return(0);
  435.  
  436.     if ( op == PUSH )
  437.     {
  438.             
  439.     if (ioctl(fd, TIOCGETP, (char *) &temp_mode) < 0)
  440.         return(-1);
  441.  
  442.         orig_mode = temp_mode ;        
  443.  
  444.     temp_mode.sg_flags |= RAW;    /* turn RAW mode on */
  445.     temp_mode.sg_flags &= ~ECHO;    /* turn ECHO off */
  446.     }
  447.     else if (op == POP )
  448.         temp_mode = orig_mode;
  449.     else
  450.     {
  451.         fprintf(stderr, "tty_noecho() bad OP \n");
  452.         return -1;
  453.     }
  454.  
  455.     if (ioctl(fd, TIOCSETP, (char *) &temp_mode) < 0)
  456.         return(-1);
  457.  
  458.     return(0);
  459. }
  460.  
  461. /* return TRUE if the slave is
  462.  * in RAW or CBREAK mode, or has turned off ECHO
  463.  */
  464. int tty_silentmode( fd )
  465. int fd;
  466. {
  467. struct sgttyb params;
  468.  
  469.     if ( ! isatty(fd) )
  470.     return(0);
  471.  
  472.     (void) ioctl(fd, TIOCGETP, ¶ms);
  473.  
  474.     return (
  475.         ((params.sg_flags & (RAW | CBREAK)) != 0) ||
  476.                             (params.sg_flags & ECHO) == 0 ) ;
  477. }
  478.  
  479.  
  480. /* replicate Master fd state onto slave fd */
  481. void tty_replic( mfd, sfd )
  482. int mfd;
  483. int sfd;
  484. {
  485. struct sgttyb tty_sgttyb;
  486. struct tchars tty_tchars;
  487. struct ltchars tty_ltchars;
  488. struct winsize tty_winsize;
  489. int tty_mode;
  490.  
  491.     (void) ioctl(mfd, TIOCGETP, &tty_sgttyb);
  492.     (void) ioctl(sfd, TIOCSETP, &tty_sgttyb);
  493.  
  494.     /* tty line discipline */
  495.  
  496.     (void) ioctl(mfd, TIOCGETD, &tty_ldisc);
  497.     (void) ioctl(sfd, TIOCSETD, &tty_ldisc);
  498.  
  499.     /* tty tchars */
  500.  
  501.     (void) ioctl(mfd, TIOCGETC, &tty_tchars);
  502.     (void) ioctl(sfd, TIOCSETC, &tty_tchars);
  503.  
  504.     /* tty mode */
  505.  
  506.     (void) ioctl(mfd, TIOCLGET, &tty_mode);
  507.     (void) ioctl(sfd, TIOCLSET, &tty_mode);
  508.  
  509.     /* tty ltchars */
  510.  
  511.     (void) ioctl(mfd, TIOCGLTC, &tty_ltchars);
  512.     (void) ioctl(sfd, TIOCSLTC, &tty_ltchars);
  513.  
  514.  
  515. #ifdef TIOCGWINSZ
  516.     /* tty windsize */
  517.     (void) ioctl(mfd, TIOCGWINSZ, &tty_winsize);
  518.     (void) ioctl(sfd, TIOCSWINSZ, &tty_winsize);
  519.  
  520. #endif
  521. }
  522.  
  523.  
  524. #endif /* HAVE_TERMIO_H */
  525.  
  526.  
  527. /*
  528.  * kill processes associated with a tty
  529.  */
  530. int tty_killpg(fd)
  531. int fd;
  532. {
  533.     int pgrp;
  534.     if ( ! isatty(fd) )
  535.     return;
  536.  
  537.     (void) ioctl(fd, TIOCGPGRP, (char *) &pgrp);
  538.     if ( pgrp > 1 ) /* ?? */
  539.         (void) killpg(pgrp, SIGTERM);
  540. }
  541.  
  542.  
  543. /* disassociate from controlling terminal */
  544. void tty_NoCtty()
  545. {
  546. #ifdef TIOCNOTTY
  547.     int tty;
  548.  
  549.     setpgrp(0, 0);
  550.     if ((tty = open("/dev/tty", O_RDWR) == -1) ||
  551.         (ioctl(0, TIOCNOTTY, 0) == -1) ||
  552.         (close(tty) == -1))
  553.     {
  554.         perror("ile - TIOCNOTTY on /dev/tty");
  555.     }
  556. #else
  557.         setpgrp();
  558. #endif
  559. }
  560.  
  561. int tty_wincols()
  562. {
  563.  
  564. #ifdef SIGWINCH
  565.     return  (tty_win.ws_col <= 0) ? 80 : tty_win.ws_col ;
  566. #else
  567.     return 80;
  568.  
  569. #endif
  570. }
  571.  
  572.  
  573.