1 /* $OpenBSD: tty.c,v 1.2 1996/10/01 02:05:51 downsj 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 108 if (tty_fd >= 0) { 109 close(tty_fd); 110 tty_fd = -1; 111 } 112 tty_devtty = 1; 113 114 /* SCO can't job control on /dev/tty, so don't try... */ 115 #if !defined(__SCO__) 116 if ((tfd = open("/dev/tty", O_RDWR, 0)) < 0) { 117 #ifdef __NeXT 118 /* rlogin on NeXT boxes does not set up the controlling tty, 119 * so force it to be done here... 120 */ 121 { 122 extern char *ttyname ARGS((int)); 123 char *s = ttyname(isatty(2) ? 2 : 0); 124 int fd; 125 126 if (s && (fd = open(s, O_RDWR, 0)) >= 0) { 127 close(fd); 128 tfd = open("/dev/tty", O_RDWR, 0); 129 } 130 } 131 #endif /* __NeXT */ 132 133 /* X11R5 xterm on mips doesn't set controlling tty properly - temporary hack */ 134 # if !defined(__mips) || !(defined(_SYSTYPE_BSD43) || defined(__SYSTYPE_BSD43)) 135 if (tfd < 0) { 136 tty_devtty = 0; 137 warningf(FALSE, 138 "No controlling tty (open /dev/tty: %s)", 139 strerror(errno)); 140 } 141 # endif /* __mips */ 142 } 143 #else /* !__SCO__ */ 144 tfd = -1; 145 #endif /* __SCO__ */ 146 147 if (tfd < 0) { 148 do_close = 0; 149 if (isatty(0)) 150 tfd = 0; 151 else if (isatty(2)) 152 tfd = 2; 153 else { 154 warningf(FALSE, "Can't find tty file descriptor"); 155 return; 156 } 157 } 158 if ((tty_fd = ksh_dupbase(tfd, FDBASE)) < 0) { 159 warningf(FALSE, "j_ttyinit: dup of tty fd failed: %s", 160 strerror(errno)); 161 } else if (fd_clexec(tty_fd) < 0) { 162 warningf(FALSE, "j_ttyinit: can't set close-on-exec flag: %s", 163 strerror(errno)); 164 close(tty_fd); 165 tty_fd = -1; 166 } else if (init_ttystate) 167 get_tty(tty_fd, &tty_state); 168 if (do_close) 169 close(tfd); 170 } 171 172 void 173 tty_close() 174 { 175 if (tty_fd >= 0) { 176 close(tty_fd); 177 tty_fd = -1; 178 } 179 } 180