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