1 /* $NetBSD: ibcs2_ioctl.c,v 1.6 1995/03/14 15:12:28 scottb Exp $ */
4 * Copyright (c) 1994, 1995 Scott Bartram
7 * based on compat/sunos/sun_ioctl.c
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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
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.
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
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>
38 #include <sys/filedesc.h>
39 #include <sys/filio.h>
42 #include <sys/mutex.h>
43 #include <sys/sysproto.h>
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>
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
*);
64 int sp_speed
; /* Speed. */
65 int sp_code
; /* Code. */
68 static struct speedtab sptab
[] = {
89 static u_long s2btab
[] = {
109 ttspeedtab(int speed
, struct speedtab
*table
)
112 for ( ; table
->sp_speed
!= -1; table
++)
113 if (table
->sp_speed
== speed
)
114 return (table
->sp_code
);
120 struct ibcs2_termios
*st
;
123 register u_long l
, r
;
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
;
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
;
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;
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
;
162 bt
->c_ispeed
= bt
->c_ospeed
= s2btab
[l
& 0x0000000f];
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
;
176 st
->c_cc
[IBCS2_VINTR
] ? st
->c_cc
[IBCS2_VINTR
] : _POSIX_VDISABLE
;
178 st
->c_cc
[IBCS2_VQUIT
] ? st
->c_cc
[IBCS2_VQUIT
] : _POSIX_VDISABLE
;
180 st
->c_cc
[IBCS2_VERASE
] ? st
->c_cc
[IBCS2_VERASE
] : _POSIX_VDISABLE
;
182 st
->c_cc
[IBCS2_VKILL
] ? st
->c_cc
[IBCS2_VKILL
] : _POSIX_VDISABLE
;
183 if (bt
->c_lflag
& ICANON
) {
185 st
->c_cc
[IBCS2_VEOF
] ? st
->c_cc
[IBCS2_VEOF
] : _POSIX_VDISABLE
;
187 st
->c_cc
[IBCS2_VEOL
] ? st
->c_cc
[IBCS2_VEOL
] : _POSIX_VDISABLE
;
189 bt
->c_cc
[VMIN
] = st
->c_cc
[IBCS2_VMIN
];
190 bt
->c_cc
[VTIME
] = st
->c_cc
[IBCS2_VTIME
];
193 st
->c_cc
[IBCS2_VEOL2
] ? st
->c_cc
[IBCS2_VEOL2
] : _POSIX_VDISABLE
;
196 st
->c_cc
[IBCS2_VSWTCH
] ? st
->c_cc
[IBCS2_VSWTCH
] : _POSIX_VDISABLE
;
199 st
->c_cc
[IBCS2_VSTART
] ? st
->c_cc
[IBCS2_VSTART
] : _POSIX_VDISABLE
;
201 st
->c_cc
[IBCS2_VSTOP
] ? st
->c_cc
[IBCS2_VSTOP
] : _POSIX_VDISABLE
;
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
;
215 struct ibcs2_termios
*st
;
217 register u_long l
, r
;
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
;
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
;
241 l
= bt
->c_cflag
; r
= 0;
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;
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
;
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
;
267 l
= ttspeedtab(bt
->c_ospeed
, sptab
);
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;
285 st
->c_cc
[IBCS2_VMIN
] = bt
->c_cc
[VMIN
];
286 st
->c_cc
[IBCS2_VTIME
] = bt
->c_cc
[VTIME
];
288 st
->c_cc
[IBCS2_VEOL2
] =
289 bt
->c_cc
[VEOL2
] != _POSIX_VDISABLE
? bt
->c_cc
[VEOL2
] : 0;
290 st
->c_cc
[IBCS2_VSWTCH
] =
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;
304 struct ibcs2_termios
*ts
;
305 struct ibcs2_termio
*t
;
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
);
317 struct ibcs2_termio
*t
;
318 struct ibcs2_termios
*ts
;
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
);
331 struct ibcs2_ioctl_args
*uap
;
333 struct proc
*p
= td
->td_proc
;
338 error
= fget(td
, uap
->fd
, cap_rights_init(&rights
, CAP_IOCTL
), &fp
);
340 DPRINTF(("ibcs2_ioctl(%d): bad fd %d ", p
->p_pid
,
345 if ((fp
->f_flag
& (FREAD
|FWRITE
)) == 0) {
347 DPRINTF(("ibcs2_ioctl(%d): bad fp flag ", p
->p_pid
));
357 struct ibcs2_termios sts
;
358 struct ibcs2_termio st
;
360 if ((error
= fo_ioctl(fp
, TIOCGETA
, (caddr_t
)&bts
,
361 td
->td_ucred
, td
)) != 0)
364 btios2stios (&bts
, &sts
);
365 if (uap
->cmd
== IBCS2_TCGETA
) {
366 stios2stio (&sts
, &st
);
367 error
= copyout((caddr_t
)&st
, uap
->data
,
371 DPRINTF(("ibcs2_ioctl(%d): copyout failed ",
376 error
= copyout((caddr_t
)&sts
, uap
->data
,
388 struct ibcs2_termios sts
;
389 struct ibcs2_termio st
;
391 if ((error
= copyin(uap
->data
, (caddr_t
)&st
,
393 DPRINTF(("ibcs2_ioctl(%d): TCSET copyin failed ",
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 ",
407 * convert to iBCS2 termios, copy in information from
408 * termio, and convert back, then set new values.
410 btios2stios(&bts
, &sts
);
411 stio2stios(&st
, &sts
);
412 stios2btios(&sts
, &bts
);
414 error
= fo_ioctl(fp
, uap
->cmd
- IBCS2_TCSETA
+ TIOCSETA
,
415 (caddr_t
)&bts
, td
->td_ucred
, td
);
424 struct ibcs2_termios sts
;
426 if ((error
= copyin(uap
->data
, (caddr_t
)&sts
,
429 stios2btios (&sts
, &bts
);
430 error
= fo_ioctl(fp
, uap
->cmd
- IBCS2_XCSETA
+ TIOCSETA
,
431 (caddr_t
)&bts
, td
->td_ucred
, td
);
440 struct ibcs2_termios sts
;
442 if ((error
= copyin(uap
->data
, (caddr_t
)&sts
,
445 stios2btios (&sts
, &bts
);
446 error
= fo_ioctl(fp
, uap
->cmd
- IBCS2_OXCSETA
+ TIOCSETA
,
447 (caddr_t
)&bts
, td
->td_ucred
, td
);
452 DPRINTF(("ibcs2_ioctl(%d): TCSBRK ", p
->p_pid
));
458 switch ((int)uap
->data
) {
461 DPRINTF(("ibcs2_ioctl(%d): TCXONC ", p
->p_pid
));
465 error
= fo_ioctl(fp
, TIOCSTOP
, (caddr_t
)0,
469 error
= fo_ioctl(fp
, TIOCSTART
, (caddr_t
)1,
483 switch ((int)uap
->data
) {
491 arg
= FREAD
| FWRITE
;
497 error
= fo_ioctl(fp
, TIOCFLUSH
, (caddr_t
)&arg
, td
->td_ucred
,
502 case IBCS2_TIOCGWINSZ
:
503 uap
->cmd
= TIOCGWINSZ
;
504 error
= sys_ioctl(td
, (struct ioctl_args
*)uap
);
507 case IBCS2_TIOCSWINSZ
:
508 uap
->cmd
= TIOCSWINSZ
;
509 error
= sys_ioctl(td
, (struct ioctl_args
*)uap
);
512 case IBCS2_TIOCGPGRP
:
517 pg_id
= p
->p_pgrp
->pg_id
;
519 error
= copyout((caddr_t
)&pg_id
, uap
->data
,
524 case IBCS2_TIOCSPGRP
: /* XXX - is uap->data a pointer to pgid? */
526 struct setpgid_args sa
;
529 sa
.pgid
= (int)uap
->data
;
530 error
= sys_setpgid(td
, &sa
);
534 case IBCS2_TCGETSC
: /* SCO console - get scancode flags */
535 error
= EINTR
; /* ENOSYS; */
538 case IBCS2_TCSETSC
: /* SCO console - set scancode flags */
539 error
= 0; /* ENOSYS; */
542 case IBCS2_JWINSIZE
: /* Unix to Jerq I/O control */
544 struct ibcs2_jwinsize
{
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
);
561 error
= copyout((caddr_t
)&ibcs2_jwinsize
, uap
->data
,
562 sizeof(ibcs2_jwinsize
));
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
);
573 case IBCS2_KDSKBMODE
: /* set keyboard translation mode */
574 uap
->cmd
= KDSKBMODE
;
575 error
= sys_ioctl(td
, (struct ioctl_args
*)uap
);
578 case IBCS2_KDMKTONE
: /* sound tone */
580 error
= sys_ioctl(td
, (struct ioctl_args
*)uap
);
583 case IBCS2_KDGETMODE
: /* get text/graphics mode */
584 uap
->cmd
= KDGETMODE
;
585 error
= sys_ioctl(td
, (struct ioctl_args
*)uap
);
588 case IBCS2_KDSETMODE
: /* set text/graphics mode */
589 uap
->cmd
= KDSETMODE
;
590 error
= sys_ioctl(td
, (struct ioctl_args
*)uap
);
593 case IBCS2_KDSBORDER
: /* set ega color border */
594 uap
->cmd
= KDSBORDER
;
595 error
= sys_ioctl(td
, (struct ioctl_args
*)uap
);
598 case IBCS2_KDGKBSTATE
:
599 uap
->cmd
= KDGKBSTATE
;
600 error
= sys_ioctl(td
, (struct ioctl_args
*)uap
);
605 error
= sys_ioctl(td
, (struct ioctl_args
*)uap
);
608 case IBCS2_KDENABIO
: /* enable direct I/O to ports */
610 error
= sys_ioctl(td
, (struct ioctl_args
*)uap
);
613 case IBCS2_KDDISABIO
: /* disable direct I/O to ports */
614 uap
->cmd
= KDDISABIO
;
615 error
= sys_ioctl(td
, (struct ioctl_args
*)uap
);
618 case IBCS2_KIOCSOUND
: /* start sound generation */
619 uap
->cmd
= KIOCSOUND
;
620 error
= sys_ioctl(td
, (struct ioctl_args
*)uap
);
623 case IBCS2_KDGKBTYPE
: /* get keyboard type */
624 uap
->cmd
= KDGKBTYPE
;
625 error
= sys_ioctl(td
, (struct ioctl_args
*)uap
);
628 case IBCS2_KDGETLED
: /* get keyboard LED status */
630 error
= sys_ioctl(td
, (struct ioctl_args
*)uap
);
633 case IBCS2_KDSETLED
: /* set keyboard LED status */
635 error
= sys_ioctl(td
, (struct ioctl_args
*)uap
);
638 /* Xenix keyboard and display ioctl's from sys/kd.h -- type 'k' */
639 case IBCS2_GETFKEY
: /* Get function key */
641 error
= sys_ioctl(td
, (struct ioctl_args
*)uap
);
644 case IBCS2_SETFKEY
: /* Set function key */
646 error
= sys_ioctl(td
, (struct ioctl_args
*)uap
);
649 case IBCS2_GIO_SCRNMAP
: /* Get screen output map table */
650 uap
->cmd
= GIO_SCRNMAP
;
651 error
= sys_ioctl(td
, (struct ioctl_args
*)uap
);
654 case IBCS2_PIO_SCRNMAP
: /* Set screen output map table */
655 uap
->cmd
= PIO_SCRNMAP
;
656 error
= sys_ioctl(td
, (struct ioctl_args
*)uap
);
659 case IBCS2_GIO_KEYMAP
: /* Get keyboard map table */
660 uap
->cmd
= OGIO_KEYMAP
;
661 error
= sys_ioctl(td
, (struct ioctl_args
*)uap
);
664 case IBCS2_PIO_KEYMAP
: /* Set keyboard map table */
665 uap
->cmd
= OPIO_KEYMAP
;
666 error
= sys_ioctl(td
, (struct ioctl_args
*)uap
);
670 case IBCS2_SIOCSOCKSYS
:
671 error
= ibcs2_socksys(td
, (struct ibcs2_socksys_args
*)uap
);
675 case IBCS2_I_NREAD
: /* STREAMS */
677 error
= sys_ioctl(td
, (struct ioctl_args
*)uap
);
681 DPRINTF(("ibcs2_ioctl(%d): unknown cmd 0x%lx ",
682 td
->proc
->p_pid
, uap
->cmd
));