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