Home | History | Annotate | Download | only in strace
      1 /*
      2  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs (at) 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 term_ioctl(struct tcb *tcp, long code, long arg)
    182 {
    183 	struct termios tios;
    184 #ifndef FREEBSD
    185 	struct termio tio;
    186 #else
    187 	#define TCGETS	TIOCGETA
    188 	#define TCSETS	TIOCSETA
    189 	#define TCSETSW	TIOCSETAW
    190 	#define TCSETSF	TIOCSETAF
    191 #endif
    192 	struct winsize ws;
    193 #ifdef TIOCGSIZE
    194 	struct  ttysize ts;
    195 #endif
    196 	int i;
    197 
    198 	if (entering(tcp))
    199 		return 0;
    200 
    201 	switch (code) {
    202 
    203 	/* ioctls with termios or termio args */
    204 
    205 #ifdef TCGETS
    206 	case TCGETS:
    207 		if (syserror(tcp))
    208 			return 0;
    209 	case TCSETS:
    210 	case TCSETSW:
    211 	case TCSETSF:
    212 		if (!verbose(tcp) || umove(tcp, arg, &tios) < 0)
    213 			return 0;
    214 		if (abbrev(tcp)) {
    215 			tprintf(", {");
    216 #ifndef FREEBSD
    217 			printxval(baud_options, tios.c_cflag & CBAUD, "B???");
    218 #else
    219 			printxval(baud_options, tios.c_ispeed, "B???");
    220 			if (tios.c_ispeed != tios.c_ospeed) {
    221 				tprintf(" (in)");
    222 				printxval(baud_options, tios.c_ospeed, "B???");
    223 				tprintf(" (out)");
    224 			}
    225 #endif
    226 			tprintf(" %sopost %sisig %sicanon %secho ...}",
    227 				(tios.c_oflag & OPOST) ? "" : "-",
    228 				(tios.c_lflag & ISIG) ? "" : "-",
    229 				(tios.c_lflag & ICANON) ? "" : "-",
    230 				(tios.c_lflag & ECHO) ? "" : "-");
    231 			return 1;
    232 		}
    233 		tprintf(", {c_iflags=%#lx, c_oflags=%#lx, ",
    234 			(long) tios.c_iflag, (long) tios.c_oflag);
    235 		tprintf("c_cflags=%#lx, c_lflags=%#lx, ",
    236 			(long) tios.c_cflag, (long) tios.c_lflag);
    237 #if !defined(SVR4) && !defined(FREEBSD)
    238 		tprintf("c_line=%u, ", tios.c_line);
    239 #endif
    240 		if (!(tios.c_lflag & ICANON))
    241 			tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ",
    242 				tios.c_cc[VMIN], tios.c_cc[VTIME]);
    243 		tprintf("c_cc=\"");
    244 		for (i = 0; i < NCCS; i++)
    245 			tprintf("\\x%02x", tios.c_cc[i]);
    246 		tprintf("\"}");
    247 		return 1;
    248 #endif /* TCGETS */
    249 
    250 #ifdef TCGETA
    251 	case TCGETA:
    252 		if (syserror(tcp))
    253 			return 0;
    254 	case TCSETA:
    255 	case TCSETAW:
    256 	case TCSETAF:
    257 		if (!verbose(tcp) || umove(tcp, arg, &tio) < 0)
    258 			return 0;
    259 		if (abbrev(tcp)) {
    260 			tprintf(", {");
    261 			printxval(baud_options, tio.c_cflag & CBAUD, "B???");
    262 			tprintf(" %sopost %sisig %sicanon %secho ...}",
    263 				(tio.c_oflag & OPOST) ? "" : "-",
    264 				(tio.c_lflag & ISIG) ? "" : "-",
    265 				(tio.c_lflag & ICANON) ? "" : "-",
    266 				(tio.c_lflag & ECHO) ? "" : "-");
    267 			return 1;
    268 		}
    269 		tprintf(", {c_iflags=%#lx, c_oflags=%#lx, ",
    270 			(long) tio.c_iflag, (long) tio.c_oflag);
    271 		tprintf("c_cflags=%#lx, c_lflags=%#lx, ",
    272 			(long) tio.c_cflag, (long) tio.c_lflag);
    273 		tprintf("c_line=%u, ", tio.c_line);
    274 #ifdef _VMIN
    275 		if (!(tio.c_lflag & ICANON))
    276 			tprintf("c_cc[_VMIN]=%d, c_cc[_VTIME]=%d, ",
    277 				tio.c_cc[_VMIN], tio.c_cc[_VTIME]);
    278 #else /* !_VMIN */
    279 		if (!(tio.c_lflag & ICANON))
    280 			tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ",
    281 				tio.c_cc[VMIN], tio.c_cc[VTIME]);
    282 #endif /* !_VMIN */
    283 		tprintf("c_cc=\"");
    284 		for (i = 0; i < NCC; i++)
    285 			tprintf("\\x%02x", tio.c_cc[i]);
    286 		tprintf("\"}");
    287 		return 1;
    288 #endif /* TCGETA */
    289 
    290 	/* ioctls with winsize or ttysize args */
    291 
    292 #ifdef TIOCGWINSZ
    293 	case TIOCGWINSZ:
    294 		if (syserror(tcp))
    295 			return 0;
    296 	case TIOCSWINSZ:
    297 		if (!verbose(tcp) || umove(tcp, arg, &ws) < 0)
    298 			return 0;
    299 		tprintf(", {ws_row=%d, ws_col=%d, ws_xpixel=%d, ws_ypixel=%d}",
    300 			ws.ws_row, ws.ws_col, ws.ws_xpixel, ws.ws_ypixel);
    301 		return 1;
    302 #endif /* TIOCGWINSZ */
    303 
    304 #ifdef TIOCGSIZE
    305 	case TIOCGSIZE:
    306 		if (syserror(tcp))
    307 			return 0;
    308 	case TIOCSSIZE:
    309 		if (!verbose(tcp) || umove(tcp, arg, &ts) < 0)
    310 			return 0;
    311 		tprintf(", {ts_lines=%d, ts_cols=%d}",
    312 			ts.ts_lines, ts.ts_cols);
    313 		return 1;
    314 #endif
    315 
    316 	/* ioctls with a direct decodable arg */
    317 #ifdef TCXONC
    318 	case TCXONC:
    319 		tprintf(", ");
    320 		printxval(tcxonc_options, arg, "TC???");
    321 		return 1;
    322 #endif
    323 #ifdef TCLFLSH
    324 	case TCFLSH:
    325 		tprintf(", ");
    326 		printxval(tcflsh_options, arg, "TC???");
    327 		return 1;
    328 #endif
    329 
    330 	/* ioctls with an indirect parameter displayed as modem flags */
    331 
    332 #ifdef TIOCMGET
    333 	case TIOCMGET:
    334 	case TIOCMBIS:
    335 	case TIOCMBIC:
    336 	case TIOCMSET:
    337 		if (umove(tcp, arg, &i) < 0)
    338 			return 0;
    339 		tprintf(", [");
    340 		printflags(modem_flags, i, "TIOCM_???");
    341 		tprintf("]");
    342 		return 1;
    343 #endif /* TIOCMGET */
    344 
    345 	/* ioctls with an indirect parameter displayed in decimal */
    346 
    347 	case TIOCSPGRP:
    348 	case TIOCGPGRP:
    349 #ifdef TIOCGETPGRP
    350 	case TIOCGETPGRP:
    351 #endif
    352 #ifdef TIOCSETPGRP
    353 	case TIOCSETPGRP:
    354 #endif
    355 #ifdef FIONREAD
    356 	case FIONREAD:
    357 #endif
    358 	case TIOCOUTQ:
    359 #ifdef FIONBIO
    360 	case FIONBIO:
    361 #endif
    362 #ifdef FIOASYNC
    363 	case FIOASYNC:
    364 #endif
    365 #ifdef FIOGETOWN
    366 	case FIOGETOWN:
    367 #endif
    368 #ifdef FIOSETOWN
    369 	case FIOSETOWN:
    370 #endif
    371 #ifdef TIOCGETD
    372 	case TIOCGETD:
    373 #endif
    374 #ifdef TIOCSETD
    375 	case TIOCSETD:
    376 #endif
    377 #ifdef TIOCPKT
    378 	case TIOCPKT:
    379 #endif
    380 #ifdef TIOCREMOTE
    381 	case TIOCREMOTE:
    382 #endif
    383 #ifdef TIOCUCNTL
    384 	case TIOCUCNTL:
    385 #endif
    386 #ifdef TIOCTCNTL
    387 	case TIOCTCNTL:
    388 #endif
    389 #ifdef TIOCSIGNAL
    390 	case TIOCSIGNAL:
    391 #endif
    392 #ifdef TIOCSSOFTCAR
    393 	case TIOCSSOFTCAR:
    394 #endif
    395 #ifdef TIOCGSOFTCAR
    396 	case TIOCGSOFTCAR:
    397 #endif
    398 #ifdef TIOCISPACE
    399 	case TIOCISPACE:
    400 #endif
    401 #ifdef TIOCISIZE
    402 	case TIOCISIZE:
    403 #endif
    404 #ifdef TIOCSINTR
    405 	case TIOCSINTR:
    406 #endif
    407 #ifdef TIOCSPTLCK
    408 	case TIOCSPTLCK:
    409 #endif
    410 #ifdef TIOCGPTN
    411 	case TIOCGPTN:
    412 #endif
    413 		tprintf(", ");
    414 		printnum_int(tcp, arg, "%d");
    415 		return 1;
    416 
    417 	/* ioctls with an indirect parameter displayed as a char */
    418 
    419 #ifdef TIOCSTI
    420 	case TIOCSTI:
    421 #endif
    422 		tprintf(", ");
    423 		printstr(tcp, arg, 1);
    424 		return 1;
    425 
    426 	/* ioctls with no parameters */
    427 
    428 #ifdef TIOCSCTTY
    429 	case TIOCSCTTY:
    430 #endif
    431 #ifdef TIOCNOTTY
    432 	case TIOCNOTTY:
    433 #endif
    434 #ifdef FIOCLEX
    435 	case FIOCLEX:
    436 #endif
    437 #ifdef FIONCLEX
    438 	case FIONCLEX:
    439 #endif
    440 #ifdef TIOCCONS
    441 	case TIOCCONS:
    442 #endif
    443 		return 1;
    444 
    445 	/* ioctls which are unknown */
    446 
    447 	default:
    448 		return 0;
    449 	}
    450 }
    451