302 lines
6.5 KiB
C
302 lines
6.5 KiB
C
/*
|
|
Dedicated to the ioctl system call, MON 54.
|
|
*/
|
|
|
|
/* $Header$ */
|
|
|
|
#include "sysidf.h"
|
|
#include "v7ioctl.h"
|
|
#include "global.h"
|
|
#include "mem.h"
|
|
#include "warn.h"
|
|
|
|
#include <sgtty.h>
|
|
|
|
#ifdef V7IOCTL /* define the proper V7 requests */
|
|
|
|
#define V7IOGETP (('t'<<8)|8)
|
|
#define V7IOSETP (('t'<<8)|9)
|
|
#define V7IOSETN (('t'<<8)|10)
|
|
#define V7IOEXCL (('t'<<8)|13)
|
|
#define V7IONXCL (('t'<<8)|14)
|
|
#define V7IOHPCL (('t'<<8)|2)
|
|
#define V7IOFLUSH (('t'<<8)|16)
|
|
|
|
#define V7IOSETC (('t'<<8)|17)
|
|
#define V7IOGETC (('t'<<8)|18)
|
|
|
|
#endif V7IOCTL
|
|
|
|
|
|
/************************************************************************
|
|
* do_ioctl handles all ioctl system calls. It is called by the *
|
|
* moncall() routine, case 54. It was too big to leave it there. *
|
|
* The ioctl system call is divided into 5 parts. *
|
|
* Ioctl's dealing with respectively: *
|
|
* sgttyb, tchars, local mode word, ltchars, and miscellaneous ioctl's. *
|
|
* Some of the sgttyb-calls are only possible under the new tty-driver. *
|
|
* All of these are to be found in the miscellaneous section. *
|
|
* do_ioctl() simply returns the value ioctl() would return itself. *
|
|
* (0 for success, -1 for failure) *
|
|
***********************************************************************/
|
|
|
|
int do_ioctl(fd, req, addr)
|
|
int fd, req;
|
|
ptr addr;
|
|
{
|
|
register long e;
|
|
struct sgttyb sg_buf;
|
|
|
|
#ifdef BSD_X /* from system.h */
|
|
#ifndef V7IOCTL
|
|
char c;
|
|
int mask; /* will get ALIGNMENT problems with this one */
|
|
long count; /* might get ALIGNMENT problems with this one */
|
|
int ldisc; /* might get ALIGNMENT problems with this one */
|
|
int pgrp; /* might get ALIGNMENT problems with this one */
|
|
#endif V7IOCTL
|
|
|
|
struct tchars tc_buf;
|
|
#ifndef V7IOCTL
|
|
struct ltchars ltc_buf;
|
|
#endif V7IOCTL
|
|
#endif BSD_X
|
|
|
|
|
|
#ifdef V7IOCTL
|
|
switch (req) { /* translate the V7 requests */
|
|
/* and reject the non-V7 ones */
|
|
case V7IOGETP:
|
|
req = TIOCGETP;
|
|
break;
|
|
case V7IOSETP:
|
|
req = TIOCSETP;
|
|
break;
|
|
case V7IOEXCL:
|
|
req = TIOCEXCL;
|
|
break;
|
|
case V7IONXCL:
|
|
req = TIOCNXCL;
|
|
break;
|
|
case V7IOHPCL:
|
|
req = TIOCHPCL;
|
|
break;
|
|
#ifdef BSD_X /* from system.h */
|
|
case V7IOSETN:
|
|
req = TIOCSETN;
|
|
break;
|
|
|
|
case V7IOSETC:
|
|
req = TIOCSETC;
|
|
break;
|
|
case V7IOGETC:
|
|
req = TIOCGETC;
|
|
break;
|
|
#endif BSD_X
|
|
|
|
default:
|
|
einval(WBADIOCTL);
|
|
return (-1); /* Fake return value */
|
|
}
|
|
|
|
#endif V7IOCTL
|
|
|
|
|
|
switch (req) {
|
|
|
|
/*************************************/
|
|
/****** Struct sgttyb ioctl's ********/
|
|
/*************************************/
|
|
|
|
case TIOCGETP:
|
|
/* Get fd's current param's and store at dsp2 */
|
|
if ( (e = ioctl(fd, req, (char *) &sg_buf)) == -1
|
|
|| !sgttyb2mem(addr, &sg_buf)
|
|
) {
|
|
e = -1; /* errno already set */
|
|
}
|
|
break;
|
|
|
|
case TIOCSETP:
|
|
#ifdef BSD4_1 /* from system.h */
|
|
case TIOCSETN:
|
|
#endif BSD4_1
|
|
/* set fd's parameters according to sgtty buffer */
|
|
/* pointed to (addr), so first fill sg_buf properly. */
|
|
if ( !mem2sgtty(addr, &sg_buf)
|
|
|| (e = ioctl(fd, req, (char *) &sg_buf)) == -1
|
|
) {
|
|
e = -1; /* errno already set */
|
|
}
|
|
break;
|
|
|
|
case TIOCEXCL:
|
|
case TIOCNXCL:
|
|
case TIOCHPCL:
|
|
/* These have no third argument. */
|
|
e = ioctl(fd, req, (char *) 0);
|
|
break;
|
|
|
|
#ifdef BSD_X /* from system.h */
|
|
/*************************************/
|
|
/****** Struct tchars ioctl's ********/
|
|
/*************************************/
|
|
|
|
case TIOCGETC:
|
|
/* get special char's; store at addr */
|
|
if ( (e = ioctl(fd, req, (char *) &tc_buf)) == -1
|
|
|| !tchars2mem(addr, &tc_buf)
|
|
) {
|
|
e = -1; /* errno already set */
|
|
}
|
|
break;
|
|
|
|
case TIOCSETC:
|
|
/* set special char's; load from addr */
|
|
if ( !mem2tchars(addr, &tc_buf)
|
|
|| (e = ioctl(fd, req, (char *) &tc_buf)) == -1
|
|
) {
|
|
e = -1;
|
|
}
|
|
break;
|
|
|
|
#ifndef V7IOCTL
|
|
/***************************************/
|
|
/****** Local mode word ioctl's ********/
|
|
/***************************************/
|
|
|
|
case TIOCLBIS: /* addr points to mask which is or-ed with lmw */
|
|
case TIOCLBIC: /* addr points to mask, ~mask & lmw is done */
|
|
case TIOCLSET: /* addr points to mask, lmw is replaced by it */
|
|
if (memfault(addr, wsize)) {
|
|
e = -1;
|
|
}
|
|
else {
|
|
mask = mem_ldu(addr, wsize);
|
|
e = ioctl(fd, req, (char *) &mask);
|
|
}
|
|
break;
|
|
|
|
case TIOCLGET: /* addr points to space, store lmw there */
|
|
if ( memfault(addr, wsize)
|
|
|| (e = ioctl(fd, req, (char *) &mask)) == -1
|
|
) {
|
|
e = -1;
|
|
}
|
|
else {
|
|
mem_stn(addr, (long) mask, wsize);
|
|
}
|
|
break;
|
|
|
|
/**************************************/
|
|
/****** Struct ltchars ioctl's ********/
|
|
/**************************************/
|
|
|
|
case TIOCGLTC:
|
|
/* get current ltc's; store at addr */
|
|
if ( (e = ioctl(fd, req, (char *) <c_buf)) == -1
|
|
|| !ltchars2mem(addr, <c_buf)
|
|
) {
|
|
e = -1; /* errno already set */
|
|
}
|
|
break;
|
|
|
|
case TIOCSLTC:
|
|
/* set ltc_buf; load from addr */
|
|
if ( !mem2ltchars(addr, <c_buf)
|
|
|| (e = ioctl(fd, req, (char *) <c_buf)) == -1
|
|
) {
|
|
e = -1;
|
|
}
|
|
break;
|
|
|
|
/*************************************/
|
|
/****** Miscellaneous ioctl's ********/
|
|
/*************************************/
|
|
|
|
case TIOCGETD:
|
|
/* Get line discipline, store at addr */
|
|
if ( memfault(addr, wsize)
|
|
|| (e = ioctl(fd, req, (char *) &ldisc)) == -1
|
|
) {
|
|
e = -1;
|
|
}
|
|
else {
|
|
mem_stn(addr, (long) ldisc, wsize);
|
|
}
|
|
break;
|
|
|
|
case TIOCSETD:
|
|
/* Set line discipline, load from addr */
|
|
if (memfault(addr, wsize)) {
|
|
e = -1;
|
|
}
|
|
else {
|
|
ldisc = (int) mem_ldu(addr, wsize);
|
|
e = ioctl(fd, req, (char *) &ldisc);
|
|
}
|
|
break;
|
|
|
|
/* The following are not standard vanilla 7 UNIX */
|
|
case TIOCSBRK: /* These have no argument */
|
|
case TIOCCBRK: /* They work on parts of struct sgttyb */
|
|
case TIOCSDTR:
|
|
case TIOCCDTR:
|
|
e = ioctl(fd, req, (char *) 0);
|
|
break;
|
|
|
|
/* The following are used to set the line discipline */
|
|
case OTTYDISC:
|
|
case NETLDISC:
|
|
case NTTYDISC:
|
|
e = ioctl(fd, req, (char *) 0);
|
|
break;
|
|
|
|
case TIOCSTI: /* addr = address of character */
|
|
if (memfault(addr, 1L)) {
|
|
e = -1;
|
|
}
|
|
else {
|
|
c = (char) mem_ldu(addr, 1L);
|
|
e = ioctl(fd, req, (char *) &c);
|
|
}
|
|
break;
|
|
|
|
case TIOCGPGRP:
|
|
/* store proc grp number of control term in addr */
|
|
if ( memfault(addr, wsize)
|
|
|| (e = ioctl(fd, req, (char *) &pgrp)) == -1
|
|
) {
|
|
e = -1;
|
|
}
|
|
else {
|
|
mem_stn(addr, (long) pgrp, wsize);
|
|
}
|
|
break;
|
|
|
|
case TIOCSPGRP: /* addr is NO POINTER !! */
|
|
e = ioctl(fd, req, (char *) addr);
|
|
break;
|
|
|
|
case FIONREAD: /* do the ioctl, addr is long-int ptr now */
|
|
if ( memfault(addr, wsize)
|
|
|| (e = ioctl(fd, req, (char *) &count)) == -1
|
|
) {
|
|
e = -1;
|
|
}
|
|
else {
|
|
mem_stn(addr, count, wsize);
|
|
}
|
|
break;
|
|
|
|
#endif V7IOCTL
|
|
#endif BSD_X
|
|
|
|
default:
|
|
einval(WBADIOCTL);
|
|
e = -1; /* Fake return value */
|
|
break;
|
|
}
|
|
return (e);
|
|
}
|