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