[comp.sources.misc] Working Pty Driver for UnixPC

eric@ms.uky.edu@mandrill.CWRU.Edu (Eric Herrin) (09/24/87)

Mr. Moderator:

The pty driver which I posted earlier this week was the wrong version,
ie. it didn't work.  This one does, so if you have not yet sent
the earlier one out, please replace it with this one.

Sorry for the inconvenience.

			eric


|									      | 
|    Eric Herrin II				     	cbosgd!ukma!eric      |
|    "'tis better to be silent                         	eric@UKMA.BITNET      |
|     and be THOUGHT a fool, than to open              	eric@ms.uky.csnet     |
|     one's mouth and remove all doubt."                eric@ms.uky.edu       |

___________________________cut here___________________________________

#! /bin/sh
: This is a shell archive, meaning:
: 1. Remove everything above the '#! /bin/sh' line.
: 2. Save the resulting text in a file.
: 3. Execute the file with /bin/sh '(not csh)' to create the files:
:	'Install'
:	'MakeFloppy'
:	'MakePtys'
:	'Name'
:	'PTSCNT'
:	'README.3b1'
:	'READ_ME'
:	'Remove'
:	'Size'
:	'pty.c'
:	'pty.mk'
: This archive created: 'Sun Sep 20 11:44:39 1987
'
export PATH; PATH=/bin:$PATH
echo shar: extracting "'Install'" '(1558 characters)'
if test -f 'Install'
then
	echo shar: will not over-write existing file "'Install'"
else
sed 's/^X//'  >'Install' <<'SHAR_EOF'
X# Eric H. Herrin II
X# University of Kentucky Mathematical Sciences
X# eric@ms.uky.edu, eric@ms.uky.csnet, !cbosgd!ukma!eric
X#
X# Install script for System V Pty driver
XMODULE=pty
X# put the module in the appropriate place
Xcp ${MODULE}.o /etc/lddrv/${MODULE}.o
X# add the entry to the /etc/master file
X/etc/masterupd -a char open release close read write ioctl ${MODULE}
X# get the assigned device number
XMODULEDEVNO=`/etc/masterupd -c ${MODULE}`
Xif [  ! ${MODULEDEVNO} ]
Xthen 
X	echo "${MODULEDEVNO} cannot be added to the /etc/master file"
X	exit 1
Xfi
X# NOTE!!!!!!!!!!!!!!
X# To change the number of ptys, change the value in PTSCNT
X# VVVVVVV
XPTSCNT=`cat PTSCNT`
X# make the pty device files
Xcnt=0
Xfor x in p q r s t u v w x y z
Xdo
X	for y in 0 1 2 3 4 5 6 7 8 9 a b c d e f
X	do
X		i=$x$y
X		if [ $cnt -ge ${PTSCNT} ] 
X		then 
X			break
X		fi
X		/etc/mknod /dev/pty$i c ${MODULEDEVNO}\
X `expr $cnt + $PTSCNT`
X		/etc/mknod /dev/tty$i c ${MODULEDEVNO} $cnt
X		cnt=`expr $cnt + 1`
X	done
Xdone
X
X# put an entry in /etc/lddrv/InstDrv for ${MODULE}
Xecho "Name=${MODULE} driver" 				>> /etc/lddrv/InstDrv
Xecho "File=${MODULE}"     				>> /etc/lddrv/InstDrv
Xecho "Comment=Pseudo tty (pty) driver (Slave & Master side)" 	>> /etc/lddrv/InstDrv
Xcd /etc/lddrv
X# allocate and load the module
X./lddrv -av -o ${MODULE}.o ${MODULE}
Xif [ $? -eq 0 ]
Xthen
X	echo "Driver ${MODULE} successfully loaded"
Xelse
X	echo "Error: Driver ${MODULE} failed loading stage"
X	exit 1
Xfi
X
X# load the ${MODULE} at boot time
Xecho ${MODULE} >> /etc/lddrv/drivers
X
Xecho "Pseudo tty drivers are now installed"
Xexit 0
SHAR_EOF
if test 1558 -ne "`wc -c < 'Install'`"
then
	echo shar: error transmitting "'Install'" '(should have been 1558 characters)'
fi
chmod +x 'Install'
fi # end of overwriting check
echo shar: extracting "'MakeFloppy'" '(139 characters)'
if test -f 'MakeFloppy'
then
	echo shar: will not over-write existing file "'MakeFloppy'"
else
sed 's/^X//'  >'MakeFloppy' <<'SHAR_EOF'
Xecho "Insert floppy disk and press return"
Xread junk
X/usr/bin/fdfmt.nl
Xfind Size Name Remove Install pty.o -print | cpio -oBc > /dev/fp021
SHAR_EOF
if test 139 -ne "`wc -c < 'MakeFloppy'`"
then
	echo shar: error transmitting "'MakeFloppy'" '(should have been 139 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'MakePtys'" '(133 characters)'
if test -f 'MakePtys'
then
	echo shar: will not over-write existing file "'MakePtys'"
else
sed 's/^X//'  >'MakePtys' <<'SHAR_EOF'
XPTYCNT=`cat ./PTSCNT`
XDEFS=" -DKERNEL -Ddefined_io -DUNIXPC -UDEBUG -DNOSTREAMS -D\"PTSCNT=$PTYCNT\""
Xmake -f pty.mk "DEFS=$DEFS" $*
SHAR_EOF
if test 133 -ne "`wc -c < 'MakePtys'`"
then
	echo shar: error transmitting "'MakePtys'" '(should have been 133 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'Name'" '(78 characters)'
if test -f 'Name'
then
	echo shar: will not over-write existing file "'Name'"
else
sed 's/^X//'  >'Name' <<'SHAR_EOF'
XPty Driver (Modified for the UNIX-PC by University of Kentucky Math Sciences)
SHAR_EOF
if test 78 -ne "`wc -c < 'Name'`"
then
	echo shar: error transmitting "'Name'" '(should have been 78 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'PTSCNT'" '(3 characters)'
if test -f 'PTSCNT'
then
	echo shar: will not over-write existing file "'PTSCNT'"
else
sed 's/^X//'  >'PTSCNT' <<'SHAR_EOF'
X32
SHAR_EOF
if test 3 -ne "`wc -c < 'PTSCNT'`"
then
	echo shar: error transmitting "'PTSCNT'" '(should have been 3 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'README.3b1'" '(4121 characters)'
if test -f 'README.3b1'
then
	echo shar: will not over-write existing file "'README.3b1'"
else
sed 's/^X//'  >'README.3b1' <<'SHAR_EOF'
XREADME: Eric H. Herrin II
X	University of Kentucky Mathematical Sciences Laboratories
X 	915 Patterson Office Tower
X	University of Kentucky
X	Lexington, KY 40506
X	eric@ms.uky.edu, eric@ms.uky.csnet, !cbosgd!ukma!eric 
X
XThis directory contains the PD pty driver for System V, modified for
Xuse with the AT&T UnixPC or Convergent Technologies Safari 4 computers,
Xrunning Version 3.51 of the UNIX System V OS (it may also work on
Xearlier versions, but I have no way of verifying this).  Anyone using
Xthis driver should have no problems, but I will provide no support.
XQuestions should be sent to the above address, either with ground mail
Xor real (e-)mail.
X
X
XThis README is intended to mark the changes made to the PD pty driver to
Xsatisfy the author's request.  It was not easy or feasible to clearly mark
Xevery change in the code, thus it was decided that an explanation of the
Xprocedure would probably be enough.  A brief introduction to UnixPC 
Xdevice drivers is followed by the list of changes made.  A couple of
Xhacks will also be explained.
X
XNOTE: The #ifdef DEBUG statements use eprintf() instead of printf().
X      This puts any messages into the queue of system errors of
X      the error icon at the top of the console.
X
X
XUnixPC device drivers:
X
X	The UnixPC has a different kind of device driver from other 
XSystem V machines.  They can be loaded while the machine is running or
Xat boot time, but are always linked into the OS while the kernel is
Xactive.  However nice this may be, there ARE some problems.  
X
X	1.  Loadable device drivers CANNOT communicate with one another.
X	    That is, one driver cannot use a data structure defined in 
X	    another driver.  
X	2.  Conf.c doesn't exist, it is redone by the /etc/lddrv -av 
X	    program and relinked into the kernel.  Thus, one can't
X	    declare common structures this way.
X	
X
XChanges to the PD pty driver:
X
X	The following changes (hacks?) were made to the PD pty driver for
Xthe purpose of making it usable on the UnixPC.
X
X	   Problem 1 & 2 influenced me to try to make a single driver
X	   (there were two, ptm and pts).  How could one do this?
X	   My solution (and I would be very interested if you can
X	   think of a better one) was to create the slave devices
X	   /dev/tty[p-z][0-f] with minor numbers 0-(PTSCNT/2-1) and
X	   master devices /dev/pty[p-z][0-f] with minor numbers 
X	   (PTSCNT/2)-(PTSCNT-1).  Major numbers of both types of devices
X	   are the same. I can then simply define a macro to determine 
X	   whether the dev_t passed to the driver was a slave or master 
X	   pty.  Once determined, I can perform the appropriate duties.  
X	   Also, it was more readable to merge the ptm and pts modules 
X	   into a single set of pty[open, close, ioctl, read, write]
X	   routines.  I added a release routine so that the kernel will
X	   think the device has properly released if one deallocates
X	   the driver. 
X
XMaking alterations to the number of ptys, etc.
X	   The number of ptys is defined in the file PTSCNT.  This number
X	   should not exceed the maximum minor device number divided by
X	   two.  Ie. a maximum minor device number of 128 would allow
X	   a maximum of 64 ptys.  It is currently defined at 32, but
X	   I believe this is quite liberal.
X
XPty driver generation and installation procedure.
X	   Put the number of ptys you want in the file PTSCNT.
X	   Type "/bin/sh MakePty"
X	   Insert a floppy diskette.
X	   Type "/bin/sh MakeFloppy"
X	   Use the UA to install the diskette.
X	   (you can skip the floppy part and simply run the Install script 
X	   in the same directory the pty.o object is located)
X
XAcknowledgement:  I realize the usage of a single major device number is
Xa severe hack, and I welcome any improvements/solutions.  I do not assume
Xany responsibility for the changes I have made, nor do I imply any 
Xliability on the part of the original author.  I include a complete set
Xof {Install, Remove, etc, etc} scripts so that binary floppies may be
Xmade to be installed by the UnixPC user agent.  I do not assume any
Xresponsibility for these either.
X
X	    Eric H. Herrin II
X	    University of Kentucky Mathematical Sciences Laboratories
SHAR_EOF
if test 4121 -ne "`wc -c < 'README.3b1'`"
then
	echo shar: error transmitting "'README.3b1'" '(should have been 4121 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'READ_ME'" '(1624 characters)'
if test -f 'READ_ME'
then
	echo shar: will not over-write existing file "'READ_ME'"
else
sed 's/^X//'  >'READ_ME' <<'SHAR_EOF'
XThis is a pseudo tty driver for system V machines. It works very
Xsimilar to ptys on BSD, for instance emacs works fine. To install this
Xdriver you will need to modify your `master' and `dfile' file which
Xcontains your driver specifications. As these vary from machine to machine,
Xyou will have to look up in your manual how to do that. Here is an example
Xfor a sperry s5050 alias ncr tower 32 :
X
XAdd the following two lines to the driver description section in master:
Xpts	0	237	244	pts	0	0	28	32	0	tty
Xptm	0	37	344	ptm	0	0	29	0	0
X
XThis says there are max 32 pts devices at major number 28 having associated
Xtty structures and 0 ptm devices having major number 29 with no associated
Xdata. The number of ptm devices is not configurable, as this depends on the
Xnumber of pts's.
X
XThe following two lines go in the dfile:
Xpts	0	0	0
Xptm	0	0	0
X
XProbably you will also want to increase the NCLIST parameter.
X
XIf your configuration procedure is different, you must change the shell
Xscript mkpty, which is used to create the device nodes in /dev.
X
XThe ptm devices (/dev/pty[p-z][0-9a-f]) are the controlling ones, everything
Xwritten there will show up at the associated pts device
X(/dev/tty[p-z][0-9a-f]), as well as erverything which is written on the pts
Xdevice will show up on the ptm device. The pts side will accept the usual
Xtermio ioctl calls. The master side is a bit different, as ioctl calls which
Xnormally wait for output to drain flush output. The reason for this funny
Xbehaviour is that otherwise the master side will hang. Also the master side
Xmay be opened only once, further open calls will result in an EBUSY error.
SHAR_EOF
if test 1624 -ne "`wc -c < 'READ_ME'`"
then
	echo shar: error transmitting "'READ_ME'" '(should have been 1624 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'Remove'" '(943 characters)'
if test -f 'Remove'
then
	echo shar: will not over-write existing file "'Remove'"
else
sed 's/^X//'  >'Remove' <<'SHAR_EOF'
X#
X# Eric H. Herrin II
X# University of Kentucky Mathematical Sciences
X# eric@ms.uky.edu, eric@ms.uky.csnet, !cbosgd!ukma!eric
X#
X# Remove script for pty driver.
XMODULE=pty
X/etc/lddrv/lddrv -d ${MODULE}
X/etc/masterupd -d ${MODULE}
XPTSCNT=`cat PTSCNT`
X# remove the pty device files
Xcnt=0
Xfor x in p q r s t u v w x y z
Xdo
X	for y in 0 1 2 3 4 5 6 7 8 9 a b c d e f
X	do
X		i=$x$y
X		if [ ${cnt} -ge ${PTSCNT} ] 
X		then 
X			break
X		fi
X		/bin/rm -f /dev/pty$i
X		/bin/rm -f /dev/tty$i
X		cnt=`expr ${cnt} + 1`
X	done
Xdone
X# get rid of stuff in /etc/lddrv
X/bin/rm -f /etc/lddrv/${MODULE}.o /etc/lddrv/${MODULE} \
X	/etc/lddrv/ifile.${MODULE}
Xgrep -v "^${MODULE}" /etc/lddrv/drivers > /tmp/XXX$$
Xmv /tmp/XXX$$ /etc/lddrv/drivers
Xgrep -v "${MODULE}" /etc/lddrv/InstDrv > /tmp/XXX$$
Xmv /tmp/XXX$$ /etc/lddrv/InstDrv
Xchmod +r /etc/lddrv/drivers /etc/lddrv/InstDrv
Xchmod go-w /etc/lddrv/drivers /etc/lddrv/InstDrv
Xchown root /etc/lddrv/drivers /etc/lddrv/InstDrv
SHAR_EOF
if test 943 -ne "`wc -c < 'Remove'`"
then
	echo shar: error transmitting "'Remove'" '(should have been 943 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'Size'" '(3 characters)'
if test -f 'Size'
then
	echo shar: will not over-write existing file "'Size'"
else
sed 's/^X//'  >'Size' <<'SHAR_EOF'
X83
SHAR_EOF
if test 3 -ne "`wc -c < 'Size'`"
then
	echo shar: error transmitting "'Size'" '(should have been 3 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'pty.c'" '(9592 characters)'
if test -f 'pty.c'
then
	echo shar: will not over-write existing file "'pty.c'"
else
sed 's/^X//'  >'pty.c' <<'SHAR_EOF'
X
X
X/*
X * pty.c - Berkeley style pseudo tty driver for system V
X *
X * Copyright (c) 1987, Jens-Uwe Mager, FOCUS Computer GmbH
X * Not derived from licensed software.
X *
X * Permission is granted to freely use, copy, modify, and redistribute
X * this software, provided that no attempt is made to gain profit from it,
X * the author is not construed to be liable for any results of using the
X * software, alterations are clearly marked as such, and this notice is
X * not modified.
X */
X
X/*
X * Modified for use on the UnixPC by:
X * Eric H. Herrin II
X * University of Kentucky Mathematical Sciences Laboratories
X * eric@ms.uky.edu, eric@ms.uky.csnet, !cbosgd!ukma!eric
X *
X * See README.3b1 for details of port and installation.
X */
X
X/*
X * the following are arbitrary 3 unused bits from t_state
X * in sys/tty.h
X */
X/* The UnixPC does not have any extra bits in t_state, thus
X * one must provide other means of storing the state.
X */
X#define MRWAIT	01	/* master waiting in read */
X#define t_rloc	t_cc[0]		/* wchannel */
X#define MWWAIT	02	/* master waiting in write */
X#define t_wloc	t_cc[1]		/* wchannel */
X#define MOPEN	04	/* master is open */
X
X#include "sys/param.h"
X#include "sys/types.h"
X#include "sys/sysmacros.h"
X#include "sys/systm.h"
X#include "sys/file.h"
X#include "sys/conf.h"
X#include "sys/proc.h"
X#include "sys/dir.h"
X#include "sys/tty.h"
X#include "sys/signal.h"
X#include "sys/user.h"
X#include "sys/errno.h"
X#include "sys/termio.h"
X#include "sys/ttold.h"
X
X#define True  (1 == 1)
X#define False (0 == 1)
X
X/* This number comes from the file PTSCNT in the current directory 
X */
X#define PTYCNT (dev_t)PTSCNT
X/* The tty structures must be local to this driver.  One doesn't have
X * conf.c
X */
Xstruct tty pts_tty[PTYCNT];
Xint pts_cnt = PTYCNT;
Xint ptystate[PTYCNT];
X/* This macro returns True if the parameter is a major device number,
X * False otherwise.
X */
X#define Master( dev )	(minor(dev) >= PTYCNT)
Xextern int ptsproc();
X
Xptyopen(dev, flag)
X	dev_t		dev;
X	int		flag;
X{
X	register struct tty *tp;
X
X	dev = minor(dev);
X	if (Master(dev) == True) {
X#		ifdef DEBUG
X		eprintf("open(master): \n");
X#		endif
X		dev -= PTYCNT; 
X		tp = &pts_tty[dev];
X		if (dev >= pts_cnt) {
X			u.u_error = ENXIO;
X			return;
X		}
X		/*
X	 	* allow only one controlling process
X	 	*/
X		if (ptystate[dev] & MOPEN) {
X			u.u_error = EBUSY;
X			return;
X		}
X		if (tp->t_state & WOPEN)
X			wakeup((caddr_t)&tp->t_canq);
X		tp->t_state |= CARR_ON;
X		ptystate[dev] |= MOPEN;
X	} else {
X#		ifdef DEBUG
X		eprintf("open(slave): \n");
X#		endif
X		tp = &pts_tty[dev];
X		if (dev >= pts_cnt) {
X			u.u_error = ENXIO;
X			return;
X		}
X		if ((tp->t_state & (ISOPEN|WOPEN)) == 0) {
X			ttinit(tp);
X			tp->t_proc = ptsproc;
X		}
X		/*
X	  	 * if master is still open, don't wait for carrier
X	 	 */
X		if (ptystate[dev] & MOPEN)
X			tp->t_state |= CARR_ON;
X		if (!(flag & FNDELAY)) {
X			while ((tp->t_state & CARR_ON) == 0) {
X				tp->t_state |= WOPEN;
X				sleep((caddr_t)&tp->t_canq, TTIPRI);
X			}
X		}
X		(*linesw[tp->t_line].l_open)(tp);
X	}
X}
X
Xptyclose(dev, flag)
X	dev_t		dev;
X	int		flag;
X{
X	register struct tty *tp;
X
X	dev = minor(dev);
X	if (Master(dev) == True) {
X#		ifdef DEBUG
X		eprintf("close(master): \n");
X#		endif
X		dev -= PTYCNT;
X		tp = &pts_tty[dev];
X		if (tp->t_state & ISOPEN) {
X			signal(tp->t_pgrp, SIGHUP);
X			ttyflush(tp, FREAD|FWRITE);
X		}
X		/*
X	 	 * virtual carrier gone
X	 	 */
X		tp->t_state &= ~(CARR_ON);
X		ptystate[dev] &= ~MOPEN;
X	} else {
X#		ifdef DEBUG
X		eprintf("close(slave): \n");
X#		endif
X		tp = &pts_tty[dev];
X		(*linesw[tp->t_line].l_close)(tp);
X		tp->t_state &= ~CARR_ON;
X	}
X}
X
Xptyread(dev)
X	dev_t		dev;
X{
X	register struct tty *tp;
X	register n;
X
X	dev = minor(dev);
X	if (Master(dev) == True) {
X#		ifdef DEBUG
X		eprintf("read(master): \n");
X#		endif
X		dev -= PTYCNT;
X		tp = &pts_tty[dev];
X		if ((tp->t_state & ISOPEN) == 0) {
X			u.u_error = EIO;
X			return;
X		}
X		while (u.u_count) {
X			ptsproc(tp, T_OUTPUT);
X			if ((tp->t_state & (TTSTOP|TIMEOUT))
X			    || tp->t_tbuf.c_ptr == NULL || tp->t_tbuf.c_count == 0) {
X				if (u.u_fmode & FNDELAY)
X					break;
X#				ifdef DEBUG
X				eprintf("read(master): master going to sleep\n");
X#				endif
X				ptystate[dev] |= MRWAIT;
X				sleep((caddr_t)&tp->t_rloc, TTIPRI);
X#				ifdef DEBUG
X				eprintf("read(master): master woke up\n");
X#				endif
X
X				continue;
X			}
X			n = min(u.u_count, tp->t_tbuf.c_count);
X			if (n) {
X#				ifdef DEBUG
X				eprintf("read(master): got some stuff\n");
X#				endif
X				if (copyout(tp->t_tbuf.c_ptr, u.u_base, n)) {
X					u.u_error = EFAULT;
X					break;
X				}
X				tp->t_tbuf.c_count -= n;
X				tp->t_tbuf.c_ptr += n;
X				u.u_base += n;
X				u.u_count -= n;
X			}
X		}
X	} else {
X#		ifdef DEBUG
X		eprintf("read(slave): \n");
X#		endif
X		tp = &pts_tty[dev];
X#		ifdef DEBUG
X		eprintf("read(slave): got some stuff\n");
X#		endif
X		(*linesw[tp->t_line].l_read)(tp);
X	}
X}
X	
Xptywrite(dev)
X	dev_t		dev;
X{
X	register struct tty *tp;
X	register n;
X
X	dev = minor(dev);
X	if (Master(dev) == True) {
X#		ifdef DEBUG
X		eprintf("write(master): \n");
X#		endif
X		dev -= PTYCNT;
X		tp = &pts_tty[dev];
X		if ((tp->t_state & ISOPEN) == 0) {
X			u.u_error = EIO;
X			return;
X		}
X		while (u.u_count) {
X			if ((tp->t_state & TBLOCK) || tp->t_rbuf.c_ptr == NULL) {
X				if (u.u_fmode & FNDELAY)
X					break;
X				ptystate[dev] |= MWWAIT;
X#				ifdef DEBUG
X				eprintf("write(master): going to sleep\n");
X#				endif
X
X				sleep((caddr_t)&tp->t_wloc, TTOPRI);
X
X#				ifdef DEBUG
X				eprintf("write: waking up\n");
X#				endif
X
X				continue;
X			}
X			n = min(u.u_count, tp->t_rbuf.c_count);
X			if (n) {
X#				ifdef DEBUG
X				eprintf("write(master): sending some stuff\n");
X#				endif
X				if (copyin(u.u_base,tp->t_rbuf.c_ptr, n)) {
X					u.u_error = EFAULT;
X					break;
X				}
X				tp->t_rbuf.c_count -= n;
X				u.u_base += n;
X				u.u_count -= n;
X			}
X			(*linesw[tp->t_line].l_input)(tp);
X		}
X	} else {
X#		ifdef DEBUG
X		eprintf("write(slave): \n");
X#		endif
X		tp = &pts_tty[dev];
X#		ifdef DEBUG
X		eprintf("write(slave): sending some stuff\n");
X#		endif
X		(*linesw[tp->t_line].l_write)(tp);
X	}
X}
X
Xptyioctl(dev, cmd, arg, mode)
X	dev_t		dev;
X	int		cmd, arg, mode;
X{
X	register struct tty *tp;
X
X	dev = minor(dev);
X	if (Master(dev) == True) {
X#		ifdef DEBUG
X		eprintf("ioctl(master): \n");
X#		endif
X		dev -= PTYCNT;
X		tp = &pts_tty[dev];
X		/*
X	 	 * sorry, but we can't fiddle with the tty struct without
X	 	 * having done LDOPEN
X	 	 */
X		if (tp->t_state & ISOPEN) {
X			if (cmd == TCSBRK && arg ==  NULL) {
X				signal(tp->t_pgrp, SIGINT);
X				if ((tp->t_iflag & NOFLSH) == 0)
X					ttyflush(tp, FREAD|FWRITE);
X			} else {
X				/*
X			 	 * we must flush output to avoid hang in ttywait
X			 	 */
X				if (cmd == TCSETAW || cmd == TCSETAF || 
X				   cmd == TCSBRK || cmd == TIOCSETP)
X					ttyflush(tp, FWRITE);
X				ttiocom(tp, cmd, arg, mode);
X			}
X		}
X	} else {
X#		ifdef DEBUG
X		eprintf("ioctl(slave): \n");
X#		endif
X		tp = &pts_tty[dev];
X		ttiocom(tp, cmd, arg, mode);
X	}
X}
X
Xptsproc(tp, cmd)
Xregister struct tty *tp;
X{
X	register struct ccblock *tbuf;
X	extern ttrstrt();
X
X	switch (cmd) {
X	case T_TIME:
X#		ifdef DEBUG
X		eprintf("ptsproc: T_TIME:\n");
X#		endif
X		tp->t_state &= ~TIMEOUT;
X		goto start;
X	case T_WFLUSH:
X#		ifdef DEBUG
X		eprintf("ptsproc: T_WFLUSH:\n");
X#		endif
X		tp->t_tbuf.c_size  -= tp->t_tbuf.c_count;
X		tp->t_tbuf.c_count = 0;
X		/* fall through */
X	case T_RESUME:
X#		ifdef DEBUG
X		eprintf("ptsproc: T_RESUME:\n");
X#		endif
X		tp->t_state &= ~TTSTOP;
X		/* fall through */
X	case T_OUTPUT:
Xstart:
X#		ifdef DEBUG
X		eprintf("ptsproc: T_OUTPUT:\n");
X#		endif
X		if (tp->t_state & (TTSTOP|TIMEOUT))
X			break;
X#		ifdef DEBUG
X		eprintf("ptsproc: T_OUTPUT: past(TTSTOP|TIMEOUT)");
X#		endif
X		tbuf = &tp->t_tbuf;
X		if (tbuf->c_ptr == NULL || tbuf->c_count == 0) {
X#		ifdef DEBUG
X		eprintf("ptsproc: T_OUTPUT: tbuf empty, may break\n");
X#		endif
X			if (tbuf->c_ptr)
X				tbuf->c_ptr -= tbuf->c_size;
X			if (!(CPRES & (*linesw[tp->t_line].l_output)(tp)))
X				break;
X		}
X		if (tbuf->c_count && (ptystate[tp-pts_tty] & MRWAIT)) {
X#		ifdef DEBUG
X		eprintf("ptsproc: T_OUTPUT: waking up master\n");
X#		endif
X			ptystate[tp-pts_tty] &= ~MRWAIT;
X			wakeup((caddr_t)&tp->t_rloc);
X		}
X#		ifdef DEBUG
X		eprintf("ptsproc: T_OUTPUT: leaving end\n");
X#		endif
X		break;
X	case T_SUSPEND:
X#		ifdef DEBUG
X		eprintf("ptsproc: T_SUSPEND:\n");
X#		endif
X		tp->t_state |= TTSTOP;
X		break;
X	case T_BLOCK:
X#		ifdef DEBUG
X		eprintf("ptsproc: T_BLOCK:\n");
X#		endif
X		/*
X		 * the check for ICANON appears to be neccessary
X		 * to avoid a hang when overflowing input
X		 */
X		if ((tp->t_iflag & ICANON) == 0)
X			tp->t_state |= TBLOCK;
X		break;
X	case T_BREAK:
X#		ifdef DEBUG
X		eprintf("ptsproc: T_BREAK:\n");
X#		endif
X		tp->t_state |= TIMEOUT;
X		timeout(ttrstrt, tp, HZ/4);
X		break;
X#ifdef T_LOG_FLUSH
X	case T_LOG_FLUSH:
X#endif
X	case T_RFLUSH:
X#		ifdef DEBUG
X		eprintf("ptsproc: T_RFLUSH:\n");
X#		endif
X		if (!(tp->t_state & TBLOCK))
X			break;
X		/* fall through */
X	case T_UNBLOCK:
X#		ifdef DEBUG
X		eprintf("ptsproc: T_UNBLOCK:\n");
X#		endif
X		tp->t_state &= ~(TTXOFF|TBLOCK);
X		/* fall through */
X	case T_INPUT:
X#		ifdef DEBUG
X		eprintf("ptsproc: T_INPUT:\n");
X#		endif
X		if (ptystate[tp-pts_tty] & MWWAIT) {
X			ptystate[tp-pts_tty] &= ~MWWAIT;
X#			ifdef DEBUG
X			eprintf("ptsproc: T_INPUT: waking up master\n");
X#			endif
X			wakeup((caddr_t)&tp->t_wloc);
X		}
X		break;
X	default:
X#		ifdef DEBUG
X		eprintf("ptsproc: default:\n");
X#		else
X		;
X#		endif
X	}
X}
X	
X/* this routine is a silly stub to allow /etc/lddrv to believe the
X * release of the 'device' was performed without error.  If this is
X * not done, the driver will not unload properly (ie. ya gotta reboot).
X */
Xptyrelease()
X{
X#	ifdef DEBUG
X	eprintf("ptyrelease:\n");
X#	endif
X	/* stub for /etc/lddrv */
X}
SHAR_EOF
if test 9592 -ne "`wc -c < 'pty.c'`"
then
	echo shar: error transmitting "'pty.c'" '(should have been 9592 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'pty.mk'" '(129 characters)'
if test -f 'pty.mk'
then
	echo shar: will not over-write existing file "'pty.mk'"
else
sed 's/^X//'  >'pty.mk' <<'SHAR_EOF'
XCFLAGS= -O -c ${DEFS}
X
X.c.o:
X	${CC} ${CFLAGS} $<
X
Xall: pty.o
X
Xinstall: all
X	/bin/sh Install
X
Xclean: 
X	rm pty.o
X
Xclobber: clean
X	
SHAR_EOF
if test 129 -ne "`wc -c < 'pty.mk'`"
then
	echo shar: error transmitting "'pty.mk'" '(should have been 129 characters)'
fi
fi # end of overwriting check
:	End of shell archive
exit 0