]> granicus.if.org Git - strace/blob - term.c
Fix macros encosure in a do/while loop
[strace] / term.c
1 /*
2  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
3  * Copyright (c) 1996-2017 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
42 decode_termios(struct tcb *const tcp, const kernel_ulong_t addr)
43 {
44         struct termios tios;
45         int i;
46
47         tprints(", ");
48         if (umove_or_printaddr(tcp, addr, &tios))
49                 return;
50         if (abbrev(tcp)) {
51                 tprints("{");
52                 printxval(baud_options, tios.c_cflag & CBAUD, "B???");
53                 tprintf(" %sopost %sisig %sicanon %secho ...}",
54                         (tios.c_oflag & OPOST) ? "" : "-",
55                         (tios.c_lflag & ISIG) ? "" : "-",
56                         (tios.c_lflag & ICANON) ? "" : "-",
57                         (tios.c_lflag & ECHO) ? "" : "-");
58                 return;
59         }
60         tprintf("{c_iflags=%#lx, c_oflags=%#lx, ",
61                 (long) tios.c_iflag, (long) tios.c_oflag);
62         tprintf("c_cflags=%#lx, c_lflags=%#lx, ",
63                 (long) tios.c_cflag, (long) tios.c_lflag);
64         tprintf("c_line=%u, ", tios.c_line);
65         if (!(tios.c_lflag & ICANON))
66                 tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ",
67                         tios.c_cc[VMIN], tios.c_cc[VTIME]);
68         tprints("c_cc=\"");
69         for (i = 0; i < NCCS; i++)
70                 tprintf("\\x%02x", tios.c_cc[i]);
71         tprints("\"}");
72 }
73
74 static void
75 decode_termio(struct tcb *const tcp, const kernel_ulong_t addr)
76 {
77         struct termio tio;
78         int i;
79
80         tprints(", ");
81         if (umove_or_printaddr(tcp, addr, &tio))
82                 return;
83         if (abbrev(tcp)) {
84                 tprints("{");
85                 printxval(baud_options, tio.c_cflag & CBAUD, "B???");
86                 tprintf(" %sopost %sisig %sicanon %secho ...}",
87                         (tio.c_oflag & OPOST) ? "" : "-",
88                         (tio.c_lflag & ISIG) ? "" : "-",
89                         (tio.c_lflag & ICANON) ? "" : "-",
90                         (tio.c_lflag & ECHO) ? "" : "-");
91                 return;
92         }
93         tprintf("{c_iflags=%#lx, c_oflags=%#lx, ",
94                 (long) tio.c_iflag, (long) tio.c_oflag);
95         tprintf("c_cflags=%#lx, c_lflags=%#lx, ",
96                 (long) tio.c_cflag, (long) tio.c_lflag);
97         tprintf("c_line=%u, ", tio.c_line);
98 #ifdef _VMIN
99         if (!(tio.c_lflag & ICANON))
100                 tprintf("c_cc[_VMIN]=%d, c_cc[_VTIME]=%d, ",
101                         tio.c_cc[_VMIN], tio.c_cc[_VTIME]);
102 #else /* !_VMIN */
103         if (!(tio.c_lflag & ICANON))
104                 tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ",
105                         tio.c_cc[VMIN], tio.c_cc[VTIME]);
106 #endif /* !_VMIN */
107         tprints("c_cc=\"");
108         for (i = 0; i < NCC; i++)
109                 tprintf("\\x%02x", tio.c_cc[i]);
110         tprints("\"}");
111 }
112
113 static void
114 decode_winsize(struct tcb *const tcp, const kernel_ulong_t addr)
115 {
116         struct winsize ws;
117
118         tprints(", ");
119         if (umove_or_printaddr(tcp, addr, &ws))
120                 return;
121         tprintf("{ws_row=%d, ws_col=%d, ws_xpixel=%d, ws_ypixel=%d}",
122                 ws.ws_row, ws.ws_col, ws.ws_xpixel, ws.ws_ypixel);
123 }
124
125 #ifdef TIOCGSIZE
126 static void
127 decode_ttysize(struct tcb *const tcp, const kernel_ulong_t addr)
128 {
129         struct ttysize ts;
130
131         tprints(", ");
132         if (umove_or_printaddr(tcp, addr, &ts))
133                 return;
134         tprintf("{ts_lines=%d, ts_cols=%d}",
135                 ts.ts_lines, ts.ts_cols);
136 }
137 #endif
138
139 static void
140 decode_modem_flags(struct tcb *const tcp, const kernel_ulong_t addr)
141 {
142         int i;
143
144         tprints(", ");
145         if (umove_or_printaddr(tcp, addr, &i))
146                 return;
147         tprints("[");
148         printflags(modem_flags, i, "TIOCM_???");
149         tprints("]");
150 }
151
152 int
153 term_ioctl(struct tcb *const tcp, const unsigned int code,
154            const kernel_ulong_t arg)
155 {
156         switch (code) {
157         /* struct termios */
158         case TCGETS:
159 #ifdef TCGETS2
160         case TCGETS2:
161 #endif
162         case TIOCGLCKTRMIOS:
163                 if (entering(tcp))
164                         return 0;
165         case TCSETS:
166 #ifdef TCSETS2
167         case TCSETS2:
168 #endif
169         case TCSETSW:
170 #ifdef TCSETSW2
171         case TCSETSW2:
172 #endif
173         case TCSETSF:
174 #ifdef TCSETSF2
175         case TCSETSF2:
176 #endif
177         case TIOCSLCKTRMIOS:
178                 decode_termios(tcp, arg);
179                 break;
180
181         /* struct termio */
182         case TCGETA:
183                 if (entering(tcp))
184                         return 0;
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         case TIOCSWINSZ:
196                 decode_winsize(tcp, arg);
197                 break;
198
199         /* struct ttysize */
200 #ifdef TIOCGSIZE
201         case TIOCGSIZE:
202                 if (entering(tcp))
203                         return 0;
204         case TIOCSSIZE:
205                 decode_ttysize(tcp, arg);
206                 break;
207 #endif
208
209         /* ioctls with a direct decodable arg */
210         case TCXONC:
211                 tprints(", ");
212                 printxval64(tcxonc_options, arg, "TC???");
213                 break;
214         case TCFLSH:
215                 tprints(", ");
216                 printxval64(tcflsh_options, arg, "TC???");
217                 break;
218         case TCSBRK:
219         case TCSBRKP:
220         case TIOCSCTTY:
221                 tprintf(", %d", (int) arg);
222                 break;
223
224         /* ioctls with an indirect parameter displayed as modem flags */
225         case TIOCMGET:
226                 if (entering(tcp))
227                         return 0;
228         case TIOCMBIS:
229         case TIOCMBIC:
230         case TIOCMSET:
231                 decode_modem_flags(tcp, arg);
232                 break;
233
234         /* ioctls with an indirect parameter displayed in decimal */
235         case TIOCGPGRP:
236         case TIOCGSID:
237         case TIOCGETD:
238         case TIOCGSOFTCAR:
239         case TIOCGPTN:
240         case FIONREAD:
241         case TIOCOUTQ:
242 #ifdef TIOCGEXCL
243         case TIOCGEXCL:
244 #endif
245 #ifdef TIOCGDEV
246         case TIOCGDEV:
247 #endif
248                 if (entering(tcp))
249                         return 0;
250         case TIOCSPGRP:
251         case TIOCSETD:
252         case FIONBIO:
253         case FIOASYNC:
254         case TIOCPKT:
255         case TIOCSSOFTCAR:
256         case TIOCSPTLCK:
257                 tprints(", ");
258                 printnum_int(tcp, arg, "%d");
259                 break;
260
261         /* ioctls with an indirect parameter displayed as a char */
262         case TIOCSTI:
263                 tprints(", ");
264                 printstrn(tcp, arg, 1);
265                 break;
266
267         /* ioctls with no parameters */
268
269         case TIOCSBRK:
270         case TIOCCBRK:
271         case TIOCCONS:
272         case TIOCNOTTY:
273         case TIOCEXCL:
274         case TIOCNXCL:
275         case FIOCLEX:
276         case FIONCLEX:
277 #ifdef TIOCVHANGUP
278         case TIOCVHANGUP:
279 #endif
280 #ifdef TIOCSSERIAL
281         case TIOCSSERIAL:
282 #endif
283                 break;
284
285         /* ioctls which are unknown */
286
287         default:
288                 return RVAL_DECODED;
289         }
290
291         return RVAL_DECODED | 1;
292 }