home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
DRIVERS
/
SRC
/
ptys.lzh
/
ptyman.c
< prev
next >
Wrap
Text File
|
1990-04-25
|
13KB
|
464 lines
/* This software is copyright (C) 1989 by Reimer Mellin *
* *
* Permission is granted to reproduce and distribute *
* this package by any means so long as no fee is charged *
* above a nominal handling fee and so long as this *
* notice is always included in the copies. *
* Commerical use or incorporation into commercial software *
* is prohibited without the written permission of the *
* author. *
* *
* Other rights are reserved except as explicitly granted *
* by written permission of the author. *
* Reimer Mellin *
* *
* Sulenstr.8 *
* D-8000 Muenchen 71 (Federal Republic of Germany) *
* *
* EMAIL: *
* mellin@lan.informatik.tu-muenchen.dbp.de *
* ram@altger.UUCP *
* ....!pyramid!tmpmbx!doitcr!ramsys!ram (home) *
* */
/* */
/*
* HauptModul des PtyManagers -- Einsprung-Routinen vom Assembler-Interface
*
* $Header: /h0/USR/REIMER/PTYMAN/RCS/ptyman.c_v 1.2.1.2 89/09/04 13:14:23 ram Exp $
*
* $Log: ptyman.c_v $
* Revision 1.2.1.2 89/09/04 13:14:23 ram
* added some comments
*
* Revision 1.2.1.1 89/08/31 12:26:06 ram
* Copyright-message added
*
* Revision 1.2 89/07/16 01:06:12 ram
* minor changes to Sub-net Release
*
* Revision 1.1.1.1 89/07/14 19:49:56 ram
* Fixed: SS_SSig Bug. Sub-Net Beta-Release
*
* Revision 1.1 89/07/13 23:22:15 ram
* Initial revision
*
*/
#include <types.h>
#include <reg.h>
#include "Ptyman.h"
#include <path.h>
#include <sg_codes.h>
#include <procid.h>
#include <modes.h>
#include <sgstat.h>
#include <setsys.h>
#include <signal.h>
#include <errno.h>
#ifdef ST
#include <stconfuncs.h>
#endif
#include "misc.h"
union pathdesc pd; /* a6 points to the Path-Descriptor !!! */
extern int _prsnam();
extern int strcmp();
extern void memcpy();
extern void initbuf();
extern void kill();
extern int dosleep();
extern int hangup();
extern int cpinraw();
extern int cpin();
extern int cpoutraw();
extern int cpout();
/*
* O P E N
*/
Open(procdesc, ustack)
procid *procdesc;
REGISTERS *ustack;
{
register u_char *name = (u_char *) ustack->a[0];
register int namcnt,i;
register Pathdesc ptr;
pd.ptypvt.pd_typ = (name[1] == 'P' || name[1] == 'p') ? PTY : TTY;
if( ( namcnt = _prsnam(name)) < 0)
return -1;
if( name[namcnt] != '/') {
errno = E_BPNAM;
return -1;
}
name += namcnt+1;
if( ( namcnt = _prsnam(name)) < 0 || namcnt > 28 || name[namcnt] != '\0' ) {
errno = E_BPNAM;
return -1;
}
pd.path.pd_mod = (u_char) ustack->d[0];
for(i=0; i < namcnt;i++)
pd.ptyopt.pd_name[i] = upchar(name[i]);
pd.ptyopt.pd_namlen = namcnt;
if( pd.ptypvt.pd_typ != PTY) {
/* tty */
/* look for correspondent pty in path-list and register, else sleep(0) */
do {
ptr = ((Ptystatic) pd.path.pd_dev->V_stat)->v_sysio.v_paths;
for(; ptr ; ptr = ptr->path.pd_paths)
if( ptr->ptypvt.pd_typ == PTY && strcmp( ptr->ptyopt.pd_name, pd.ptyopt.pd_name) == 0 ) {
pd.ptypvt.pd_pty = ptr;
goto outloop;
}
} while ( dosleep(procdesc) == 0);
return -1;
} else {
/* pty */
/* iff same name exists, exists with error */
ptr = ((Ptystatic) pd.path.pd_dev->V_stat)->v_sysio.v_paths;
for(; ptr ; ptr = ptr->path.pd_paths)
if( ptr->ptypvt.pd_typ == PTY && ptr != &pd && strcmp( ptr->ptyopt.pd_name, pd.ptyopt.pd_name) == 0 ) {
errno = E_SHARE;
return -1;
}
/* set buffersize and allocate them */
pd.ptypvt.pd_rbuf.size = pd.ptypvt.pd_wbuf.size = DEFBUFSIZE;
if( (pd.ptypvt.pd_rbuf.buf = (u_char *)_srqmem( (pd.ptypvt.pd_rbuf.size))) == (u_char *)0 ||
(pd.ptypvt.pd_wbuf.buf = (u_char *)_srqmem( (pd.ptypvt.pd_wbuf.size))) == (u_char *)0 ) {
if( pd.ptypvt.pd_wbuf.buf )
(void) _srtmem(pd.ptypvt.pd_wbuf.buf,pd.ptypvt.pd_wbuf.size);
if( pd.ptypvt.pd_rbuf.buf )
(void) _srtmem(pd.ptypvt.pd_rbuf.buf,pd.ptypvt.pd_rbuf.size);
return -1;
}
pd.ptypvt.pd_rbuf.rptr = pd.ptypvt.pd_rbuf.wptr = pd.ptypvt.pd_rbuf.buf;
pd.ptypvt.pd_wbuf.rptr = pd.ptypvt.pd_wbuf.wptr = pd.ptypvt.pd_wbuf.buf;
ptr = ((Ptystatic) pd.path.pd_dev->V_stat)->v_sysio.v_paths;
/* look for a sleeping tty -- and wake it up */
for(; ptr ; ptr = ptr->path.pd_paths)
if( ptr->ptypvt.pd_typ == TTY && strcmp( ptr->ptyopt.pd_name, pd.ptyopt.pd_name) == 0 ) {
if( ptr->path.pd_cpr != 0 )
kill(ptr->path.pd_cpr,
(ptr->ptypvt.pd_esig ? ptr->ptypvt.pd_esig : SIGWAKE));
}
}
outloop:
return 0;
}
/*
* C l o s e
*/
Close(procdesc, ustack)
procid *procdesc;
REGISTERS *ustack;
{
register struct ptybuf *bptr;
/* clear _ss_sign() */
bptr = ( pd.ptypvt.pd_typ == PTY) ? &pd.ptypvt.pd_rbuf : &((pd.ptypvt.pd_pty)->ptypvt.pd_wbuf);
if( bptr->rpid == procdesc->_id )
bptr->rpid = 0;
/* deallocate buffer if we are the last incarnation */
if( pd.path.pd_count == 0 )
if( pd.ptypvt.pd_typ == PTY ) {
register Pathdesc ptr = ((Ptystatic) pd.path.pd_dev->V_stat)->v_sysio.v_paths;
/*
* and send all listening ttys a HUP and mark that the connection is severed
*/
for(; ptr ; ptr = ptr->path.pd_paths)
if( ptr->ptypvt.pd_typ == TTY && ptr->ptypvt.pd_pty == &pd ) {
ptr->ptypvt.pd_pty = (union pathdesc *) 0;
kill( (ptr->path.pd_cpr ? ptr->path.pd_cpr : ptr->path.pd_lproc)
,(ptr->ptypvt.pd_esig ? ptr->ptypvt.pd_esig : SIGHUP));
}
(void) _srtmem( pd.ptypvt.pd_rbuf.buf, pd.ptypvt.pd_rbuf.size);
(void) _srtmem( pd.ptypvt.pd_wbuf.buf, pd.ptypvt.pd_wbuf.size);
} else {
if((pd.ptypvt.pd_pty)->ptypvt.pd_rbuf.lpd = &pd)
(pd.ptypvt.pd_pty)->ptypvt.pd_rbuf.lpd = NULL;
if( pd.path.pd_buf )
(void) _srtmem( pd.path.pd_buf, LINEBUFSIZ);
}
return(0);
}
Read(procdesc, ustack)
procid *procdesc;
REGISTERS *ustack;
{
register int numbytes;
if( hangup(procdesc) )
return -1;
/*
* select buffer ...
*/
if( pd.ptypvt.pd_typ == PTY ) {
numbytes = cpinraw( &pd.ptypvt.pd_rbuf, &pd.ptypvt.pd_wbuf,
ustack, procdesc);
} else {
numbytes = cpinraw( &((pd.ptypvt.pd_pty)->ptypvt.pd_wbuf),
&((pd.ptypvt.pd_pty)->ptypvt.pd_rbuf), ustack, procdesc);
}
/*
* a neg. count means an error ....
*/
if( numbytes < 0) {
ustack->d[1] += numbytes;
return -1;
}
ustack->d[1] -= numbytes;
return(0);
}
ReadLn(procdesc, ustack)
procid *procdesc;
REGISTERS *ustack;
{
register int numbytes;
if( hangup(procdesc) )
return -1;
/*
* the line-editing buffer
*/
if( pd.path.pd_buf == NULL) {
if((pd.path.pd_buf = (u_char *) _srqmem(LINEBUFSIZ)) == NULL)
return(-1);
else
initbuf(pd.path.pd_buf, LINEBUFSIZ-1); /* dont change !! */
}
if( ustack->d[1] > LINEBUFSIZ )
ustack->d[1] = LINEBUFSIZ;
/*
* select buffer ...
*/
if( pd.ptypvt.pd_typ == PTY ) {
numbytes = cpin( &pd.ptypvt.pd_rbuf, &pd.ptypvt.pd_wbuf,
ustack, procdesc);
} else {
numbytes = cpin( &((pd.ptypvt.pd_pty)->ptypvt.pd_wbuf), &((pd.ptypvt.pd_pty)->ptypvt.pd_rbuf),
ustack, procdesc);
}
/*
* a neg. count means an error ....
*/
if( numbytes < 0) {
ustack->d[1] += numbytes;
return(-1);
}
ustack->d[1] -= numbytes;
return(0);
}
Write(procdesc, ustack)
procid *procdesc;
REGISTERS *ustack;
{
register int numbytes;
if( hangup(procdesc) )
return -1;
if( pd.ptypvt.pd_typ == PTY ) {
numbytes = cpoutraw( &pd.ptypvt.pd_wbuf, &pd.ptypvt.pd_rbuf, ustack, procdesc);
} else {
numbytes = cpoutraw( &((pd.ptypvt.pd_pty)->ptypvt.pd_rbuf), &((pd.ptypvt.pd_pty)->ptypvt.pd_wbuf), ustack, procdesc);
}
if( numbytes < 0) {
ustack->d[1] += numbytes;
return -1;
}
ustack->d[1] -= numbytes;
return(0);
}
WriteLn(procdesc, ustack)
procid *procdesc;
REGISTERS *ustack;
{
register int numbytes;
if( hangup(procdesc) )
return -1;
if( pd.ptypvt.pd_typ == PTY ) {
numbytes = cpout( &pd.ptypvt.pd_wbuf, &pd.ptypvt.pd_rbuf,
ustack, procdesc);
} else {
numbytes = cpout( &((pd.ptypvt.pd_pty)->ptypvt.pd_rbuf),
&((pd.ptypvt.pd_pty)->ptypvt.pd_wbuf), ustack, procdesc);
}
if( numbytes < 0) {
ustack->d[1] += numbytes;
return -1;
}
ustack->d[1] -= numbytes;
return(0);
}
/*
* G e t S t a t
*/
GetStat(procdesc, ustack)
procid *procdesc;
REGISTERS *ustack;
{
register struct ptybuf *ptr;
if( hangup(procdesc) )
return -1;
switch (ustack->d[1] & 0x0ffff) {
case SS_DevNm:
/*
* returns name of the [pt]ty ...
*/
memcpy( ustack->a[0], pd.ptyopt.pd_name, pd.ptyopt.pd_namlen);
*((u_char *) ustack->a[0] + pd.ptyopt.pd_namlen) = '\0';
break;
case SS_Opt:
/*
* copy the option-field
*/
memcpy( ustack->a[0], &(pd.ptyopt.pd_dtp), OPTMAX);
break;
case SS_Ready:
/*
* return TRUE if number of chars in buffer > 0 ...
*/
ptr = ( pd.ptypvt.pd_typ == PTY) ? &pd.ptypvt.pd_rbuf : &((pd.ptypvt.pd_pty)->ptypvt.pd_wbuf);
if((ustack->d[1] = (ptr->wptr - ptr->rptr)) <= 0 ) {
errno = E_NOTRDY;
return -1;
}
break;
case SS_EOF:
/*
* always return 0
*/
ustack->d[1] = 0;
break;
case SS_BlkRd:
/*
* like a Read
*/
ustack->d[1] = ustack->d[2];
return( Read( procdesc, ustack));
default:
pd.path.pd_errno = E_UNKSVC;
return(-1);
}
return (0);
}
/*
* S e t S t a t
*/
SetStat(procdesc, ustack)
procid *procdesc;
REGISTERS *ustack;
{
register struct ptybuf *ptr;
if( hangup(procdesc) )
return -1;
switch (ustack->d[1] & 0x0ffff) {
case SS_Opt:
/*
* copy the option-field
*/
memcpy( &(pd.ptyopt.pd_dtp), ustack->a[0], OPTMAX);
break;
case SS_SSig:
/*
* set ssig, if someother is already waiting --> error
* if data is already available --> send sig immediatly
*/
ptr = ( pd.ptypvt.pd_typ == PTY) ? &pd.ptypvt.pd_rbuf : &((pd.ptypvt.pd_pty)->ptypvt.pd_wbuf);
if( ptr->rpid ) {
errno = E_NOTRDY;
return -1;
}
if( ((ptr->wptr - ptr->rptr)) <= 0 ) {
ptr->rpid = procdesc->_id;
ptr->rsig = ustack->d[2];
} else kill(procdesc->_id,ustack->d[2]);
break;
case SS_Relea:
/*
* clear _ss_sign()
*/
ptr = ( pd.ptypvt.pd_typ == PTY) ? &pd.ptypvt.pd_rbuf : &((pd.ptypvt.pd_pty)->ptypvt.pd_wbuf);
if( ptr->rpid == procdesc->_id)
ptr->rpid = 0;
break;
case SS_EnRTS:
case SS_DsRTS:
case SS_DCOn:
break;
case SS_DCOff:
/*
* set the pd_esig -- thats all
*/
if( pd.ptypvt.pd_typ == TTY)
pd.ptypvt.pd_esig = (u_short) ustack->d[2];
break;
#ifdef ST
/*
* like Blkwr
*/
case SS_Screen:
if( ustack->d[2] != ScrOut )
break;
ustack->d[2] = ustack->d[3];
#endif
case SS_BlkWr:
/*
* like a Write
*/
ustack->d[1] = ustack->d[2];
return( Write( procdesc, ustack));
default:
pd.path.pd_errno = E_UNKSVC;
return(-1);
}
return (0);
}