301 lines
		
	
	
	
		
			6.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			301 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);
 | 
						|
}
 |