• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@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
decode_termios(struct tcb * const tcp,const kernel_ulong_t addr)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
decode_termio(struct tcb * const tcp,const kernel_ulong_t addr)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
decode_winsize(struct tcb * const tcp,const kernel_ulong_t addr)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
decode_ttysize(struct tcb * const tcp,const kernel_ulong_t addr)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
decode_modem_flags(struct tcb * const tcp,const kernel_ulong_t addr)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
term_ioctl(struct tcb * const tcp,const unsigned int code,const kernel_ulong_t arg)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