Home | History | Annotate | Line # | Download | only in ksh
      1  1.10  andvar /*	$NetBSD: tty.c,v 1.10 2021/07/24 21:31:31 andvar 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.10  andvar __RCSID("$NetBSD: tty.c,v 1.10 2021/07/24 21:31:31 andvar Exp $");
      7   1.4     agc #endif
      8   1.4     agc 
      9   1.8   kamil #include <sys/stat.h>
     10   1.2     tls 
     11   1.1     jtc #include "sh.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 	    ret = ioctl(fd, TIOCSETN, &ts->sgttyb);
     78   1.1     jtc #   ifdef TIOCGATC
     79   1.1     jtc 	if (ioctl(fd, TIOCSATC, &ts->lchars) < 0)
     80   1.1     jtc 		ret = -1;
     81   1.1     jtc #   else
     82   1.1     jtc 	if (ioctl(fd, TIOCSETC, &ts->tchars) < 0)
     83   1.1     jtc 		ret = -1;
     84   1.1     jtc #    ifdef TIOCGLTC
     85   1.1     jtc 	if (ioctl(fd, TIOCSLTC, &ts->ltchars) < 0)
     86   1.1     jtc 		ret = -1;
     87   1.1     jtc #    endif /* TIOCGLTC */
     88   1.1     jtc #   endif /* TIOCGATC */
     89   1.1     jtc #  endif /* HAVE_TERMIO_H */
     90   1.1     jtc # endif /* HAVE_TERIOS_H */
     91   1.1     jtc 	return ret;
     92   1.1     jtc }
     93   1.1     jtc 
     94   1.1     jtc 
     95  1.10  andvar /* Initialize tty_fd.  Used for saving/resetting tty modes upon
     96   1.1     jtc  * foreground job completion and for setting up tty process group.
     97   1.1     jtc  */
     98   1.1     jtc void
     99   1.1     jtc tty_init(init_ttystate)
    100   1.1     jtc 	int init_ttystate;
    101   1.1     jtc {
    102   1.1     jtc 	int	do_close = 1;
    103   1.1     jtc 	int	tfd;
    104   1.3    fair 	const char	*devtty = _PATH_TTY;
    105   1.1     jtc 
    106   1.1     jtc 	if (tty_fd >= 0) {
    107   1.1     jtc 		close(tty_fd);
    108   1.1     jtc 		tty_fd = -1;
    109   1.1     jtc 	}
    110   1.1     jtc 	tty_devtty = 1;
    111   1.1     jtc 
    112   1.3    fair 	if ((tfd = open(devtty, O_RDWR, 0)) < 0) {
    113   1.2     tls 		if (tfd < 0) {
    114   1.2     tls 			tty_devtty = 0;
    115   1.9   kamil 			warningf(false,
    116   1.3    fair 				"No controlling tty (open %s: %s)",
    117   1.3    fair 				devtty, strerror(errno));
    118   1.2     tls 		}
    119   1.1     jtc 	}
    120   1.1     jtc 
    121   1.1     jtc 	if (tfd < 0) {
    122   1.1     jtc 		do_close = 0;
    123   1.1     jtc 		if (isatty(0))
    124   1.1     jtc 			tfd = 0;
    125   1.1     jtc 		else if (isatty(2))
    126   1.1     jtc 			tfd = 2;
    127   1.1     jtc 		else {
    128   1.9   kamil 			warningf(false, "Can't find tty file descriptor");
    129   1.1     jtc 			return;
    130   1.1     jtc 		}
    131   1.1     jtc 	}
    132   1.1     jtc 	if ((tty_fd = ksh_dupbase(tfd, FDBASE)) < 0) {
    133   1.9   kamil 		warningf(false, "j_ttyinit: dup of tty fd failed: %s",
    134   1.1     jtc 			strerror(errno));
    135   1.1     jtc 	} else if (fd_clexec(tty_fd) < 0) {
    136   1.9   kamil 		warningf(false, "j_ttyinit: can't set close-on-exec flag: %s",
    137   1.1     jtc 			strerror(errno));
    138   1.1     jtc 		close(tty_fd);
    139   1.1     jtc 		tty_fd = -1;
    140   1.1     jtc 	} else if (init_ttystate)
    141   1.1     jtc 		get_tty(tty_fd, &tty_state);
    142   1.1     jtc 	if (do_close)
    143   1.1     jtc 		close(tfd);
    144   1.1     jtc }
    145   1.1     jtc 
    146   1.1     jtc void
    147   1.1     jtc tty_close()
    148   1.1     jtc {
    149   1.1     jtc 	if (tty_fd >= 0) {
    150   1.1     jtc 		close(tty_fd);
    151   1.1     jtc 		tty_fd = -1;
    152   1.1     jtc 	}
    153   1.1     jtc }
    154