1 /*
2 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include "defs.h"
29 /*
30 * The C library's definition of struct termios might differ from
31 * the kernel one, and we need to use the kernel layout.
32 */
33 #include <linux/termios.h>
34
35 #include "xlat/tcxonc_options.h"
36 #include "xlat/tcflsh_options.h"
37 #include "xlat/baud_options.h"
38 #include "xlat/modem_flags.h"
39
40 static void
decode_termios(struct tcb * const tcp,const kernel_ulong_t addr)41 decode_termios(struct tcb *const tcp, const kernel_ulong_t addr)
42 {
43 struct termios tios;
44 int i;
45
46 tprints(", ");
47 if (umove_or_printaddr(tcp, addr, &tios))
48 return;
49 if (abbrev(tcp)) {
50 tprints("{");
51 printxval(baud_options, tios.c_cflag & CBAUD, "B???");
52 tprintf(" %sopost %sisig %sicanon %secho ...}",
53 (tios.c_oflag & OPOST) ? "" : "-",
54 (tios.c_lflag & ISIG) ? "" : "-",
55 (tios.c_lflag & ICANON) ? "" : "-",
56 (tios.c_lflag & ECHO) ? "" : "-");
57 return;
58 }
59 tprintf("{c_iflags=%#lx, c_oflags=%#lx, ",
60 (long) tios.c_iflag, (long) tios.c_oflag);
61 tprintf("c_cflags=%#lx, c_lflags=%#lx, ",
62 (long) tios.c_cflag, (long) tios.c_lflag);
63 tprintf("c_line=%u, ", tios.c_line);
64 if (!(tios.c_lflag & ICANON))
65 tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ",
66 tios.c_cc[VMIN], tios.c_cc[VTIME]);
67 tprints("c_cc=\"");
68 for (i = 0; i < NCCS; i++)
69 tprintf("\\x%02x", tios.c_cc[i]);
70 tprints("\"}");
71 }
72
73 static void
decode_termio(struct tcb * const tcp,const kernel_ulong_t addr)74 decode_termio(struct tcb *const tcp, const kernel_ulong_t addr)
75 {
76 struct termio tio;
77 int i;
78
79 tprints(", ");
80 if (umove_or_printaddr(tcp, addr, &tio))
81 return;
82 if (abbrev(tcp)) {
83 tprints("{");
84 printxval(baud_options, tio.c_cflag & CBAUD, "B???");
85 tprintf(" %sopost %sisig %sicanon %secho ...}",
86 (tio.c_oflag & OPOST) ? "" : "-",
87 (tio.c_lflag & ISIG) ? "" : "-",
88 (tio.c_lflag & ICANON) ? "" : "-",
89 (tio.c_lflag & ECHO) ? "" : "-");
90 return;
91 }
92 tprintf("{c_iflags=%#lx, c_oflags=%#lx, ",
93 (long) tio.c_iflag, (long) tio.c_oflag);
94 tprintf("c_cflags=%#lx, c_lflags=%#lx, ",
95 (long) tio.c_cflag, (long) tio.c_lflag);
96 tprintf("c_line=%u, ", tio.c_line);
97 #ifdef _VMIN
98 if (!(tio.c_lflag & ICANON))
99 tprintf("c_cc[_VMIN]=%d, c_cc[_VTIME]=%d, ",
100 tio.c_cc[_VMIN], tio.c_cc[_VTIME]);
101 #else /* !_VMIN */
102 if (!(tio.c_lflag & ICANON))
103 tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ",
104 tio.c_cc[VMIN], tio.c_cc[VTIME]);
105 #endif /* !_VMIN */
106 tprints("c_cc=\"");
107 for (i = 0; i < NCC; i++)
108 tprintf("\\x%02x", tio.c_cc[i]);
109 tprints("\"}");
110 }
111
112 static void
decode_winsize(struct tcb * const tcp,const kernel_ulong_t addr)113 decode_winsize(struct tcb *const tcp, const kernel_ulong_t addr)
114 {
115 struct winsize ws;
116
117 tprints(", ");
118 if (umove_or_printaddr(tcp, addr, &ws))
119 return;
120 tprintf("{ws_row=%d, ws_col=%d, ws_xpixel=%d, ws_ypixel=%d}",
121 ws.ws_row, ws.ws_col, ws.ws_xpixel, ws.ws_ypixel);
122 }
123
124 #ifdef TIOCGSIZE
125 static void
decode_ttysize(struct tcb * const tcp,const kernel_ulong_t addr)126 decode_ttysize(struct tcb *const tcp, const kernel_ulong_t addr)
127 {
128 struct ttysize ts;
129
130 tprints(", ");
131 if (umove_or_printaddr(tcp, addr, &ts))
132 return;
133 tprintf("{ts_lines=%d, ts_cols=%d}",
134 ts.ts_lines, ts.ts_cols);
135 }
136 #endif
137
138 static void
decode_modem_flags(struct tcb * const tcp,const kernel_ulong_t addr)139 decode_modem_flags(struct tcb *const tcp, const kernel_ulong_t addr)
140 {
141 int i;
142
143 tprints(", ");
144 if (umove_or_printaddr(tcp, addr, &i))
145 return;
146 tprints("[");
147 printflags(modem_flags, i, "TIOCM_???");
148 tprints("]");
149 }
150
151 int
term_ioctl(struct tcb * const tcp,const unsigned int code,const kernel_ulong_t arg)152 term_ioctl(struct tcb *const tcp, const unsigned int code,
153 const kernel_ulong_t arg)
154 {
155 switch (code) {
156 /* struct termios */
157 case TCGETS:
158 #ifdef TCGETS2
159 case TCGETS2:
160 #endif
161 case TIOCGLCKTRMIOS:
162 if (entering(tcp))
163 return 0;
164 case TCSETS:
165 #ifdef TCSETS2
166 case TCSETS2:
167 #endif
168 case TCSETSW:
169 #ifdef TCSETSW2
170 case TCSETSW2:
171 #endif
172 case TCSETSF:
173 #ifdef TCSETSF2
174 case TCSETSF2:
175 #endif
176 case TIOCSLCKTRMIOS:
177 decode_termios(tcp, arg);
178 break;
179
180 /* struct termio */
181 case TCGETA:
182 if (entering(tcp))
183 return 0;
184 case TCSETA:
185 case TCSETAW:
186 case TCSETAF:
187 decode_termio(tcp, arg);
188 break;
189
190 /* struct winsize */
191 case TIOCGWINSZ:
192 if (entering(tcp))
193 return 0;
194 case TIOCSWINSZ:
195 decode_winsize(tcp, arg);
196 break;
197
198 /* struct ttysize */
199 #ifdef TIOCGSIZE
200 case TIOCGSIZE:
201 if (entering(tcp))
202 return 0;
203 case TIOCSSIZE:
204 decode_ttysize(tcp, arg);
205 break;
206 #endif
207
208 /* ioctls with a direct decodable arg */
209 case TCXONC:
210 tprints(", ");
211 printxval64(tcxonc_options, arg, "TC???");
212 break;
213 case TCFLSH:
214 tprints(", ");
215 printxval64(tcflsh_options, arg, "TC???");
216 break;
217 case TCSBRK:
218 case TCSBRKP:
219 case TIOCSCTTY:
220 tprintf(", %d", (int) arg);
221 break;
222
223 /* ioctls with an indirect parameter displayed as modem flags */
224 case TIOCMGET:
225 if (entering(tcp))
226 return 0;
227 case TIOCMBIS:
228 case TIOCMBIC:
229 case TIOCMSET:
230 decode_modem_flags(tcp, arg);
231 break;
232
233 /* ioctls with an indirect parameter displayed in decimal */
234 case TIOCGPGRP:
235 case TIOCGSID:
236 case TIOCGETD:
237 case TIOCGSOFTCAR:
238 case TIOCGPTN:
239 case FIONREAD:
240 case TIOCOUTQ:
241 #ifdef TIOCGEXCL
242 case TIOCGEXCL:
243 #endif
244 #ifdef TIOCGDEV
245 case TIOCGDEV:
246 #endif
247 if (entering(tcp))
248 return 0;
249 case TIOCSPGRP:
250 case TIOCSETD:
251 case FIONBIO:
252 case FIOASYNC:
253 case TIOCPKT:
254 case TIOCSSOFTCAR:
255 case TIOCSPTLCK:
256 tprints(", ");
257 printnum_int(tcp, arg, "%d");
258 break;
259
260 /* ioctls with an indirect parameter displayed as a char */
261 case TIOCSTI:
262 tprints(", ");
263 printstrn(tcp, arg, 1);
264 break;
265
266 /* ioctls with no parameters */
267
268 case TIOCSBRK:
269 case TIOCCBRK:
270 case TIOCCONS:
271 case TIOCNOTTY:
272 case TIOCEXCL:
273 case TIOCNXCL:
274 case FIOCLEX:
275 case FIONCLEX:
276 #ifdef TIOCVHANGUP
277 case TIOCVHANGUP:
278 #endif
279 #ifdef TIOCSSERIAL
280 case TIOCSSERIAL:
281 #endif
282 break;
283
284 /* ioctls which are unknown */
285
286 default:
287 return RVAL_DECODED;
288 }
289
290 return RVAL_DECODED | 1;
291 }
292