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