etc/protocols - sync with NetBSD-8
[minix.git] / bin / ksh / tty.c
blob8a60d732956c9afedc968ccb0dca4c5d659640c8
1 /* $NetBSD: tty.c,v 1.4 2003/06/23 11:39:06 agc Exp $ */
3 #include <sys/cdefs.h>
5 #ifndef lint
6 __RCSID("$NetBSD: tty.c,v 1.4 2003/06/23 11:39:06 agc Exp $");
7 #endif
10 #include "sh.h"
11 #include "ksh_stat.h"
12 #define EXTERN
13 #include "tty.h"
14 #undef EXTERN
16 int
17 get_tty(fd, ts)
18 int fd;
19 TTY_state *ts;
21 int ret;
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;
46 int
47 set_tty(fd, ts, flags)
48 int fd;
49 TTY_state *ts;
50 int flags;
52 int ret = 0;
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...).
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;
105 /* Initialize tty_fd. Used for saving/reseting tty modes upon
106 * foreground job completion and for setting up tty process group.
108 void
109 tty_init(init_ttystate)
110 int init_ttystate;
112 int do_close = 1;
113 int tfd;
114 const char *devtty = _PATH_TTY;
116 if (tty_fd >= 0) {
117 close(tty_fd);
118 tty_fd = -1;
120 tty_devtty = 1;
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...
130 extern char *ttyname ARGS((int));
131 char *s = ttyname(isatty(2) ? 2 : 0);
132 int fd;
134 if (s && (fd = open(s, O_RDWR, 0)) >= 0) {
135 close(fd);
136 tfd = open(devtty, O_RDWR, 0);
139 #endif /* __NeXT */
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));
149 # endif /* __mips */
151 #else /* !__SCO__ */
152 tfd = -1;
153 #endif /* __SCO__ */
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;
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);
180 void
181 tty_close()
183 if (tty_fd >= 0) {
184 close(tty_fd);
185 tty_fd = -1;