v06i048: Xenix pty driver
Brandon S. Allbery - comp.sources.misc
allbery at uunet.UU.NET
Sun Mar 5 07:31:27 AEST 1989
Posting-number: Volume 6, Issue 48
Submitted-by: chip at ateng.ateng.com (Chip Salzenberg)
Archive-name: ptys.sco
This driver adds Berkeley-style ptys (pseudo-ttys) to SCO Xenix/286 and
Xenix/386. It has a long history. It is derived from a System V version,
but is now specific to SCO Xenix.
Note that although Xenix/386 2.3 includes ptys, they are *broken*. They are
incapable of non-blocking reads on the master side. This bug hangs Emacs.
All Xenix users would be well advised to avoid SCO's pty driver and use this.
--
Chip Salzenberg <chip at ateng.com> or <uunet!ateng!chip>
A T Engineering "Designed with your mind in mind."
--
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of shell archive."
# Contents: Makefile INSTALL MKDEVS Makefile PTYCNT README.SCO pty.c
# Wrapped by chip at ateng on Mon Feb 13 17:51:07 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(357 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X#
X# Uncomment the definition of FOR286 if you are compling for Xenix/286.
X#
X#FOR286 = -LARGE -M2em
XCFLAGS = ${FOR286} -O -K -DM_KERNEL ${DEFS}
X
Xall: pty.o
Xinstall: pty.o
X ./INSTALL
Xclean:
X rm pty.o
Xclobber: clean
Xshar: pty.sh
X
Xpty.o: pty.c PTYCNT
X $(CC) $(CFLAGS) -c pty.c
X
Xpty.sh:
X shar Makefile INSTALL MKDEVS Makefile PTYCNT README.SCO pty.c >$@
END_OF_FILE
if test 357 -ne `wc -c <'Makefile'`; then
echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'INSTALL' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'INSTALL'\"
else
echo shar: Extracting \"'INSTALL'\" \(1896 characters\)
sed "s/^X//" >'INSTALL' <<'END_OF_FILE'
X: INSTALL
X# Xenix pty installation.
X
Xif [ ! -f /etc/systemid ]
Xthen
X echo "This is not a Xenix system" 1>&2
X exit 1
Xfi
X
Xif [ ! -f pty.o ]
Xthen
X echo "you must make pty.o before running INSTALL" 1>&2
X exit 1
Xfi
X
XPATH=/usr/sys/conf:$PATH; export PATH
X
Xcp pty.o /usr/sys/conf
X
X# NOTE!!!!!!!!!!!!!!
X# To change the number of ptys, change the value in PTYCNT
X
XPTYCNT=`sed -n 's/.*PTYCNT//p' PTYCNT`
XMASTERMINOR=`sed -n 's/.*MASTERMINOR//p' PTYCNT`
X
Xcd /usr/sys/conf
X
X# get the first available major number.
X
XPTYMAJOR=0
X
Xfor i in `majorsinuse`
Xdo
X [ $i != $PTYMAJOR ] && break
X PTYMAJOR=`expr $i + 1`
Xdone
X
Xconfigure -a ptyopen ptyclose ptyread ptywrite ptyioctl -m $PTYMAJOR -c
X
Xif [ $? -ne 0 ]
Xthen
X echo "pty cannot be added to the master file" 1>&2
X exit 1
Xfi
X
Xif [ $? -ne 0 ]
Xthen
X echo "support files not updated" 1>&2
X exit 1
Xfi
X
X# make the pty device files in /dev
X
XLETTER=p
X
Xcnt=0
Xwhile [ $cnt -lt $PTYCNT ]
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=$LETTER$y
X if [ $cnt -ge ${PTYCNT} ]
X then
X break
X fi
X
X [ -c /dev/pty$i ] && rm -f /dev/pty$i
X [ -c /dev/tty$i ] && rm -f /dev/tty$i
X
X /etc/mknod /dev/pty$i c ${PTYMAJOR} \
X `expr $cnt + $MASTERMINOR` &&
X /etc/mknod /dev/tty$i c ${PTYMAJOR} $cnt ||
X exit 1
X chmod 666 /dev/pty$i /dev/tty$i
X chown root /dev/pty$i /dev/tty$i
X chgrp root /dev/pty$i /dev/tty$i
X
X cnt=`expr $cnt + 1`
X done
X LETTER=`echo $LETTER | tr '[a-z][A-Y]' '[b-z][A-Z]'`
Xdone
X
X# add pty.o to the link_xenix script
X
Xif fgrep pty.o link_xenix >/dev/null
Xthen
X : fine
Xelse
X ed - link_xenix <<'-EOF'
X /kid\.o/s//kid.o pty.o/
X w
X EOF
Xfi
X
X# relink the kernel
X
Xsh -v link_xenix || exit 1
X
X# tell the user what to do next
X
Xecho ""
Xecho "The new kernel with ptys has been linked as /usr/sys/conf/xenix."
Xecho "To make this kernel the default, type the following commands:"
Xecho " mv /xenix /xenix.prev"
Xecho " ln /usr/sys/conf/xenix /"
Xecho ""
END_OF_FILE
if test 1896 -ne `wc -c <'INSTALL'`; then
echo shar: \"'INSTALL'\" unpacked with wrong size!
fi
chmod +x 'INSTALL'
# end of 'INSTALL'
fi
if test -f 'MKDEVS' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'MKDEVS'\"
else
echo shar: Extracting \"'MKDEVS'\" \(697 characters\)
sed "s/^X//" >'MKDEVS' <<'END_OF_FILE'
X# make the pty device files in /dev
X
XPTYCNT=`sed -n 's/.*PTYCNT//p' PTYCNT`
XMASTERMINOR=`sed -n 's/.*MASTERMINOR//p' PTYCNT`
X
XPTYMAJOR=10
XLETTER=p
X
Xcnt=0
Xwhile [ $cnt -lt $PTYCNT ]
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=$LETTER$y
X if [ $cnt -ge ${PTYCNT} ]
X then
X break
X fi
X
X [ -c /dev/pty$i ] && rm -f /dev/pty$i
X [ -c /dev/tty$i ] && rm -f /dev/tty$i
X
X /etc/mknod /dev/pty$i c ${PTYMAJOR} \
X `expr $cnt + $MASTERMINOR` &&
X /etc/mknod /dev/tty$i c ${PTYMAJOR} $cnt ||
X exit 1
X chmod 666 /dev/pty$i /dev/tty$i
X chown root /dev/pty$i /dev/tty$i
X chgrp root /dev/pty$i /dev/tty$i
X
X cnt=`expr $cnt + 1`
X done
X LETTER=`echo $LETTER | tr '[a-z][A-Y]' '[b-z][A-Z]'`
Xdone
END_OF_FILE
if test 697 -ne `wc -c <'MKDEVS'`; then
echo shar: \"'MKDEVS'\" unpacked with wrong size!
fi
chmod +x 'MKDEVS'
# end of 'MKDEVS'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(357 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X#
X# Uncomment the definition of FOR286 if you are compling for Xenix/286.
X#
X#FOR286 = -LARGE -M2em
XCFLAGS = ${FOR286} -O -K -DM_KERNEL ${DEFS}
X
Xall: pty.o
Xinstall: pty.o
X ./INSTALL
Xclean:
X rm pty.o
Xclobber: clean
Xshar: pty.sh
X
Xpty.o: pty.c PTYCNT
X $(CC) $(CFLAGS) -c pty.c
X
Xpty.sh:
X shar Makefile INSTALL MKDEVS Makefile PTYCNT README.SCO pty.c >$@
END_OF_FILE
if test 357 -ne `wc -c <'Makefile'`; then
echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'PTYCNT' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'PTYCNT'\"
else
echo shar: Extracting \"'PTYCNT'\" \(131 characters\)
sed "s/^X//" >'PTYCNT' <<'END_OF_FILE'
X/* be careful; this file is read and used by the INSTALL script */
X#define PTYCNT 32
X#define MASTERMINOR 128
X#define MASTERBIT 128
END_OF_FILE
if test 131 -ne `wc -c <'PTYCNT'`; then
echo shar: \"'PTYCNT'\" unpacked with wrong size!
fi
# end of 'PTYCNT'
fi
if test -f 'README.SCO' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'README.SCO'\"
else
echo shar: Extracting \"'README.SCO'\" \(1521 characters\)
sed "s/^X//" >'README.SCO' <<'END_OF_FILE'
XPublic domain pty driver originally written by:
X
XCopyright (c) 1987, Jens-Uwe Mager, FOCUS Computer GmbH
X
XMods (for 3b1) by:
X
X 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 at ms.uky.edu, eric at ms.uky.csnet, !cbosgd!ukma!eric
X
X Also modified by:
X Mike "Ford" Ditto
X Chief Executive Hacker, Omnicron Data Systems
X P.O. Box 1721
X Bonita, CA 92002
X (619) 421-1055
X kenobi!ford at crash.CTS.COM, ...!crash!kenobi!ford
X
X Modifications for SCO XENIX {2,3}86 by:
X Keith Gabryelski
X UUCP: {cbosgd, hplabs!hp-sdd, sdcsvax, nosc}!crash!portnoy!ag
X INET: ag at portnoy.cts.com
X ARPA: crash!portnoy!ag at nosc.mil
X
X Further modifications to Xenix installation by:
X Chip Salzenberg
X A T Engineering
X <chip at ateng.com> or <uunet!ateng!chip>
X
X
XPick a directory for this software to reside. Mine was /usr/sys/conf/pty.
Xuntar and uncompress (if need be) and look at the Makefile. Uncomment
Xthe definition of FOR286 if you are using a 286 machine.
X
X make
X
XIf that worked, try:
X
X make install
X
XThen, if that worked, follow the displayed directions. When you reboot your
Xmachine, you should have pty's.
X
XTo test:
X compile emacs with:
X
X #define FIRST_PTY_LETTER 'p'
X #define HAVE_PTYS
X #define subprocesses
X
X and try:
X M-x shell
X
X When you get a shell prompt try:
X tty (and)
X stty -a
X
X You should be on a tty named "ttyp0" or something real similar.
X
XOr:
X cat /dev/ttyp0 &
X date > /dev/ptyp0
X
X (This should print the date)
X
XPax, Keith
END_OF_FILE
if test 1521 -ne `wc -c <'README.SCO'`; then
echo shar: \"'README.SCO'\" unpacked with wrong size!
fi
# end of 'README.SCO'
fi
if test -f 'pty.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'pty.c'\"
else
echo shar: Extracting \"'pty.c'\" \(12061 characters\)
sed "s/^X//" >'pty.c' <<'END_OF_FILE'
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 at ms.uky.edu, eric at ms.uky.csnet, !cbosgd!ukma!eric
X *
X * Further modified and improved by:
X * Mike "Ford" Ditto
X * Chief Executive Hacker, Omnicron Data Systems
X * kenobi!ford at crash.CTS.COM, ...!crash!kenobi!ford
X *
X * See README.3b1 for details of port and installation.
X */
X
X/*
X * Yet more geefing done by:
X * Keith M. Gabryelski
X * Random
X * ...crash!portnoy!ag, ag at portnoy.cts.com
X *
X * See README.SCO for detials of port and installation.
X */
X /* XON, XOFF control flow added by Bob Best (bob at dhw68k.cts.com)
X 6/13/88
X*/
X
X/* The UnixPC does not have any extra bits in t_state, thus
X * we provide other means of storing the state.
X */
X#define MRWAIT 0x01 /* master waiting in read */
X#define t_rloc t_cc[0] /* wchannel for MRWAIT */
X#define MWWAIT 0x02 /* master waiting in write */
X#define t_wloc t_cc[1] /* wchannel for MWWAIT */
X#define MOPEN 0x04 /* master is open */
X#define SOPEN 0x08 /* slave is open */
X
X#define KERNEL 1
X#define defined_io 1
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/page.h" /* structure defs --kmg */
X#include "sys/dir.h" /* structure defs --kmg */
X#include "sys/seg.h" /* structure defs --kmg */
X#include "sys/proc.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" /* included in sys/tty.h --kmg */
X#include "sys/ttold.h"
X
X#define eprintf printf /* So what do ya want, whicker? */
X
X#include "PTYCNT" /* find out about PTYCNT and MASTERMINOR */
X
X/* PTYCNT is the maximum number of master/slave pairs that will work */
X#ifndef PTYCNT
X#define PTYCNT 32
X#endif
X
X/* MASTERMINOR is the lowest minor device number for master devices */
X#ifndef MASTERMINOR
X#define MASTERMINOR ((minor(0xFFFF)+1)/2)
X#endif
X
X/* This macro is true if the device number passed corresponds to */
X/* the MASTER side of a pty */
X#ifdef MASTERBIT
X#define Master(dev) ((dev)&MASTERBIT)
X#else
X#define Master(dev) (minor((dev)) >= MASTERMINOR)
X#endif MASTERBIT
X
X/* The tty structures must be local to this driver, since there
X * is no conf.c
X */
X
Xstruct tty pty_tty[PTYCNT];
Xint ptystate[PTYCNT];
X
Xint ptsproc();
X
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)) {
X# ifdef DEBUG
X eprintf("pty: open(master): \n");
X# endif
X dev -= MASTERMINOR;
X tp = &pty_tty[dev];
X if (dev >= PTYCNT) {
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 ptystate[dev] |= MOPEN;
X tp->t_state |= CARR_ON;
X if (tp->t_state & WOPEN)
X {
X tp->t_state &= ~WOPEN;
X wakeup((caddr_t)&tp->t_canq);
X }
X } else {
X# ifdef DEBUG
X eprintf("pty: open(slave): \n");
X# endif
X tp = &pty_tty[dev];
X if (dev >= PTYCNT) {
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 (!(flag & FNDELAY)) {
X while ((tp->t_state & CARR_ON) == 0) {
X /* eprintf("slave_open going to sleep!"); */
X tp->t_state |= WOPEN;
X if (sleep((caddr_t)&tp->t_canq, TTIPRI|PCATCH)) {
X tp->t_state &= ~WOPEN;
X wakeup((caddr_t)&tp->t_canq);
X /* eprintf("slave open: interrupted"); */
X u.u_error = EINTR;
X return;
X }
X /* eprintf("slave_open woke up! %x %x",
X tp->t_state, u.u_procp->p_sig); */
X }
X }
X ptystate[dev] |= SOPEN;
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)) {
X# ifdef DEBUG
X eprintf("pty: close(master): \n");
X# endif
X dev -= MASTERMINOR;
X tp = &pty_tty[dev];
X if (!(ptystate[dev] & SOPEN)) {
X tp->t_tbuf.c_size -= tp->t_tbuf.c_count;
X tp->t_tbuf.c_count = 0;
X tp->t_rbuf.c_size -= tp->t_rbuf.c_count;
X tp->t_rbuf.c_count = 0;
X (*linesw[tp->t_line].l_close)(tp);
X } else {
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("pty: close(slave): \n");
X# endif
X tp = &pty_tty[dev];
X if (!(ptystate[dev] & MOPEN)) {
X tp->t_tbuf.c_size -= tp->t_tbuf.c_count;
X tp->t_tbuf.c_count = 0;
X tp->t_rbuf.c_size -= tp->t_rbuf.c_count;
X tp->t_rbuf.c_count = 0;
X (*linesw[tp->t_line].l_close)(tp);
X }
X ptystate[dev] &= ~SOPEN;
X if (ptystate[dev] & MRWAIT)
X {
X ptystate[dev] &= ~MRWAIT;
X wakeup((caddr_t)&tp->t_rloc);
X }
X if (ptystate[dev] & MWWAIT)
X {
X ptystate[dev] &= ~MRWAIT;
X wakeup((caddr_t)&tp->t_wloc);
X }
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)) {
X int didsome=0;
X# ifdef DEBUG
X eprintf("pty: read(master): \n");
X# endif
X dev -= MASTERMINOR;
X tp = &pty_tty[dev];
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 (didsome)
X break;
X if ((ptystate[dev] & SOPEN) == 0) {
X u.u_error = EIO;
X return;
X }
X if (u.u_fmode & FNDELAY)
X break;
X# ifdef DEBUG
X eprintf("pty: 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("pty: 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("pty: read(master): got some stuff\n");
X# endif
X ++didsome;
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("pty: read(slave): \n");
X# endif
X tp = &pty_tty[dev];
X# ifdef DEBUG
X eprintf("pty: 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 int flg;
X
X dev = minor(dev);
X if (Master(dev)) {
X# ifdef DEBUG
X eprintf("pty: write(master): \n");
X# endif
X dev -= MASTERMINOR;
X tp = &pty_tty[dev];
X while (u.u_count) {
X if ((tp->t_state & TBLOCK)
X || tp->t_rbuf.c_ptr == NULL) {
X if ((ptystate[dev] & SOPEN) == 0) {
X u.u_error = EIO;
X return;
X }
X if (u.u_fmode & FNDELAY)
X break;
X ptystate[dev] |= MWWAIT;
X# ifdef DEBUG
X eprintf("pty: write(master): going to sleep\n");
X# endif
X
X sleep((caddr_t)&tp->t_wloc, TTOPRI);
X
X# ifdef DEBUG
X eprintf("pty: 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("pty: write(master): sending some stuff\n");
X# endif
X flg=tp->t_iflag;
X if(flg & IXON) {
X char ctmp;
X copyin(u.u_base, &ctmp, 1);
X ctmp &= 0177;
X if(tp->t_state & TTSTOP) {
X if(ctmp==CSTART || flg & IXANY)
X (*tp->t_proc)(tp,T_RESUME);
X } else if(ctmp==CSTOP) {
X (*tp->t_proc)(tp,T_SUSPEND);
X }
X if(ctmp==CSTART || ctmp==CSTOP) {
X u.u_base++;
X u.u_count--;
X continue;
X }
X }
X if (copyin(u.u_base,tp->t_rbuf.c_ptr, 1)) {
X u.u_error = EFAULT;
X break;
X }
X tp->t_rbuf.c_count--;
X u.u_base++;
X u.u_count--;
X }
X (*linesw[tp->t_line].l_input)(tp);
X }
X } else {
X# ifdef DEBUG
X eprintf("pty: write(slave): \n");
X# endif
X tp = &pty_tty[dev];
X# ifdef DEBUG
X eprintf("pty: 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)) {
X# ifdef DEBUG
X eprintf("pty: ioctl(master): \n");
X# endif
X dev -= MASTERMINOR;
X tp = &pty_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 == 0) { /* 0 was NULL
X --kmg */
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 } else
X u.u_error = EINVAL;
X } else {
X# ifdef DEBUG
X eprintf("pty: ioctl(slave): \n");
X# endif
X tp = &pty_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("pty: ptsproc: T_TIME:\n");
X# endif
X tp->t_state &= ~TIMEOUT;
X goto start;
X case T_WFLUSH:
X# ifdef DEBUG
X eprintf("pty: 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("pty: ptsproc: T_RESUME:\n");
X# endif
X tp->t_state &= ~TTSTOP;
X /* fall through */
X case T_OUTPUT:
Xstart:
X# ifdef DEBUG
X eprintf("pty: ptsproc: T_OUTPUT:\n");
X# endif
X if (tp->t_state & (TTSTOP|TIMEOUT))
X break;
X# ifdef DEBUG
X eprintf("pty: 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("pty: 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-pty_tty] & MRWAIT)) {
X# ifdef DEBUG
X eprintf("pty: ptsproc: T_OUTPUT: waking up master\n");
X# endif
X ptystate[tp-pty_tty] &= ~MRWAIT;
X wakeup((caddr_t)&tp->t_rloc);
X }
X# ifdef DEBUG
X eprintf("pty: ptsproc: T_OUTPUT: leaving end\n");
X# endif
X break;
X case T_SUSPEND:
X# ifdef DEBUG
X eprintf("pty: ptsproc: T_SUSPEND:\n");
X# endif
X tp->t_state |= TTSTOP;
X break;
X case T_BLOCK:
X# ifdef DEBUG
X eprintf("pty: 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("pty: 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("pty: 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("pty: ptsproc: T_UNBLOCK:\n");
X# endif
X tp->t_state &= ~(TTXOFF|TBLOCK);
X /* fall through */
X case T_INPUT:
X# ifdef DEBUG
X eprintf("pty: ptsproc: T_INPUT:\n");
X# endif
X if (ptystate[tp-pty_tty] & MWWAIT) {
X ptystate[tp-pty_tty] &= ~MWWAIT;
X# ifdef DEBUG
X eprintf("pty: 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("pty: ptsproc: default:\n");
X# else
X ;
X# endif
X }
X}
X
X/* PTYRELEASE is a 3b1ism.
X *
X * ptyrelease()
X * {
X * register i;
X * # ifdef DEBUG
X * eprintf("pty: ptyrelease:\n");
X * # endif
X * for ( i=0 ; i<PTYCNT ; ++i )
X * if ( (ptystate[i] & (SOPEN|MOPEN))
X * || (pty_tty[i].t_state & WOPEN) )
X * {
X * u.u_error = EBUSY;
X * return;
X * }
X * return;
X * }
X */
END_OF_FILE
if test 12061 -ne `wc -c <'pty.c'`; then
echo shar: \"'pty.c'\" unpacked with wrong size!
fi
# end of 'pty.c'
fi
echo shar: End of shell archive.
exit 0
More information about the Comp.sources.misc
mailing list