]> granicus.if.org Git - strace/blob - term.c
2008-07-18 Andreas Schwab <schwab@suse.de>
[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  *      $Id$
28  */
29
30 #include "defs.h"
31
32 #ifdef LINUX
33 /*
34  * The C library's definition of struct termios might differ from
35  * the kernel one, and we need to use the kernel layout.
36  */
37 #include <linux/termios.h>
38 #else
39
40 #ifdef HAVE_TERMIO_H
41 #include <termio.h>
42 #endif /* HAVE_TERMIO_H */
43
44 #include <termios.h>
45 #endif
46
47 #ifdef HAVE_SYS_FILIO_H
48 #include <sys/filio.h>
49 #endif
50
51 static const struct xlat tcxonc_options[] = {
52         { TCOOFF,       "TCOOFF"        },
53         { TCOON,        "TCOON"         },
54         { TCIOFF,       "TCIOFF"        },
55         { TCION,        "TCION"         },
56         { 0,            NULL            },
57 };
58
59 #ifdef TCLFLSH
60 static const struct xlat tcflsh_options[] = {
61         { TCIFLUSH,     "TCIFLUSH"      },
62         { TCOFLUSH,     "TCOFLUSH"      },
63         { TCIOFLUSH,    "TCIOFLUSH"     },
64         { 0,            NULL            },
65 };
66 #endif
67
68 static const struct xlat baud_options[] = {
69         { B0,           "B0"            },
70         { B50,          "B50"           },
71         { B75,          "B75"           },
72         { B110,         "B110"          },
73         { B134,         "B134"          },
74         { B150,         "B150"          },
75         { B200,         "B200"          },
76         { B300,         "B300"          },
77         { B600,         "B600"          },
78         { B1200,        "B1200"         },
79         { B1800,        "B1800"         },
80         { B2400,        "B2400"         },
81         { B4800,        "B4800"         },
82         { B9600,        "B9600"         },
83 #ifdef B19200
84         { B19200,       "B19200"        },
85 #endif
86 #ifdef B38400
87         { B38400,       "B38400"        },
88 #endif
89 #ifdef B57600
90         { B57600,       "B57600"        },
91 #endif
92 #ifdef B115200
93         { B115200,      "B115200"       },
94 #endif
95 #ifdef B230400
96         { B230400,      "B230400"       },
97 #endif
98 #ifdef B460800
99         { B460800,      "B460800"       },
100 #endif
101 #ifdef B500000
102         { B500000,      "B500000"       },
103 #endif
104 #ifdef B576000
105         { B576000,      "B576000"       },
106 #endif
107 #ifdef B921600
108         { B921600,      "B921600"       },
109 #endif
110 #ifdef B1000000
111         { B1000000,     "B1000000"      },
112 #endif
113 #ifdef B1152000
114         { B1152000,     "B1152000"      },
115 #endif
116 #ifdef B1500000
117         { B1500000,     "B1500000"      },
118 #endif
119 #ifdef B2000000
120         { B2000000,     "B2000000"      },
121 #endif
122 #ifdef B2500000
123         { B2500000,     "B2500000"      },
124 #endif
125 #ifdef B3000000
126         { B3000000,     "B3000000"      },
127 #endif
128 #ifdef B3500000
129         { B3500000,     "B3500000"      },
130 #endif
131 #ifdef B4000000
132         { B4000000,     "B4000000"      },
133 #endif
134 #ifdef EXTA
135         { EXTA,         "EXTA"          },
136 #endif
137 #ifdef EXTB
138         { EXTB,         "EXTB"          },
139 #endif
140         { 0,            NULL            },
141 };
142
143 static const struct xlat modem_flags[] = {
144 #ifdef TIOCM_LE
145         { TIOCM_LE,     "TIOCM_LE",     },
146 #endif
147 #ifdef TIOCM_DTR
148         { TIOCM_DTR,    "TIOCM_DTR",    },
149 #endif
150 #ifdef TIOCM_RTS
151         { TIOCM_RTS,    "TIOCM_RTS",    },
152 #endif
153 #ifdef TIOCM_ST
154         { TIOCM_ST,     "TIOCM_ST",     },
155 #endif
156 #ifdef TIOCM_SR
157         { TIOCM_SR,     "TIOCM_SR",     },
158 #endif
159 #ifdef TIOCM_CTS
160         { TIOCM_CTS,    "TIOCM_CTS",    },
161 #endif
162 #ifdef TIOCM_CAR
163         { TIOCM_CAR,    "TIOCM_CAR",    },
164 #endif
165 #ifdef TIOCM_CD
166         { TIOCM_CD,     "TIOCM_CD",     },
167 #endif
168 #ifdef TIOCM_RNG
169         { TIOCM_RNG,    "TIOCM_RNG",    },
170 #endif
171 #ifdef TIOCM_RI
172         { TIOCM_RI,     "TIOCM_RI",     },
173 #endif
174 #ifdef TIOCM_DSR
175         { TIOCM_DSR,    "TIOCM_DSR",    },
176 #endif
177         { 0,            NULL,           },
178 };
179
180
181 int
182 term_ioctl(tcp, code, arg)
183 struct tcb *tcp;
184 long code, arg;
185 {
186         struct termios tios;
187 #ifndef FREEBSD
188         struct termio tio;
189 #else
190         #define TCGETS  TIOCGETA
191         #define TCSETS  TIOCSETA
192         #define TCSETSW TIOCSETAW
193         #define TCSETSF TIOCSETAF
194 #endif
195         struct winsize ws;
196 #ifdef TIOCGSIZE
197         struct  ttysize ts;
198 #endif
199         int i;
200
201         if (entering(tcp))
202                 return 0;
203
204         switch (code) {
205
206         /* ioctls with termios or termio args */
207
208 #ifdef TCGETS
209         case TCGETS:
210                 if (syserror(tcp))
211                         return 0;
212         case TCSETS:
213         case TCSETSW:
214         case TCSETSF:
215                 if (!verbose(tcp) || umove(tcp, arg, &tios) < 0)
216                         return 0;
217                 if (abbrev(tcp)) {
218                         tprintf(", {");
219 #ifndef FREEBSD
220                         printxval(baud_options, tios.c_cflag & CBAUD, "B???");
221 #else
222                         printxval(baud_options, tios.c_ispeed, "B???");
223                         if (tios.c_ispeed != tios.c_ospeed) {
224                                 tprintf(" (in)");
225                                 printxval(baud_options, tios.c_ospeed, "B???");
226                                 tprintf(" (out)");
227                         }
228 #endif
229                         tprintf(" %sopost %sisig %sicanon %secho ...}",
230                                 (tios.c_oflag & OPOST) ? "" : "-",
231                                 (tios.c_lflag & ISIG) ? "" : "-",
232                                 (tios.c_lflag & ICANON) ? "" : "-",
233                                 (tios.c_lflag & ECHO) ? "" : "-");
234                         return 1;
235                 }
236                 tprintf(", {c_iflags=%#lx, c_oflags=%#lx, ",
237                         (long) tios.c_iflag, (long) tios.c_oflag);
238                 tprintf("c_cflags=%#lx, c_lflags=%#lx, ",
239                         (long) tios.c_cflag, (long) tios.c_lflag);
240 #if !defined(SVR4) && !defined(FREEBSD)
241                 tprintf("c_line=%u, ", tios.c_line);
242 #endif
243                 if (!(tios.c_lflag & ICANON))
244                         tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ",
245                                 tios.c_cc[VMIN], tios.c_cc[VTIME]);
246                 tprintf("c_cc=\"");
247                 for (i = 0; i < NCCS; i++)
248                         tprintf("\\x%02x", tios.c_cc[i]);
249                 tprintf("\"}");
250                 return 1;
251 #endif /* TCGETS */
252
253 #ifdef TCGETA
254         case TCGETA:
255                 if (syserror(tcp))
256                         return 0;
257         case TCSETA:
258         case TCSETAW:
259         case TCSETAF:
260                 if (!verbose(tcp) || umove(tcp, arg, &tio) < 0)
261                         return 0;
262                 if (abbrev(tcp)) {
263                         tprintf(", {");
264                         printxval(baud_options, tio.c_cflag & CBAUD, "B???");
265                         tprintf(" %sopost %sisig %sicanon %secho ...}",
266                                 (tio.c_oflag & OPOST) ? "" : "-",
267                                 (tio.c_lflag & ISIG) ? "" : "-",
268                                 (tio.c_lflag & ICANON) ? "" : "-",
269                                 (tio.c_lflag & ECHO) ? "" : "-");
270                         return 1;
271                 }
272                 tprintf(", {c_iflags=%#lx, c_oflags=%#lx, ",
273                         (long) tio.c_iflag, (long) tio.c_oflag);
274                 tprintf("c_cflags=%#lx, c_lflags=%#lx, ",
275                         (long) tio.c_cflag, (long) tio.c_lflag);
276                 tprintf("c_line=%u, ", tio.c_line);
277 #ifdef _VMIN
278                 if (!(tio.c_lflag & ICANON))
279                         tprintf("c_cc[_VMIN]=%d, c_cc[_VTIME]=%d, ",
280                                 tio.c_cc[_VMIN], tio.c_cc[_VTIME]);
281 #else /* !_VMIN */
282                 if (!(tio.c_lflag & ICANON))
283                         tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ",
284                                 tio.c_cc[VMIN], tio.c_cc[VTIME]);
285 #endif /* !_VMIN */
286                 tprintf("c_cc=\"");
287                 for (i = 0; i < NCC; i++)
288                         tprintf("\\x%02x", tio.c_cc[i]);
289                 tprintf("\"}");
290                 return 1;
291 #endif /* TCGETA */
292
293         /* ioctls with winsize or ttysize args */
294
295 #ifdef TIOCGWINSZ
296         case TIOCGWINSZ:
297                 if (syserror(tcp))
298                         return 0;
299         case TIOCSWINSZ:
300                 if (!verbose(tcp) || umove(tcp, arg, &ws) < 0)
301                         return 0;
302                 tprintf(", {ws_row=%d, ws_col=%d, ws_xpixel=%d, ws_ypixel=%d}",
303                         ws.ws_row, ws.ws_col, ws.ws_xpixel, ws.ws_ypixel);
304                 return 1;
305 #endif /* TIOCGWINSZ */
306
307 #ifdef TIOCGSIZE
308         case TIOCGSIZE:
309                 if (syserror(tcp))
310                         return 0;
311         case TIOCSSIZE:
312                 if (!verbose(tcp) || umove(tcp, arg, &ts) < 0)
313                         return 0;
314                 tprintf(", {ts_lines=%d, ts_cols=%d}",
315                         ts.ts_lines, ts.ts_cols);
316                 return 1;
317 #endif
318
319         /* ioctls with a direct decodable arg */
320 #ifdef TCXONC
321         case TCXONC:
322                 tprintf(", ");
323                 printxval(tcxonc_options, arg, "TC???");
324                 return 1;
325 #endif
326 #ifdef TCLFLSH
327         case TCFLSH:
328                 tprintf(", ");
329                 printxval(tcflsh_options, arg, "TC???");
330                 return 1;
331 #endif
332
333         /* ioctls with an indirect parameter displayed as modem flags */
334
335 #ifdef TIOCMGET
336         case TIOCMGET:
337         case TIOCMBIS:
338         case TIOCMBIC:
339         case TIOCMSET:
340                 if (umove(tcp, arg, &i) < 0)
341                         return 0;
342                 tprintf(", [");
343                 printflags(modem_flags, i, "TIOCM_???");
344                 tprintf("]");
345                 return 1;
346 #endif /* TIOCMGET */
347
348         /* ioctls with an indirect parameter displayed in decimal */
349
350         case TIOCSPGRP:
351         case TIOCGPGRP:
352 #ifdef TIOCGETPGRP
353         case TIOCGETPGRP:
354 #endif
355 #ifdef TIOCSETPGRP
356         case TIOCSETPGRP:
357 #endif
358 #ifdef FIONREAD
359         case FIONREAD:
360 #endif
361         case TIOCOUTQ:
362 #ifdef FIONBIO
363         case FIONBIO:
364 #endif
365 #ifdef FIOASYNC
366         case FIOASYNC:
367 #endif
368 #ifdef FIOGETOWN
369         case FIOGETOWN:
370 #endif
371 #ifdef FIOSETOWN
372         case FIOSETOWN:
373 #endif
374 #ifdef TIOCGETD
375         case TIOCGETD:
376 #endif
377 #ifdef TIOCSETD
378         case TIOCSETD:
379 #endif
380 #ifdef TIOCPKT
381         case TIOCPKT:
382 #endif
383 #ifdef TIOCREMOTE
384         case TIOCREMOTE:
385 #endif
386 #ifdef TIOCUCNTL
387         case TIOCUCNTL:
388 #endif
389 #ifdef TIOCTCNTL
390         case TIOCTCNTL:
391 #endif
392 #ifdef TIOCSIGNAL
393         case TIOCSIGNAL:
394 #endif
395 #ifdef TIOCSSOFTCAR
396         case TIOCSSOFTCAR:
397 #endif
398 #ifdef TIOCGSOFTCAR
399         case TIOCGSOFTCAR:
400 #endif
401 #ifdef TIOCISPACE
402         case TIOCISPACE:
403 #endif
404 #ifdef TIOCISIZE
405         case TIOCISIZE:
406 #endif
407 #ifdef TIOCSINTR
408         case TIOCSINTR:
409 #endif
410 #ifdef TIOCSPTLCK
411         case TIOCSPTLCK:
412 #endif
413 #ifdef TIOCGPTN
414         case TIOCGPTN:
415 #endif
416                 tprintf(", ");
417                 printnum_int(tcp, arg, "%d");
418                 return 1;
419
420 #if 0
421         /* ioctls with an indirect parameter displayed in hex */
422
423                 tprintf(", ");
424                 printnum(tcp, arg, "%#x");
425                 return 1;
426 #endif
427
428         /* ioctls with an indirect parameter displayed as a char */
429
430 #ifdef TIOCSTI
431         case TIOCSTI:
432 #endif
433                 tprintf(", ");
434                 printstr(tcp, arg, 1);
435                 return 1;
436
437         /* ioctls with no parameters */
438
439 #ifdef TIOCSCTTY
440         case TIOCSCTTY:
441 #endif
442 #ifdef TIOCNOTTY
443         case TIOCNOTTY:
444 #endif
445 #ifdef FIOCLEX
446         case FIOCLEX:
447 #endif
448 #ifdef FIONCLEX
449         case FIONCLEX:
450 #endif
451 #ifdef TIOCCONS
452         case TIOCCONS:
453 #endif
454                 return 1;
455
456         /* ioctls which are unknown */
457
458         default:
459                 return 0;
460         }
461 }