tty.c revision 1.9 1 1.9 kamil /* $NetBSD: tty.c,v 1.9 2017/06/30 04:41:19 kamil Exp $ */
2 1.4 agc
3 1.4 agc #include <sys/cdefs.h>
4 1.4 agc
5 1.4 agc #ifndef lint
6 1.9 kamil __RCSID("$NetBSD: tty.c,v 1.9 2017/06/30 04:41:19 kamil Exp $");
7 1.4 agc #endif
8 1.4 agc
9 1.8 kamil #include <sys/stat.h>
10 1.2 tls
11 1.1 jtc #include "sh.h"
12 1.1 jtc #define EXTERN
13 1.1 jtc #include "tty.h"
14 1.1 jtc #undef EXTERN
15 1.1 jtc
16 1.1 jtc int
17 1.1 jtc get_tty(fd, ts)
18 1.1 jtc int fd;
19 1.1 jtc TTY_state *ts;
20 1.1 jtc {
21 1.1 jtc int ret;
22 1.1 jtc
23 1.1 jtc # ifdef HAVE_TERMIOS_H
24 1.1 jtc ret = tcgetattr(fd, ts);
25 1.1 jtc # else /* HAVE_TERIOS_H */
26 1.1 jtc # ifdef HAVE_TERMIO_H
27 1.1 jtc ret = ioctl(fd, TCGETA, ts);
28 1.1 jtc # else /* HAVE_TERMIO_H */
29 1.1 jtc ret = ioctl(fd, TIOCGETP, &ts->sgttyb);
30 1.1 jtc # ifdef TIOCGATC
31 1.1 jtc if (ioctl(fd, TIOCGATC, &ts->lchars) < 0)
32 1.1 jtc ret = -1;
33 1.1 jtc # else
34 1.1 jtc if (ioctl(fd, TIOCGETC, &ts->tchars) < 0)
35 1.1 jtc ret = -1;
36 1.1 jtc # ifdef TIOCGLTC
37 1.1 jtc if (ioctl(fd, TIOCGLTC, &ts->ltchars) < 0)
38 1.1 jtc ret = -1;
39 1.1 jtc # endif /* TIOCGLTC */
40 1.1 jtc # endif /* TIOCGATC */
41 1.1 jtc # endif /* HAVE_TERMIO_H */
42 1.1 jtc # endif /* HAVE_TERIOS_H */
43 1.1 jtc return ret;
44 1.1 jtc }
45 1.1 jtc
46 1.1 jtc int
47 1.1 jtc set_tty(fd, ts, flags)
48 1.1 jtc int fd;
49 1.1 jtc TTY_state *ts;
50 1.1 jtc int flags;
51 1.1 jtc {
52 1.1 jtc int ret = 0;
53 1.1 jtc
54 1.1 jtc # ifdef HAVE_TERMIOS_H
55 1.1 jtc ret = tcsetattr(fd, TCSADRAIN, ts);
56 1.1 jtc # else /* HAVE_TERIOS_H */
57 1.1 jtc # ifdef HAVE_TERMIO_H
58 1.1 jtc # ifndef TCSETAW /* e.g. Cray-2 */
59 1.1 jtc /* first wait for output to drain */
60 1.1 jtc # ifdef TCSBRK
61 1.1 jtc if (ioctl(tty_fd, TCSBRK, 1) < 0)
62 1.1 jtc ret = -1;
63 1.1 jtc # else /* the following kludge is minimally intrusive, but sometimes fails */
64 1.1 jtc if (flags & TF_WAIT)
65 1.1 jtc sleep((unsigned)1); /* fake it */
66 1.1 jtc # endif
67 1.1 jtc # endif /* !TCSETAW */
68 1.1 jtc # if defined(_BSD_SYSV) || !defined(TCSETAW)
69 1.1 jtc /* _BSD_SYSV must force TIOCSETN instead of TIOCSETP (preserve type-ahead) */
70 1.1 jtc if (ioctl(tty_fd, TCSETA, ts) < 0)
71 1.1 jtc ret = -1;
72 1.1 jtc # else
73 1.1 jtc if (ioctl(tty_fd, TCSETAW, ts) < 0)
74 1.1 jtc ret = -1;
75 1.1 jtc # endif
76 1.1 jtc # else /* HAVE_TERMIO_H */
77 1.1 jtc ret = ioctl(fd, TIOCSETN, &ts->sgttyb);
78 1.1 jtc # ifdef TIOCGATC
79 1.1 jtc if (ioctl(fd, TIOCSATC, &ts->lchars) < 0)
80 1.1 jtc ret = -1;
81 1.1 jtc # else
82 1.1 jtc if (ioctl(fd, TIOCSETC, &ts->tchars) < 0)
83 1.1 jtc ret = -1;
84 1.1 jtc # ifdef TIOCGLTC
85 1.1 jtc if (ioctl(fd, TIOCSLTC, &ts->ltchars) < 0)
86 1.1 jtc ret = -1;
87 1.1 jtc # endif /* TIOCGLTC */
88 1.1 jtc # endif /* TIOCGATC */
89 1.1 jtc # endif /* HAVE_TERMIO_H */
90 1.1 jtc # endif /* HAVE_TERIOS_H */
91 1.1 jtc return ret;
92 1.1 jtc }
93 1.1 jtc
94 1.1 jtc
95 1.1 jtc /* Initialize tty_fd. Used for saving/reseting tty modes upon
96 1.1 jtc * foreground job completion and for setting up tty process group.
97 1.1 jtc */
98 1.1 jtc void
99 1.1 jtc tty_init(init_ttystate)
100 1.1 jtc int init_ttystate;
101 1.1 jtc {
102 1.1 jtc int do_close = 1;
103 1.1 jtc int tfd;
104 1.3 fair const char *devtty = _PATH_TTY;
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.3 fair if ((tfd = open(devtty, O_RDWR, 0)) < 0) {
113 1.2 tls if (tfd < 0) {
114 1.2 tls tty_devtty = 0;
115 1.9 kamil warningf(false,
116 1.3 fair "No controlling tty (open %s: %s)",
117 1.3 fair devtty, strerror(errno));
118 1.2 tls }
119 1.1 jtc }
120 1.1 jtc
121 1.1 jtc if (tfd < 0) {
122 1.1 jtc do_close = 0;
123 1.1 jtc if (isatty(0))
124 1.1 jtc tfd = 0;
125 1.1 jtc else if (isatty(2))
126 1.1 jtc tfd = 2;
127 1.1 jtc else {
128 1.9 kamil warningf(false, "Can't find tty file descriptor");
129 1.1 jtc return;
130 1.1 jtc }
131 1.1 jtc }
132 1.1 jtc if ((tty_fd = ksh_dupbase(tfd, FDBASE)) < 0) {
133 1.9 kamil warningf(false, "j_ttyinit: dup of tty fd failed: %s",
134 1.1 jtc strerror(errno));
135 1.1 jtc } else if (fd_clexec(tty_fd) < 0) {
136 1.9 kamil warningf(false, "j_ttyinit: can't set close-on-exec flag: %s",
137 1.1 jtc strerror(errno));
138 1.1 jtc close(tty_fd);
139 1.1 jtc tty_fd = -1;
140 1.1 jtc } else if (init_ttystate)
141 1.1 jtc get_tty(tty_fd, &tty_state);
142 1.1 jtc if (do_close)
143 1.1 jtc close(tfd);
144 1.1 jtc }
145 1.1 jtc
146 1.1 jtc void
147 1.1 jtc tty_close()
148 1.1 jtc {
149 1.1 jtc if (tty_fd >= 0) {
150 1.1 jtc close(tty_fd);
151 1.1 jtc tty_fd = -1;
152 1.1 jtc }
153 1.1 jtc }
154