1 /*
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This software was developed by the Computer Systems Engineering group
6 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
7 * contributed to Berkeley.
8 *
9 * All advertising materials mentioning features or use of this software
10 * must display the following acknowledgement:
11 * This product includes software developed by the University of
12 * California, Lawrence Berkeley Laboratory.
13 *
14 * %sccs.include.redist.c%
15 *
16 * @(#)sun_ioctl.c 8.1 (Berkeley) 06/11/93
17 *
18 * from: $Header: sun_ioctl.c,v 1.7 93/05/28 04:40:43 torek Exp $
19 */
20
21 #include <sys/param.h>
22 #include <sys/proc.h>
23 #include <sys/file.h>
24 #include <sys/filedesc.h>
25 #include <sys/ioctl.h>
26 #include <sys/termios.h>
27 #include <sys/tty.h>
28
29 /*
30 * SunOS ioctl calls.
31 * This file is something of a hodge-podge.
32 * Support gets added as things turn up....
33 */
34
35 struct sun_ttysize {
36 int ts_row;
37 int ts_col;
38 };
39
40 struct sun_termio {
41 u_short c_iflag;
42 u_short c_oflag;
43 u_short c_cflag;
44 u_short c_lflag;
45 char c_line;
46 unsigned char c_cc[8];
47 };
48
49 struct sun_ioctl_args {
50 int fd;
51 int cmd;
52 caddr_t data;
53 };
sun_ioctl(p,uap,retval)54 sun_ioctl(p, uap, retval)
55 register struct proc *p;
56 register struct sun_ioctl_args *uap;
57 int *retval;
58 {
59 register struct filedesc *fdp = p->p_fd;
60 register struct file *fp;
61 register int (*ctl)();
62 int error;
63
64 if ((unsigned)uap->fd >= fdp->fd_nfiles ||
65 (fp = fdp->fd_ofiles[uap->fd]) == NULL)
66 return (EBADF);
67 if ((fp->f_flag & (FREAD|FWRITE)) == 0)
68 return (EBADF);
69 ctl = fp->f_ops->fo_ioctl;
70
71 switch (uap->cmd) {
72
73 case _IOR('t', 0, int):
74 uap->cmd = TIOCGETD;
75 break;
76
77 case _IOW('t', 1, int):
78 uap->cmd = TIOCSETD;
79 break;
80
81 case _IO('t', 36): { /* sun TIOCCONS, no parameters */
82 int on = 1;
83 return ((*ctl)(fp, TIOCCONS, (caddr_t)&on, p));
84 }
85
86 case _IOW('t', 37, struct sun_ttysize): {
87 struct winsize ws;
88 if ((error = (*ctl)(fp, TIOCGWINSZ, (caddr_t)&ws, p)) != 0)
89 return (error);
90 ws.ws_row = ((struct sun_ttysize *)uap->data)->ts_row;
91 ws.ws_col = ((struct sun_ttysize *)uap->data)->ts_col;
92 return ((*ctl)(fp, TIOCSWINSZ, (caddr_t)&ws, p));
93 }
94
95 case _IOW('t', 38, struct sun_ttysize): {
96 struct winsize ws;
97 if ((error = (*ctl)(fp, TIOCGWINSZ, (caddr_t)&ws, p)) != 0)
98 return (error);
99 ((struct sun_ttysize *)uap->data)->ts_row = ws.ws_row;
100 ((struct sun_ttysize *)uap->data)->ts_col = ws.ws_col;
101 return (0);
102 }
103
104 case _IOR('t', 130, int):
105 uap->cmd = TIOCSPGRP;
106 break;
107
108 case _IOR('t', 131, int):
109 uap->cmd = TIOCGPGRP;
110 break;
111
112 case _IO('t', 132):
113 uap->cmd = TIOCSCTTY;
114 break;
115
116 case _IOR('T', 1, struct sun_termio): {
117 struct termios bt;
118 struct sun_termio st;
119 int speed;
120 static struct speedtab sptab[] = {
121 { 0, 0 }, { 50, 1 }, { 75, 2 }, { 110, 3 },
122 { 134, 4 }, { 135, 4 }, { 150, 5 }, { 200, 6 },
123 { 300, 7 }, { 600, 8 }, { 1200, 9 }, { 1800, 10 },
124 { 2400, 11 }, { 4800, 12 }, { 9600, 13 },
125 { 19200, 14 }, { 38400, 15 }, { -1, -1 }
126 };
127
128 if ((error = (*ctl)(fp, TIOCGETA, (caddr_t)&bt, p)) != 0)
129 return (error);
130 /* most bits match */
131 st.c_iflag = bt.c_iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK|
132 ISTRIP|INLCR|IGNCR|ICRNL|IXANY|IMAXBEL);
133 if (bt.c_iflag & IXON)
134 st.c_iflag |= 0x0400;
135 if (bt.c_iflag & IXOFF)
136 st.c_iflag |= 0x1000;
137 st.c_oflag = bt.c_oflag & OPOST;
138 if (bt.c_oflag & ONLCR)
139 st.c_oflag |= 0x0004;
140 if (bt.c_oflag & OXTABS)
141 st.c_oflag |= 0x1800;
142 speed = ttspeedtab(bt.c_ospeed, sptab);
143 st.c_cflag = speed >= 0 ? speed : 0;
144 st.c_cflag |= (bt.c_cflag & CSIZE) >> 4;
145 if (bt.c_cflag & CSTOPB)
146 st.c_cflag |= 0x40;
147 if (bt.c_cflag & PARENB)
148 st.c_cflag |= 0x100;
149 if (bt.c_cflag & PARODD)
150 st.c_cflag |= 0x200;
151 if (bt.c_cflag & HUPCL)
152 st.c_cflag |= 0x400;
153 if (bt.c_cflag & CLOCAL)
154 st.c_cflag |= 0x800;
155 st.c_lflag = 0;
156 if (bt.c_lflag & (ECHOKE|ECHOE|ECHOK))
157 st.c_lflag |= 0x0800;
158 if (bt.c_lflag & ECHO)
159 st.c_lflag |= 0x0008;
160 if (bt.c_lflag & ECHONL)
161 st.c_lflag |= 0x0040;
162 if (bt.c_lflag & ECHOPRT)
163 st.c_lflag |= 0x0400;
164 if (bt.c_lflag & ECHOCTL)
165 st.c_lflag |= 0x0200;
166 if (bt.c_lflag & ISIG)
167 st.c_lflag |= 0x0001;
168 if (bt.c_lflag & ICANON)
169 st.c_lflag |= 0x0002;
170 if (bt.c_lflag & IEXTEN)
171 st.c_lflag |= 0x8000;
172 if (bt.c_lflag & NOFLSH)
173 st.c_lflag |= 0x0080;
174 #define mapcc(x) ((x) == _POSIX_VDISABLE ? 0 : (x))
175 st.c_cc[0] = mapcc(bt.c_cc[VINTR]);
176 st.c_cc[1] = mapcc(bt.c_cc[VQUIT]);
177 st.c_cc[2] = mapcc(bt.c_cc[VERASE]);
178 st.c_cc[3] = mapcc(bt.c_cc[VKILL]);
179 st.c_cc[4] = mapcc(bt.c_cc[VEOF]);
180 st.c_cc[5] = mapcc(bt.c_cc[VEOL]);
181 st.c_cc[6] = mapcc(bt.c_cc[VEOL2]);
182 st.c_cc[7] = 0;
183 return (copyout((caddr_t)&st, uap->data, sizeof(st)));
184 }
185 }
186 return (ioctl(p, uap, retval));
187 }
188