mellin@lan.informatik.tu-muenchen.dbp.de (Reiner Mellin) (09/04/89)
#! /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 archive 2 (of 2)."
# Contents: funcs.c ptyman.c
# Wrapped by ram@ramsys on Mon Sep 4 13:17:20 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'funcs.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'funcs.c'\"
else
echo shar: Extracting \"'funcs.c'\" \(17169 characters\)
sed "s/^X//" >'funcs.c' <<'END_OF_FILE'
X/* This software is copyright (C) 1989 by Reimer Mellin *
X* *
X* Permission is granted to reproduce and distribute *
X* this package by any means so long as no fee is charged *
X* above a nominal handling fee and so long as this *
X* notice is always included in the copies. *
X* Commerical use or incorporation into commercial software *
X* is prohibited without the written permission of the *
X* author. *
X* *
X* Other rights are reserved except as explicitly granted *
X* by written permission of the author. *
X* Reimer Mellin *
X* *
X* Sulenstr.8 *
X* D-8000 Muenchen 71 (Federal Republic of Germany) *
X* *
X* EMAIL: *
X* mellin@lan.informatik.tu-muenchen.dbp.de *
X* ram@altger.UUCP *
X* ....!pyramid!tmpmbx!doitcr!ramsys!ram (home) *
X* */
X/* */
X
X/*
X * Funcs.c : Unterfunktionen zum Pty-FileManager.
X *
X * $Header: /h0/USR/REIMER/PTYMAN/RCS/funcs.c_v 1.2.1.2 89/09/04 13:12:41 ram Exp $
X *
X * $Log: funcs.c_v $
X * Revision 1.2.1.2 89/09/04 13:12:41 ram
X * added some comments
X *
X * Revision 1.2.1.1 89/08/31 12:24:51 ram
X * negative Read/Write Counts are made positive
X *
X * Revision 1.2 89/07/16 01:04:51 ram
X * minor changes to Sub-net release
X *
X * Revision 1.1.1.1 89/07/14 19:48:36 ram
X * Fixed: kbich, kbach. Sub-net Beta-Release
X *
X * Revision 1.1 89/07/13 23:21:10 ram
X * Initial revision
X *
X */
X
X#include <types.h>
X#include <MACHINE/reg.h>
X#include "ptyman.h"
X#include <path.h>
X#include <sg_codes.h>
X#include <procid.h>
X#include <signal.h>
X#include <modes.h>
X#include <errno.h>
X
X#include "misc.h"
X
Xextern union pathdesc pd;
X
Xextern u_char *_srqmem();
Xextern void _srtmem();
Xextern void iowait();
Xextern void kill();
Xextern int getctrlchar();
X
Xextern int tsleep();
X
Xint
Xhangup(procdesc)
Xregister procid *procdesc;
X{
X /* TRUE:
X * - pty-typ is a tty
X * - and correspondent pty has gone
X * Action: send a SIGHUP, if conection was severed by server
X */
X
X if(pd.ptypvt.pd_typ == TTY && pd.ptypvt.pd_pty == (union pathdesc *) 0) {
X errno = E_HANGUP;
X kill( procdesc->_id, (pd.ptypvt.pd_esig ?
X pd.ptypvt.pd_esig : SIGHUP));
X return TRUE;
X }
X return FALSE;
X}
X
Xint inline
Xdosleep( procdesc )
Xregister procid *procdesc;
X{
X /*
X * 0: - if wakedup by SIGWAKE
X * -1: - if signal is < 32 ( ENOENT ) orseq process has been aborted
X * 0: - other
X */
X
X if( tsleep(0) == 0 && procdesc->_signal == 0)
X return 0;
X if( (errno = procdesc->_signal) < 32 || procdesc->_state & P_CONDEMNED)
X return -1;
X return 0;
X}
X
X/*
X * Falls Echo angeschaltet ist, schreibe einen Charakter in den Echobuffer
X * 1: - falls echo ausgeschaltet ist oder echo erfolgreich
X * -1: - Fehler bei Ausgabe (z.b. Prozess aborted)
X */
Xint
Xechochar( ch, buf, procdesc)
Xregister u_char ch;
Xregister struct ptybuf *buf;
X procid *procdesc;
X{ register int rv;
X
X /*
X * if echo is off, return success
X */
X if( pd.ptyopt.pd_eko == '\0')
X return(1);
X
X /*
X * wait for other I/O, and register for SIGINT,SIGQUIT
X */
X iowait( buf->wpid);
X buf->wsig = SIGWAKE;
X buf->lpd = &pd;
X
X /*
X * my standard output-loop
X */
X while( buf->wptr >= (buf->buf + buf->size)) {
X WAKE(buf->rpid, buf->rsig);
X buf->wpid = procdesc->_id;
X do {
X if( dosleep(procdesc) < 0) {
X rv = -1;
X goto outloop;
X }
X } while( buf->wpid);
X }
X *(buf->wptr)++ = ch;
X rv = 1;
Xoutloop:
X buf->wpid = 0;
X if( buf->wptr > buf->rptr)
X WAKE(buf->rpid, buf->rsig);
X return( rv );
X}
X
X/*
X * Lese cnt-Bytes im Raw-modus ein. Kein Echo, Lineediting etc....
X * 0: - cnt-bytes gelesen
X * x: - (cnt-x) bytes gelesen
X * -x: - nach (cnt-x) ist Fehler aufgetreten (Interupted, Hangup etc.)
X */
Xint
Xcpinraw(buf, echobuf, ustack, procdesc)
Xregister struct ptybuf *buf;
Xregister struct ptybuf *echobuf;
X REGISTERS *ustack;
X procid *procdesc;
X{ register int cnt = ustack->d[1] & 0x7fffffff; /* no neg. counts */
X register u_char *dest = (u_char *) ustack->a[0];
X
X /*
X * this can only happen if _ss_sign() was set
X */
X if( buf->rpid == procdesc->_id) {
X errno = E_NOTRDY;
X return -cnt;
X }
X
X iowait( buf->rpid);
X buf->rsig = SIGWAKE;
X
X for(; cnt > 0; --cnt) {
X while( buf->rptr >= buf->wptr ) {
X buf->wptr = buf->rptr = buf->buf;
X WAKE(buf->wpid, buf->wsig);
X buf->rpid = procdesc->_id;
X do {
X if( dosleep(procdesc) < 0) {
X cnt = -cnt;
X goto outloop;
X }
X } while ( buf->rpid);
X }
X /*
X * in read, one has still to check for SIGQUIT etc..
X * the signal is sent by the writing-process
X */
X switch( getctrlchar( *dest++ = *(buf->rptr)++)) {
X case INT:
X errno = SIGINT;
X cnt = - (--cnt);
X goto outloop;
X
X case QUT:
X errno = SIGQUIT;
X cnt = - (--cnt);
X goto outloop;
X
X case EOR:
X pd.ptypvt.pd_line = 0;
X break;
X }
X }
Xoutloop:
X if(buf->rptr >= buf->wptr ) {
X buf->wptr = buf->rptr = buf->buf;
X WAKE(buf->wpid, buf->wsig);
X }
X buf->rpid = 0;
X return( cnt);
X}
X
X/*
X * Lese cnt-Bytes. Echo, Lineediting, vorzeitiger Abbruch bei Lesen von CR
X * 0: - cnt-bytes gelesen
X * x: - (cnt-x) bytes gelesen
X * -x: - nach (cnt-x) ist Fehler aufgetreten (Interupted, Hangup etc.)
X */
Xint
Xcpin(buf, echobuf, ustack, procdesc)
Xregister struct ptybuf *buf;
X struct ptybuf *echobuf;
X REGISTERS *ustack;
X procid *procdesc;
X{ register int cnt = ustack->d[1] & 0x7fffffff; /* no neg. counts */
X register u_char *dest = (u_char *) ustack->a[0];
X register u_char *old = pd.path.pd_buf;
X register u_char ch;
X
X /*
X * this can only happen if _ss_sign() was set
X */
X if( buf->rpid == procdesc->_id) {
X errno = E_NOTRDY;
X return -cnt;
X }
X
X iowait( buf->rpid);
X buf->rsig = SIGWAKE;
X
X for(; cnt > 0; --cnt) {
X while( buf->rptr >= buf->wptr ) {
X buf->wptr = buf->rptr = buf->buf;
X WAKE(buf->wpid, buf->wsig);
X buf->rpid = procdesc->_id;
X do {
X if( dosleep(procdesc) < 0) {
X cnt = -cnt;
X goto outloop;
X }
X } while( buf->rpid);
X }
X ch = (pd.ptyopt.pd_upc ? upchar(*(buf->rptr)++) : *(buf->rptr)++);
X switch( getctrlchar(ch) ) {
X case BSP:
X /*
X * look in the Tech. manual to see what is meant here
X */
X if( ( pd.ptyopt.pd_bso ?
X (echochar( pd.ptyopt.pd_bse, echobuf, procdesc) +
X echochar( ' ' ,echobuf, procdesc) +
X echochar( pd.ptyopt.pd_bse, echobuf, procdesc) < 3) :
X (echochar( pd.ptyopt.pd_bse, echobuf, procdesc) < 1))) {
X cnt = -cnt;
X goto outloop;
X }
X dest--; old--;
X dest = MAX( (dest), ((u_char *) ustack->a[0]));
X old = MAX( (old ), pd.path.pd_buf);
X if( cnt == ustack->d[1] )
X cnt = ustack->d[1]+1;
X else
X cnt += 2;
X break;
X
X case EOR:
X /*
X * EOR resets pd_line and finishes
X */
X pd.ptypvt.pd_line = 0;
X *old++ = *dest++ = ch;
X if( ( echochar( ch, echobuf, procdesc) < 0
X || ( pd.ptyopt.pd_alf && echochar( '\l', echobuf, procdesc) < 0))) {
X cnt = -cnt;
X goto outloop;
X }
X cnt--;
X goto outloop;
X
X case INT:
X *old = *dest = errno = SIGINT;
X cnt = - (--cnt);
X goto outloop;
X
X case QUT:
X *old = *dest = errno = SIGQUIT;
X cnt = - (--cnt);
X goto outloop;
X
X case EOF:
X /*
X * EOF only as first character !
X */
X if( old == pd.path.pd_buf) {
X errno = E_EOF;
X cnt = -cnt;
X goto outloop;
X }
X
X case DEL:
X if( pd.ptyopt.pd_dlo != '\0' ) {
X for(; old > pd.path.pd_buf; --old,cnt++)
X if( ( pd.ptyopt.pd_bso ?
X (echochar( pd.ptyopt.pd_bse, echobuf, procdesc) +
X echochar( ' ' ,echobuf, procdesc) +
X echochar( pd.ptyopt.pd_bse, echobuf, procdesc) < 3) :
X (echochar( pd.ptyopt.pd_bse, echobuf, procdesc) < 1))) {
X cnt = -cnt;
X goto outloop;
X }
X }
X else
X if( (echochar( pd.ptyopt.pd_eor, echobuf, procdesc)
X + echochar( '\l', echobuf, procdesc) < 2)) {
X cnt = -cnt;
X goto outloop;
X }
X dest = (u_char *) ustack->a[0];
X old = pd.path.pd_buf;
X cnt = ustack->d[1]+1;
X break;
X
X case DUP:
X for(; cnt > 0 ; --cnt) {
X if((ch = *dest++ = *old++) == pd.ptyopt.pd_eor &&
X pd.ptyopt.pd_eor) {
X dest--; old--;
X break;
X }
X if( echochar( (ch < ' ' ? '.': ch), echobuf, procdesc) < 0) {
X cnt = - (--cnt);
X goto outloop;
X }
X }
X break;
X
X case RPR:
X *old = *dest = pd.ptyopt.pd_eor;
X if(( echochar( *old, echobuf, procdesc) < 0
X || ( pd.ptyopt.pd_alf && echochar( '\l', echobuf, procdesc) < 0))) {
X cnt = -cnt;
X goto outloop;
X }
X {
X register u_char *tmp = pd.path.pd_buf;
X
X for(; tmp < old; tmp++)
X if( echochar( *tmp, echobuf, procdesc) < 0) {
X cnt = - cnt;
X goto outloop;
X }
X }
X break;
X
X case PSC:
X /*
X * not supported
X */
X default:
X *old++ = *dest++ = ch;
X if( echochar( (ch < ' ' ? '.': ch)
X , echobuf, procdesc) < 0) {
X cnt = - (--cnt);
X goto outloop;
X }
X }
X }
Xoutloop:
X buf->rpid = 0;
X if( buf->rptr >= buf->wptr ) {
X buf->wptr = buf->rptr = buf->buf;
X WAKE(buf->wpid, buf->wsig);
X }
X return( cnt);
X}
X
X/*
X * Schreibe cnt-Bytes im Raw-modus. Kein Alf etc....
X * 0: - cnt-bytes geschrieben
X * x: - (cnt-x) bytes geschrieben
X * -x: - nach (cnt-x) ist Fehler aufgetreten (Interupted, Hangup etc.)
X */
Xint
Xcpoutraw(buf, echobuf, ustack, procdesc)
Xregister struct ptybuf *buf;
Xregister struct ptybuf *echobuf;
X REGISTERS *ustack;
X procid *procdesc;
X{ register int cnt = ustack->d[1] & 0x7fffffff;
X register u_char *src = (u_char *) ustack->a[0];
X register u_char ch;
X register u_int bufend = (u_int) buf->buf + buf->size;
X
X iowait( buf->wpid);
X buf->wsig = SIGWAKE;
X buf->lpd = &pd;
X
X for(; cnt > 0; --cnt) {
X while( buf->wptr >= (u_char *) bufend) {
X WAKE(buf->rpid, buf->rsig);
X buf->wpid = procdesc->_id;
X do {
X if( dosleep(procdesc) < 0) {
X cnt = -cnt;
X goto outloop;
X }
X } while( buf->wpid);
X }
X ch = *(buf->wptr)++ = *src++;
X if( ch && echobuf->lpd ) {
X /*
X * here the INT and QUIT signals are sent
X */
X if( echobuf->lpd->ptyopt.pd_int == ch)
X kill(echobuf->lpd->path.pd_lproc,SIGINT);
X if( echobuf->lpd->ptyopt.pd_qut == ch)
X kill(echobuf->lpd->path.pd_lproc,SIGQUIT);
X }
X }
Xoutloop:
X buf->wpid = 0;
X if( buf->wptr > buf->rptr)
X WAKE(buf->rpid, buf->rsig);
X return( cnt);
X}
X
X/*
X * Schreibe cnt-Bytes. Alf, Tab-expanding, Pause-behandlung, Abbruch bei
X * vorzeitigem CR
X * 0: - cnt-bytes geschrieben
X * x: - (cnt-x) bytes geschrieben
X * -x: - nach (cnt-x) ist Fehler aufgetreten (Interupted, Hangup etc.)
X */
Xint
Xcpout(buf, echobuf, ustack, procdesc)
Xregister struct ptybuf *buf;
Xregister struct ptybuf *echobuf;
X REGISTERS *ustack;
X procid *procdesc;
X{ register int cnt = ustack->d[1] & 0x7fffffff;
X register u_char *src = (u_char *) ustack->a[0];
X register u_char ch;
X register u_int bufend = (u_int) buf->buf + buf->size;
X
X iowait( buf->wpid );
X buf->wsig = SIGWAKE;
X buf->lpd = &pd;
X
X for(; cnt > 0; --cnt) {
X while( buf->wptr >= (u_char *) bufend) {
X WAKE(buf->rpid, buf->rsig);
X buf->wpid = procdesc->_id;
X do {
X if( dosleep(procdesc) < 0) {
X cnt = -cnt;
X goto outloop;
X }
X } while( buf->wpid);
X }
X pd.ptyopt.pd_Col++;
X ch = *(buf->wptr)++ = (pd.ptyopt.pd_upc ? upchar(*src++) : *src++);
X /*
X * QUIT and INT signals to last writing device
X */
X if( ch && echobuf->lpd ) {
X if( echobuf->lpd->ptyopt.pd_int == ch)
X kill(echobuf->lpd->path.pd_lproc,SIGINT);
X if( echobuf->lpd->ptyopt.pd_qut == ch)
X kill(echobuf->lpd->path.pd_lproc,SIGQUIT);
X }
X if( ch && ch == pd.ptyopt.pd_eor ) {
X pd.ptyopt.pd_Col = 0;
X if( pd.ptyopt.pd_pau && ++pd.ptypvt.pd_line == pd.ptyopt.pd_pag ) {
X pd.ptypvt.pd_line = 0;
X iowait( echobuf->rpid);
X WAKE(echobuf->wpid, echobuf->wsig);
X echobuf->rpid = procdesc->_id;
X do {
X if( dosleep(procdesc) < 0) {
X cnt = -cnt;
X goto outloop;
X }
X } while( echobuf->rpid);
X echobuf->rptr++;
X }
X if( pd.ptyopt.pd_alf ) {
X if( buf->wptr >= (buf->buf + buf->size)) {
X WAKE(buf->rpid, buf->rsig);
X buf->wpid = procdesc->_id;
X do {
X if( dosleep(procdesc) < 0) {
X cnt = -cnt;
X goto outloop;
X }
X } while( buf->wpid);
X }
X *(buf->wptr)++ = '\l';
X }
X --cnt;
X break;
X } else
X if( pd.ptyopt.pd_Tabs && pd.ptyopt.pd_Tab && ch == pd.ptyopt.pd_Tab) {
X register short i = (pd.ptyopt.pd_Col-1) % pd.ptyopt.pd_Tabs;
X *(buf->wptr - 1) = ' ';
X for(; i > 0; i--) {
X while( buf->wptr >= (buf->buf + buf->size)) {
X WAKE(buf->rpid, buf->rsig);
X buf->wpid = procdesc->_id;
X do {
X if( dosleep(procdesc) < 0) {
X cnt = -cnt;
X goto outloop;
X }
X } while( buf->wpid);
X }
X *(buf->wptr)++ = ' ';
X }
X
X }
X }
Xoutloop:
X buf->wpid = 0;
X if( buf->wptr > buf->rptr)
X WAKE(buf->rpid, buf->rsig);
X return( cnt);
X}
END_OF_FILE
if test 17169 -ne `wc -c <'funcs.c'`; then
echo shar: \"'funcs.c'\" unpacked with wrong size!
fi
# end of 'funcs.c'
fi
if test -f 'ptyman.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'ptyman.c'\"
else
echo shar: Extracting \"'ptyman.c'\" \(13417 characters\)
sed "s/^X//" >'ptyman.c' <<'END_OF_FILE'
X/* This software is copyright (C) 1989 by Reimer Mellin *
X* *
X* Permission is granted to reproduce and distribute *
X* this package by any means so long as no fee is charged *
X* above a nominal handling fee and so long as this *
X* notice is always included in the copies. *
X* Commerical use or incorporation into commercial software *
X* is prohibited without the written permission of the *
X* author. *
X* *
X* Other rights are reserved except as explicitly granted *
X* by written permission of the author. *
X* Reimer Mellin *
X* *
X* Sulenstr.8 *
X* D-8000 Muenchen 71 (Federal Republic of Germany) *
X* *
X* EMAIL: *
X* mellin@lan.informatik.tu-muenchen.dbp.de *
X* ram@altger.UUCP *
X* ....!pyramid!tmpmbx!doitcr!ramsys!ram (home) *
X* */
X
X/* */
X
X/*
X * HauptModul des PtyManagers -- Einsprung-Routinen vom Assembler-Interface
X *
X * $Header: /h0/USR/REIMER/PTYMAN/RCS/ptyman.c_v 1.2.1.2 89/09/04 13:14:23 ram Exp $
X *
X * $Log: ptyman.c_v $
X * Revision 1.2.1.2 89/09/04 13:14:23 ram
X * added some comments
X *
X * Revision 1.2.1.1 89/08/31 12:26:06 ram
X * Copyright-message added
X *
X * Revision 1.2 89/07/16 01:06:12 ram
X * minor changes to Sub-net Release
X *
X * Revision 1.1.1.1 89/07/14 19:49:56 ram
X * Fixed: SS_SSig Bug. Sub-Net Beta-Release
X *
X * Revision 1.1 89/07/13 23:22:15 ram
X * Initial revision
X *
X */
X
X#include <types.h>
X#include <MACHINE/reg.h>
X#include "Ptyman.h"
X#include <path.h>
X#include <sg_codes.h>
X#include <procid.h>
X#include <modes.h>
X#include <sgstat.h>
X#include <setsys.h>
X#include <signal.h>
X#include <errno.h>
X
X#ifdef ST
X#include <stconfuncs.h>
X#endif
X
X#include "misc.h"
X
Xunion pathdesc pd; /* a6 points to the Path-Descriptor !!! */
X
Xextern int _prsnam();
X
Xextern int strcmp();
Xextern void memcpy();
Xextern void initbuf();
Xextern void kill();
X
Xextern int dosleep();
Xextern int hangup();
Xextern int cpinraw();
Xextern int cpin();
Xextern int cpoutraw();
Xextern int cpout();
X
X/*
X * O P E N
X */
XOpen(procdesc, ustack)
X procid *procdesc;
X REGISTERS *ustack;
X{
X register u_char *name = (u_char *) ustack->a[0];
X register int namcnt,i;
X register Pathdesc ptr;
X
X pd.ptypvt.pd_typ = (name[1] == 'P' || name[1] == 'p') ? PTY : TTY;
X
X if( ( namcnt = _prsnam(name)) < 0)
X return -1;
X if( name[namcnt] != '/') {
X errno = E_BPNAM;
X return -1;
X }
X name += namcnt+1;
X
X if( ( namcnt = _prsnam(name)) < 0 || namcnt > 28 || name[namcnt] != '\0' ) {
X errno = E_BPNAM;
X return -1;
X }
X
X pd.path.pd_mod = (u_char) ustack->d[0];
X
X for(i=0; i < namcnt;i++)
X pd.ptyopt.pd_name[i] = upchar(name[i]);
X pd.ptyopt.pd_namlen = namcnt;
X
X if( pd.ptypvt.pd_typ != PTY) {
X /* tty */
X /* look for correspondent pty in path-list and register, else sleep(0) */
X do {
X ptr = ((Ptystatic) pd.path.pd_dev->V_stat)->v_sysio.v_paths;
X for(; ptr ; ptr = ptr->path.pd_paths)
X if( ptr->ptypvt.pd_typ == PTY && strcmp( ptr->ptyopt.pd_name, pd.ptyopt.pd_name) == 0 ) {
X pd.ptypvt.pd_pty = ptr;
X goto outloop;
X }
X } while ( dosleep(procdesc) == 0);
X return -1;
X } else {
X /* pty */
X /* iff same name exists, exists with error */
X ptr = ((Ptystatic) pd.path.pd_dev->V_stat)->v_sysio.v_paths;
X
X for(; ptr ; ptr = ptr->path.pd_paths)
X if( ptr->ptypvt.pd_typ == PTY && ptr != &pd && strcmp( ptr->ptyopt.pd_name, pd.ptyopt.pd_name) == 0 ) {
X errno = E_SHARE;
X return -1;
X }
X /* set buffersize and allocate them */
X pd.ptypvt.pd_rbuf.size = pd.ptypvt.pd_wbuf.size = DEFBUFSIZE;
X if( (pd.ptypvt.pd_rbuf.buf = (u_char *)_srqmem( (pd.ptypvt.pd_rbuf.size))) == (u_char *)0 ||
X (pd.ptypvt.pd_wbuf.buf = (u_char *)_srqmem( (pd.ptypvt.pd_wbuf.size))) == (u_char *)0 ) {
X if( pd.ptypvt.pd_wbuf.buf )
X (void) _srtmem(pd.ptypvt.pd_wbuf.buf,pd.ptypvt.pd_wbuf.size);
X if( pd.ptypvt.pd_rbuf.buf )
X (void) _srtmem(pd.ptypvt.pd_rbuf.buf,pd.ptypvt.pd_rbuf.size);
X return -1;
X }
X
X pd.ptypvt.pd_rbuf.rptr = pd.ptypvt.pd_rbuf.wptr = pd.ptypvt.pd_rbuf.buf;
X pd.ptypvt.pd_wbuf.rptr = pd.ptypvt.pd_wbuf.wptr = pd.ptypvt.pd_wbuf.buf;
X
X ptr = ((Ptystatic) pd.path.pd_dev->V_stat)->v_sysio.v_paths;
X /* look for a sleeping tty -- and wake it up */
X for(; ptr ; ptr = ptr->path.pd_paths)
X if( ptr->ptypvt.pd_typ == TTY && strcmp( ptr->ptyopt.pd_name, pd.ptyopt.pd_name) == 0 ) {
X if( ptr->path.pd_cpr != 0 )
X kill(ptr->path.pd_cpr,
X (ptr->ptypvt.pd_esig ? ptr->ptypvt.pd_esig : SIGWAKE));
X }
X }
Xoutloop:
X return 0;
X}
X
X/*
X * C l o s e
X */
XClose(procdesc, ustack)
X procid *procdesc;
X REGISTERS *ustack;
X{
X register struct ptybuf *bptr;
X
X /* clear _ss_sign() */
X bptr = ( pd.ptypvt.pd_typ == PTY) ? &pd.ptypvt.pd_rbuf : &((pd.ptypvt.pd_pty)->ptypvt.pd_wbuf);
X if( bptr->rpid == procdesc->_id )
X bptr->rpid = 0;
X
X /* deallocate buffer if we are the last incarnation */
X if( pd.path.pd_count == 0 )
X if( pd.ptypvt.pd_typ == PTY ) {
X register Pathdesc ptr = ((Ptystatic) pd.path.pd_dev->V_stat)->v_sysio.v_paths;
X
X /*
X * and send all listening ttys a HUP and mark that the connection is severed
X */
X for(; ptr ; ptr = ptr->path.pd_paths)
X if( ptr->ptypvt.pd_typ == TTY && ptr->ptypvt.pd_pty == &pd ) {
X ptr->ptypvt.pd_pty = (union pathdesc *) 0;
X kill( (ptr->path.pd_cpr ? ptr->path.pd_cpr : ptr->path.pd_lproc)
X ,(ptr->ptypvt.pd_esig ? ptr->ptypvt.pd_esig : SIGHUP));
X }
X (void) _srtmem( pd.ptypvt.pd_rbuf.buf, pd.ptypvt.pd_rbuf.size);
X (void) _srtmem( pd.ptypvt.pd_wbuf.buf, pd.ptypvt.pd_wbuf.size);
X } else {
X if((pd.ptypvt.pd_pty)->ptypvt.pd_rbuf.lpd = &pd)
X (pd.ptypvt.pd_pty)->ptypvt.pd_rbuf.lpd = NULL;
X if( pd.path.pd_buf )
X (void) _srtmem( pd.path.pd_buf, LINEBUFSIZ);
X }
X return(0);
X}
X
XRead(procdesc, ustack)
X procid *procdesc;
X REGISTERS *ustack;
X{
X register int numbytes;
X
X if( hangup(procdesc) )
X return -1;
X
X /*
X * select buffer ...
X */
X if( pd.ptypvt.pd_typ == PTY ) {
X numbytes = cpinraw( &pd.ptypvt.pd_rbuf, &pd.ptypvt.pd_wbuf,
X ustack, procdesc);
X } else {
X numbytes = cpinraw( &((pd.ptypvt.pd_pty)->ptypvt.pd_wbuf),
X &((pd.ptypvt.pd_pty)->ptypvt.pd_rbuf), ustack, procdesc);
X }
X /*
X * a neg. count means an error ....
X */
X if( numbytes < 0) {
X ustack->d[1] += numbytes;
X return -1;
X }
X ustack->d[1] -= numbytes;
X return(0);
X}
X
XReadLn(procdesc, ustack)
X procid *procdesc;
X REGISTERS *ustack;
X{
X register int numbytes;
X
X if( hangup(procdesc) )
X return -1;
X /*
X * the line-editing buffer
X */
X if( pd.path.pd_buf == NULL) {
X if((pd.path.pd_buf = (u_char *) _srqmem(LINEBUFSIZ)) == NULL)
X return(-1);
X else
X initbuf(pd.path.pd_buf, LINEBUFSIZ-1); /* dont change !! */
X }
X
X if( ustack->d[1] > LINEBUFSIZ )
X ustack->d[1] = LINEBUFSIZ;
X
X /*
X * select buffer ...
X */
X if( pd.ptypvt.pd_typ == PTY ) {
X numbytes = cpin( &pd.ptypvt.pd_rbuf, &pd.ptypvt.pd_wbuf,
X ustack, procdesc);
X } else {
X numbytes = cpin( &((pd.ptypvt.pd_pty)->ptypvt.pd_wbuf), &((pd.ptypvt.pd_pty)->ptypvt.pd_rbuf),
X ustack, procdesc);
X }
X /*
X * a neg. count means an error ....
X */
X if( numbytes < 0) {
X ustack->d[1] += numbytes;
X return(-1);
X }
X ustack->d[1] -= numbytes;
X return(0);
X}
X
XWrite(procdesc, ustack)
X procid *procdesc;
X REGISTERS *ustack;
X{
X register int numbytes;
X
X if( hangup(procdesc) )
X return -1;
X
X if( pd.ptypvt.pd_typ == PTY ) {
X numbytes = cpoutraw( &pd.ptypvt.pd_wbuf, &pd.ptypvt.pd_rbuf, ustack, procdesc);
X } else {
X numbytes = cpoutraw( &((pd.ptypvt.pd_pty)->ptypvt.pd_rbuf), &((pd.ptypvt.pd_pty)->ptypvt.pd_wbuf), ustack, procdesc);
X }
X if( numbytes < 0) {
X ustack->d[1] += numbytes;
X return -1;
X }
X ustack->d[1] -= numbytes;
X return(0);
X}
X
XWriteLn(procdesc, ustack)
X procid *procdesc;
X REGISTERS *ustack;
X{
X register int numbytes;
X
X if( hangup(procdesc) )
X return -1;
X
X if( pd.ptypvt.pd_typ == PTY ) {
X numbytes = cpout( &pd.ptypvt.pd_wbuf, &pd.ptypvt.pd_rbuf,
X ustack, procdesc);
X } else {
X numbytes = cpout( &((pd.ptypvt.pd_pty)->ptypvt.pd_rbuf),
X &((pd.ptypvt.pd_pty)->ptypvt.pd_wbuf), ustack, procdesc);
X }
X if( numbytes < 0) {
X ustack->d[1] += numbytes;
X return -1;
X }
X ustack->d[1] -= numbytes;
X return(0);
X}
X
X
X/*
X * G e t S t a t
X */
XGetStat(procdesc, ustack)
X procid *procdesc;
X REGISTERS *ustack;
X{
X register struct ptybuf *ptr;
X
X if( hangup(procdesc) )
X return -1;
X switch (ustack->d[1] & 0x0ffff) {
X
X case SS_DevNm:
X /*
X * returns name of the [pt]ty ...
X */
X memcpy( ustack->a[0], pd.ptyopt.pd_name, pd.ptyopt.pd_namlen);
X *((u_char *) ustack->a[0] + pd.ptyopt.pd_namlen) = '\0';
X break;
X
X case SS_Opt:
X /*
X * copy the option-field
X */
X memcpy( ustack->a[0], &(pd.ptyopt.pd_dtp), OPTMAX);
X break;
X
X case SS_Ready:
X /*
X * return TRUE if number of chars in buffer > 0 ...
X */
X ptr = ( pd.ptypvt.pd_typ == PTY) ? &pd.ptypvt.pd_rbuf : &((pd.ptypvt.pd_pty)->ptypvt.pd_wbuf);
X if((ustack->d[1] = (ptr->wptr - ptr->rptr)) <= 0 ) {
X errno = E_NOTRDY;
X return -1;
X }
X break;
X
X case SS_EOF:
X /*
X * always return 0
X */
X ustack->d[1] = 0;
X break;
X
X case SS_BlkRd:
X /*
X * like a Read
X */
X ustack->d[1] = ustack->d[2];
X return( Read( procdesc, ustack));
X
X default:
X pd.path.pd_errno = E_UNKSVC;
X return(-1);
X }
X return (0);
X}
X
X
X/*
X * S e t S t a t
X */
XSetStat(procdesc, ustack)
X procid *procdesc;
X REGISTERS *ustack;
X{
X register struct ptybuf *ptr;
X
X if( hangup(procdesc) )
X return -1;
X switch (ustack->d[1] & 0x0ffff) {
X
X case SS_Opt:
X /*
X * copy the option-field
X */
X memcpy( &(pd.ptyopt.pd_dtp), ustack->a[0], OPTMAX);
X break;
X
X case SS_SSig:
X /*
X * set ssig, if someother is already waiting --> error
X * if data is already available --> send sig immediatly
X */
X ptr = ( pd.ptypvt.pd_typ == PTY) ? &pd.ptypvt.pd_rbuf : &((pd.ptypvt.pd_pty)->ptypvt.pd_wbuf);
X if( ptr->rpid ) {
X errno = E_NOTRDY;
X return -1;
X }
X if( ((ptr->wptr - ptr->rptr)) <= 0 ) {
X ptr->rpid = procdesc->_id;
X ptr->rsig = ustack->d[2];
X } else kill(procdesc->_id,ustack->d[2]);
X break;
X
X case SS_Relea:
X /*
X * clear _ss_sign()
X */
X ptr = ( pd.ptypvt.pd_typ == PTY) ? &pd.ptypvt.pd_rbuf : &((pd.ptypvt.pd_pty)->ptypvt.pd_wbuf);
X if( ptr->rpid == procdesc->_id)
X ptr->rpid = 0;
X break;
X
X case SS_EnRTS:
X case SS_DsRTS:
X case SS_DCOn:
X break;
X
X case SS_DCOff:
X /*
X * set the pd_esig -- thats all
X */
X if( pd.ptypvt.pd_typ == TTY)
X pd.ptypvt.pd_esig = (u_short) ustack->d[2];
X break;
X
X#ifdef ST
X /*
X * like Blkwr
X */
X case SS_Screen:
X if( ustack->d[2] != ScrOut )
X break;
X ustack->d[2] = ustack->d[3];
X#endif
X
X case SS_BlkWr:
X /*
X * like a Write
X */
X ustack->d[1] = ustack->d[2];
X return( Write( procdesc, ustack));
X
X default:
X pd.path.pd_errno = E_UNKSVC;
X return(-1);
X }
X return (0);
X}
END_OF_FILE
if test 13417 -ne `wc -c <'ptyman.c'`; then
echo shar: \"'ptyman.c'\" unpacked with wrong size!
fi
# end of 'ptyman.c'
fi
echo shar: End of archive 2 \(of 2\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked both archives.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
--
| Reimer Mellin | mellin@lan.informatik.tu-muenchen.dbp.de |
| Sulenstr. 8 | |
| D-8000 Muenchen 71 | Technische Universitaet Muenchen |