Home | History | Annotate | Line # | Download | only in ksh
tty.c revision 1.4
      1  1.4   agc /*	$NetBSD: tty.c,v 1.4 2003/06/23 11:39:06 agc Exp $	*/
      2  1.4   agc 
      3  1.4   agc #include <sys/cdefs.h>
      4  1.4   agc 
      5  1.4   agc #ifndef lint
      6  1.4   agc __RCSID("$NetBSD: tty.c,v 1.4 2003/06/23 11:39:06 agc Exp $");
      7  1.4   agc #endif
      8  1.4   agc 
      9  1.2   tls 
     10  1.1   jtc #include "sh.h"
     11  1.1   jtc #include "ksh_stat.h"
     12  1.1   jtc #define EXTERN
     13  1.1   jtc #include "tty.h"
     14  1.1   jtc #undef EXTERN
     15  1.1   jtc 
     16  1.1   jtc int
     17  1.1   jtc get_tty(fd, ts)
     18  1.1   jtc 	int fd;
     19  1.1   jtc 	TTY_state *ts;
     20  1.1   jtc {
     21  1.1   jtc 	int ret;
     22  1.1   jtc 
     23  1.1   jtc # ifdef HAVE_TERMIOS_H
     24  1.1   jtc 	ret = tcgetattr(fd, ts);
     25  1.1   jtc # else /* HAVE_TERIOS_H */
     26  1.1   jtc #  ifdef HAVE_TERMIO_H
     27  1.1   jtc 	ret = ioctl(fd, TCGETA, ts);
     28  1.1   jtc #  else /* HAVE_TERMIO_H */
     29  1.1   jtc 	ret = ioctl(fd, TIOCGETP, &ts->sgttyb);
     30  1.1   jtc #   ifdef TIOCGATC
     31  1.1   jtc 	if (ioctl(fd, TIOCGATC, &ts->lchars) < 0)
     32  1.1   jtc 		ret = -1;
     33  1.1   jtc #   else
     34  1.1   jtc 	if (ioctl(fd, TIOCGETC, &ts->tchars) < 0)
     35  1.1   jtc 		ret = -1;
     36  1.1   jtc #    ifdef TIOCGLTC
     37  1.1   jtc 	if (ioctl(fd, TIOCGLTC, &ts->ltchars) < 0)
     38  1.1   jtc 		ret = -1;
     39  1.1   jtc #    endif /* TIOCGLTC */
     40  1.1   jtc #   endif /* TIOCGATC */
     41  1.1   jtc #  endif /* HAVE_TERMIO_H */
     42  1.1   jtc # endif /* HAVE_TERIOS_H */
     43  1.1   jtc 	return ret;
     44  1.1   jtc }
     45  1.1   jtc 
     46  1.1   jtc int
     47  1.1   jtc set_tty(fd, ts, flags)
     48  1.1   jtc 	int fd;
     49  1.1   jtc 	TTY_state *ts;
     50  1.1   jtc 	int flags;
     51  1.1   jtc {
     52  1.1   jtc 	int ret = 0;
     53  1.1   jtc 
     54  1.1   jtc # ifdef HAVE_TERMIOS_H
     55  1.1   jtc 	ret = tcsetattr(fd, TCSADRAIN, ts);
     56  1.1   jtc # else /* HAVE_TERIOS_H */
     57  1.1   jtc #  ifdef HAVE_TERMIO_H
     58  1.1   jtc #   ifndef TCSETAW				/* e.g. Cray-2 */
     59  1.1   jtc 		/* first wait for output to drain */
     60  1.1   jtc #    ifdef TCSBRK
     61  1.1   jtc 		if (ioctl(tty_fd, TCSBRK, 1) < 0)
     62  1.1   jtc 			ret = -1;
     63  1.1   jtc #    else /* the following kludge is minimally intrusive, but sometimes fails */
     64  1.1   jtc 		if (flags & TF_WAIT)
     65  1.1   jtc 			sleep((unsigned)1);	/* fake it */
     66  1.1   jtc #    endif
     67  1.1   jtc #   endif /* !TCSETAW */
     68  1.1   jtc #   if defined(_BSD_SYSV) || !defined(TCSETAW)
     69  1.1   jtc /* _BSD_SYSV must force TIOCSETN instead of TIOCSETP (preserve type-ahead) */
     70  1.1   jtc 		if (ioctl(tty_fd, TCSETA, ts) < 0)
     71  1.1   jtc 			ret = -1;
     72  1.1   jtc #   else
     73  1.1   jtc 		if (ioctl(tty_fd, TCSETAW, ts) < 0)
     74  1.1   jtc 			ret = -1;
     75  1.1   jtc #   endif
     76  1.1   jtc #  else /* HAVE_TERMIO_H */
     77  1.1   jtc #   if defined(__mips) && (defined(_SYSTYPE_BSD43) || defined(__SYSTYPE_BSD43))
     78  1.1   jtc 	/* Under RISC/os 5.00, bsd43 environment, after a tty driver
     79  1.1   jtc 	 * generated interrupt (eg, INTR, TSTP), all output to tty is
     80  1.1   jtc 	 * lost until a SETP is done (there must be a better way of
     81  1.1   jtc 	 * doing this...).
     82  1.1   jtc 	 */
     83  1.1   jtc 	if (flags & TF_MIPSKLUDGE)
     84  1.1   jtc 		ret = ioctl(fd, TIOCSETP, &ts->sgttyb);
     85  1.1   jtc 	else
     86  1.1   jtc #   endif /* _SYSTYPE_BSD43 */
     87  1.1   jtc 	    ret = ioctl(fd, TIOCSETN, &ts->sgttyb);
     88  1.1   jtc #   ifdef TIOCGATC
     89  1.1   jtc 	if (ioctl(fd, TIOCSATC, &ts->lchars) < 0)
     90  1.1   jtc 		ret = -1;
     91  1.1   jtc #   else
     92  1.1   jtc 	if (ioctl(fd, TIOCSETC, &ts->tchars) < 0)
     93  1.1   jtc 		ret = -1;
     94  1.1   jtc #    ifdef TIOCGLTC
     95  1.1   jtc 	if (ioctl(fd, TIOCSLTC, &ts->ltchars) < 0)
     96  1.1   jtc 		ret = -1;
     97  1.1   jtc #    endif /* TIOCGLTC */
     98  1.1   jtc #   endif /* TIOCGATC */
     99  1.1   jtc #  endif /* HAVE_TERMIO_H */
    100  1.1   jtc # endif /* HAVE_TERIOS_H */
    101  1.1   jtc 	return ret;
    102  1.1   jtc }
    103  1.1   jtc 
    104  1.1   jtc 
    105  1.1   jtc /* Initialize tty_fd.  Used for saving/reseting tty modes upon
    106  1.1   jtc  * foreground job completion and for setting up tty process group.
    107  1.1   jtc  */
    108  1.1   jtc void
    109  1.1   jtc tty_init(init_ttystate)
    110  1.1   jtc 	int init_ttystate;
    111  1.1   jtc {
    112  1.1   jtc 	int	do_close = 1;
    113  1.1   jtc 	int	tfd;
    114  1.3  fair 	const char	*devtty = _PATH_TTY;
    115  1.1   jtc 
    116  1.1   jtc 	if (tty_fd >= 0) {
    117  1.1   jtc 		close(tty_fd);
    118  1.1   jtc 		tty_fd = -1;
    119  1.1   jtc 	}
    120  1.1   jtc 	tty_devtty = 1;
    121  1.1   jtc 
    122  1.1   jtc 	/* SCO can't job control on /dev/tty, so don't try... */
    123  1.1   jtc #if !defined(__SCO__)
    124  1.3  fair 	if ((tfd = open(devtty, O_RDWR, 0)) < 0) {
    125  1.2   tls #ifdef __NeXT
    126  1.2   tls 		/* rlogin on NeXT boxes does not set up the controlling tty,
    127  1.2   tls 		 * so force it to be done here...
    128  1.2   tls 		 */
    129  1.2   tls 		{
    130  1.2   tls 			extern char *ttyname ARGS((int));
    131  1.2   tls 			char *s = ttyname(isatty(2) ? 2 : 0);
    132  1.2   tls 			int fd;
    133  1.2   tls 
    134  1.2   tls 			if (s && (fd = open(s, O_RDWR, 0)) >= 0) {
    135  1.2   tls 				close(fd);
    136  1.3  fair 				tfd = open(devtty, O_RDWR, 0);
    137  1.2   tls 			}
    138  1.2   tls 		}
    139  1.2   tls #endif /* __NeXT */
    140  1.2   tls 
    141  1.1   jtc /* X11R5 xterm on mips doesn't set controlling tty properly - temporary hack */
    142  1.1   jtc # if !defined(__mips) || !(defined(_SYSTYPE_BSD43) || defined(__SYSTYPE_BSD43))
    143  1.2   tls 		if (tfd < 0) {
    144  1.2   tls 			tty_devtty = 0;
    145  1.2   tls 			warningf(FALSE,
    146  1.3  fair 				"No controlling tty (open %s: %s)",
    147  1.3  fair 				devtty, strerror(errno));
    148  1.2   tls 		}
    149  1.1   jtc # endif /* __mips  */
    150  1.1   jtc 	}
    151  1.1   jtc #else /* !__SCO__ */
    152  1.1   jtc 	tfd = -1;
    153  1.1   jtc #endif /* __SCO__ */
    154  1.1   jtc 
    155  1.1   jtc 	if (tfd < 0) {
    156  1.1   jtc 		do_close = 0;
    157  1.1   jtc 		if (isatty(0))
    158  1.1   jtc 			tfd = 0;
    159  1.1   jtc 		else if (isatty(2))
    160  1.1   jtc 			tfd = 2;
    161  1.1   jtc 		else {
    162  1.1   jtc 			warningf(FALSE, "Can't find tty file descriptor");
    163  1.1   jtc 			return;
    164  1.1   jtc 		}
    165  1.1   jtc 	}
    166  1.1   jtc 	if ((tty_fd = ksh_dupbase(tfd, FDBASE)) < 0) {
    167  1.1   jtc 		warningf(FALSE, "j_ttyinit: dup of tty fd failed: %s",
    168  1.1   jtc 			strerror(errno));
    169  1.1   jtc 	} else if (fd_clexec(tty_fd) < 0) {
    170  1.1   jtc 		warningf(FALSE, "j_ttyinit: can't set close-on-exec flag: %s",
    171  1.1   jtc 			strerror(errno));
    172  1.1   jtc 		close(tty_fd);
    173  1.1   jtc 		tty_fd = -1;
    174  1.1   jtc 	} else if (init_ttystate)
    175  1.1   jtc 		get_tty(tty_fd, &tty_state);
    176  1.1   jtc 	if (do_close)
    177  1.1   jtc 		close(tfd);
    178  1.1   jtc }
    179  1.1   jtc 
    180  1.1   jtc void
    181  1.1   jtc tty_close()
    182  1.1   jtc {
    183  1.1   jtc 	if (tty_fd >= 0) {
    184  1.1   jtc 		close(tty_fd);
    185  1.1   jtc 		tty_fd = -1;
    186  1.1   jtc 	}
    187  1.1   jtc }
    188