]> granicus.if.org Git - strace/blob - term.c
x32: fix decoding of flags argument of preadv2 and pwritev2 syscalls
[strace] / term.c
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
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
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
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
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
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
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 }