[comp.os.os9] PTY Filemanager sources - part 2/2

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      |