You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
296 lines
7.0 KiB
296 lines
7.0 KiB
/* |
|
* Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com> |
|
* Copyright (c) 1996-2018 The strace developers. |
|
* All rights reserved. |
|
* |
|
* Redistribution and use in source and binary forms, with or without |
|
* modification, are permitted provided that the following conditions |
|
* are met: |
|
* 1. Redistributions of source code must retain the above copyright |
|
* notice, this list of conditions and the following disclaimer. |
|
* 2. Redistributions in binary form must reproduce the above copyright |
|
* notice, this list of conditions and the following disclaimer in the |
|
* documentation and/or other materials provided with the distribution. |
|
* 3. The name of the author may not be used to endorse or promote products |
|
* derived from this software without specific prior written permission. |
|
* |
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
*/ |
|
|
|
#include "defs.h" |
|
/* |
|
* The C library's definition of struct termios might differ from |
|
* the kernel one, and we need to use the kernel layout. |
|
*/ |
|
#include <linux/termios.h> |
|
|
|
#include "xlat/tcxonc_options.h" |
|
#include "xlat/tcflsh_options.h" |
|
#include "xlat/baud_options.h" |
|
#include "xlat/modem_flags.h" |
|
|
|
static void |
|
decode_termios(struct tcb *const tcp, const kernel_ulong_t addr) |
|
{ |
|
struct termios tios; |
|
|
|
tprints(", "); |
|
if (umove_or_printaddr(tcp, addr, &tios)) |
|
return; |
|
if (abbrev(tcp)) { |
|
tprints("{"); |
|
printxval(baud_options, tios.c_cflag & CBAUD, "B???"); |
|
tprintf(" %sopost %sisig %sicanon %secho ...}", |
|
(tios.c_oflag & OPOST) ? "" : "-", |
|
(tios.c_lflag & ISIG) ? "" : "-", |
|
(tios.c_lflag & ICANON) ? "" : "-", |
|
(tios.c_lflag & ECHO) ? "" : "-"); |
|
return; |
|
} |
|
tprintf("{c_iflags=%#lx, c_oflags=%#lx, ", |
|
(long) tios.c_iflag, (long) tios.c_oflag); |
|
tprintf("c_cflags=%#lx, c_lflags=%#lx, ", |
|
(long) tios.c_cflag, (long) tios.c_lflag); |
|
tprintf("c_line=%u, ", tios.c_line); |
|
if (!(tios.c_lflag & ICANON)) |
|
tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ", |
|
tios.c_cc[VMIN], tios.c_cc[VTIME]); |
|
tprints("c_cc="); |
|
print_quoted_string((char *) tios.c_cc, NCCS, QUOTE_FORCE_HEX); |
|
tprints("}"); |
|
} |
|
|
|
static void |
|
decode_termio(struct tcb *const tcp, const kernel_ulong_t addr) |
|
{ |
|
struct termio tio; |
|
int i; |
|
|
|
tprints(", "); |
|
if (umove_or_printaddr(tcp, addr, &tio)) |
|
return; |
|
if (abbrev(tcp)) { |
|
tprints("{"); |
|
printxval(baud_options, tio.c_cflag & CBAUD, "B???"); |
|
tprintf(" %sopost %sisig %sicanon %secho ...}", |
|
(tio.c_oflag & OPOST) ? "" : "-", |
|
(tio.c_lflag & ISIG) ? "" : "-", |
|
(tio.c_lflag & ICANON) ? "" : "-", |
|
(tio.c_lflag & ECHO) ? "" : "-"); |
|
return; |
|
} |
|
tprintf("{c_iflags=%#lx, c_oflags=%#lx, ", |
|
(long) tio.c_iflag, (long) tio.c_oflag); |
|
tprintf("c_cflags=%#lx, c_lflags=%#lx, ", |
|
(long) tio.c_cflag, (long) tio.c_lflag); |
|
tprintf("c_line=%u, ", tio.c_line); |
|
#ifdef _VMIN |
|
if (!(tio.c_lflag & ICANON)) |
|
tprintf("c_cc[_VMIN]=%d, c_cc[_VTIME]=%d, ", |
|
tio.c_cc[_VMIN], tio.c_cc[_VTIME]); |
|
#else /* !_VMIN */ |
|
if (!(tio.c_lflag & ICANON)) |
|
tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ", |
|
tio.c_cc[VMIN], tio.c_cc[VTIME]); |
|
#endif /* !_VMIN */ |
|
tprints("c_cc=\""); |
|
for (i = 0; i < NCC; i++) |
|
tprintf("\\x%02x", tio.c_cc[i]); |
|
tprints("\"}"); |
|
} |
|
|
|
static void |
|
decode_winsize(struct tcb *const tcp, const kernel_ulong_t addr) |
|
{ |
|
struct winsize ws; |
|
|
|
tprints(", "); |
|
if (umove_or_printaddr(tcp, addr, &ws)) |
|
return; |
|
tprintf("{ws_row=%d, ws_col=%d, ws_xpixel=%d, ws_ypixel=%d}", |
|
ws.ws_row, ws.ws_col, ws.ws_xpixel, ws.ws_ypixel); |
|
} |
|
|
|
#ifdef TIOCGSIZE |
|
static void |
|
decode_ttysize(struct tcb *const tcp, const kernel_ulong_t addr) |
|
{ |
|
struct ttysize ts; |
|
|
|
tprints(", "); |
|
if (umove_or_printaddr(tcp, addr, &ts)) |
|
return; |
|
tprintf("{ts_lines=%d, ts_cols=%d}", |
|
ts.ts_lines, ts.ts_cols); |
|
} |
|
#endif |
|
|
|
static void |
|
decode_modem_flags(struct tcb *const tcp, const kernel_ulong_t addr) |
|
{ |
|
int i; |
|
|
|
tprints(", "); |
|
if (umove_or_printaddr(tcp, addr, &i)) |
|
return; |
|
tprints("["); |
|
printflags(modem_flags, i, "TIOCM_???"); |
|
tprints("]"); |
|
} |
|
|
|
int |
|
term_ioctl(struct tcb *const tcp, const unsigned int code, |
|
const kernel_ulong_t arg) |
|
{ |
|
switch (code) { |
|
/* struct termios */ |
|
case TCGETS: |
|
#ifdef TCGETS2 |
|
case TCGETS2: |
|
#endif |
|
case TIOCGLCKTRMIOS: |
|
if (entering(tcp)) |
|
return 0; |
|
ATTRIBUTE_FALLTHROUGH; |
|
case TCSETS: |
|
#ifdef TCSETS2 |
|
case TCSETS2: |
|
#endif |
|
case TCSETSW: |
|
#ifdef TCSETSW2 |
|
case TCSETSW2: |
|
#endif |
|
case TCSETSF: |
|
#ifdef TCSETSF2 |
|
case TCSETSF2: |
|
#endif |
|
case TIOCSLCKTRMIOS: |
|
decode_termios(tcp, arg); |
|
break; |
|
|
|
/* struct termio */ |
|
case TCGETA: |
|
if (entering(tcp)) |
|
return 0; |
|
ATTRIBUTE_FALLTHROUGH; |
|
case TCSETA: |
|
case TCSETAW: |
|
case TCSETAF: |
|
decode_termio(tcp, arg); |
|
break; |
|
|
|
/* struct winsize */ |
|
case TIOCGWINSZ: |
|
if (entering(tcp)) |
|
return 0; |
|
ATTRIBUTE_FALLTHROUGH; |
|
case TIOCSWINSZ: |
|
decode_winsize(tcp, arg); |
|
break; |
|
|
|
/* struct ttysize */ |
|
#ifdef TIOCGSIZE |
|
case TIOCGSIZE: |
|
if (entering(tcp)) |
|
return 0; |
|
ATTRIBUTE_FALLTHROUGH; |
|
case TIOCSSIZE: |
|
decode_ttysize(tcp, arg); |
|
break; |
|
#endif |
|
|
|
/* ioctls with a direct decodable arg */ |
|
case TCXONC: |
|
tprints(", "); |
|
printxval64(tcxonc_options, arg, "TC???"); |
|
break; |
|
case TCFLSH: |
|
tprints(", "); |
|
printxval64(tcflsh_options, arg, "TC???"); |
|
break; |
|
case TCSBRK: |
|
case TCSBRKP: |
|
case TIOCSCTTY: |
|
tprintf(", %d", (int) arg); |
|
break; |
|
|
|
/* ioctls with an indirect parameter displayed as modem flags */ |
|
case TIOCMGET: |
|
if (entering(tcp)) |
|
return 0; |
|
ATTRIBUTE_FALLTHROUGH; |
|
case TIOCMBIS: |
|
case TIOCMBIC: |
|
case TIOCMSET: |
|
decode_modem_flags(tcp, arg); |
|
break; |
|
|
|
/* ioctls with an indirect parameter displayed in decimal */ |
|
case TIOCGPGRP: |
|
case TIOCGSID: |
|
case TIOCGETD: |
|
case TIOCGSOFTCAR: |
|
case TIOCGPTN: |
|
case FIONREAD: |
|
case TIOCOUTQ: |
|
#ifdef TIOCGEXCL |
|
case TIOCGEXCL: |
|
#endif |
|
#ifdef TIOCGDEV |
|
case TIOCGDEV: |
|
#endif |
|
if (entering(tcp)) |
|
return 0; |
|
ATTRIBUTE_FALLTHROUGH; |
|
case TIOCSPGRP: |
|
case TIOCSETD: |
|
case FIONBIO: |
|
case FIOASYNC: |
|
case TIOCPKT: |
|
case TIOCSSOFTCAR: |
|
case TIOCSPTLCK: |
|
tprints(", "); |
|
printnum_int(tcp, arg, "%d"); |
|
break; |
|
|
|
/* ioctls with an indirect parameter displayed as a char */ |
|
case TIOCSTI: |
|
tprints(", "); |
|
printstrn(tcp, arg, 1); |
|
break; |
|
|
|
/* ioctls with no parameters */ |
|
|
|
case TIOCSBRK: |
|
case TIOCCBRK: |
|
case TIOCCONS: |
|
case TIOCNOTTY: |
|
case TIOCEXCL: |
|
case TIOCNXCL: |
|
case FIOCLEX: |
|
case FIONCLEX: |
|
#ifdef TIOCVHANGUP |
|
case TIOCVHANGUP: |
|
#endif |
|
#ifdef TIOCSSERIAL |
|
case TIOCSSERIAL: |
|
#endif |
|
break; |
|
|
|
/* ioctls which are unknown */ |
|
|
|
default: |
|
return RVAL_DECODED; |
|
} |
|
|
|
return RVAL_IOCTL_DECODED; |
|
}
|
|
|