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