home *** CD-ROM | disk | FTP | other *** search
- /*
- * tty.c - ile - Hops 07.06.94 *
- */
-
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <signal.h>
- #include <stdio.h>
-
-
- #ifdef HAVE_TERMIO_H
- #include <termio.h>
- #else
- #include <sys/ioctl.h>
- #endif /* HAVE_TERMIO_H */
-
- /* Include the local include file after all the system includes */
- #include "ile.h"
-
-
- /* These are the terminal manipulation routines. :) Fun! */
-
-
- #ifdef SIGWINCH /* Starting window structure */
-
- /* I am using struct winsize here, but redefining it, because
- Each system seems to define it in a different place, or not
- at all. The actual structure never seems to change though. :)
- */
-
- struct winstats {
- unsigned short ws_row; /* rows, in characters */
- unsigned short ws_col; /* columns, in characters */
- unsigned short ws_xpixel; /* horizontal size, pixels - not used */
- unsigned short ws_ypixel; /* vertical size, pixels - not used */
- } tty_win;
-
-
- /* The window size has changed, let the pty know. Used as a signal handler */
-
-
-
- /*------------------------------------------------------------------*/
-
- /*
- * If the window changes size, tell the slave_tty about it.
- */
- void
- change_window()
- {
- int pgrp;
-
- #ifdef TIOCGWINSZ
- (void) ioctl(0, TIOCGWINSZ, &tty_win);
- (void) ioctl(slave_tty, TIOCSWINSZ, &tty_win);
- #endif /* TIOCGWINSZ */
-
- (void) ioctl(slave_tty, TIOCGPGRP, (char *) &pgrp);
- if ( pgrp > 1 ) /* ?? */
- (void) killpg(pgrp, SIGWINCH);
-
- /* note the change so that we don't die after select */
-
- windowchanged = TRUE;
- }
-
- #if 0
- void updatewin()
- {
- #ifdef TIOCGWINSZ
- (void) ioctl(ttyfd, TIOCGWINSZ, &tty_win);
- (void) ioctl(masterfd, TIOCSWINSZ, &tty_win);
- #endif /* TIOCGWINSZ */
-
- /* An interesting note...
- I had code here to send a SIGWINCH to the pty
- process, but it turns out the kernel does when
- the pty recieves the TIOCSWINSZ ioctl. */
- }
- #endif /* 0 */
-
-
- #endif /* SIGWINCH */
-
-
- #ifdef HAVE_TERMIO_H
-
- /* Get the modes of the contorlling tty and save them. Saves
- ttymodes in tty_mode and returns -1 if ioctl fails. */
-
- struct termio tty_mode; /* Save tty mode here */
- int tty_init=0;
-
-
- int tty_getmode(fd)
- int fd;
- {
- tty_init=1; /* Flag: we have initialized the tty_mode struct */
- d_zero((char *)&tty_mode, sizeof(struct termio));
-
- if ( ! isatty(fd) )
- return(0);
-
- if (ioctl(fd, TCGETA, (char *) &tty_mode) < 0)
- return(-1);
-
- #if defined(SIGWINCH) && defined(TIOCGWINSZ)
- d_zero((char *)&tty_win, sizeof(struct winstats));
-
- (void) ioctl(fd, TIOCGWINSZ, &tty_win);
- #endif /* SIGWINCH */
-
- return(0);
- }
-
-
- /* Restore terminal's mode to whatever it was on the most
- recent call to the tty_getmode() function. */
-
- int tty_reset(fd)
- int fd;
- {
- if ( ! tty_init )
- return(-1);
-
- if ( ! isatty(fd) )
- return(0);
-
- if (ioctl(fd, TCSETA, (char *) &tty_mode) < 0)
- return(-1);
-
- #if defined(SIGWINCH) && defined(TIOCSWINSZ)
- (void) ioctl(fd, TIOCSWINSZ, &tty_win);
- #endif /* SIGWINCH */
-
- return(0);
- }
-
-
- /* Set a tty to a sane mode */
-
- int tty_sane(fd)
- int fd;
- {
- struct termio temp_mode;
-
- if ( ! isatty(fd) )
- return(0);
-
- #ifdef DEBUG
- fprintf(stderr, "tty_init: %d\r\n", tty_init);
- #endif
-
- temp_mode.c_lflag=(ISIG|ICANON|ECHO|ECHOE);
- temp_mode.c_iflag=(BRKINT|IGNPAR|ISTRIP|ICRNL|IXON);
- temp_mode.c_oflag=(OPOST|ONLCR);
- temp_mode.c_cflag=(CS7|PARENB|CREAD);
- temp_mode.c_cc[VERASE]=('H'^64);
- temp_mode.c_cc[VKILL]=('U'^64);
- temp_mode.c_cc[VQUIT]=('\\'^64);
- temp_mode.c_cc[VINTR]=('C'^64);
- temp_mode.c_cc[VEOF]=('D'^64);
-
- if (ioctl(fd, TCSETA, (char *) &temp_mode) < 0)
- return(-1);
-
- return(0);
- }
-
-
- /* Set a terminal in raw mode */
-
- int tty_raw(fd)
- int fd; /* file descriptor of tty device */
- {
- struct termio temp_mode;
-
- if ( ! isatty(fd) )
- return(0);
-
- if ( ioctl(fd, TCGETA, (char *)&temp_mode) < 0 )
- return(-1);
-
- temp_mode.c_iflag=(IGNBRK | ISTRIP); /* turn off all input control */
- temp_mode.c_oflag &= ~(OLCUC | ONLCR | OCRNL | ONLRET);
- /* disable output post-processing */
- temp_mode.c_lflag = 0;
- temp_mode.c_cc[VMIN]=1; /* 1 or more chars satisfy read */
- temp_mode.c_cc[VTIME]=0; /* 10'ths of seconds between chars */
-
- if (ioctl(fd, TCSETA, (char *) &temp_mode) < 0)
- return(-1);
- return(0);
- }
-
-
- /* Function to set a tty echo or no echo */
-
- int tty_echo(fd, echo)
- int fd;
- int echo;
- {
- struct termio temp_mode;
-
- if ( ! isatty(fd) )
- return(0);
-
- if ( ioctl(fd, TCGETA, &temp_mode) < 0 )
- return(-1);
-
- if ( echo )
- temp_mode.c_lflag|=ECHO;
- else
- temp_mode.c_lflag&=(~ECHO);
-
- if ( ioctl(fd, TCSETA, &temp_mode) < 0 )
- return(-1);
- return(0);
- }
-
- /* one level stack for pushing or popping echo status
- * must push first ( turns echo off )
- * pop to restore orig modes
- */
- int tty_noecho(fd, op)
- int fd;
- int op; /* PUSH or POP */
- {
- static struct termio orig_mode;
- struct termio temp_mode;
-
- if ( ! isatty(fd) )
- return(0);
-
- if ( op == PUSH )
- {
-
- if ( ioctl(fd, TCGETA, &temp_mode) < 0 )
- {
- fprintf(stderr, "tty_noecho TCGETA failed \n");
- return(-1);
- }
-
- orig_mode = temp_mode ;
- temp_mode.c_lflag &= (~ECHO);
- }
- else if (op == POP )
- temp_mode = orig_mode;
- else
- {
- fprintf(stderr, "tty_noecho() bad OP \n");
- return -1;
- }
-
- if ( ioctl(fd, TCSETA, &temp_mode) < 0 )
- {
- fprintf(stderr, "tty_noecho TCSETA failed \n");
- return(-1);
- }
- return(0);
- }
-
-
- /* return TRUE if the fd has echo off */
- int tty_silentmode( fd )
- int fd;
- {
- struct termio params;
-
- if ( ! isatty(fd) )
- return(0);
-
-
- (void) ioctl(fd, TCGETA, ¶ms);
-
- return (( params.c_lflag & ECHO) == 0);
- }
-
- /* replicate master tty modes into slave */
- void tty_replic( mfd, sfd )
- int mfd;
- int sfd;
- {
- struct termio temp_mode;
-
- if ( !isatty(mfd) || !isatty(sfd) )
- return;
-
-
- ioctl(mfd, TCGETA, (char *) &temp_mode);
-
- ioctl(sfd, TCSETA, (char *)&temp_mode) ;
-
- }
-
- #else /* ---------------- no /usr/include/termio.h ---------------- */
-
-
- /* Get the modes of the controlling tty and save them. Saves
- ttymodes in tty_mode and returns 1 if ioctl fails. */
-
- static struct sgttyb tty_mode; /* save tty mode here */
- int tty_init=0;
-
- int tty_getmode(fd)
- int fd;
- {
- if ( ! isatty(fd) )
- return(0);
-
- tty_init=1; /* Flag: we have initialized the tty_mode struct */
-
- if (ioctl(fd, TIOCGETP, (char *) &tty_mode) < 0)
- return(-1);
-
- #ifdef SIGWINCH
- if ( ioctl(fd, TIOCGWINSZ, &tty_win) < 0 )
- perror("ioctl TIOCGWINSZ error");
- #endif /* SIGWINCH */
-
- return(0);
- }
-
-
- /*
- * Restore a terminal's mode to whatever it was on the most
- * recent call to the tty_getmode() function above.
- */
-
- int tty_reset(fd)
- int fd; /* of terminal device */
- {
- if ( ! tty_init ) /* Have we been initialized? */
- return(-1);
-
- if ( ! isatty(fd) )
- return(0);
-
- if (ioctl(fd, TIOCSETP, (char *) &tty_mode) < 0)
- return(-1);
-
- #ifdef SIGWINCH
- (void) ioctl(fd, TIOCSWINSZ, &tty_win);
- #endif /* SIGWINCH */
-
- return(0);
- }
- /* Set a tty to a sane mode */
-
- int tty_sane(fd)
- int fd;
- {
- struct sgttyb temp_mode;
-
- if ( ! isatty(fd) )
- return(0);
-
- if (ioctl(fd, TIOCGETP, (char *) &temp_mode) < 0)
- return(-1);
-
- temp_mode.sg_flags &= ~RAW; /* turn RAW mode off */
- temp_mode.sg_flags |= ECHO; /* turn ECHO on */
-
- if (ioctl(fd, TIOCSETP, (char *) &temp_mode) < 0)
- return(-1);
-
- return(0);
- }
-
- /*
- * Put a terminal device into RAW mode with ECHO off.
- */
-
- int tty_raw(fd)
- int fd; /* of terminal device */
- {
- struct sgttyb temp_mode;
-
- if ( ! isatty(fd) )
- return(0);
-
- if (ioctl(fd, TIOCGETP, (char *) &temp_mode) < 0)
- return(-1);
-
- temp_mode.sg_flags |= RAW; /* turn RAW mode on */
- temp_mode.sg_flags &= ~ECHO; /* turn ECHO off */
-
- if (ioctl(fd, TIOCSETP, (char *) &temp_mode) < 0)
- return(-1);
-
- return(0);
- }
-
-
- /* Set a terminal echo or no echo, as requested. */
-
- int tty_echo(fd, echo)
- int fd;
- int echo;
- {
- struct sgttyb temp_mode;
-
- if ( ! isatty(fd) )
- return(0);
-
- if (ioctl(fd, TIOCGETP, (char *) &temp_mode) < 0)
- return(-1);
-
- if ( echo )
- temp_mode.sg_flags |= ECHO; /* turn ECHO on */
- else
- temp_mode.sg_flags &= ~ECHO; /* turn ECHO off */
-
- if (ioctl(fd, TIOCSETP, (char *) &temp_mode) < 0)
- return(-1);
-
- return(0);
- }
-
-
- /* one level stack for pushing or popping echo status
- * must push first ( turns echo off )
- * pop to restore orig modes
- */
- int tty_noecho(fd, op)
- int fd;
- int op; /* PUSH or POP */
- {
- static struct termio orig_mode;
- struct termio temp_mode;
-
- if ( ! isatty(fd) )
- return(0);
-
- if ( op == PUSH )
- {
-
- if (ioctl(fd, TIOCGETP, (char *) &temp_mode) < 0)
- return(-1);
-
- orig_mode = temp_mode ;
-
- temp_mode.sg_flags |= RAW; /* turn RAW mode on */
- temp_mode.sg_flags &= ~ECHO; /* turn ECHO off */
- }
- else if (op == POP )
- temp_mode = orig_mode;
- else
- {
- fprintf(stderr, "tty_noecho() bad OP \n");
- return -1;
- }
-
- if (ioctl(fd, TIOCSETP, (char *) &temp_mode) < 0)
- return(-1);
-
- return(0);
- }
-
- /* return TRUE if the slave is
- * in RAW or CBREAK mode, or has turned off ECHO
- */
- int tty_silentmode( fd )
- int fd;
- {
- struct sgttyb params;
-
- if ( ! isatty(fd) )
- return(0);
-
- (void) ioctl(fd, TIOCGETP, ¶ms);
-
- return (
- ((params.sg_flags & (RAW | CBREAK)) != 0) ||
- (params.sg_flags & ECHO) == 0 ) ;
- }
-
-
- /* replicate Master fd state onto slave fd */
- void tty_replic( mfd, sfd )
- int mfd;
- int sfd;
- {
- struct sgttyb tty_sgttyb;
- struct tchars tty_tchars;
- struct ltchars tty_ltchars;
- struct winsize tty_winsize;
- int tty_mode;
-
- (void) ioctl(mfd, TIOCGETP, &tty_sgttyb);
- (void) ioctl(sfd, TIOCSETP, &tty_sgttyb);
-
- /* tty line discipline */
-
- (void) ioctl(mfd, TIOCGETD, &tty_ldisc);
- (void) ioctl(sfd, TIOCSETD, &tty_ldisc);
-
- /* tty tchars */
-
- (void) ioctl(mfd, TIOCGETC, &tty_tchars);
- (void) ioctl(sfd, TIOCSETC, &tty_tchars);
-
- /* tty mode */
-
- (void) ioctl(mfd, TIOCLGET, &tty_mode);
- (void) ioctl(sfd, TIOCLSET, &tty_mode);
-
- /* tty ltchars */
-
- (void) ioctl(mfd, TIOCGLTC, &tty_ltchars);
- (void) ioctl(sfd, TIOCSLTC, &tty_ltchars);
-
-
- #ifdef TIOCGWINSZ
- /* tty windsize */
- (void) ioctl(mfd, TIOCGWINSZ, &tty_winsize);
- (void) ioctl(sfd, TIOCSWINSZ, &tty_winsize);
-
- #endif
- }
-
-
- #endif /* HAVE_TERMIO_H */
-
-
- /*
- * kill processes associated with a tty
- */
- int tty_killpg(fd)
- int fd;
- {
- int pgrp;
- if ( ! isatty(fd) )
- return;
-
- (void) ioctl(fd, TIOCGPGRP, (char *) &pgrp);
- if ( pgrp > 1 ) /* ?? */
- (void) killpg(pgrp, SIGTERM);
- }
-
-
- /* disassociate from controlling terminal */
- void tty_NoCtty()
- {
- #ifdef TIOCNOTTY
- int tty;
-
- setpgrp(0, 0);
- if ((tty = open("/dev/tty", O_RDWR) == -1) ||
- (ioctl(0, TIOCNOTTY, 0) == -1) ||
- (close(tty) == -1))
- {
- perror("ile - TIOCNOTTY on /dev/tty");
- }
- #else
- setpgrp();
- #endif
- }
-
- int tty_wincols()
- {
-
- #ifdef SIGWINCH
- return (tty_win.ws_col <= 0) ? 80 : tty_win.ws_col ;
- #else
- return 80;
-
- #endif
- }
-
-
-