]> granicus.if.org Git - strace/blob - term.c
clone: fix print_tls_arg on x86
[strace] / term.c
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  * SPDX-License-Identifier: LGPL-2.1-or-later
7  */
8
9 #include "defs.h"
10 /*
11  * The C library's definition of struct termios might differ from
12  * the kernel one, and we need to use the kernel layout.
13  */
14 #include <linux/termios.h>
15
16 #include "xlat/tcxonc_options.h"
17 #include "xlat/tcflsh_options.h"
18 #include "xlat/baud_options.h"
19 #include "xlat/modem_flags.h"
20
21 static void
22 decode_termios(struct tcb *const tcp, const kernel_ulong_t addr)
23 {
24         struct termios tios;
25
26         tprints(", ");
27         if (umove_or_printaddr(tcp, addr, &tios))
28                 return;
29         if (abbrev(tcp)) {
30                 tprints("{");
31                 printxval(baud_options, tios.c_cflag & CBAUD, "B???");
32                 tprintf(" %sopost %sisig %sicanon %secho ...}",
33                         (tios.c_oflag & OPOST) ? "" : "-",
34                         (tios.c_lflag & ISIG) ? "" : "-",
35                         (tios.c_lflag & ICANON) ? "" : "-",
36                         (tios.c_lflag & ECHO) ? "" : "-");
37                 return;
38         }
39         tprintf("{c_iflags=%#lx, c_oflags=%#lx, ",
40                 (long) tios.c_iflag, (long) tios.c_oflag);
41         tprintf("c_cflags=%#lx, c_lflags=%#lx, ",
42                 (long) tios.c_cflag, (long) tios.c_lflag);
43         tprintf("c_line=%u, ", tios.c_line);
44         if (!(tios.c_lflag & ICANON))
45                 tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ",
46                         tios.c_cc[VMIN], tios.c_cc[VTIME]);
47         tprints("c_cc=");
48         print_quoted_string((char *) tios.c_cc, NCCS, QUOTE_FORCE_HEX);
49         tprints("}");
50 }
51
52 static void
53 decode_termio(struct tcb *const tcp, const kernel_ulong_t addr)
54 {
55         struct termio tio;
56         int i;
57
58         tprints(", ");
59         if (umove_or_printaddr(tcp, addr, &tio))
60                 return;
61         if (abbrev(tcp)) {
62                 tprints("{");
63                 printxval(baud_options, tio.c_cflag & CBAUD, "B???");
64                 tprintf(" %sopost %sisig %sicanon %secho ...}",
65                         (tio.c_oflag & OPOST) ? "" : "-",
66                         (tio.c_lflag & ISIG) ? "" : "-",
67                         (tio.c_lflag & ICANON) ? "" : "-",
68                         (tio.c_lflag & ECHO) ? "" : "-");
69                 return;
70         }
71         tprintf("{c_iflags=%#lx, c_oflags=%#lx, ",
72                 (long) tio.c_iflag, (long) tio.c_oflag);
73         tprintf("c_cflags=%#lx, c_lflags=%#lx, ",
74                 (long) tio.c_cflag, (long) tio.c_lflag);
75         tprintf("c_line=%u, ", tio.c_line);
76 #ifdef _VMIN
77         if (!(tio.c_lflag & ICANON))
78                 tprintf("c_cc[_VMIN]=%d, c_cc[_VTIME]=%d, ",
79                         tio.c_cc[_VMIN], tio.c_cc[_VTIME]);
80 #else /* !_VMIN */
81         if (!(tio.c_lflag & ICANON))
82                 tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ",
83                         tio.c_cc[VMIN], tio.c_cc[VTIME]);
84 #endif /* !_VMIN */
85         tprints("c_cc=\"");
86         for (i = 0; i < NCC; i++)
87                 tprintf("\\x%02x", tio.c_cc[i]);
88         tprints("\"}");
89 }
90
91 static void
92 decode_winsize(struct tcb *const tcp, const kernel_ulong_t addr)
93 {
94         struct winsize ws;
95
96         tprints(", ");
97         if (umove_or_printaddr(tcp, addr, &ws))
98                 return;
99         tprintf("{ws_row=%d, ws_col=%d, ws_xpixel=%d, ws_ypixel=%d}",
100                 ws.ws_row, ws.ws_col, ws.ws_xpixel, ws.ws_ypixel);
101 }
102
103 #ifdef TIOCGSIZE
104 static void
105 decode_ttysize(struct tcb *const tcp, const kernel_ulong_t addr)
106 {
107         struct ttysize ts;
108
109         tprints(", ");
110         if (umove_or_printaddr(tcp, addr, &ts))
111                 return;
112         tprintf("{ts_lines=%d, ts_cols=%d}",
113                 ts.ts_lines, ts.ts_cols);
114 }
115 #endif
116
117 static void
118 decode_modem_flags(struct tcb *const tcp, const kernel_ulong_t addr)
119 {
120         int i;
121
122         tprints(", ");
123         if (umove_or_printaddr(tcp, addr, &i))
124                 return;
125         tprints("[");
126         printflags(modem_flags, i, "TIOCM_???");
127         tprints("]");
128 }
129
130 int
131 term_ioctl(struct tcb *const tcp, const unsigned int code,
132            const kernel_ulong_t arg)
133 {
134         switch (code) {
135         /* struct termios */
136         case TCGETS:
137 #ifdef TCGETS2
138         case TCGETS2:
139 #endif
140         case TIOCGLCKTRMIOS:
141                 if (entering(tcp))
142                         return 0;
143                 ATTRIBUTE_FALLTHROUGH;
144         case TCSETS:
145 #ifdef TCSETS2
146         case TCSETS2:
147 #endif
148         case TCSETSW:
149 #ifdef TCSETSW2
150         case TCSETSW2:
151 #endif
152         case TCSETSF:
153 #ifdef TCSETSF2
154         case TCSETSF2:
155 #endif
156         case TIOCSLCKTRMIOS:
157                 decode_termios(tcp, arg);
158                 break;
159
160         /* struct termio */
161         case TCGETA:
162                 if (entering(tcp))
163                         return 0;
164                 ATTRIBUTE_FALLTHROUGH;
165         case TCSETA:
166         case TCSETAW:
167         case TCSETAF:
168                 decode_termio(tcp, arg);
169                 break;
170
171         /* struct winsize */
172         case TIOCGWINSZ:
173                 if (entering(tcp))
174                         return 0;
175                 ATTRIBUTE_FALLTHROUGH;
176         case TIOCSWINSZ:
177                 decode_winsize(tcp, arg);
178                 break;
179
180         /* struct ttysize */
181 #ifdef TIOCGSIZE
182         case TIOCGSIZE:
183                 if (entering(tcp))
184                         return 0;
185                 ATTRIBUTE_FALLTHROUGH;
186         case TIOCSSIZE:
187                 decode_ttysize(tcp, arg);
188                 break;
189 #endif
190
191         /* ioctls with a direct decodable arg */
192         case TCXONC:
193                 tprints(", ");
194                 printxval64(tcxonc_options, arg, "TC???");
195                 break;
196         case TCFLSH:
197                 tprints(", ");
198                 printxval64(tcflsh_options, arg, "TC???");
199                 break;
200         case TCSBRK:
201         case TCSBRKP:
202         case TIOCSCTTY:
203                 tprintf(", %d", (int) arg);
204                 break;
205
206         /* ioctls with an indirect parameter displayed as modem flags */
207         case TIOCMGET:
208                 if (entering(tcp))
209                         return 0;
210                 ATTRIBUTE_FALLTHROUGH;
211         case TIOCMBIS:
212         case TIOCMBIC:
213         case TIOCMSET:
214                 decode_modem_flags(tcp, arg);
215                 break;
216
217         /* ioctls with an indirect parameter displayed in decimal */
218         case TIOCGPGRP:
219         case TIOCGSID:
220         case TIOCGETD:
221         case TIOCGSOFTCAR:
222         case TIOCGPTN:
223         case FIONREAD:
224         case TIOCOUTQ:
225 #ifdef TIOCGEXCL
226         case TIOCGEXCL:
227 #endif
228 #ifdef TIOCGDEV
229         case TIOCGDEV:
230 #endif
231                 if (entering(tcp))
232                         return 0;
233                 ATTRIBUTE_FALLTHROUGH;
234         case TIOCSPGRP:
235         case TIOCSETD:
236         case FIONBIO:
237         case FIOASYNC:
238         case TIOCPKT:
239         case TIOCSSOFTCAR:
240         case TIOCSPTLCK:
241                 tprints(", ");
242                 printnum_int(tcp, arg, "%d");
243                 break;
244
245         /* ioctls with an indirect parameter displayed as a char */
246         case TIOCSTI:
247                 tprints(", ");
248                 printstrn(tcp, arg, 1);
249                 break;
250
251         /* ioctls with no parameters */
252
253         case TIOCSBRK:
254         case TIOCCBRK:
255         case TIOCCONS:
256         case TIOCNOTTY:
257         case TIOCEXCL:
258         case TIOCNXCL:
259         case FIOCLEX:
260         case FIONCLEX:
261 #ifdef TIOCVHANGUP
262         case TIOCVHANGUP:
263 #endif
264 #ifdef TIOCSSERIAL
265         case TIOCSSERIAL:
266 #endif
267                 break;
268
269         /* ioctls which are unknown */
270
271         default:
272                 return RVAL_DECODED;
273         }
274
275         return RVAL_IOCTL_DECODED;
276 }