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