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