⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ioctl.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
字号:
#ifndef lintstatic	char	*sccsid = "@(#)ioctl.c	4.1	(ULTRIX)	7/3/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1985-1990 by			* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//************************************************************************ *			Modification History				* *									* *	David L Ballenger, 28-Mar-1985					* * 0001	Modify for use with merged ULTRIX/SYSTEM-V header files.	* *									* *	Tim Burke, 07-Dec-1987						* *	No need to map the termio ioctl calls with pack() and unpack().	* *	The ioctl calls can be nade directly.				* *									* *	Tim Burke, 04-Feb-1988						* *	Fixed up handling of tabs in pack and unpack.			* *									* *	Grant Sullivan, 16-Jan-1990					* *	conditionalized word struct so MIPSEL (includes mips) is the	* *	  same as "vax"							* ************************************************************************//*	ioctl -- system call emulation for 4.2BSD	last edit:	28-Dec-1984	D A Gwyn	Because there is not a 1-1 mapping between Bell and Berkeley	terminal driver modes, some flag bits have an "adjusted" meaning	in an attempt to provide improved mapping reversibility.	Special note:  sg_flags is an int, not a short, and it contains	both the standard sgttyb flags and Berkeley's added local flags.	Beware!  Setting NOFLSH in c_flag will set ALL the Berkeley	local flags unless you have fixed this bug in the tty driver.	(On 4.1cBSD, there is a similar problem with BSDLY.)*//* Make sure this is compiled for ULTRIX System V emulation. */#ifndef SYSTEM_FIVE#define SYSTEM_FIVE#endif  SYSTEM_FIVE#include	<errno.h>#include	<sys/termio.h>#include	<sys/ttold.h>#include	<sys/time.h>/*	differing 4.2BSD sg_flag bits:	*/#define X_TANDEM	0x00000001	/* automatic flow control */#define X_CBREAK	0x00000002	/* half-cooked mode */#define X_TBDELAY	0x00000c00	/* tab delay code: */#define X_XTABS 	0x00000c00	/* map tabs to spaces *//*	added 4.2BSD sg_flag bits:	*/#define X_CRTBS 	0x00010000	/* fancy BS erase */#define X_PRTERA	0x00020000	/* \.../ erase */#define X_CRTERA	0x00040000	/* BS-SP-BS erase */#define X_TILDE 	0x00080000	/* Hazeltine kludge */#define X_MDMBUF	0x00100000	/* DTR stall kludge */#define X_LITOUT	0x00200000	/* literal output */#define X_TOSTOP	0x00400000	/* SIGSTOP on bkgnd output */#define X_FLUSHO	0x00800000	/* set by ^O */#define X_NOHANG	0x01000000	/* no SIGHUP on hangup */#define X_ETXACK	0x02000000	/* ETX->ACK protocol */#define X_CRTKIL	0x04000000	/* BS-SP-BS kill */#define X_INTRUP	0x08000000	/* SIGTINT when input ready */#define X_CTLECH	0x10000000	/* echo ctrl-X as "^X" */#define X_PENDIN	0x20000000	/* reread raw queue */#define X_DECCTQ	0x40000000	/* strict DC3/DC1 protocol */#define X_NOFLSH	0x80000000	/* no output flush on signal *//*	Kludge for accessing "local flags" part of sg_flags:	*/#if vax | MIPSEL /* VAX and RISC MISPEL machines have same order */typedef struct	{	short	low;			/* low half (standard flags) */	short	high;			/* high half (local flags) */	}	word;			/* map onto sg_flags */#else	/* Gould, etc. */typedef struct	{	short	high;			/* high half (local flags) */	short	low;			/* low half (standard flags) */	}	word;			/* map onto sg_flags */#endifextern int	_ioctl(), select();static void	nap(), new_tty(), unfudge();static int	fudge(), get_sgttyb(), pack(), set_sgttyb(), unpack();intioctl( fildes, request, arg )		/* returns 0 if ok, else -1 */	int		fildes; 	/* file descriptor */	int		request;	/* command */	int		arg;		/* command arguments */	{	struct sgttyb	tb;		/* [gs]tty values */	switch ( request )		{	case TIOCGETP:		new_tty( fildes );		if ( get_sgttyb( fildes, (struct sgttyb *)arg ) < 0 )			return -1;	/* errno already set */		unfudge( (struct sgttyb *)arg );		return 0;	case TIOCSETP:		new_tty( fildes );		tb = *(struct sgttyb *)arg;	/* local copy */		if ( fudge( fildes, &tb ) < 0		  || set_sgttyb( fildes, &tb, 1 ) < 0		   )			return -1;	/* errno already set */		return 0;		/*	 	 * It is no longer to map the termio ioctl calls.  They can be	 	 * made directly.	 	 */	default:		return _ioctl( fildes, request, (char *)arg );		}	}static voidnew_tty( fildes )		/* make sure new tty handler is used */	{	static int	ldisc = OTTYDISC;	/* line discipline */	if ( ldisc != NTTYDISC		/* first time this process */	  && (ioctl( fildes, TIOCGETD, &ldisc ) != 0	/* unknown */	   || ldisc != NTTYDISC		/* known but not "new tty" */	     )	   )	{		ldisc = NTTYDISC;	/* force new tty handler */		(void)_ioctl( fildes, TIOCSETD, &ldisc );		}	}/*	I used to take a really ugly efficiency shortcut in the next	two routines, but the Gould byte order put a stop to that.   */static intget_sgttyb( fildes, tbp )		/* extended gtty */	int			fildes; /* file descriptor */	register struct sgttyb	*tbp;	/* -> where to put data */	{	int			lf;	/* local flags */	struct sgttyb_ULTRIX	xb;	/* native data */	if ( _ioctl( fildes, TIOCGETP, (char *)&xb ) < 0 )		return -1;		/* errno already set */	tbp->sg_ispeed = xb.sg_ispeed;	tbp->sg_ospeed = xb.sg_ospeed;	tbp->sg_erase = xb.sg_erase;	tbp->sg_kill = xb.sg_kill;	((word *)&tbp->sg_flags)->low = xb.sg_flags;	if ( _ioctl( fildes, TIOCLGET, (char *)&lf ) < 0 )		return -1;		/* errno already set */	((word *)&tbp->sg_flags)->high = (short)lf;	return 0;	}static intset_sgttyb( fildes, tbp, wait ) 	/* extended stty */	int			fildes; /* file descriptor */	register struct sgttyb	*tbp;	/* -> data to be set */	int			wait;	/* "wait for output to drain" */{	int			lf;	/* local flags */	struct sgttyb_ULTRIX	xb;	/* native data */	xb.sg_ispeed = tbp->sg_ispeed;	xb.sg_ospeed = tbp->sg_ospeed;	xb.sg_erase = tbp->sg_erase;	xb.sg_kill = tbp->sg_kill;	xb.sg_flags = ((word *)&tbp->sg_flags)->low;	if ( _ioctl( fildes, wait != 0 ? TIOCSETP : TIOCSETN,		     (char *)&xb		   ) < 0	   )		return -1;		/* errno already set */	lf = (int)((word *)&tbp->sg_flags)->high;	if ( _ioctl( fildes, TIOCLSET, (char *)&lf ) < 0 )		return -1;		/* errno already set */	return 0;}static intfudge( fildes, tbp )			/* map Sys V stty to 4.2BSD */	int			fildes; /* file descriptor */	register struct sgttyb	*tbp;	/* -> data about to be set */	{	if ( (tbp->sg_flags & O_XTABS) != 0 )		tbp->sg_flags |= X_XTABS;	if ( (tbp->sg_flags & O_HUPCL) != 0	  && _ioctl( fildes, TIOCHPCL, (char *)0 ) < 0	   )		return -1;		/* errno already set */	tbp->sg_flags &= ~(O_XTABS | O_HUPCL);	return 0;	}static voidunfudge( tbp )				/* map 4.2BSD gtty to Sys V */	register struct sgttyb	*tbp;	/* -> data just gotten */	{	if ( (tbp->sg_flags & X_CBREAK) != 0 )		tbp->sg_flags |= O_RAW; /* approximation */	tbp->sg_flags &= ~(X_CBREAK | X_TANDEM);	if ( (tbp->sg_flags & X_TBDELAY) == X_XTABS )		{		tbp->sg_flags &= ~X_TBDELAY;		tbp->sg_flags |= O_XTABS;		}	else if ( (tbp->sg_flags & X_TBDELAY) != 0 )		{		tbp->sg_flags |= O_TBDELAY;		tbp->sg_flags &= ~O_NOAL;		}	}static intpack( fildes, argp, tbp )		/* map termio to 4.2BSD stty */	int			fildes; /* file descriptor */	register struct termio	*argp;	/* -> desired state info */	register struct sgttyb	*tbp;	/* -> stty buffer */	{	register int		flag;	/* holds sg_flags */	struct tchars		tc;	/* 4.2BSD magic characters */	struct ltchars		ltc;	/* more 4.2BSD magic chars */	if ( (argp->c_lflag & ICANON) != 0 )	/* no MIN, TIME */		{		if ( (tc.t_eofc = argp->c_cc[VEOF]) == CNUL )			tc.t_eofc = (char)-1;		if ( (tc.t_brkc = argp->c_cc[VEOL]) == CNUL )			tc.t_brkc = (char)-1;		}	else if ( _ioctl( fildes, TIOCGETC, (char *)&tc ) < 0 )		return -1;		/* errno already set */	if ( (argp->c_lflag & (ICANON | ISIG)) == ICANON )		tc.t_intrc = tc.t_quitc = (char)-1;	/* disable */	else	{		if ( (tc.t_intrc = argp->c_cc[VINTR]) == CNUL )			tc.t_intrc = (char)-1;		if ( (tc.t_quitc = argp->c_cc[VQUIT]) == CNUL )			tc.t_quitc = (char)-1;		}	if ( (argp->c_iflag & IXON) == 0 )		tc.t_startc = tc.t_stopc = (char)-1;	/* disable */	else	{		tc.t_startc = CSTART;		tc.t_stopc = CSTOP;		}	if ( _ioctl( fildes, TIOCSETC, (char *)&tc ) < 0 )		return -1;		/* errno already set */	if ( _ioctl( fildes, TIOCGLTC, (char *)&ltc ) == 0 )		{			/* new tty handler */				if ( (ltc.t_suspc = argp->c_cc[VSWTCH]) == CNUL )			ltc.t_suspc = (char)-1;		if ( _ioctl( fildes, TIOCSLTC, (char *)&ltc ) < 0 )			return -1;	/* errno already set */		}	if ( (argp->c_cflag & HUPCL) != 0	  && _ioctl( fildes, TIOCHPCL, (char *)0 ) < 0	   )		return -1;		/* errno already set */	tbp->sg_erase = argp->c_cc[VERASE];	tbp->sg_kill = argp->c_cc[VKILL];	tbp->sg_ispeed = tbp->sg_ospeed = argp->c_cflag & CBAUD;	flag = X_CTLECH;		/* everybody gets this */	if ( (argp->c_lflag & ICANON) == 0 )		flag |= O_RAW;	if ( (argp->c_lflag & XCASE) != 0 )		flag |= O_LCASE;	if ( (argp->c_lflag & ECHO) != 0 )		flag |= O_ECHO;	if ( (argp->c_lflag & ECHOE) != 0 )		{		flag |= X_CRTBS;		if ( tbp->sg_ospeed >= B1200 )			flag |= X_CRTERA | X_CRTKIL;		}	else		flag |= X_PRTERA;#ifndef gould	/* at least for now */	if ( (argp->c_lflag & NOFLSH) != 0 )		flag |= X_NOFLSH;#endif	if ( (argp->c_cflag & PARODD) != 0 )		flag |= O_ODDP;	else if ( (argp->c_iflag & INPCK) != 0 )		flag |= O_EVENP;	else		flag |= O_ODDP | O_EVENP;	if ( (argp->c_cflag & CLOCAL) != 0 )		flag |= X_MDMBUF | X_NOHANG;	/* The following is done even if OPOST is off, to keep track: */	if ( (argp->c_oflag & ONLCR) != 0 )		{		flag |= O_CRMOD;		if ( (argp->c_oflag & CRDLY) == CR1 )			flag |= O_NL1;	/* sorry `bout that */		else if ( (argp->c_oflag & CRDLY) == CR2 )			flag |= O_CR1;	/* approximation */		else if ( (argp->c_oflag & CRDLY) != 0 )			flag |= O_CR2;	/* approximation to CR3 */		}	else if ( (argp->c_oflag & ONLRET) != 0 )		{		if ( (argp->c_oflag & CR2) != 0 )	/* CR2 or CR3 */			flag |= O_NL2;		else if ( (argp->c_oflag & CR1) != 0 )	/* CR1 */			flag |= O_NL1;		}	else		if ( (argp->c_oflag & NLDLY) != 0 )			flag |= O_NL2;	flag |= (long)((argp->c_oflag & TABDLY) );	if ( (argp->c_oflag & (VTDLY | FFDLY)) != 0 )		flag |= O_VTDELAY;#ifndef gould	/* at least for now */	if ( (argp->c_oflag & BSDLY) != 0 )		flag |= O_BSDELAY;#endif	if ( (argp->c_iflag & (IXON | IXANY)) == IXON )		flag |= X_DECCTQ;	if ( (argp->c_iflag & IXOFF) != 0 )		flag |= X_TANDEM;	tbp->sg_flags = flag;	return 0;	}static intunpack( fildes, tbp, argp )		/* map 4.2BSD gtty to termio */	int			fildes; /* file descriptor */	struct sgttyb		*tbp;	/* -> gtty buffer */	register struct termio	*argp;	/* where to put unpacking */	{	struct tchars		tc;	/* 4.2BSD magic characters */	struct ltchars		ltc;	/* more 4.2BSD magic chars */	register int		flag = tbp->sg_flags;	/* for speed */	if ( _ioctl( fildes, TIOCGETC, (char *)&tc ) < 0 )		return -1;		/* errno already set */	argp->c_cc[VERASE] = tbp->sg_erase;	argp->c_cc[VKILL] = tbp->sg_kill;	if ( tc.t_intrc == (char)-1 && tc.t_quitc == (char)-1 )		{			/* assume defaults */		argp->c_cc[VINTR] = CINTR;		argp->c_cc[VQUIT] = CQUIT;		argp->c_lflag = 0;	/* no ISIG */		}	else	{		if ( (argp->c_cc[VINTR] = tc.t_intrc) == (char)-1 )			argp->c_cc[VINTR] = CNUL;		if ( (argp->c_cc[VQUIT] = tc.t_quitc) == (char)-1 )			argp->c_cc[VQUIT] = CNUL;		argp->c_lflag = ISIG;		}	if ( tc.t_startc == (char)-1 && tc.t_stopc == (char)-1 )		argp->c_iflag = 0;	/* no IXON */	else		argp->c_iflag = (flag & X_DECCTQ) != 0 ? IXON						       : IXON | IXANY;	if ( (argp->c_cc[VEOF] = tc.t_eofc) == (char)-1 )		argp->c_cc[VEOF] = CNUL;	if ( (argp->c_cc[VEOL] = tc.t_brkc) == (char)-1 )		argp->c_cc[VEOL] = CNUL;	argp->c_cc[VEOL2] = CNUL;	if ( _ioctl( fildes, TIOCGLTC, (char *)&ltc ) < 0					/* old tty handler */	  || (argp->c_cc[VSWTCH] = ltc.t_suspc) == (char)-1	   )		argp->c_cc[VSWTCH] = CNUL;	argp->c_oflag = (unsigned short)(flag & X_TBDELAY);	if ( (argp->c_cflag = tbp->sg_ispeed & CBAUD | CREAD)	      == (B110 | CREAD)	   )		argp->c_cflag |= CSTOPB;	if ( (flag & (X_MDMBUF | X_NOHANG)) != 0 )		argp->c_cflag |= CLOCAL;	if ( (flag & O_LCASE) != 0 )		{		argp->c_iflag |= IUCLC;		argp->c_oflag |= OLCUC;		argp->c_lflag |= XCASE;		}	if ( (flag & O_ECHO) != 0 )		argp->c_lflag |= ECHO;	if ( (flag & X_NOFLSH) != 0 )		argp->c_lflag |= NOFLSH;	else		argp->c_lflag |= ECHOK;	if ( (flag & O_CRMOD) != 0 )		{		argp->c_iflag |= ICRNL;		argp->c_oflag |= ONLCR;		if ( (flag & O_NL2) != 0 )	/* O_NL2 or O_NL3 */			argp->c_oflag |= NL1;		else if ( (flag & O_NL1) != 0 ) /* O_NL1 */			argp->c_oflag |= CR1;		else if ( (flag & O_CR2) != 0 ) /* O_CR2 or O_CR3 */			argp->c_oflag |= ONOCR | CR3;	/* approx. */		else if ( (flag & O_CR1) != 0 ) /* O_CR1 */			argp->c_oflag |= ONOCR | CR2;	/* approx. */		}	else	{		argp->c_oflag |= ONLRET;		if ( (flag & O_NL1) != 0 )			argp->c_oflag |= CR1;		if ( (flag & O_NL2) != 0 )			argp->c_oflag |= CR2;		}	if ( (flag & O_VTDELAY) != 0 )		argp->c_oflag |= FF1 | VT1;	if ( (flag & O_BSDELAY) != 0 )		argp->c_oflag |= BS1;	if ( (flag & O_RAW) != 0 )		{		argp->c_cflag |= CS8;		argp->c_iflag &= ~(ICRNL | IUCLC);		argp->c_lflag &= ~ISIG;		}	else	{		argp->c_cflag |= CS7 | PARENB;		argp->c_iflag |= BRKINT | IGNPAR | INPCK | ISTRIP;		argp->c_oflag |= OPOST;		argp->c_lflag |= ICANON;		}	if ( (flag & O_ODDP) != 0 )		if ( (flag & O_EVENP) != 0 )			argp->c_iflag &= ~INPCK;		else			argp->c_cflag |= PARODD;	if ( (flag & X_CRTBS) != 0 )		argp->c_lflag |= ECHOE;	if ( (flag & X_TANDEM) != 0 )		argp->c_iflag |= IXOFF;	argp->c_line = 0;		/* default line discipline */	return 0;	}static voidnap( usec )				/* returns 0 if ok, else -1 */	long		usec;		/* delay in microseconds */	{	static struct timeval delay;	/* `timeval' */	delay.tv_sec = usec / 1000000L;	delay.tv_usec = usec % 1000000L;	select( 0, (long *)0, (long *)0, (long *)0, &delay );	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -