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: term.c,v 1.8 2005/06/01 19:02:38 roland Exp $
     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, &arg) < 0)
    341 			return 0;
    342 		tprintf(", [");
    343 		printflags(modem_flags, arg, "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(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 }
    462