tty.c revision 1.1 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 jtc /* X11R5 xterm on mips doesn't set controlling tty properly - temporary hack */
116 1.1 jtc # if !defined(__mips) || !(defined(_SYSTYPE_BSD43) || defined(__SYSTYPE_BSD43))
117 1.1 jtc tty_devtty = 0;
118 1.1 jtc warningf(FALSE, "No controlling tty (open /dev/tty: %s)",
119 1.1 jtc strerror(errno));
120 1.1 jtc # endif /* __mips */
121 1.1 jtc }
122 1.1 jtc #else /* !__SCO__ */
123 1.1 jtc tfd = -1;
124 1.1 jtc #endif /* __SCO__ */
125 1.1 jtc
126 1.1 jtc if (tfd < 0) {
127 1.1 jtc do_close = 0;
128 1.1 jtc if (isatty(0))
129 1.1 jtc tfd = 0;
130 1.1 jtc else if (isatty(2))
131 1.1 jtc tfd = 2;
132 1.1 jtc else {
133 1.1 jtc warningf(FALSE, "Can't find tty file descriptor");
134 1.1 jtc return;
135 1.1 jtc }
136 1.1 jtc }
137 1.1 jtc if ((tty_fd = ksh_dupbase(tfd, FDBASE)) < 0) {
138 1.1 jtc warningf(FALSE, "j_ttyinit: dup of tty fd failed: %s",
139 1.1 jtc strerror(errno));
140 1.1 jtc } else if (fd_clexec(tty_fd) < 0) {
141 1.1 jtc warningf(FALSE, "j_ttyinit: can't set close-on-exec flag: %s",
142 1.1 jtc strerror(errno));
143 1.1 jtc close(tty_fd);
144 1.1 jtc tty_fd = -1;
145 1.1 jtc } else if (init_ttystate)
146 1.1 jtc get_tty(tty_fd, &tty_state);
147 1.1 jtc if (do_close)
148 1.1 jtc close(tfd);
149 1.1 jtc }
150 1.1 jtc
151 1.1 jtc void
152 1.1 jtc tty_close()
153 1.1 jtc {
154 1.1 jtc if (tty_fd >= 0) {
155 1.1 jtc close(tty_fd);
156 1.1 jtc tty_fd = -1;
157 1.1 jtc }
158 1.1 jtc }
159