Mirror of strace – the linux syscall tracer
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.

term.c 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /*
  2. * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
  3. * Copyright (c) 1996-2018 The strace developers.
  4. * All rights reserved.
  5. *
  6. * SPDX-License-Identifier: LGPL-2.1-or-later
  7. */
  8. #include "defs.h"
  9. /*
  10. * The C library's definition of struct termios might differ from
  11. * the kernel one, and we need to use the kernel layout.
  12. */
  13. #include <linux/termios.h>
  14. #include "xlat/tcxonc_options.h"
  15. #include "xlat/tcflsh_options.h"
  16. #include "xlat/baud_options.h"
  17. #include "xlat/modem_flags.h"
  18. static void
  19. decode_termios(struct tcb *const tcp, const kernel_ulong_t addr)
  20. {
  21. struct termios tios;
  22. tprints(", ");
  23. if (umove_or_printaddr(tcp, addr, &tios))
  24. return;
  25. if (abbrev(tcp)) {
  26. tprints("{");
  27. printxval(baud_options, tios.c_cflag & CBAUD, "B???");
  28. tprintf(" %sopost %sisig %sicanon %secho ...}",
  29. (tios.c_oflag & OPOST) ? "" : "-",
  30. (tios.c_lflag & ISIG) ? "" : "-",
  31. (tios.c_lflag & ICANON) ? "" : "-",
  32. (tios.c_lflag & ECHO) ? "" : "-");
  33. return;
  34. }
  35. tprintf("{c_iflags=%#lx, c_oflags=%#lx, ",
  36. (long) tios.c_iflag, (long) tios.c_oflag);
  37. tprintf("c_cflags=%#lx, c_lflags=%#lx, ",
  38. (long) tios.c_cflag, (long) tios.c_lflag);
  39. tprintf("c_line=%u, ", tios.c_line);
  40. if (!(tios.c_lflag & ICANON))
  41. tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ",
  42. tios.c_cc[VMIN], tios.c_cc[VTIME]);
  43. tprints("c_cc=");
  44. print_quoted_string((char *) tios.c_cc, NCCS, QUOTE_FORCE_HEX);
  45. tprints("}");
  46. }
  47. static void
  48. decode_termio(struct tcb *const tcp, const kernel_ulong_t addr)
  49. {
  50. struct termio tio;
  51. int i;
  52. tprints(", ");
  53. if (umove_or_printaddr(tcp, addr, &tio))
  54. return;
  55. if (abbrev(tcp)) {
  56. tprints("{");
  57. printxval(baud_options, tio.c_cflag & CBAUD, "B???");
  58. tprintf(" %sopost %sisig %sicanon %secho ...}",
  59. (tio.c_oflag & OPOST) ? "" : "-",
  60. (tio.c_lflag & ISIG) ? "" : "-",
  61. (tio.c_lflag & ICANON) ? "" : "-",
  62. (tio.c_lflag & ECHO) ? "" : "-");
  63. return;
  64. }
  65. tprintf("{c_iflags=%#lx, c_oflags=%#lx, ",
  66. (long) tio.c_iflag, (long) tio.c_oflag);
  67. tprintf("c_cflags=%#lx, c_lflags=%#lx, ",
  68. (long) tio.c_cflag, (long) tio.c_lflag);
  69. tprintf("c_line=%u, ", tio.c_line);
  70. #ifdef _VMIN
  71. if (!(tio.c_lflag & ICANON))
  72. tprintf("c_cc[_VMIN]=%d, c_cc[_VTIME]=%d, ",
  73. tio.c_cc[_VMIN], tio.c_cc[_VTIME]);
  74. #else /* !_VMIN */
  75. if (!(tio.c_lflag & ICANON))
  76. tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ",
  77. tio.c_cc[VMIN], tio.c_cc[VTIME]);
  78. #endif /* !_VMIN */
  79. tprints("c_cc=\"");
  80. for (i = 0; i < NCC; i++)
  81. tprintf("\\x%02x", tio.c_cc[i]);
  82. tprints("\"}");
  83. }
  84. static void
  85. decode_winsize(struct tcb *const tcp, const kernel_ulong_t addr)
  86. {
  87. struct winsize ws;
  88. tprints(", ");
  89. if (umove_or_printaddr(tcp, addr, &ws))
  90. return;
  91. tprintf("{ws_row=%d, ws_col=%d, ws_xpixel=%d, ws_ypixel=%d}",
  92. ws.ws_row, ws.ws_col, ws.ws_xpixel, ws.ws_ypixel);
  93. }
  94. #ifdef TIOCGSIZE
  95. static void
  96. decode_ttysize(struct tcb *const tcp, const kernel_ulong_t addr)
  97. {
  98. struct ttysize ts;
  99. tprints(", ");
  100. if (umove_or_printaddr(tcp, addr, &ts))
  101. return;
  102. tprintf("{ts_lines=%d, ts_cols=%d}",
  103. ts.ts_lines, ts.ts_cols);
  104. }
  105. #endif
  106. static void
  107. decode_modem_flags(struct tcb *const tcp, const kernel_ulong_t addr)
  108. {
  109. int i;
  110. tprints(", ");
  111. if (umove_or_printaddr(tcp, addr, &i))
  112. return;
  113. tprints("[");
  114. printflags(modem_flags, i, "TIOCM_???");
  115. tprints("]");
  116. }
  117. int
  118. term_ioctl(struct tcb *const tcp, const unsigned int code,
  119. const kernel_ulong_t arg)
  120. {
  121. switch (code) {
  122. /* struct termios */
  123. case TCGETS:
  124. #ifdef TCGETS2
  125. case TCGETS2:
  126. #endif
  127. case TIOCGLCKTRMIOS:
  128. if (entering(tcp))
  129. return 0;
  130. ATTRIBUTE_FALLTHROUGH;
  131. case TCSETS:
  132. #ifdef TCSETS2
  133. case TCSETS2:
  134. #endif
  135. case TCSETSW:
  136. #ifdef TCSETSW2
  137. case TCSETSW2:
  138. #endif
  139. case TCSETSF:
  140. #ifdef TCSETSF2
  141. case TCSETSF2:
  142. #endif
  143. case TIOCSLCKTRMIOS:
  144. decode_termios(tcp, arg);
  145. break;
  146. /* struct termio */
  147. case TCGETA:
  148. if (entering(tcp))
  149. return 0;
  150. ATTRIBUTE_FALLTHROUGH;
  151. case TCSETA:
  152. case TCSETAW:
  153. case TCSETAF:
  154. decode_termio(tcp, arg);
  155. break;
  156. /* struct winsize */
  157. case TIOCGWINSZ:
  158. if (entering(tcp))
  159. return 0;
  160. ATTRIBUTE_FALLTHROUGH;
  161. case TIOCSWINSZ:
  162. decode_winsize(tcp, arg);
  163. break;
  164. /* struct ttysize */
  165. #ifdef TIOCGSIZE
  166. case TIOCGSIZE:
  167. if (entering(tcp))
  168. return 0;
  169. ATTRIBUTE_FALLTHROUGH;
  170. case TIOCSSIZE:
  171. decode_ttysize(tcp, arg);
  172. break;
  173. #endif
  174. /* ioctls with a direct decodable arg */
  175. case TCXONC:
  176. tprints(", ");
  177. printxval64(tcxonc_options, arg, "TC???");
  178. break;
  179. case TCFLSH:
  180. tprints(", ");
  181. printxval64(tcflsh_options, arg, "TC???");
  182. break;
  183. case TCSBRK:
  184. case TCSBRKP:
  185. case TIOCSCTTY:
  186. tprintf(", %d", (int) arg);
  187. break;
  188. /* ioctls with an indirect parameter displayed as modem flags */
  189. case TIOCMGET:
  190. if (entering(tcp))
  191. return 0;
  192. ATTRIBUTE_FALLTHROUGH;
  193. case TIOCMBIS:
  194. case TIOCMBIC:
  195. case TIOCMSET:
  196. decode_modem_flags(tcp, arg);
  197. break;
  198. /* ioctls with an indirect parameter displayed in decimal */
  199. case TIOCGPGRP:
  200. case TIOCGSID:
  201. case TIOCGETD:
  202. case TIOCGSOFTCAR:
  203. case TIOCGPTN:
  204. case FIONREAD:
  205. case TIOCOUTQ:
  206. #ifdef TIOCGEXCL
  207. case TIOCGEXCL:
  208. #endif
  209. #ifdef TIOCGDEV
  210. case TIOCGDEV:
  211. #endif
  212. if (entering(tcp))
  213. return 0;
  214. ATTRIBUTE_FALLTHROUGH;
  215. case TIOCSPGRP:
  216. case TIOCSETD:
  217. case FIONBIO:
  218. case FIOASYNC:
  219. case TIOCPKT:
  220. case TIOCSSOFTCAR:
  221. case TIOCSPTLCK:
  222. tprints(", ");
  223. printnum_int(tcp, arg, "%d");
  224. break;
  225. /* ioctls with an indirect parameter displayed as a char */
  226. case TIOCSTI:
  227. tprints(", ");
  228. printstrn(tcp, arg, 1);
  229. break;
  230. /* ioctls with no parameters */
  231. case TIOCSBRK:
  232. case TIOCCBRK:
  233. case TIOCCONS:
  234. case TIOCNOTTY:
  235. case TIOCEXCL:
  236. case TIOCNXCL:
  237. case FIOCLEX:
  238. case FIONCLEX:
  239. #ifdef TIOCVHANGUP
  240. case TIOCVHANGUP:
  241. #endif
  242. #ifdef TIOCSSERIAL
  243. case TIOCSSERIAL:
  244. #endif
  245. break;
  246. /* ioctls which are unknown */
  247. default:
  248. return RVAL_DECODED;
  249. }
  250. return RVAL_IOCTL_DECODED;
  251. }