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