home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
DRIVERS
/
SRC
/
ptys.lzh
/
funcs.c
< prev
next >
Wrap
Text File
|
1990-03-08
|
17KB
|
544 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) *
* */
/* */
/*
* Funcs.c : Unterfunktionen zum Pty-FileManager.
*
* $Header: /h0/USR/REIMER/PTYMAN/RCS/funcs.c_v 1.2.1.2 89/09/04 13:12:41 ram Exp $
*
* $Log: funcs.c_v $
* Revision 1.2.1.2 89/09/04 13:12:41 ram
* added some comments
*
* Revision 1.2.1.1 89/08/31 12:24:51 ram
* negative Read/Write Counts are made positive
*
* Revision 1.2 89/07/16 01:04:51 ram
* minor changes to Sub-net release
*
* Revision 1.1.1.1 89/07/14 19:48:36 ram
* Fixed: kbich, kbach. Sub-net Beta-Release
*
* Revision 1.1 89/07/13 23:21:10 ram
* Initial revision
*
*/
#include <types.h>
#include <reg.h>
#include "ptyman.h"
#include <path.h>
#include <sg_codes.h>
#include <procid.h>
#include <signal.h>
#include <modes.h>
#include <errno.h>
#include "misc.h"
extern union pathdesc pd;
extern u_char *_srqmem();
extern void _srtmem();
extern void iowait();
extern void kill();
extern int getctrlchar();
extern int tsleep();
int
hangup(procdesc)
register procid *procdesc;
{
/* TRUE:
* - pty-typ is a tty
* - and correspondent pty has gone
* Action: send a SIGHUP, if conection was severed by server
*/
if(pd.ptypvt.pd_typ == TTY && pd.ptypvt.pd_pty == (union pathdesc *) 0) {
errno = E_HANGUP;
kill( procdesc->_id, (pd.ptypvt.pd_esig ?
pd.ptypvt.pd_esig : SIGHUP));
return TRUE;
}
return FALSE;
}
int inline
dosleep( procdesc )
register procid *procdesc;
{
/*
* 0: - if wakedup by SIGWAKE
* -1: - if signal is < 32 ( ENOENT ) orseq process has been aborted
* 0: - other
*/
if( tsleep(0) == 0 && procdesc->_signal == 0)
return 0;
if( (errno = procdesc->_signal) < 32 || procdesc->_state & P_CONDEMNED)
return -1;
return 0;
}
/*
* Falls Echo angeschaltet ist, schreibe einen Charakter in den Echobuffer
* 1: - falls echo ausgeschaltet ist oder echo erfolgreich
* -1: - Fehler bei Ausgabe (z.b. Prozess aborted)
*/
int
echochar( ch, buf, procdesc)
register u_char ch;
register struct ptybuf *buf;
procid *procdesc;
{ register int rv;
/*
* if echo is off, return success
*/
if( pd.ptyopt.pd_eko == '\0')
return(1);
/*
* wait for other I/O, and register for SIGINT,SIGQUIT
*/
iowait( buf->wpid);
buf->wsig = SIGWAKE;
buf->lpd = &pd;
/*
* my standard output-loop
*/
while( buf->wptr >= (buf->buf + buf->size)) {
WAKE(buf->rpid, buf->rsig);
buf->wpid = procdesc->_id;
do {
if( dosleep(procdesc) < 0) {
rv = -1;
goto outloop;
}
} while( buf->wpid);
}
*(buf->wptr)++ = ch;
rv = 1;
outloop:
buf->wpid = 0;
if( buf->wptr > buf->rptr)
WAKE(buf->rpid, buf->rsig);
return( rv );
}
/*
* Lese cnt-Bytes im Raw-modus ein. Kein Echo, Lineediting etc....
* 0: - cnt-bytes gelesen
* x: - (cnt-x) bytes gelesen
* -x: - nach (cnt-x) ist Fehler aufgetreten (Interupted, Hangup etc.)
*/
int
cpinraw(buf, echobuf, ustack, procdesc)
register struct ptybuf *buf;
register struct ptybuf *echobuf;
REGISTERS *ustack;
procid *procdesc;
{ register int cnt = ustack->d[1] & 0x7fffffff; /* no neg. counts */
register u_char *dest = (u_char *) ustack->a[0];
/*
* this can only happen if _ss_sign() was set
*/
if( buf->rpid == procdesc->_id) {
errno = E_NOTRDY;
return -cnt;
}
iowait( buf->rpid);
buf->rsig = SIGWAKE;
for(; cnt > 0; --cnt) {
while( buf->rptr >= buf->wptr ) {
buf->wptr = buf->rptr = buf->buf;
WAKE(buf->wpid, buf->wsig);
buf->rpid = procdesc->_id;
do {
if( dosleep(procdesc) < 0) {
cnt = -cnt;
goto outloop;
}
} while ( buf->rpid);
}
/*
* in read, one has still to check for SIGQUIT etc..
* the signal is sent by the writing-process
*/
switch( getctrlchar( *dest++ = *(buf->rptr)++)) {
case INT:
errno = SIGINT;
cnt = - (--cnt);
goto outloop;
case QUT:
errno = SIGQUIT;
cnt = - (--cnt);
goto outloop;
case EOR:
pd.ptypvt.pd_line = 0;
break;
}
}
outloop:
if(buf->rptr >= buf->wptr ) {
buf->wptr = buf->rptr = buf->buf;
WAKE(buf->wpid, buf->wsig);
}
buf->rpid = 0;
return( cnt);
}
/*
* Lese cnt-Bytes. Echo, Lineediting, vorzeitiger Abbruch bei Lesen von CR
* 0: - cnt-bytes gelesen
* x: - (cnt-x) bytes gelesen
* -x: - nach (cnt-x) ist Fehler aufgetreten (Interupted, Hangup etc.)
*/
int
cpin(buf, echobuf, ustack, procdesc)
register struct ptybuf *buf;
struct ptybuf *echobuf;
REGISTERS *ustack;
procid *procdesc;
{ register int cnt = ustack->d[1] & 0x7fffffff; /* no neg. counts */
register u_char *dest = (u_char *) ustack->a[0];
register u_char *old = pd.path.pd_buf;
register u_char ch;
/*
* this can only happen if _ss_sign() was set
*/
if( buf->rpid == procdesc->_id) {
errno = E_NOTRDY;
return -cnt;
}
iowait( buf->rpid);
buf->rsig = SIGWAKE;
for(; cnt > 0; --cnt) {
while( buf->rptr >= buf->wptr ) {
buf->wptr = buf->rptr = buf->buf;
WAKE(buf->wpid, buf->wsig);
buf->rpid = procdesc->_id;
do {
if( dosleep(procdesc) < 0) {
cnt = -cnt;
goto outloop;
}
} while( buf->rpid);
}
ch = (pd.ptyopt.pd_upc ? upchar(*(buf->rptr)++) : *(buf->rptr)++);
switch( getctrlchar(ch) ) {
case BSP:
/*
* look in the Tech. manual to see what is meant here
*/
if( ( pd.ptyopt.pd_bso ?
(echochar( pd.ptyopt.pd_bse, echobuf, procdesc) +
echochar( ' ' ,echobuf, procdesc) +
echochar( pd.ptyopt.pd_bse, echobuf, procdesc) < 3) :
(echochar( pd.ptyopt.pd_bse, echobuf, procdesc) < 1))) {
cnt = -cnt;
goto outloop;
}
dest--; old--;
dest = MAX( (dest), ((u_char *) ustack->a[0]));
old = MAX( (old ), pd.path.pd_buf);
if( cnt == ustack->d[1] )
cnt = ustack->d[1]+1;
else
cnt += 2;
break;
case EOR:
/*
* EOR resets pd_line and finishes
*/
pd.ptypvt.pd_line = 0;
*old++ = *dest++ = ch;
if( ( echochar( ch, echobuf, procdesc) < 0
|| ( pd.ptyopt.pd_alf && echochar( '\l', echobuf, procdesc) < 0))) {
cnt = -cnt;
goto outloop;
}
cnt--;
goto outloop;
case INT:
*old = *dest = errno = SIGINT;
cnt = - (--cnt);
goto outloop;
case QUT:
*old = *dest = errno = SIGQUIT;
cnt = - (--cnt);
goto outloop;
case EOF:
/*
* EOF only as first character !
*/
if( old == pd.path.pd_buf) {
errno = E_EOF;
cnt = -cnt;
goto outloop;
}
case DEL:
if( pd.ptyopt.pd_dlo != '\0' ) {
for(; old > pd.path.pd_buf; --old,cnt++)
if( ( pd.ptyopt.pd_bso ?
(echochar( pd.ptyopt.pd_bse, echobuf, procdesc) +
echochar( ' ' ,echobuf, procdesc) +
echochar( pd.ptyopt.pd_bse, echobuf, procdesc) < 3) :
(echochar( pd.ptyopt.pd_bse, echobuf, procdesc) < 1))) {
cnt = -cnt;
goto outloop;
}
}
else
if( (echochar( pd.ptyopt.pd_eor, echobuf, procdesc)
+ echochar( '\l', echobuf, procdesc) < 2)) {
cnt = -cnt;
goto outloop;
}
dest = (u_char *) ustack->a[0];
old = pd.path.pd_buf;
cnt = ustack->d[1]+1;
break;
case DUP:
for(; cnt > 0 ; --cnt) {
if((ch = *dest++ = *old++) == pd.ptyopt.pd_eor &&
pd.ptyopt.pd_eor) {
dest--; old--;
break;
}
if( echochar( (ch < ' ' ? '.': ch), echobuf, procdesc) < 0) {
cnt = - (--cnt);
goto outloop;
}
}
break;
case RPR:
*old = *dest = pd.ptyopt.pd_eor;
if(( echochar( *old, echobuf, procdesc) < 0
|| ( pd.ptyopt.pd_alf && echochar( '\l', echobuf, procdesc) < 0))) {
cnt = -cnt;
goto outloop;
}
{
register u_char *tmp = pd.path.pd_buf;
for(; tmp < old; tmp++)
if( echochar( *tmp, echobuf, procdesc) < 0) {
cnt = - cnt;
goto outloop;
}
}
break;
case PSC:
/*
* not supported
*/
default:
*old++ = *dest++ = ch;
if( echochar( (ch < ' ' ? '.': ch)
, echobuf, procdesc) < 0) {
cnt = - (--cnt);
goto outloop;
}
}
}
outloop:
buf->rpid = 0;
if( buf->rptr >= buf->wptr ) {
buf->wptr = buf->rptr = buf->buf;
WAKE(buf->wpid, buf->wsig);
}
return( cnt);
}
/*
* Schreibe cnt-Bytes im Raw-modus. Kein Alf etc....
* 0: - cnt-bytes geschrieben
* x: - (cnt-x) bytes geschrieben
* -x: - nach (cnt-x) ist Fehler aufgetreten (Interupted, Hangup etc.)
*/
int
cpoutraw(buf, echobuf, ustack, procdesc)
register struct ptybuf *buf;
register struct ptybuf *echobuf;
REGISTERS *ustack;
procid *procdesc;
{ register int cnt = ustack->d[1] & 0x7fffffff;
register u_char *src = (u_char *) ustack->a[0];
register u_char ch;
register u_int bufend = (u_int) buf->buf + buf->size;
iowait( buf->wpid);
buf->wsig = SIGWAKE;
buf->lpd = &pd;
for(; cnt > 0; --cnt) {
while( buf->wptr >= (u_char *) bufend) {
WAKE(buf->rpid, buf->rsig);
buf->wpid = procdesc->_id;
do {
if( dosleep(procdesc) < 0) {
cnt = -cnt;
goto outloop;
}
} while( buf->wpid);
}
ch = *(buf->wptr)++ = *src++;
if( ch && echobuf->lpd ) {
/*
* here the INT and QUIT signals are sent
*/
if( echobuf->lpd->ptyopt.pd_int == ch)
kill(echobuf->lpd->path.pd_lproc,SIGINT);
if( echobuf->lpd->ptyopt.pd_qut == ch)
kill(echobuf->lpd->path.pd_lproc,SIGQUIT);
}
}
outloop:
buf->wpid = 0;
if( buf->wptr > buf->rptr)
WAKE(buf->rpid, buf->rsig);
return( cnt);
}
/*
* Schreibe cnt-Bytes. Alf, Tab-expanding, Pause-behandlung, Abbruch bei
* vorzeitigem CR
* 0: - cnt-bytes geschrieben
* x: - (cnt-x) bytes geschrieben
* -x: - nach (cnt-x) ist Fehler aufgetreten (Interupted, Hangup etc.)
*/
int
cpout(buf, echobuf, ustack, procdesc)
register struct ptybuf *buf;
register struct ptybuf *echobuf;
REGISTERS *ustack;
procid *procdesc;
{ register int cnt = ustack->d[1] & 0x7fffffff;
register u_char *src = (u_char *) ustack->a[0];
register u_char ch;
register u_int bufend = (u_int) buf->buf + buf->size;
iowait( buf->wpid );
buf->wsig = SIGWAKE;
buf->lpd = &pd;
for(; cnt > 0; --cnt) {
while( buf->wptr >= (u_char *) bufend) {
WAKE(buf->rpid, buf->rsig);
buf->wpid = procdesc->_id;
do {
if( dosleep(procdesc) < 0) {
cnt = -cnt;
goto outloop;
}
} while( buf->wpid);
}
pd.ptyopt.pd_Col++;
ch = *(buf->wptr)++ = (pd.ptyopt.pd_upc ? upchar(*src++) : *src++);
/*
* QUIT and INT signals to last writing device
*/
if( ch && echobuf->lpd ) {
if( echobuf->lpd->ptyopt.pd_int == ch)
kill(echobuf->lpd->path.pd_lproc,SIGINT);
if( echobuf->lpd->ptyopt.pd_qut == ch)
kill(echobuf->lpd->path.pd_lproc,SIGQUIT);
}
if( ch && ch == pd.ptyopt.pd_eor ) {
pd.ptyopt.pd_Col = 0;
if( pd.ptyopt.pd_pau && ++pd.ptypvt.pd_line == pd.ptyopt.pd_pag ) {
pd.ptypvt.pd_line = 0;
iowait( echobuf->rpid);
WAKE(echobuf->wpid, echobuf->wsig);
echobuf->rpid = procdesc->_id;
do {
if( dosleep(procdesc) < 0) {
cnt = -cnt;
goto outloop;
}
} while( echobuf->rpid);
echobuf->rptr++;
}
if( pd.ptyopt.pd_alf ) {
if( buf->wptr >= (buf->buf + buf->size)) {
WAKE(buf->rpid, buf->rsig);
buf->wpid = procdesc->_id;
do {
if( dosleep(procdesc) < 0) {
cnt = -cnt;
goto outloop;
}
} while( buf->wpid);
}
*(buf->wptr)++ = '\l';
}
--cnt;
break;
} else
if( pd.ptyopt.pd_Tabs && pd.ptyopt.pd_Tab && ch == pd.ptyopt.pd_Tab) {
register short i = (pd.ptyopt.pd_Col-1) % pd.ptyopt.pd_Tabs;
*(buf->wptr - 1) = ' ';
for(; i > 0; i--) {
while( buf->wptr >= (buf->buf + buf->size)) {
WAKE(buf->rpid, buf->rsig);
buf->wpid = procdesc->_id;
do {
if( dosleep(procdesc) < 0) {
cnt = -cnt;
goto outloop;
}
} while( buf->wpid);
}
*(buf->wptr)++ = ' ';
}
}
}
outloop:
buf->wpid = 0;
if( buf->wptr > buf->rptr)
WAKE(buf->rpid, buf->rsig);
return( cnt);
}