b700662b06
Back in 2009 I changed the ABI of the GIO_KEYMAP and PIO_KEYMAP ioctls to support wide characters. I created a patch to add ABI compatibility for the old calls, but I didn't get any feedback to that. It seems now people are upgrading from 8 to 9 they experience this issue, so add it anyway.
687 lines
17 KiB
C
687 lines
17 KiB
C
/* $NetBSD: ibcs2_ioctl.c,v 1.6 1995/03/14 15:12:28 scottb Exp $ */
|
|
|
|
/*-
|
|
* Copyright (c) 1994, 1995 Scott Bartram
|
|
* All rights reserved.
|
|
*
|
|
* based on compat/sunos/sun_ioctl.c
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. The name of the author may not be used to endorse or promote products
|
|
* derived from this software without specific prior written permission
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#include <sys/cdefs.h>
|
|
__FBSDID("$FreeBSD$");
|
|
|
|
#include <sys/param.h>
|
|
#include <sys/systm.h>
|
|
#include <sys/consio.h>
|
|
#include <sys/fcntl.h>
|
|
#include <sys/file.h>
|
|
#include <sys/filedesc.h>
|
|
#include <sys/filio.h>
|
|
#include <sys/kbio.h>
|
|
#include <sys/lock.h>
|
|
#include <sys/mutex.h>
|
|
#include <sys/sysproto.h>
|
|
#include <sys/tty.h>
|
|
|
|
#include <i386/ibcs2/ibcs2_signal.h>
|
|
#include <i386/ibcs2/ibcs2_socksys.h>
|
|
#include <i386/ibcs2/ibcs2_stropts.h>
|
|
#include <i386/ibcs2/ibcs2_proto.h>
|
|
#include <i386/ibcs2/ibcs2_termios.h>
|
|
#include <i386/ibcs2/ibcs2_util.h>
|
|
#include <i386/ibcs2/ibcs2_ioctl.h>
|
|
|
|
static void stios2btios(struct ibcs2_termios *, struct termios *);
|
|
static void btios2stios(struct termios *, struct ibcs2_termios *);
|
|
static void stios2stio(struct ibcs2_termios *, struct ibcs2_termio *);
|
|
static void stio2stios(struct ibcs2_termio *, struct ibcs2_termios *);
|
|
|
|
/*
|
|
* iBCS2 ioctl calls.
|
|
*/
|
|
|
|
struct speedtab {
|
|
int sp_speed; /* Speed. */
|
|
int sp_code; /* Code. */
|
|
};
|
|
|
|
static struct speedtab sptab[] = {
|
|
{ 0, 0 },
|
|
{ 50, 1 },
|
|
{ 75, 2 },
|
|
{ 110, 3 },
|
|
{ 134, 4 },
|
|
{ 135, 4 },
|
|
{ 150, 5 },
|
|
{ 200, 6 },
|
|
{ 300, 7 },
|
|
{ 600, 8 },
|
|
{ 1200, 9 },
|
|
{ 1800, 10 },
|
|
{ 2400, 11 },
|
|
{ 4800, 12 },
|
|
{ 9600, 13 },
|
|
{ 19200, 14 },
|
|
{ 38400, 15 },
|
|
{ -1, -1 }
|
|
};
|
|
|
|
static u_long s2btab[] = {
|
|
0,
|
|
50,
|
|
75,
|
|
110,
|
|
134,
|
|
150,
|
|
200,
|
|
300,
|
|
600,
|
|
1200,
|
|
1800,
|
|
2400,
|
|
4800,
|
|
9600,
|
|
19200,
|
|
38400,
|
|
};
|
|
|
|
static int
|
|
ttspeedtab(int speed, struct speedtab *table)
|
|
{
|
|
|
|
for ( ; table->sp_speed != -1; table++)
|
|
if (table->sp_speed == speed)
|
|
return (table->sp_code);
|
|
return (-1);
|
|
}
|
|
|
|
static void
|
|
stios2btios(st, bt)
|
|
struct ibcs2_termios *st;
|
|
struct termios *bt;
|
|
{
|
|
register u_long l, r;
|
|
|
|
l = st->c_iflag; r = 0;
|
|
if (l & IBCS2_IGNBRK) r |= IGNBRK;
|
|
if (l & IBCS2_BRKINT) r |= BRKINT;
|
|
if (l & IBCS2_IGNPAR) r |= IGNPAR;
|
|
if (l & IBCS2_PARMRK) r |= PARMRK;
|
|
if (l & IBCS2_INPCK) r |= INPCK;
|
|
if (l & IBCS2_ISTRIP) r |= ISTRIP;
|
|
if (l & IBCS2_INLCR) r |= INLCR;
|
|
if (l & IBCS2_IGNCR) r |= IGNCR;
|
|
if (l & IBCS2_ICRNL) r |= ICRNL;
|
|
if (l & IBCS2_IXON) r |= IXON;
|
|
if (l & IBCS2_IXANY) r |= IXANY;
|
|
if (l & IBCS2_IXOFF) r |= IXOFF;
|
|
if (l & IBCS2_IMAXBEL) r |= IMAXBEL;
|
|
bt->c_iflag = r;
|
|
|
|
l = st->c_oflag; r = 0;
|
|
if (l & IBCS2_OPOST) r |= OPOST;
|
|
if (l & IBCS2_ONLCR) r |= ONLCR;
|
|
if (l & IBCS2_TAB3) r |= TAB3;
|
|
bt->c_oflag = r;
|
|
|
|
l = st->c_cflag; r = 0;
|
|
switch (l & IBCS2_CSIZE) {
|
|
case IBCS2_CS5: r |= CS5; break;
|
|
case IBCS2_CS6: r |= CS6; break;
|
|
case IBCS2_CS7: r |= CS7; break;
|
|
case IBCS2_CS8: r |= CS8; break;
|
|
}
|
|
if (l & IBCS2_CSTOPB) r |= CSTOPB;
|
|
if (l & IBCS2_CREAD) r |= CREAD;
|
|
if (l & IBCS2_PARENB) r |= PARENB;
|
|
if (l & IBCS2_PARODD) r |= PARODD;
|
|
if (l & IBCS2_HUPCL) r |= HUPCL;
|
|
if (l & IBCS2_CLOCAL) r |= CLOCAL;
|
|
bt->c_cflag = r;
|
|
|
|
bt->c_ispeed = bt->c_ospeed = s2btab[l & 0x0000000f];
|
|
|
|
l = st->c_lflag; r = 0;
|
|
if (l & IBCS2_ISIG) r |= ISIG;
|
|
if (l & IBCS2_ICANON) r |= ICANON;
|
|
if (l & IBCS2_ECHO) r |= ECHO;
|
|
if (l & IBCS2_ECHOE) r |= ECHOE;
|
|
if (l & IBCS2_ECHOK) r |= ECHOK;
|
|
if (l & IBCS2_ECHONL) r |= ECHONL;
|
|
if (l & IBCS2_NOFLSH) r |= NOFLSH;
|
|
if (l & IBCS2_TOSTOP) r |= TOSTOP;
|
|
bt->c_lflag = r;
|
|
|
|
bt->c_cc[VINTR] =
|
|
st->c_cc[IBCS2_VINTR] ? st->c_cc[IBCS2_VINTR] : _POSIX_VDISABLE;
|
|
bt->c_cc[VQUIT] =
|
|
st->c_cc[IBCS2_VQUIT] ? st->c_cc[IBCS2_VQUIT] : _POSIX_VDISABLE;
|
|
bt->c_cc[VERASE] =
|
|
st->c_cc[IBCS2_VERASE] ? st->c_cc[IBCS2_VERASE] : _POSIX_VDISABLE;
|
|
bt->c_cc[VKILL] =
|
|
st->c_cc[IBCS2_VKILL] ? st->c_cc[IBCS2_VKILL] : _POSIX_VDISABLE;
|
|
if (bt->c_lflag & ICANON) {
|
|
bt->c_cc[VEOF] =
|
|
st->c_cc[IBCS2_VEOF] ? st->c_cc[IBCS2_VEOF] : _POSIX_VDISABLE;
|
|
bt->c_cc[VEOL] =
|
|
st->c_cc[IBCS2_VEOL] ? st->c_cc[IBCS2_VEOL] : _POSIX_VDISABLE;
|
|
} else {
|
|
bt->c_cc[VMIN] = st->c_cc[IBCS2_VMIN];
|
|
bt->c_cc[VTIME] = st->c_cc[IBCS2_VTIME];
|
|
}
|
|
bt->c_cc[VEOL2] =
|
|
st->c_cc[IBCS2_VEOL2] ? st->c_cc[IBCS2_VEOL2] : _POSIX_VDISABLE;
|
|
#if 0
|
|
bt->c_cc[VSWTCH] =
|
|
st->c_cc[IBCS2_VSWTCH] ? st->c_cc[IBCS2_VSWTCH] : _POSIX_VDISABLE;
|
|
#endif
|
|
bt->c_cc[VSTART] =
|
|
st->c_cc[IBCS2_VSTART] ? st->c_cc[IBCS2_VSTART] : _POSIX_VDISABLE;
|
|
bt->c_cc[VSTOP] =
|
|
st->c_cc[IBCS2_VSTOP] ? st->c_cc[IBCS2_VSTOP] : _POSIX_VDISABLE;
|
|
bt->c_cc[VSUSP] =
|
|
st->c_cc[IBCS2_VSUSP] ? st->c_cc[IBCS2_VSUSP] : _POSIX_VDISABLE;
|
|
bt->c_cc[VDSUSP] = _POSIX_VDISABLE;
|
|
bt->c_cc[VREPRINT] = _POSIX_VDISABLE;
|
|
bt->c_cc[VDISCARD] = _POSIX_VDISABLE;
|
|
bt->c_cc[VWERASE] = _POSIX_VDISABLE;
|
|
bt->c_cc[VLNEXT] = _POSIX_VDISABLE;
|
|
bt->c_cc[VSTATUS] = _POSIX_VDISABLE;
|
|
}
|
|
|
|
static void
|
|
btios2stios(bt, st)
|
|
struct termios *bt;
|
|
struct ibcs2_termios *st;
|
|
{
|
|
register u_long l, r;
|
|
|
|
l = bt->c_iflag; r = 0;
|
|
if (l & IGNBRK) r |= IBCS2_IGNBRK;
|
|
if (l & BRKINT) r |= IBCS2_BRKINT;
|
|
if (l & IGNPAR) r |= IBCS2_IGNPAR;
|
|
if (l & PARMRK) r |= IBCS2_PARMRK;
|
|
if (l & INPCK) r |= IBCS2_INPCK;
|
|
if (l & ISTRIP) r |= IBCS2_ISTRIP;
|
|
if (l & INLCR) r |= IBCS2_INLCR;
|
|
if (l & IGNCR) r |= IBCS2_IGNCR;
|
|
if (l & ICRNL) r |= IBCS2_ICRNL;
|
|
if (l & IXON) r |= IBCS2_IXON;
|
|
if (l & IXANY) r |= IBCS2_IXANY;
|
|
if (l & IXOFF) r |= IBCS2_IXOFF;
|
|
if (l & IMAXBEL) r |= IBCS2_IMAXBEL;
|
|
st->c_iflag = r;
|
|
|
|
l = bt->c_oflag; r = 0;
|
|
if (l & OPOST) r |= IBCS2_OPOST;
|
|
if (l & ONLCR) r |= IBCS2_ONLCR;
|
|
if (l & TAB3) r |= IBCS2_TAB3;
|
|
st->c_oflag = r;
|
|
|
|
l = bt->c_cflag; r = 0;
|
|
switch (l & CSIZE) {
|
|
case CS5: r |= IBCS2_CS5; break;
|
|
case CS6: r |= IBCS2_CS6; break;
|
|
case CS7: r |= IBCS2_CS7; break;
|
|
case CS8: r |= IBCS2_CS8; break;
|
|
}
|
|
if (l & CSTOPB) r |= IBCS2_CSTOPB;
|
|
if (l & CREAD) r |= IBCS2_CREAD;
|
|
if (l & PARENB) r |= IBCS2_PARENB;
|
|
if (l & PARODD) r |= IBCS2_PARODD;
|
|
if (l & HUPCL) r |= IBCS2_HUPCL;
|
|
if (l & CLOCAL) r |= IBCS2_CLOCAL;
|
|
st->c_cflag = r;
|
|
|
|
l = bt->c_lflag; r = 0;
|
|
if (l & ISIG) r |= IBCS2_ISIG;
|
|
if (l & ICANON) r |= IBCS2_ICANON;
|
|
if (l & ECHO) r |= IBCS2_ECHO;
|
|
if (l & ECHOE) r |= IBCS2_ECHOE;
|
|
if (l & ECHOK) r |= IBCS2_ECHOK;
|
|
if (l & ECHONL) r |= IBCS2_ECHONL;
|
|
if (l & NOFLSH) r |= IBCS2_NOFLSH;
|
|
if (l & TOSTOP) r |= IBCS2_TOSTOP;
|
|
st->c_lflag = r;
|
|
|
|
l = ttspeedtab(bt->c_ospeed, sptab);
|
|
if ((int)l >= 0)
|
|
st->c_cflag |= l;
|
|
|
|
st->c_cc[IBCS2_VINTR] =
|
|
bt->c_cc[VINTR] != _POSIX_VDISABLE ? bt->c_cc[VINTR] : 0;
|
|
st->c_cc[IBCS2_VQUIT] =
|
|
bt->c_cc[VQUIT] != _POSIX_VDISABLE ? bt->c_cc[VQUIT] : 0;
|
|
st->c_cc[IBCS2_VERASE] =
|
|
bt->c_cc[VERASE] != _POSIX_VDISABLE ? bt->c_cc[VERASE] : 0;
|
|
st->c_cc[IBCS2_VKILL] =
|
|
bt->c_cc[VKILL] != _POSIX_VDISABLE ? bt->c_cc[VKILL] : 0;
|
|
if (bt->c_lflag & ICANON) {
|
|
st->c_cc[IBCS2_VEOF] =
|
|
bt->c_cc[VEOF] != _POSIX_VDISABLE ? bt->c_cc[VEOF] : 0;
|
|
st->c_cc[IBCS2_VEOL] =
|
|
bt->c_cc[VEOL] != _POSIX_VDISABLE ? bt->c_cc[VEOL] : 0;
|
|
} else {
|
|
st->c_cc[IBCS2_VMIN] = bt->c_cc[VMIN];
|
|
st->c_cc[IBCS2_VTIME] = bt->c_cc[VTIME];
|
|
}
|
|
st->c_cc[IBCS2_VEOL2] =
|
|
bt->c_cc[VEOL2] != _POSIX_VDISABLE ? bt->c_cc[VEOL2] : 0;
|
|
st->c_cc[IBCS2_VSWTCH] =
|
|
0;
|
|
st->c_cc[IBCS2_VSUSP] =
|
|
bt->c_cc[VSUSP] != _POSIX_VDISABLE ? bt->c_cc[VSUSP] : 0;
|
|
st->c_cc[IBCS2_VSTART] =
|
|
bt->c_cc[VSTART] != _POSIX_VDISABLE ? bt->c_cc[VSTART] : 0;
|
|
st->c_cc[IBCS2_VSTOP] =
|
|
bt->c_cc[VSTOP] != _POSIX_VDISABLE ? bt->c_cc[VSTOP] : 0;
|
|
|
|
st->c_line = 0;
|
|
}
|
|
|
|
static void
|
|
stios2stio(ts, t)
|
|
struct ibcs2_termios *ts;
|
|
struct ibcs2_termio *t;
|
|
{
|
|
t->c_iflag = ts->c_iflag;
|
|
t->c_oflag = ts->c_oflag;
|
|
t->c_cflag = ts->c_cflag;
|
|
t->c_lflag = ts->c_lflag;
|
|
t->c_line = ts->c_line;
|
|
bcopy(ts->c_cc, t->c_cc, IBCS2_NCC);
|
|
}
|
|
|
|
static void
|
|
stio2stios(t, ts)
|
|
struct ibcs2_termio *t;
|
|
struct ibcs2_termios *ts;
|
|
{
|
|
ts->c_iflag = t->c_iflag;
|
|
ts->c_oflag = t->c_oflag;
|
|
ts->c_cflag = t->c_cflag;
|
|
ts->c_lflag = t->c_lflag;
|
|
ts->c_line = t->c_line;
|
|
bcopy(t->c_cc, ts->c_cc, IBCS2_NCC);
|
|
}
|
|
|
|
int
|
|
ibcs2_ioctl(td, uap)
|
|
struct thread *td;
|
|
struct ibcs2_ioctl_args *uap;
|
|
{
|
|
struct proc *p = td->td_proc;
|
|
struct file *fp;
|
|
int error;
|
|
|
|
if ((error = fget(td, uap->fd, &fp)) != 0) {
|
|
DPRINTF(("ibcs2_ioctl(%d): bad fd %d ", p->p_pid,
|
|
uap->fd));
|
|
return EBADF;
|
|
}
|
|
|
|
if ((fp->f_flag & (FREAD|FWRITE)) == 0) {
|
|
fdrop(fp, td);
|
|
DPRINTF(("ibcs2_ioctl(%d): bad fp flag ", p->p_pid));
|
|
return EBADF;
|
|
}
|
|
|
|
switch (uap->cmd) {
|
|
case IBCS2_TCGETA:
|
|
case IBCS2_XCGETA:
|
|
case IBCS2_OXCGETA:
|
|
{
|
|
struct termios bts;
|
|
struct ibcs2_termios sts;
|
|
struct ibcs2_termio st;
|
|
|
|
if ((error = fo_ioctl(fp, TIOCGETA, (caddr_t)&bts,
|
|
td->td_ucred, td)) != 0)
|
|
break;
|
|
|
|
btios2stios (&bts, &sts);
|
|
if (uap->cmd == IBCS2_TCGETA) {
|
|
stios2stio (&sts, &st);
|
|
error = copyout((caddr_t)&st, uap->data,
|
|
sizeof (st));
|
|
#ifdef DEBUG_IBCS2
|
|
if (error)
|
|
DPRINTF(("ibcs2_ioctl(%d): copyout failed ",
|
|
p->p_pid));
|
|
#endif
|
|
break;
|
|
} else {
|
|
error = copyout((caddr_t)&sts, uap->data,
|
|
sizeof (sts));
|
|
break;
|
|
}
|
|
/*NOTREACHED*/
|
|
}
|
|
|
|
case IBCS2_TCSETA:
|
|
case IBCS2_TCSETAW:
|
|
case IBCS2_TCSETAF:
|
|
{
|
|
struct termios bts;
|
|
struct ibcs2_termios sts;
|
|
struct ibcs2_termio st;
|
|
|
|
if ((error = copyin(uap->data, (caddr_t)&st,
|
|
sizeof(st))) != 0) {
|
|
DPRINTF(("ibcs2_ioctl(%d): TCSET copyin failed ",
|
|
p->p_pid));
|
|
break;
|
|
}
|
|
|
|
/* get full BSD termios so we don't lose information */
|
|
if ((error = fo_ioctl(fp, TIOCGETA, (caddr_t)&bts,
|
|
td->td_ucred, td)) != 0) {
|
|
DPRINTF(("ibcs2_ioctl(%d): TCSET ctl failed fd %d ",
|
|
p->p_pid, uap->fd));
|
|
break;
|
|
}
|
|
|
|
/*
|
|
* convert to iBCS2 termios, copy in information from
|
|
* termio, and convert back, then set new values.
|
|
*/
|
|
btios2stios(&bts, &sts);
|
|
stio2stios(&st, &sts);
|
|
stios2btios(&sts, &bts);
|
|
|
|
error = fo_ioctl(fp, uap->cmd - IBCS2_TCSETA + TIOCSETA,
|
|
(caddr_t)&bts, td->td_ucred, td);
|
|
break;
|
|
}
|
|
|
|
case IBCS2_XCSETA:
|
|
case IBCS2_XCSETAW:
|
|
case IBCS2_XCSETAF:
|
|
{
|
|
struct termios bts;
|
|
struct ibcs2_termios sts;
|
|
|
|
if ((error = copyin(uap->data, (caddr_t)&sts,
|
|
sizeof (sts))) != 0)
|
|
break;
|
|
stios2btios (&sts, &bts);
|
|
error = fo_ioctl(fp, uap->cmd - IBCS2_XCSETA + TIOCSETA,
|
|
(caddr_t)&bts, td->td_ucred, td);
|
|
break;
|
|
}
|
|
|
|
case IBCS2_OXCSETA:
|
|
case IBCS2_OXCSETAW:
|
|
case IBCS2_OXCSETAF:
|
|
{
|
|
struct termios bts;
|
|
struct ibcs2_termios sts;
|
|
|
|
if ((error = copyin(uap->data, (caddr_t)&sts,
|
|
sizeof (sts))) != 0)
|
|
break;
|
|
stios2btios (&sts, &bts);
|
|
error = fo_ioctl(fp, uap->cmd - IBCS2_OXCSETA + TIOCSETA,
|
|
(caddr_t)&bts, td->td_ucred, td);
|
|
break;
|
|
}
|
|
|
|
case IBCS2_TCSBRK:
|
|
DPRINTF(("ibcs2_ioctl(%d): TCSBRK ", p->p_pid));
|
|
error = ENOSYS;
|
|
break;
|
|
|
|
case IBCS2_TCXONC:
|
|
{
|
|
switch ((int)uap->data) {
|
|
case 0:
|
|
case 1:
|
|
DPRINTF(("ibcs2_ioctl(%d): TCXONC ", p->p_pid));
|
|
error = ENOSYS;
|
|
break;
|
|
case 2:
|
|
error = fo_ioctl(fp, TIOCSTOP, (caddr_t)0,
|
|
td->td_ucred, td);
|
|
break;
|
|
case 3:
|
|
error = fo_ioctl(fp, TIOCSTART, (caddr_t)1,
|
|
td->td_ucred, td);
|
|
break;
|
|
default:
|
|
error = EINVAL;
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case IBCS2_TCFLSH:
|
|
{
|
|
int arg;
|
|
|
|
switch ((int)uap->data) {
|
|
case 0:
|
|
arg = FREAD;
|
|
break;
|
|
case 1:
|
|
arg = FWRITE;
|
|
break;
|
|
case 2:
|
|
arg = FREAD | FWRITE;
|
|
break;
|
|
default:
|
|
fdrop(fp, td);
|
|
return EINVAL;
|
|
}
|
|
error = fo_ioctl(fp, TIOCFLUSH, (caddr_t)&arg, td->td_ucred,
|
|
td);
|
|
break;
|
|
}
|
|
|
|
case IBCS2_TIOCGWINSZ:
|
|
uap->cmd = TIOCGWINSZ;
|
|
error = ioctl(td, (struct ioctl_args *)uap);
|
|
break;
|
|
|
|
case IBCS2_TIOCSWINSZ:
|
|
uap->cmd = TIOCSWINSZ;
|
|
error = ioctl(td, (struct ioctl_args *)uap);
|
|
break;
|
|
|
|
case IBCS2_TIOCGPGRP:
|
|
{
|
|
pid_t pg_id;
|
|
|
|
PROC_LOCK(p);
|
|
pg_id = p->p_pgrp->pg_id;
|
|
PROC_UNLOCK(p);
|
|
error = copyout((caddr_t)&pg_id, uap->data,
|
|
sizeof(pg_id));
|
|
break;
|
|
}
|
|
|
|
case IBCS2_TIOCSPGRP: /* XXX - is uap->data a pointer to pgid? */
|
|
{
|
|
struct setpgid_args sa;
|
|
|
|
sa.pid = 0;
|
|
sa.pgid = (int)uap->data;
|
|
error = setpgid(td, &sa);
|
|
break;
|
|
}
|
|
|
|
case IBCS2_TCGETSC: /* SCO console - get scancode flags */
|
|
error = EINTR; /* ENOSYS; */
|
|
break;
|
|
|
|
case IBCS2_TCSETSC: /* SCO console - set scancode flags */
|
|
error = 0; /* ENOSYS; */
|
|
break;
|
|
|
|
case IBCS2_JWINSIZE: /* Unix to Jerq I/O control */
|
|
{
|
|
struct ibcs2_jwinsize {
|
|
char bytex, bytey;
|
|
short bitx, bity;
|
|
} ibcs2_jwinsize;
|
|
|
|
PROC_LOCK(p);
|
|
SESS_LOCK(p->p_session);
|
|
ibcs2_jwinsize.bytex = 80;
|
|
/* p->p_session->s_ttyp->t_winsize.ws_col; XXX */
|
|
ibcs2_jwinsize.bytey = 25;
|
|
/* p->p_session->s_ttyp->t_winsize.ws_row; XXX */
|
|
ibcs2_jwinsize.bitx =
|
|
p->p_session->s_ttyp->t_winsize.ws_xpixel;
|
|
ibcs2_jwinsize.bity =
|
|
p->p_session->s_ttyp->t_winsize.ws_ypixel;
|
|
SESS_UNLOCK(p->p_session);
|
|
PROC_UNLOCK(p);
|
|
error = copyout((caddr_t)&ibcs2_jwinsize, uap->data,
|
|
sizeof(ibcs2_jwinsize));
|
|
break;
|
|
}
|
|
|
|
/* keyboard and display ioctl's -- type 'K' */
|
|
case IBCS2_KDGKBMODE: /* get keyboard translation mode */
|
|
uap->cmd = KDGKBMODE;
|
|
/* printf("ioctl KDGKBMODE = %x\n", uap->cmd);*/
|
|
error = ioctl(td, (struct ioctl_args *)uap);
|
|
break;
|
|
|
|
case IBCS2_KDSKBMODE: /* set keyboard translation mode */
|
|
uap->cmd = KDSKBMODE;
|
|
error = ioctl(td, (struct ioctl_args *)uap);
|
|
break;
|
|
|
|
case IBCS2_KDMKTONE: /* sound tone */
|
|
uap->cmd = KDMKTONE;
|
|
error = ioctl(td, (struct ioctl_args *)uap);
|
|
break;
|
|
|
|
case IBCS2_KDGETMODE: /* get text/graphics mode */
|
|
uap->cmd = KDGETMODE;
|
|
error = ioctl(td, (struct ioctl_args *)uap);
|
|
break;
|
|
|
|
case IBCS2_KDSETMODE: /* set text/graphics mode */
|
|
uap->cmd = KDSETMODE;
|
|
error = ioctl(td, (struct ioctl_args *)uap);
|
|
break;
|
|
|
|
case IBCS2_KDSBORDER: /* set ega color border */
|
|
uap->cmd = KDSBORDER;
|
|
error = ioctl(td, (struct ioctl_args *)uap);
|
|
break;
|
|
|
|
case IBCS2_KDGKBSTATE:
|
|
uap->cmd = KDGKBSTATE;
|
|
error = ioctl(td, (struct ioctl_args *)uap);
|
|
break;
|
|
|
|
case IBCS2_KDSETRAD:
|
|
uap->cmd = KDSETRAD;
|
|
error = ioctl(td, (struct ioctl_args *)uap);
|
|
break;
|
|
|
|
case IBCS2_KDENABIO: /* enable direct I/O to ports */
|
|
uap->cmd = KDENABIO;
|
|
error = ioctl(td, (struct ioctl_args *)uap);
|
|
break;
|
|
|
|
case IBCS2_KDDISABIO: /* disable direct I/O to ports */
|
|
uap->cmd = KDDISABIO;
|
|
error = ioctl(td, (struct ioctl_args *)uap);
|
|
break;
|
|
|
|
case IBCS2_KIOCSOUND: /* start sound generation */
|
|
uap->cmd = KIOCSOUND;
|
|
error = ioctl(td, (struct ioctl_args *)uap);
|
|
break;
|
|
|
|
case IBCS2_KDGKBTYPE: /* get keyboard type */
|
|
uap->cmd = KDGKBTYPE;
|
|
error = ioctl(td, (struct ioctl_args *)uap);
|
|
break;
|
|
|
|
case IBCS2_KDGETLED: /* get keyboard LED status */
|
|
uap->cmd = KDGETLED;
|
|
error = ioctl(td, (struct ioctl_args *)uap);
|
|
break;
|
|
|
|
case IBCS2_KDSETLED: /* set keyboard LED status */
|
|
uap->cmd = KDSETLED;
|
|
error = ioctl(td, (struct ioctl_args *)uap);
|
|
break;
|
|
|
|
/* Xenix keyboard and display ioctl's from sys/kd.h -- type 'k' */
|
|
case IBCS2_GETFKEY: /* Get function key */
|
|
uap->cmd = GETFKEY;
|
|
error = ioctl(td, (struct ioctl_args *)uap);
|
|
break;
|
|
|
|
case IBCS2_SETFKEY: /* Set function key */
|
|
uap->cmd = SETFKEY;
|
|
error = ioctl(td, (struct ioctl_args *)uap);
|
|
break;
|
|
|
|
case IBCS2_GIO_SCRNMAP: /* Get screen output map table */
|
|
uap->cmd = GIO_SCRNMAP;
|
|
error = ioctl(td, (struct ioctl_args *)uap);
|
|
break;
|
|
|
|
case IBCS2_PIO_SCRNMAP: /* Set screen output map table */
|
|
uap->cmd = PIO_SCRNMAP;
|
|
error = ioctl(td, (struct ioctl_args *)uap);
|
|
break;
|
|
|
|
case IBCS2_GIO_KEYMAP: /* Get keyboard map table */
|
|
uap->cmd = OGIO_KEYMAP;
|
|
error = ioctl(td, (struct ioctl_args *)uap);
|
|
break;
|
|
|
|
case IBCS2_PIO_KEYMAP: /* Set keyboard map table */
|
|
uap->cmd = OPIO_KEYMAP;
|
|
error = ioctl(td, (struct ioctl_args *)uap);
|
|
break;
|
|
|
|
/* socksys */
|
|
case IBCS2_SIOCSOCKSYS:
|
|
error = ibcs2_socksys(td, (struct ibcs2_socksys_args *)uap);
|
|
break;
|
|
|
|
case IBCS2_FIONREAD:
|
|
case IBCS2_I_NREAD: /* STREAMS */
|
|
uap->cmd = FIONREAD;
|
|
error = ioctl(td, (struct ioctl_args *)uap);
|
|
break;
|
|
|
|
default:
|
|
DPRINTF(("ibcs2_ioctl(%d): unknown cmd 0x%lx ",
|
|
td->proc->p_pid, uap->cmd));
|
|
error = ENOSYS;
|
|
break;
|
|
}
|
|
|
|
fdrop(fp, td);
|
|
return error;
|
|
}
|