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 *	$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
51static 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
60static const struct xlat tcflsh_options[] = {
61	{ TCIFLUSH,	"TCIFLUSH"	},
62	{ TCOFLUSH,	"TCOFLUSH"	},
63	{ TCIOFLUSH,	"TCIOFLUSH"	},
64	{ 0,		NULL		},
65};
66#endif
67
68static 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
143static 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
181int
182term_ioctl(tcp, code, arg)
183struct tcb *tcp;
184long 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