1 /*	$NetBSD: ibcs2_ioctl.c,v 1.6 1995/03/14 15:12:28 scottb Exp $	*/
2 
3 /*-
4  * Copyright (c) 1994, 1995 Scott Bartram
5  * All rights reserved.
6  *
7  * based on compat/sunos/sun_ioctl.c
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD: stable/10/sys/i386/ibcs2/ibcs2_ioctl.c 280258 2015-03-19 13:37:36Z rwatson $");
31 
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/capsicum.h>
35 #include <sys/consio.h>
36 #include <sys/fcntl.h>
37 #include <sys/file.h>
38 #include <sys/filedesc.h>
39 #include <sys/filio.h>
40 #include <sys/kbio.h>
41 #include <sys/lock.h>
42 #include <sys/mutex.h>
43 #include <sys/sysproto.h>
44 #include <sys/tty.h>
45 
46 #include <i386/ibcs2/ibcs2_signal.h>
47 #include <i386/ibcs2/ibcs2_socksys.h>
48 #include <i386/ibcs2/ibcs2_stropts.h>
49 #include <i386/ibcs2/ibcs2_proto.h>
50 #include <i386/ibcs2/ibcs2_termios.h>
51 #include <i386/ibcs2/ibcs2_util.h>
52 #include <i386/ibcs2/ibcs2_ioctl.h>
53 
54 static void stios2btios(struct ibcs2_termios *, struct termios *);
55 static void btios2stios(struct termios *, struct ibcs2_termios *);
56 static void stios2stio(struct ibcs2_termios *, struct ibcs2_termio *);
57 static void stio2stios(struct ibcs2_termio *, struct ibcs2_termios *);
58 
59 /*
60  * iBCS2 ioctl calls.
61  */
62 
63 struct speedtab {
64 	int sp_speed;			/* Speed. */
65 	int sp_code;			/* Code. */
66 };
67 
68 static struct speedtab sptab[] = {
69 	{ 0, 0 },
70 	{ 50, 1 },
71 	{ 75, 2 },
72 	{ 110, 3 },
73 	{ 134, 4 },
74 	{ 135, 4 },
75 	{ 150, 5 },
76 	{ 200, 6 },
77 	{ 300, 7 },
78 	{ 600, 8 },
79 	{ 1200, 9 },
80 	{ 1800, 10 },
81 	{ 2400, 11 },
82 	{ 4800, 12 },
83 	{ 9600, 13 },
84 	{ 19200, 14 },
85 	{ 38400, 15 },
86 	{ -1, -1 }
87 };
88 
89 static u_long s2btab[] = {
90 	0,
91 	50,
92 	75,
93 	110,
94 	134,
95 	150,
96 	200,
97 	300,
98 	600,
99 	1200,
100 	1800,
101 	2400,
102 	4800,
103 	9600,
104 	19200,
105 	38400,
106 };
107 
108 static int
ttspeedtab(int speed,struct speedtab * table)109 ttspeedtab(int speed, struct speedtab *table)
110 {
111 
112 	for ( ; table->sp_speed != -1; table++)
113 		if (table->sp_speed == speed)
114 			return (table->sp_code);
115 	return (-1);
116 }
117 
118 static void
stios2btios(st,bt)119 stios2btios(st, bt)
120 	struct ibcs2_termios *st;
121 	struct termios *bt;
122 {
123 	register u_long l, r;
124 
125 	l = st->c_iflag;	r = 0;
126 	if (l & IBCS2_IGNBRK)	r |= IGNBRK;
127 	if (l & IBCS2_BRKINT)	r |= BRKINT;
128 	if (l & IBCS2_IGNPAR)	r |= IGNPAR;
129 	if (l & IBCS2_PARMRK)	r |= PARMRK;
130 	if (l & IBCS2_INPCK)	r |= INPCK;
131 	if (l & IBCS2_ISTRIP)	r |= ISTRIP;
132 	if (l & IBCS2_INLCR)	r |= INLCR;
133 	if (l & IBCS2_IGNCR)	r |= IGNCR;
134 	if (l & IBCS2_ICRNL)	r |= ICRNL;
135 	if (l & IBCS2_IXON)	r |= IXON;
136 	if (l & IBCS2_IXANY)	r |= IXANY;
137 	if (l & IBCS2_IXOFF)	r |= IXOFF;
138 	if (l & IBCS2_IMAXBEL)	r |= IMAXBEL;
139 	bt->c_iflag = r;
140 
141 	l = st->c_oflag;	r = 0;
142 	if (l & IBCS2_OPOST)	r |= OPOST;
143 	if (l & IBCS2_ONLCR)	r |= ONLCR;
144 	if (l & IBCS2_TAB3)	r |= TAB3;
145 	bt->c_oflag = r;
146 
147 	l = st->c_cflag;	r = 0;
148 	switch (l & IBCS2_CSIZE) {
149 	case IBCS2_CS5:		r |= CS5; break;
150 	case IBCS2_CS6:		r |= CS6; break;
151 	case IBCS2_CS7:		r |= CS7; break;
152 	case IBCS2_CS8:		r |= CS8; break;
153 	}
154 	if (l & IBCS2_CSTOPB)	r |= CSTOPB;
155 	if (l & IBCS2_CREAD)	r |= CREAD;
156 	if (l & IBCS2_PARENB)	r |= PARENB;
157 	if (l & IBCS2_PARODD)	r |= PARODD;
158 	if (l & IBCS2_HUPCL)	r |= HUPCL;
159 	if (l & IBCS2_CLOCAL)	r |= CLOCAL;
160 	bt->c_cflag = r;
161 
162 	bt->c_ispeed = bt->c_ospeed = s2btab[l & 0x0000000f];
163 
164 	l = st->c_lflag;	r = 0;
165 	if (l & IBCS2_ISIG)	r |= ISIG;
166 	if (l & IBCS2_ICANON)	r |= ICANON;
167 	if (l & IBCS2_ECHO)	r |= ECHO;
168 	if (l & IBCS2_ECHOE)	r |= ECHOE;
169 	if (l & IBCS2_ECHOK)	r |= ECHOK;
170 	if (l & IBCS2_ECHONL)	r |= ECHONL;
171 	if (l & IBCS2_NOFLSH)	r |= NOFLSH;
172 	if (l & IBCS2_TOSTOP)	r |= TOSTOP;
173 	bt->c_lflag = r;
174 
175 	bt->c_cc[VINTR]	=
176 	    st->c_cc[IBCS2_VINTR]  ? st->c_cc[IBCS2_VINTR]  : _POSIX_VDISABLE;
177 	bt->c_cc[VQUIT] =
178 	    st->c_cc[IBCS2_VQUIT]  ? st->c_cc[IBCS2_VQUIT]  : _POSIX_VDISABLE;
179 	bt->c_cc[VERASE] =
180 	    st->c_cc[IBCS2_VERASE] ? st->c_cc[IBCS2_VERASE] : _POSIX_VDISABLE;
181 	bt->c_cc[VKILL] =
182 	    st->c_cc[IBCS2_VKILL]  ? st->c_cc[IBCS2_VKILL]  : _POSIX_VDISABLE;
183 	if (bt->c_lflag & ICANON) {
184 		bt->c_cc[VEOF] =
185 		    st->c_cc[IBCS2_VEOF] ? st->c_cc[IBCS2_VEOF] : _POSIX_VDISABLE;
186 		bt->c_cc[VEOL] =
187 		    st->c_cc[IBCS2_VEOL] ? st->c_cc[IBCS2_VEOL] : _POSIX_VDISABLE;
188 	} else {
189 		bt->c_cc[VMIN]  = st->c_cc[IBCS2_VMIN];
190 		bt->c_cc[VTIME] = st->c_cc[IBCS2_VTIME];
191 	}
192 	bt->c_cc[VEOL2] =
193 	    st->c_cc[IBCS2_VEOL2]  ? st->c_cc[IBCS2_VEOL2]  : _POSIX_VDISABLE;
194 #if 0
195 	bt->c_cc[VSWTCH] =
196 	    st->c_cc[IBCS2_VSWTCH] ? st->c_cc[IBCS2_VSWTCH] : _POSIX_VDISABLE;
197 #endif
198 	bt->c_cc[VSTART] =
199 	    st->c_cc[IBCS2_VSTART] ? st->c_cc[IBCS2_VSTART] : _POSIX_VDISABLE;
200 	bt->c_cc[VSTOP] =
201 	    st->c_cc[IBCS2_VSTOP]  ? st->c_cc[IBCS2_VSTOP]  : _POSIX_VDISABLE;
202 	bt->c_cc[VSUSP] =
203 	    st->c_cc[IBCS2_VSUSP]  ? st->c_cc[IBCS2_VSUSP]  : _POSIX_VDISABLE;
204 	bt->c_cc[VDSUSP]   = _POSIX_VDISABLE;
205 	bt->c_cc[VREPRINT] = _POSIX_VDISABLE;
206 	bt->c_cc[VDISCARD] = _POSIX_VDISABLE;
207 	bt->c_cc[VWERASE]  = _POSIX_VDISABLE;
208 	bt->c_cc[VLNEXT]   = _POSIX_VDISABLE;
209 	bt->c_cc[VSTATUS]  = _POSIX_VDISABLE;
210 }
211 
212 static void
btios2stios(bt,st)213 btios2stios(bt, st)
214 	struct termios *bt;
215 	struct ibcs2_termios *st;
216 {
217 	register u_long l, r;
218 
219 	l = bt->c_iflag;	r = 0;
220 	if (l & IGNBRK)		r |= IBCS2_IGNBRK;
221 	if (l & BRKINT)		r |= IBCS2_BRKINT;
222 	if (l & IGNPAR)		r |= IBCS2_IGNPAR;
223 	if (l & PARMRK)		r |= IBCS2_PARMRK;
224 	if (l & INPCK)		r |= IBCS2_INPCK;
225 	if (l & ISTRIP)		r |= IBCS2_ISTRIP;
226 	if (l & INLCR)		r |= IBCS2_INLCR;
227 	if (l & IGNCR)		r |= IBCS2_IGNCR;
228 	if (l & ICRNL)		r |= IBCS2_ICRNL;
229 	if (l & IXON)		r |= IBCS2_IXON;
230 	if (l & IXANY)		r |= IBCS2_IXANY;
231 	if (l & IXOFF)		r |= IBCS2_IXOFF;
232 	if (l & IMAXBEL)	r |= IBCS2_IMAXBEL;
233 	st->c_iflag = r;
234 
235 	l = bt->c_oflag;	r = 0;
236 	if (l & OPOST)		r |= IBCS2_OPOST;
237 	if (l & ONLCR)		r |= IBCS2_ONLCR;
238 	if (l & TAB3)		r |= IBCS2_TAB3;
239 	st->c_oflag = r;
240 
241 	l = bt->c_cflag;	r = 0;
242 	switch (l & CSIZE) {
243 	case CS5:		r |= IBCS2_CS5; break;
244 	case CS6:		r |= IBCS2_CS6; break;
245 	case CS7:		r |= IBCS2_CS7; break;
246 	case CS8:		r |= IBCS2_CS8; break;
247 	}
248 	if (l & CSTOPB)		r |= IBCS2_CSTOPB;
249 	if (l & CREAD)		r |= IBCS2_CREAD;
250 	if (l & PARENB)		r |= IBCS2_PARENB;
251 	if (l & PARODD)		r |= IBCS2_PARODD;
252 	if (l & HUPCL)		r |= IBCS2_HUPCL;
253 	if (l & CLOCAL)		r |= IBCS2_CLOCAL;
254 	st->c_cflag = r;
255 
256 	l = bt->c_lflag;	r = 0;
257 	if (l & ISIG)		r |= IBCS2_ISIG;
258 	if (l & ICANON)		r |= IBCS2_ICANON;
259 	if (l & ECHO)		r |= IBCS2_ECHO;
260 	if (l & ECHOE)		r |= IBCS2_ECHOE;
261 	if (l & ECHOK)		r |= IBCS2_ECHOK;
262 	if (l & ECHONL)		r |= IBCS2_ECHONL;
263 	if (l & NOFLSH)		r |= IBCS2_NOFLSH;
264 	if (l & TOSTOP)		r |= IBCS2_TOSTOP;
265 	st->c_lflag = r;
266 
267 	l = ttspeedtab(bt->c_ospeed, sptab);
268 	if ((int)l >= 0)
269 		st->c_cflag |= l;
270 
271 	st->c_cc[IBCS2_VINTR] =
272 	    bt->c_cc[VINTR]  != _POSIX_VDISABLE ? bt->c_cc[VINTR]  : 0;
273 	st->c_cc[IBCS2_VQUIT] =
274 	    bt->c_cc[VQUIT]  != _POSIX_VDISABLE ? bt->c_cc[VQUIT]  : 0;
275 	st->c_cc[IBCS2_VERASE] =
276 	    bt->c_cc[VERASE] != _POSIX_VDISABLE ? bt->c_cc[VERASE] : 0;
277 	st->c_cc[IBCS2_VKILL] =
278 	    bt->c_cc[VKILL]  != _POSIX_VDISABLE ? bt->c_cc[VKILL]  : 0;
279 	if (bt->c_lflag & ICANON) {
280 		st->c_cc[IBCS2_VEOF] =
281 		    bt->c_cc[VEOF] != _POSIX_VDISABLE ? bt->c_cc[VEOF] : 0;
282 		st->c_cc[IBCS2_VEOL] =
283 		    bt->c_cc[VEOL] != _POSIX_VDISABLE ? bt->c_cc[VEOL] : 0;
284 	} else {
285 		st->c_cc[IBCS2_VMIN]  = bt->c_cc[VMIN];
286 		st->c_cc[IBCS2_VTIME] = bt->c_cc[VTIME];
287 	}
288 	st->c_cc[IBCS2_VEOL2] =
289 	    bt->c_cc[VEOL2]  != _POSIX_VDISABLE ? bt->c_cc[VEOL2]  : 0;
290 	st->c_cc[IBCS2_VSWTCH] =
291 	    0;
292 	st->c_cc[IBCS2_VSUSP] =
293 	    bt->c_cc[VSUSP]  != _POSIX_VDISABLE ? bt->c_cc[VSUSP]  : 0;
294 	st->c_cc[IBCS2_VSTART] =
295 	    bt->c_cc[VSTART] != _POSIX_VDISABLE ? bt->c_cc[VSTART] : 0;
296 	st->c_cc[IBCS2_VSTOP] =
297 	    bt->c_cc[VSTOP]  != _POSIX_VDISABLE ? bt->c_cc[VSTOP]  : 0;
298 
299 	st->c_line = 0;
300 }
301 
302 static void
stios2stio(ts,t)303 stios2stio(ts, t)
304 	struct ibcs2_termios *ts;
305 	struct ibcs2_termio *t;
306 {
307 	t->c_iflag = ts->c_iflag;
308 	t->c_oflag = ts->c_oflag;
309 	t->c_cflag = ts->c_cflag;
310 	t->c_lflag = ts->c_lflag;
311 	t->c_line  = ts->c_line;
312 	bcopy(ts->c_cc, t->c_cc, IBCS2_NCC);
313 }
314 
315 static void
stio2stios(t,ts)316 stio2stios(t, ts)
317 	struct ibcs2_termio *t;
318 	struct ibcs2_termios *ts;
319 {
320 	ts->c_iflag = t->c_iflag;
321 	ts->c_oflag = t->c_oflag;
322 	ts->c_cflag = t->c_cflag;
323 	ts->c_lflag = t->c_lflag;
324 	ts->c_line  = t->c_line;
325 	bcopy(t->c_cc, ts->c_cc, IBCS2_NCC);
326 }
327 
328 int
ibcs2_ioctl(td,uap)329 ibcs2_ioctl(td, uap)
330 	struct thread *td;
331 	struct ibcs2_ioctl_args *uap;
332 {
333 	struct proc *p = td->td_proc;
334 	cap_rights_t rights;
335 	struct file *fp;
336 	int error;
337 
338 	error = fget(td, uap->fd, cap_rights_init(&rights, CAP_IOCTL), &fp);
339 	if (error != 0) {
340 		DPRINTF(("ibcs2_ioctl(%d): bad fd %d ", p->p_pid,
341 			 uap->fd));
342 		return EBADF;
343 	}
344 
345 	if ((fp->f_flag & (FREAD|FWRITE)) == 0) {
346 		fdrop(fp, td);
347 		DPRINTF(("ibcs2_ioctl(%d): bad fp flag ", p->p_pid));
348 		return EBADF;
349 	}
350 
351 	switch (uap->cmd) {
352 	case IBCS2_TCGETA:
353 	case IBCS2_XCGETA:
354 	case IBCS2_OXCGETA:
355 	    {
356 		struct termios bts;
357 		struct ibcs2_termios sts;
358 		struct ibcs2_termio st;
359 
360 		if ((error = fo_ioctl(fp, TIOCGETA, (caddr_t)&bts,
361 		    td->td_ucred, td)) != 0)
362 			break;
363 
364 		btios2stios (&bts, &sts);
365 		if (uap->cmd == IBCS2_TCGETA) {
366 			stios2stio (&sts, &st);
367 			error = copyout((caddr_t)&st, uap->data,
368 					sizeof (st));
369 #ifdef DEBUG_IBCS2
370 			if (error)
371 				DPRINTF(("ibcs2_ioctl(%d): copyout failed ",
372 					 p->p_pid));
373 #endif
374 			break;
375 		} else {
376 			error = copyout((caddr_t)&sts, uap->data,
377 					sizeof (sts));
378 			break;
379 		}
380 		/*NOTREACHED*/
381 	    }
382 
383 	case IBCS2_TCSETA:
384 	case IBCS2_TCSETAW:
385 	case IBCS2_TCSETAF:
386 	    {
387 		struct termios bts;
388 		struct ibcs2_termios sts;
389 		struct ibcs2_termio st;
390 
391 		if ((error = copyin(uap->data, (caddr_t)&st,
392 				    sizeof(st))) != 0) {
393 			DPRINTF(("ibcs2_ioctl(%d): TCSET copyin failed ",
394 				 p->p_pid));
395 			break;
396 		}
397 
398 		/* get full BSD termios so we don't lose information */
399 		if ((error = fo_ioctl(fp, TIOCGETA, (caddr_t)&bts,
400 		    td->td_ucred, td)) != 0) {
401 			DPRINTF(("ibcs2_ioctl(%d): TCSET ctl failed fd %d ",
402 				 p->p_pid, uap->fd));
403 			break;
404 		}
405 
406 		/*
407 		 * convert to iBCS2 termios, copy in information from
408 		 * termio, and convert back, then set new values.
409 		 */
410 		btios2stios(&bts, &sts);
411 		stio2stios(&st, &sts);
412 		stios2btios(&sts, &bts);
413 
414 		error = fo_ioctl(fp, uap->cmd - IBCS2_TCSETA + TIOCSETA,
415 			      (caddr_t)&bts, td->td_ucred, td);
416 		break;
417 	    }
418 
419 	case IBCS2_XCSETA:
420 	case IBCS2_XCSETAW:
421 	case IBCS2_XCSETAF:
422 	    {
423 		struct termios bts;
424 		struct ibcs2_termios sts;
425 
426 		if ((error = copyin(uap->data, (caddr_t)&sts,
427 				    sizeof (sts))) != 0)
428 			break;
429 		stios2btios (&sts, &bts);
430 		error = fo_ioctl(fp, uap->cmd - IBCS2_XCSETA + TIOCSETA,
431 			      (caddr_t)&bts, td->td_ucred, td);
432 		break;
433 	    }
434 
435 	case IBCS2_OXCSETA:
436 	case IBCS2_OXCSETAW:
437 	case IBCS2_OXCSETAF:
438 	    {
439 		struct termios bts;
440 		struct ibcs2_termios sts;
441 
442 		if ((error = copyin(uap->data, (caddr_t)&sts,
443 				    sizeof (sts))) != 0)
444 			break;
445 		stios2btios (&sts, &bts);
446 		error = fo_ioctl(fp, uap->cmd - IBCS2_OXCSETA + TIOCSETA,
447 			      (caddr_t)&bts, td->td_ucred, td);
448 		break;
449 	    }
450 
451 	case IBCS2_TCSBRK:
452 		DPRINTF(("ibcs2_ioctl(%d): TCSBRK ", p->p_pid));
453 		error = ENOSYS;
454 		break;
455 
456 	case IBCS2_TCXONC:
457 	    {
458 		switch ((int)uap->data) {
459 		case 0:
460 		case 1:
461 			DPRINTF(("ibcs2_ioctl(%d): TCXONC ", p->p_pid));
462 			error = ENOSYS;
463 			break;
464 		case 2:
465 			error = fo_ioctl(fp, TIOCSTOP, (caddr_t)0,
466 			    td->td_ucred, td);
467 			break;
468 		case 3:
469 			error = fo_ioctl(fp, TIOCSTART, (caddr_t)1,
470 			    td->td_ucred, td);
471 			break;
472 		default:
473 			error = EINVAL;
474 			break;
475 		}
476 		break;
477 	    }
478 
479 	case IBCS2_TCFLSH:
480 	    {
481 		int arg;
482 
483 		switch ((int)uap->data) {
484 		case 0:
485 			arg = FREAD;
486 			break;
487 		case 1:
488 			arg = FWRITE;
489 			break;
490 		case 2:
491 			arg = FREAD | FWRITE;
492 			break;
493 		default:
494 			fdrop(fp, td);
495 			return EINVAL;
496 		}
497 		error = fo_ioctl(fp, TIOCFLUSH, (caddr_t)&arg, td->td_ucred,
498 		    td);
499 		break;
500 	    }
501 
502 	case IBCS2_TIOCGWINSZ:
503 		uap->cmd = TIOCGWINSZ;
504 		error = sys_ioctl(td, (struct ioctl_args *)uap);
505 		break;
506 
507 	case IBCS2_TIOCSWINSZ:
508 		uap->cmd = TIOCSWINSZ;
509 		error = sys_ioctl(td, (struct ioctl_args *)uap);
510 		break;
511 
512 	case IBCS2_TIOCGPGRP:
513 	    {
514 		pid_t	pg_id;
515 
516 		PROC_LOCK(p);
517 		pg_id = p->p_pgrp->pg_id;
518 		PROC_UNLOCK(p);
519 		error = copyout((caddr_t)&pg_id, uap->data,
520 				sizeof(pg_id));
521 		break;
522 	    }
523 
524 	case IBCS2_TIOCSPGRP:	/* XXX - is uap->data a pointer to pgid? */
525 	    {
526 		struct setpgid_args sa;
527 
528 		sa.pid = 0;
529 		sa.pgid = (int)uap->data;
530 		error = sys_setpgid(td, &sa);
531 		break;
532 	    }
533 
534 	case IBCS2_TCGETSC:	/* SCO console - get scancode flags */
535 		error = EINTR;  /* ENOSYS; */
536 		break;
537 
538 	case IBCS2_TCSETSC:	/* SCO console - set scancode flags */
539 		error = 0;   /* ENOSYS; */
540 		break;
541 
542 	case IBCS2_JWINSIZE:	/* Unix to Jerq I/O control */
543 	    {
544 	        struct ibcs2_jwinsize {
545 		  char bytex, bytey;
546 		  short bitx, bity;
547 	        } ibcs2_jwinsize;
548 
549 		PROC_LOCK(p);
550 		SESS_LOCK(p->p_session);
551                 ibcs2_jwinsize.bytex = 80;
552 	          /* p->p_session->s_ttyp->t_winsize.ws_col; XXX */
553 	        ibcs2_jwinsize.bytey = 25;
554                   /* p->p_session->s_ttyp->t_winsize.ws_row; XXX */
555 	        ibcs2_jwinsize.bitx =
556 		  p->p_session->s_ttyp->t_winsize.ws_xpixel;
557 	        ibcs2_jwinsize.bity =
558 		  p->p_session->s_ttyp->t_winsize.ws_ypixel;
559 		SESS_UNLOCK(p->p_session);
560 		PROC_UNLOCK(p);
561 	        error = copyout((caddr_t)&ibcs2_jwinsize, uap->data,
562 			       sizeof(ibcs2_jwinsize));
563 		break;
564 	     }
565 
566 	/* keyboard and display ioctl's -- type 'K' */
567 	case IBCS2_KDGKBMODE:        /* get keyboard translation mode */
568 	        uap->cmd = KDGKBMODE;
569 /* printf("ioctl KDGKBMODE = %x\n", uap->cmd);*/
570 	        error = sys_ioctl(td, (struct ioctl_args *)uap);
571 		break;
572 
573 	case IBCS2_KDSKBMODE:        /* set keyboard translation mode */
574 	        uap->cmd = KDSKBMODE;
575 	        error = sys_ioctl(td, (struct ioctl_args *)uap);
576 		break;
577 
578 	case IBCS2_KDMKTONE:        /* sound tone */
579 	        uap->cmd = KDMKTONE;
580 	        error = sys_ioctl(td, (struct ioctl_args *)uap);
581 		break;
582 
583 	case IBCS2_KDGETMODE:        /* get text/graphics mode */
584 	        uap->cmd = KDGETMODE;
585 	        error = sys_ioctl(td, (struct ioctl_args *)uap);
586 		break;
587 
588 	case IBCS2_KDSETMODE:       /* set text/graphics mode */
589 	        uap->cmd = KDSETMODE;
590 	        error = sys_ioctl(td, (struct ioctl_args *)uap);
591 		break;
592 
593 	case IBCS2_KDSBORDER:       /* set ega color border */
594 	        uap->cmd = KDSBORDER;
595 	        error = sys_ioctl(td, (struct ioctl_args *)uap);
596 		break;
597 
598 	case IBCS2_KDGKBSTATE:
599 	        uap->cmd = KDGKBSTATE;
600 	        error = sys_ioctl(td, (struct ioctl_args *)uap);
601 		break;
602 
603 	case IBCS2_KDSETRAD:
604 	        uap->cmd = KDSETRAD;
605 	        error = sys_ioctl(td, (struct ioctl_args *)uap);
606 		break;
607 
608 	case IBCS2_KDENABIO:       /* enable direct I/O to ports */
609 	        uap->cmd = KDENABIO;
610 	        error = sys_ioctl(td, (struct ioctl_args *)uap);
611 		break;
612 
613 	case IBCS2_KDDISABIO:       /* disable direct I/O to ports */
614 	        uap->cmd = KDDISABIO;
615 	        error = sys_ioctl(td, (struct ioctl_args *)uap);
616 		break;
617 
618 	case IBCS2_KIOCSOUND:       /* start sound generation */
619 	        uap->cmd = KIOCSOUND;
620 	        error = sys_ioctl(td, (struct ioctl_args *)uap);
621 		break;
622 
623 	case IBCS2_KDGKBTYPE:       /* get keyboard type */
624 	        uap->cmd = KDGKBTYPE;
625 	        error = sys_ioctl(td, (struct ioctl_args *)uap);
626 		break;
627 
628 	case IBCS2_KDGETLED:       /* get keyboard LED status */
629 	        uap->cmd = KDGETLED;
630 	        error = sys_ioctl(td, (struct ioctl_args *)uap);
631 		break;
632 
633 	case IBCS2_KDSETLED:       /* set keyboard LED status */
634 	        uap->cmd = KDSETLED;
635 	        error = sys_ioctl(td, (struct ioctl_args *)uap);
636 		break;
637 
638 	    /* Xenix keyboard and display ioctl's from sys/kd.h -- type 'k' */
639 	case IBCS2_GETFKEY:      /* Get function key */
640 	        uap->cmd = GETFKEY;
641 	        error = sys_ioctl(td, (struct ioctl_args *)uap);
642 		break;
643 
644 	case IBCS2_SETFKEY:      /* Set function key */
645 	        uap->cmd = SETFKEY;
646 	        error = sys_ioctl(td, (struct ioctl_args *)uap);
647 		break;
648 
649 	case IBCS2_GIO_SCRNMAP:      /* Get screen output map table */
650 	        uap->cmd = GIO_SCRNMAP;
651 	        error = sys_ioctl(td, (struct ioctl_args *)uap);
652 		break;
653 
654 	case IBCS2_PIO_SCRNMAP:      /* Set screen output map table */
655 	        uap->cmd = PIO_SCRNMAP;
656 	        error = sys_ioctl(td, (struct ioctl_args *)uap);
657 		break;
658 
659 	case IBCS2_GIO_KEYMAP:      /* Get keyboard map table */
660 	        uap->cmd = OGIO_KEYMAP;
661 	        error = sys_ioctl(td, (struct ioctl_args *)uap);
662 		break;
663 
664 	case IBCS2_PIO_KEYMAP:      /* Set keyboard map table */
665 	        uap->cmd = OPIO_KEYMAP;
666 	        error = sys_ioctl(td, (struct ioctl_args *)uap);
667 		break;
668 
669 	    /* socksys */
670 	case IBCS2_SIOCSOCKSYS:
671 		error = ibcs2_socksys(td, (struct ibcs2_socksys_args *)uap);
672 		break;
673 
674 	case IBCS2_FIONREAD:
675 	case IBCS2_I_NREAD:     /* STREAMS */
676 	        uap->cmd = FIONREAD;
677 		error = sys_ioctl(td, (struct ioctl_args *)uap);
678 		break;
679 
680 	default:
681 		DPRINTF(("ibcs2_ioctl(%d): unknown cmd 0x%lx ",
682 			 td->proc->p_pid, uap->cmd));
683 		error = ENOSYS;
684 		break;
685 	}
686 
687 	fdrop(fp, td);
688 	return error;
689 }
690