This source file includes following definitions.
- linux_termio_to_bsd_termios
- bsd_termios_to_linux_termio
- linux_termios_to_bsd_termios
- bsd_termios_to_linux_termios
- linux_ioctl_termios
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 #include <sys/param.h>
36 #include <sys/proc.h>
37 #include <sys/systm.h>
38 #include <sys/file.h>
39 #include <sys/filedesc.h>
40 #include <sys/ioctl.h>
41 #include <sys/mount.h>
42 #include <sys/termios.h>
43
44 #include <sys/syscallargs.h>
45
46 #include <compat/linux/linux_types.h>
47 #include <compat/linux/linux_ioctl.h>
48 #include <compat/linux/linux_signal.h>
49 #include <compat/linux/linux_syscallargs.h>
50 #include <compat/linux/linux_util.h>
51 #include <compat/linux/linux_termios.h>
52
53 static speed_t linux_speeds[] = {
54 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
55 9600, 19200, 38400, 57600, 115200, 230400
56 };
57
58 static const int linux_spmasks[] = {
59 LINUX_B0, LINUX_B50, LINUX_B75, LINUX_B110, LINUX_B134, LINUX_B150,
60 LINUX_B200, LINUX_B300, LINUX_B600, LINUX_B1200, LINUX_B1800,
61 LINUX_B2400, LINUX_B4800, LINUX_B9600, LINUX_B19200, LINUX_B38400,
62 LINUX_B57600, LINUX_B115200, LINUX_B230400
63 };
64
65 static void linux_termio_to_bsd_termios(struct linux_termio *,
66 struct termios *);
67 static void bsd_termios_to_linux_termio(struct termios *,
68 struct linux_termio *);
69 static void linux_termios_to_bsd_termios(struct linux_termios *,
70 struct termios *);
71 static void bsd_termios_to_linux_termios(struct termios *,
72 struct linux_termios *);
73
74
75
76
77
78
79
80
81
82
83
84 static void
85 linux_termio_to_bsd_termios(lt, bts)
86 struct linux_termio *lt;
87 struct termios *bts;
88 {
89 int index;
90
91 bts->c_iflag = 0;
92 bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IGNBRK, IGNBRK);
93 bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_BRKINT, BRKINT);
94 bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IGNPAR, IGNPAR);
95 bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_INPCK, INPCK);
96 bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_ISTRIP, ISTRIP);
97 bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_INLCR, INLCR);
98 bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IGNCR, IGNCR);
99 bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_ICRNL, ICRNL);
100 bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IXON, IXON);
101 bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IXANY, IXANY);
102 bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IXOFF, IXOFF);
103 bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IMAXBEL, IMAXBEL);
104
105 bts->c_oflag = 0;
106 bts->c_oflag |= cvtto_bsd_mask(lt->c_oflag, LINUX_OPOST, OPOST);
107 bts->c_oflag |= cvtto_bsd_mask(lt->c_oflag, LINUX_ONLCR, ONLCR);
108 bts->c_oflag |= cvtto_bsd_mask(lt->c_oflag, LINUX_XTABS, OXTABS);
109
110
111
112
113
114
115 switch (lt->c_cflag & LINUX_CSIZE) {
116 case LINUX_CS5:
117 bts->c_cflag = CS5;
118 break;
119 case LINUX_CS6:
120 bts->c_cflag = CS6;
121 break;
122 case LINUX_CS7:
123 bts->c_cflag = CS7;
124 break;
125 case LINUX_CS8:
126 bts->c_cflag = CS8;
127 break;
128 }
129 bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_CSTOPB, CSTOPB);
130 bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_CREAD, CREAD);
131 bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_PARENB, PARENB);
132 bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_PARODD, PARODD);
133 bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_HUPCL, HUPCL);
134 bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_CLOCAL, CLOCAL);
135 bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_CRTSCTS, CRTSCTS);
136
137 bts->c_lflag = 0;
138 bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ISIG, ISIG);
139 bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ICANON, ICANON);
140 bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHO, ECHO);
141 bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOE, ECHOE);
142 bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOK, ECHOK);
143 bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHONL, ECHONL);
144 bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_NOFLSH, NOFLSH);
145 bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_TOSTOP, TOSTOP);
146 bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOCTL, ECHOCTL);
147 bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOPRT, ECHOPRT);
148 bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOKE, ECHOKE);
149 bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_FLUSHO, FLUSHO);
150 bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_PENDIN, PENDIN);
151 bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_IEXTEN, IEXTEN);
152
153 index = lt->c_cflag & LINUX_CBAUD;
154 if (index & LINUX_CBAUDEX)
155 index = (index & ~LINUX_CBAUDEX) + LINUX_NSPEEDS - 1;
156 bts->c_ispeed = bts->c_ospeed = linux_speeds[index];
157
158 bts->c_cc[VINTR] = lt->c_cc[LINUX_VINTR];
159 bts->c_cc[VQUIT] = lt->c_cc[LINUX_VQUIT];
160 bts->c_cc[VERASE] = lt->c_cc[LINUX_VERASE];
161 bts->c_cc[VKILL] = lt->c_cc[LINUX_VKILL];
162 bts->c_cc[VEOF] = lt->c_cc[LINUX_VEOF];
163 bts->c_cc[VTIME] = lt->c_cc[LINUX_VTIME];
164 bts->c_cc[VMIN] = lt->c_cc[LINUX_VMIN];
165 }
166
167 static void
168 bsd_termios_to_linux_termio(bts, lt)
169 struct termios *bts;
170 struct linux_termio *lt;
171 {
172 int i, mask;
173
174 lt->c_iflag = 0;
175 lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNBRK, LINUX_IGNBRK);
176 lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, BRKINT, LINUX_BRKINT);
177 lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNPAR, LINUX_IGNPAR);
178 lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, INPCK, LINUX_INPCK);
179 lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, ISTRIP, LINUX_ISTRIP);
180 lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, INLCR, LINUX_INLCR);
181 lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNCR, LINUX_IGNCR);
182 lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, ICRNL, LINUX_ICRNL);
183 lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXON, LINUX_IXON);
184 lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXANY, LINUX_IXANY);
185 lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXOFF, LINUX_IXOFF);
186 lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IMAXBEL, LINUX_IMAXBEL);
187
188 lt->c_oflag = 0;
189 lt->c_oflag |= cvtto_linux_mask(bts->c_oflag, OPOST, LINUX_OPOST);
190 lt->c_oflag |= cvtto_linux_mask(bts->c_oflag, ONLCR, LINUX_ONLCR);
191 lt->c_oflag |= cvtto_linux_mask(bts->c_oflag, OXTABS, LINUX_XTABS);
192
193 switch (bts->c_cflag & CSIZE) {
194 case CS5:
195 lt->c_cflag = LINUX_CS5;
196 break;
197 case CS6:
198 lt->c_cflag = LINUX_CS6;
199 break;
200 case CS7:
201 lt->c_cflag = LINUX_CS7;
202 break;
203 case CS8:
204 lt->c_cflag = LINUX_CS8;
205 break;
206 }
207 lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, CSTOPB, LINUX_CSTOPB);
208 lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, CREAD, LINUX_CREAD);
209 lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, PARENB, LINUX_PARENB);
210 lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, PARODD, LINUX_PARODD);
211 lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, HUPCL, LINUX_HUPCL);
212 lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, CLOCAL, LINUX_CLOCAL);
213 lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, CRTSCTS, LINUX_CRTSCTS);
214
215 lt->c_lflag = 0;
216 lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ISIG, LINUX_ISIG);
217 lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ICANON, LINUX_ICANON);
218 lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHO, LINUX_ECHO);
219 lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOE, LINUX_ECHOE);
220 lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOK, LINUX_ECHOK);
221 lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHONL, LINUX_ECHONL);
222 lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, NOFLSH, LINUX_NOFLSH);
223 lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, TOSTOP, LINUX_TOSTOP);
224 lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOCTL, LINUX_ECHOCTL);
225 lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOPRT, LINUX_ECHOPRT);
226 lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOKE, LINUX_ECHOKE);
227 lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, FLUSHO, LINUX_FLUSHO);
228 lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, PENDIN, LINUX_PENDIN);
229 lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, IEXTEN, LINUX_IEXTEN);
230
231 mask = LINUX_B9600;
232 for (i = 0; i < sizeof (linux_speeds) / sizeof (speed_t); i++) {
233 if (bts->c_ospeed == linux_speeds[i]) {
234 mask = linux_spmasks[i];
235 break;
236 }
237 }
238 lt->c_cflag |= mask;
239
240 lt->c_cc[LINUX_VINTR] = bts->c_cc[VINTR];
241 lt->c_cc[LINUX_VQUIT] = bts->c_cc[VQUIT];
242 lt->c_cc[LINUX_VERASE] = bts->c_cc[VERASE];
243 lt->c_cc[LINUX_VKILL] = bts->c_cc[VKILL];
244 lt->c_cc[LINUX_VEOF] = bts->c_cc[VEOF];
245 lt->c_cc[LINUX_VTIME] = bts->c_cc[VTIME];
246 lt->c_cc[LINUX_VMIN] = bts->c_cc[VMIN];
247 lt->c_cc[LINUX_VSWTC] = 0;
248
249
250 lt->c_line = 0;
251 }
252
253 static void
254 linux_termios_to_bsd_termios(lts, bts)
255 struct linux_termios *lts;
256 struct termios *bts;
257 {
258 int index;
259
260 bts->c_iflag = 0;
261 bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IGNBRK, IGNBRK);
262 bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_BRKINT, BRKINT);
263 bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IGNPAR, IGNPAR);
264 bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_INPCK, INPCK);
265 bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_ISTRIP, ISTRIP);
266 bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_INLCR, INLCR);
267 bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IGNCR, IGNCR);
268 bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_ICRNL, ICRNL);
269 bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IXON, IXON);
270 bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IXANY, IXANY);
271 bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IXOFF, IXOFF);
272 bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IMAXBEL, IMAXBEL);
273
274 bts->c_oflag = 0;
275 bts->c_oflag |= cvtto_bsd_mask(lts->c_oflag, LINUX_OPOST, OPOST);
276 bts->c_oflag |= cvtto_bsd_mask(lts->c_oflag, LINUX_ONLCR, ONLCR);
277 bts->c_oflag |= cvtto_bsd_mask(lts->c_oflag, LINUX_XTABS, OXTABS);
278
279 bts->c_cflag = 0;
280 switch (lts->c_cflag & LINUX_CSIZE) {
281 case LINUX_CS5:
282 bts->c_cflag = CS5;
283 break;
284 case LINUX_CS6:
285 bts->c_cflag = CS6;
286 break;
287 case LINUX_CS7:
288 bts->c_cflag = CS7;
289 break;
290 case LINUX_CS8:
291 bts->c_cflag = CS8;
292 break;
293 }
294 bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_CSTOPB, CSTOPB);
295 bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_CREAD, CREAD);
296 bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_PARENB, PARENB);
297 bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_PARODD, PARODD);
298 bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_HUPCL, HUPCL);
299 bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_CLOCAL, CLOCAL);
300 bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_CRTSCTS, CRTSCTS);
301
302 bts->c_lflag = 0;
303 bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ISIG, ISIG);
304 bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ICANON, ICANON);
305 bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHO, ECHO);
306 bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOE, ECHOE);
307 bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOK, ECHOK);
308 bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHONL, ECHONL);
309 bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_NOFLSH, NOFLSH);
310 bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_TOSTOP, TOSTOP);
311 bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOCTL, ECHOCTL);
312 bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOPRT, ECHOPRT);
313 bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOKE, ECHOKE);
314 bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_FLUSHO, FLUSHO);
315 bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_PENDIN, PENDIN);
316 bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_IEXTEN, IEXTEN);
317
318 index = lts->c_cflag & LINUX_CBAUD;
319 if (index & LINUX_CBAUDEX)
320 index = (index & ~LINUX_CBAUDEX) + LINUX_NSPEEDS - 1;
321 bts->c_ispeed = bts->c_ospeed = linux_speeds[index];
322
323 bts->c_cc[VINTR] = lts->c_cc[LINUX_VINTR];
324 bts->c_cc[VQUIT] = lts->c_cc[LINUX_VQUIT];
325 bts->c_cc[VERASE] = lts->c_cc[LINUX_VERASE];
326 bts->c_cc[VKILL] = lts->c_cc[LINUX_VKILL];
327 bts->c_cc[VEOF] = lts->c_cc[LINUX_VEOF];
328 bts->c_cc[VTIME] = lts->c_cc[LINUX_VTIME];
329 bts->c_cc[VMIN] = lts->c_cc[LINUX_VMIN];
330 bts->c_cc[VEOL] = lts->c_cc[LINUX_VEOL];
331 bts->c_cc[VEOL2] = lts->c_cc[LINUX_VEOL2];
332 bts->c_cc[VWERASE] = lts->c_cc[LINUX_VWERASE];
333 bts->c_cc[VSUSP] = lts->c_cc[LINUX_VSUSP];
334 bts->c_cc[VSTART] = lts->c_cc[LINUX_VSTART];
335 bts->c_cc[VSTOP] = lts->c_cc[LINUX_VSTOP];
336 bts->c_cc[VLNEXT] = lts->c_cc[LINUX_VLNEXT];
337 bts->c_cc[VDISCARD] = lts->c_cc[LINUX_VDISCARD];
338 bts->c_cc[VREPRINT] = lts->c_cc[LINUX_VREPRINT];
339 }
340
341 static void
342 bsd_termios_to_linux_termios(bts, lts)
343 struct termios *bts;
344 struct linux_termios *lts;
345 {
346 int i, mask;
347
348 lts->c_iflag = 0;
349 lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNBRK, LINUX_IGNBRK);
350 lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, BRKINT, LINUX_BRKINT);
351 lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNPAR, LINUX_IGNPAR);
352 lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, INPCK, LINUX_INPCK);
353 lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, ISTRIP, LINUX_ISTRIP);
354 lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, INLCR, LINUX_INLCR);
355 lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNCR, LINUX_IGNCR);
356 lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, ICRNL, LINUX_ICRNL);
357 lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXON, LINUX_IXON);
358 lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXANY, LINUX_IXANY);
359 lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXOFF, LINUX_IXOFF);
360 lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IMAXBEL, LINUX_IMAXBEL);
361
362 lts->c_oflag = 0;
363 lts->c_oflag |= cvtto_linux_mask(bts->c_oflag, OPOST, LINUX_OPOST);
364 lts->c_oflag |= cvtto_linux_mask(bts->c_oflag, ONLCR, LINUX_ONLCR);
365 lts->c_oflag |= cvtto_linux_mask(bts->c_oflag, OXTABS, LINUX_XTABS);
366
367 switch (bts->c_cflag & CSIZE) {
368 case CS5:
369 lts->c_cflag = LINUX_CS5;
370 break;
371 case CS6:
372 lts->c_cflag = LINUX_CS6;
373 break;
374 case CS7:
375 lts->c_cflag = LINUX_CS7;
376 break;
377 case CS8:
378 lts->c_cflag = LINUX_CS8;
379 break;
380 }
381 lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CS5, LINUX_CS5);
382 lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CS6, LINUX_CS6);
383 lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CS7, LINUX_CS7);
384 lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CS8, LINUX_CS8);
385 lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CSTOPB, LINUX_CSTOPB);
386 lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CREAD, LINUX_CREAD);
387 lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, PARENB, LINUX_PARENB);
388 lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, PARODD, LINUX_PARODD);
389 lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, HUPCL, LINUX_HUPCL);
390 lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CLOCAL, LINUX_CLOCAL);
391 lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CRTSCTS, LINUX_CRTSCTS);
392
393 lts->c_lflag = 0;
394 lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ISIG, LINUX_ISIG);
395 lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ICANON, LINUX_ICANON);
396 lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHO, LINUX_ECHO);
397 lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOE, LINUX_ECHOE);
398 lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOK, LINUX_ECHOK);
399 lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHONL, LINUX_ECHONL);
400 lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, NOFLSH, LINUX_NOFLSH);
401 lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, TOSTOP, LINUX_TOSTOP);
402 lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOCTL, LINUX_ECHOCTL);
403 lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOPRT, LINUX_ECHOPRT);
404 lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOKE, LINUX_ECHOKE);
405 lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, FLUSHO, LINUX_FLUSHO);
406 lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, PENDIN, LINUX_PENDIN);
407 lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, IEXTEN, LINUX_IEXTEN);
408
409 mask = LINUX_B9600;
410 for (i = 0; i < sizeof (linux_speeds) / sizeof (speed_t); i++) {
411 if (bts->c_ospeed == linux_speeds[i]) {
412 mask = linux_spmasks[i];
413 break;
414 }
415 }
416 lts->c_cflag |= mask;
417
418 lts->c_cc[LINUX_VINTR] = bts->c_cc[VINTR];
419 lts->c_cc[LINUX_VQUIT] = bts->c_cc[VQUIT];
420 lts->c_cc[LINUX_VERASE] = bts->c_cc[VERASE];
421 lts->c_cc[LINUX_VKILL] = bts->c_cc[VKILL];
422 lts->c_cc[LINUX_VEOF] = bts->c_cc[VEOF];
423 lts->c_cc[LINUX_VTIME] = bts->c_cc[VTIME];
424 lts->c_cc[LINUX_VMIN] = bts->c_cc[VMIN];
425 lts->c_cc[LINUX_VEOL] = bts->c_cc[VEOL];
426 lts->c_cc[LINUX_VEOL2] = bts->c_cc[VEOL2];
427 lts->c_cc[LINUX_VWERASE] = bts->c_cc[VWERASE];
428 lts->c_cc[LINUX_VSUSP] = bts->c_cc[VSUSP];
429 lts->c_cc[LINUX_VSTART] = bts->c_cc[VSTART];
430 lts->c_cc[LINUX_VSTOP] = bts->c_cc[VSTOP];
431 lts->c_cc[LINUX_VLNEXT] = bts->c_cc[VLNEXT];
432 lts->c_cc[LINUX_VDISCARD] = bts->c_cc[VDISCARD];
433 lts->c_cc[LINUX_VREPRINT] = bts->c_cc[VREPRINT];
434 lts->c_cc[LINUX_VSWTC] = 0;
435
436
437 lts->c_line = 0;
438 }
439
440 int
441 linux_ioctl_termios(p, v, retval)
442 struct proc *p;
443 void *v;
444 register_t *retval;
445 {
446 struct linux_sys_ioctl_args
447
448
449
450 *uap = v;
451 struct file *fp;
452 struct filedesc *fdp;
453 u_long com;
454 struct linux_termio tmplt;
455 struct linux_termios tmplts;
456 struct termios tmpbts;
457 caddr_t sg;
458 int idat;
459 struct sys_ioctl_args ia;
460 char tioclinux;
461 int error = 0;
462
463 fdp = p->p_fd;
464 if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
465 return (EBADF);
466 FREF(fp);
467
468 if ((fp->f_flag & (FREAD | FWRITE)) == 0) {
469 error = EBADF;
470 goto out;
471 }
472
473 com = SCARG(uap, com);
474 retval[0] = 0;
475
476 switch (com) {
477 case LINUX_TCGETS:
478 error = (*fp->f_ops->fo_ioctl)(fp, TIOCGETA, (caddr_t)&tmpbts,
479 p);
480 if (error)
481 goto out;
482 bsd_termios_to_linux_termios(&tmpbts, &tmplts);
483 error = copyout(&tmplts, SCARG(uap, data), sizeof tmplts);
484 goto out;
485 case LINUX_TCSETS:
486 case LINUX_TCSETSW:
487 case LINUX_TCSETSF:
488
489
490
491
492 error = (*fp->f_ops->fo_ioctl)(fp, TIOCGETA, (caddr_t)&tmpbts,
493 p);
494 if (error)
495 goto out;
496 error = copyin(SCARG(uap, data), &tmplts, sizeof tmplts);
497 if (error)
498 goto out;
499 linux_termios_to_bsd_termios(&tmplts, &tmpbts);
500 switch (com) {
501 case LINUX_TCSETS:
502 com = TIOCSETA;
503 break;
504 case LINUX_TCSETSW:
505 com = TIOCSETAW;
506 break;
507 case LINUX_TCSETSF:
508 com = TIOCSETAF;
509 break;
510 }
511 error = (*fp->f_ops->fo_ioctl)(fp, com, (caddr_t)&tmpbts, p);
512 goto out;
513 case LINUX_TCGETA:
514 error = (*fp->f_ops->fo_ioctl)(fp, TIOCGETA, (caddr_t)&tmpbts,
515 p);
516 if (error)
517 goto out;
518 bsd_termios_to_linux_termio(&tmpbts, &tmplt);
519 error = copyout(&tmplt, SCARG(uap, data), sizeof tmplt);
520 goto out;
521 case LINUX_TCSETA:
522 case LINUX_TCSETAW:
523 case LINUX_TCSETAF:
524
525
526
527
528 error = (*fp->f_ops->fo_ioctl)(fp, TIOCGETA, (caddr_t)&tmpbts,
529 p);
530 if (error)
531 goto out;
532 error = copyin(SCARG(uap, data), &tmplt, sizeof tmplt);
533 if (error)
534 goto out;
535 linux_termio_to_bsd_termios(&tmplt, &tmpbts);
536 switch (com) {
537 case LINUX_TCSETA:
538 com = TIOCSETA;
539 break;
540 case LINUX_TCSETAW:
541 com = TIOCSETAW;
542 break;
543 case LINUX_TCSETAF:
544 com = TIOCSETAF;
545 break;
546 }
547 error = (*fp->f_ops->fo_ioctl)(fp, com, (caddr_t)&tmpbts, p);
548 goto out;
549 case LINUX_TIOCGETD:
550 error = (*fp->f_ops->fo_ioctl)(fp, TIOCGETD, (caddr_t)&idat, p);
551 if (error)
552 goto out;
553 switch (idat) {
554 case TTYDISC:
555 idat = LINUX_N_TTY;
556 break;
557 case SLIPDISC:
558 idat = LINUX_N_SLIP;
559 break;
560 case PPPDISC:
561 idat = LINUX_N_PPP;
562 break;
563
564
565
566 case TABLDISC:
567 default:
568 idat = -1;
569 break;
570 }
571 error = copyout(&idat, SCARG(uap, data), sizeof idat);
572 goto out;
573 case LINUX_TIOCSETD:
574 error = copyin(SCARG(uap, data), &idat, sizeof idat);
575 if (error)
576 goto out;
577 switch (idat) {
578 case LINUX_N_TTY:
579 idat = TTYDISC;
580 break;
581 case LINUX_N_SLIP:
582 idat = SLIPDISC;
583 break;
584 case LINUX_N_PPP:
585 idat = PPPDISC;
586 break;
587
588
589
590 case LINUX_N_MOUSE:
591 default:
592 error = EINVAL;
593 goto out;
594 }
595 error = (*fp->f_ops->fo_ioctl)(fp, TIOCSETD, (caddr_t)&idat, p);
596 goto out;
597 case LINUX_TIOCLINUX:
598 error = copyin(SCARG(uap, data), &tioclinux, sizeof tioclinux);
599 if (error != 0)
600 goto out;
601 switch (tioclinux) {
602 case LINUX_TIOCLINUX_KERNMSG:
603
604
605
606
607
608 goto out;
609 case LINUX_TIOCLINUX_COPY:
610 case LINUX_TIOCLINUX_PASTE:
611 case LINUX_TIOCLINUX_UNBLANK:
612 case LINUX_TIOCLINUX_LOADLUT:
613 case LINUX_TIOCLINUX_READSHIFT:
614 case LINUX_TIOCLINUX_READMOUSE:
615 case LINUX_TIOCLINUX_VESABLANK:
616 case LINUX_TIOCLINUX_CURCONS:
617 error = EINVAL;
618 goto out;
619 }
620 break;
621 case LINUX_TIOCGWINSZ:
622 SCARG(&ia, com) = TIOCGWINSZ;
623 break;
624 case LINUX_TIOCSWINSZ:
625 SCARG(&ia, com) = TIOCSWINSZ;
626 break;
627 case LINUX_TIOCMGET:
628 SCARG(&ia, com) = TIOCMGET;
629 break;
630 case LINUX_TIOCMBIS:
631 SCARG(&ia, com) = TIOCMBIS;
632 break;
633 case LINUX_TIOCMBIC:
634 SCARG(&ia, com) = TIOCMBIC;
635 break;
636 case LINUX_TIOCMSET:
637 SCARG(&ia, com) = TIOCMSET;
638 break;
639 case LINUX_TIOCGPGRP:
640 SCARG(&ia, com) = TIOCGPGRP;
641 break;
642 case LINUX_TIOCSPGRP:
643 SCARG(&ia, com) = TIOCSPGRP;
644 break;
645 case LINUX_FIONREAD:
646 SCARG(&ia, com) = FIONREAD;
647 break;
648 case LINUX_FIONBIO:
649 SCARG(&ia, com) = FIONBIO;
650 break;
651 case LINUX_FIOASYNC:
652 SCARG(&ia, com) = FIOASYNC;
653 break;
654 case LINUX_TIOCEXCL:
655 SCARG(&ia, com) = TIOCEXCL;
656 break;
657 case LINUX_TIOCNXCL:
658 SCARG(&ia, com) = TIOCNXCL;
659 break;
660 case LINUX_TIOCSCTTY:
661 SCARG(&ia, com) = TIOCSCTTY;
662 break;
663 case LINUX_TIOCCONS:
664 SCARG(&ia, com) = TIOCCONS;
665 break;
666 case LINUX_TIOCNOTTY:
667 SCARG(&ia, com) = TIOCNOTTY;
668 break;
669 case LINUX_TCSBRK:
670 SCARG(&ia, com) = SCARG(uap, data) ? TIOCDRAIN : TIOCSBRK;
671 break;
672 case LINUX_TCXONC:
673 switch ((int)SCARG(uap, data)) {
674 case LINUX_TCOOFF:
675 SCARG(&ia, com) = TIOCSTOP;
676 break;
677 case LINUX_TCOON:
678 SCARG(&ia, com) = TIOCSTART;
679 break;
680 case LINUX_TCIOFF:
681 case LINUX_TCION: {
682 u_char c, *cp;
683 struct sys_write_args wa;
684
685 error = (*fp->f_ops->fo_ioctl)(fp, TIOCGETA,
686 (caddr_t)&tmpbts, p);
687 if (error)
688 goto out;
689 if ((int)SCARG(uap, data) == LINUX_TCIOFF)
690 c = tmpbts.c_cc[VSTOP];
691 else
692 c = tmpbts.c_cc[VSTART];
693 if (c == _POSIX_VDISABLE)
694 goto out;
695
696 sg = stackgap_init(p->p_emul);
697 cp = (char *) stackgap_alloc(&sg, 1);
698 if ((error = copyout(&c, cp, 1)))
699 goto out;
700
701 SCARG(&wa, fd) = SCARG(uap, fd);
702 SCARG(&wa, buf) = cp;
703 SCARG(&wa, nbyte) = 1;
704 error = sys_write(p, &wa, retval);
705 goto out;
706 }
707 default:
708 error = EINVAL;
709 goto out;
710 }
711 SCARG(uap, data) = 0;
712 break;
713 default:
714 error = EINVAL;
715 goto out;
716 }
717
718 SCARG(&ia, fd) = SCARG(uap, fd);
719 SCARG(&ia, data) = SCARG(uap, data);
720 error = sys_ioctl(p, &ia, retval);
721
722 out:
723 FRELE(fp);
724 return (error);
725 }