plan 9 kernel history: overview | file list | diff list

1992/0318/port/stfcall.c (diff list | history)

1992/0111/sys/src/9/port/stfcall.c:7,971992/0318/sys/src/9/port/stfcall.c:7,80 (short | long | prev | next)
1991/0521    
 
#include	"fcall.h" 
 
1991/1003    
#define DPRINT 	if(fcalldebug)kprint 
1991/0521    
                 
int fcalldebug = 0; 
                 
typedef struct Fcalld	Fcalld; 
                 
struct Fcalld{ 
	int	dev;		/* ref. for debug output */ 
	int	state; 
	int	type;		/* of current message */ 
	int	need;		/* bytes remaining in current message */ 
	int	nhdr;		/* bytes of header treasured up in hdr */ 
	uchar	hdr[16]; 
1992/0318    
enum 
{ 
	Twritehdr	= 15,	/* Min bytes for Twrite */ 
	Rreadhdr	= 8,	/* Min bytes for Rread */ 
	Twritecnt	= 13,	/* Offset in byte stream of write count */ 
	Rreadcnt	= 5,	/* Offset for Readcnt */ 
1991/0521    
}; 
 
enum { 
	Startup, Startup1, Begin, Header, Data 
}; 
                 
/* 
 *  fcall stream module definition 
 */ 
static void fcalliput(Queue*, Block*); 
static void fcalloput(Queue*, Block*); 
static void fcallopen(Queue*, Stream*); 
static void fcallclose(Queue*); 
static void fcallreset(void); 
Qinfo fcallinfo = 
1992/0318    
Qinfo fcallinfo = { fcalliput, fcalloput, fcallopen, fcallclose, "fcall", fcallreset }; 
 
static uchar msglen[256] = 
1991/0521    
{ 
	fcalliput, 
	fcalloput, 
	fcallopen, 
	fcallclose, 
	"fcall", 
	fcallreset 
1992/0318    
	[Tnop]		3, 
	[Rnop]		3, 
	[Tsession]	3, 
	[Rsession]	3, 
	[Terror]	0, 
	[Rerror]	67, 
	[Tflush]	5, 
	[Rflush]	3, 
	[Tattach]	89, 
	[Rattach]	13, 
	[Tclone]	7, 
	[Rclone]	5, 
	[Twalk]		33, 
	[Rwalk]		13, 
	[Topen]		6, 
	[Ropen]		13, 
	[Tcreate]	38, 
	[Rcreate]	13, 
	[Tread]		15, 
	[Rread]		8, 
	[Twrite]	16, 
	[Rwrite]	7, 
	[Tclunk]	5, 
	[Rclunk]	5, 
	[Tremove]	5, 
	[Rremove]	5, 
	[Tstat]		5, 
	[Rstat]		121, 
	[Twstat]	121, 
	[Rwstat]	5, 
	[Tclwalk]	35, 
	[Rclwalk]	13, 
	[Tauth]		69, 
	[Rauth]		35, 
1991/0521    
}; 
 
static Block *	putmsg(Queue*, Block*, int); 
                 
static uchar msglen[] = { 
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
	  0,  0,  3,  3,  3,  3,  0, 67,  5,  3, 89, 13,  7,  5, 33, 13, 
	  6, 13, 38, 13, 15,  8, 16,  7,  5,  5,  5,  5,  5,121,121,  5, 
1991/1003    
	 35, 13, 69, 35,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
1991/0521    
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 
}; 
static void 
fcallreset(void) 
{} 
1992/0318    
{ 
} 
1991/0521    
 
static void 
fcallopen(Queue *q, Stream *s) 
{ 
	Fcalld *f; 
                 
	DPRINT("fcallopen %d\n", s->dev); 
                 
	q->ptr = allocb(sizeof(Fcalld)); 
	f = (Fcalld *)((Block *)q->ptr)->base; 
	f->dev = s->dev; 
	f->state = Startup; 
	f->type = 0; 
	f->need = 0; 
	f->nhdr = 0; 
1992/0318    
	USED(q, s); 
1991/0521    
} 
 
static void 
fcallclose(Queue * q) 
{ 
	Fcalld *f = (Fcalld *)((Block *)q->ptr)->base; 
                 
	DPRINT("fcallstclose %d\n", f->dev); 
	freeb(q->ptr); 
	q->ptr = 0; 
1992/0318    
	USED(q); 
1991/0521    
} 
 
void 
1992/0111/sys/src/9/port/stfcall.c:100,2241992/0318/sys/src/9/port/stfcall.c:83,163
1991/0521    
	PUTNEXT(q, bp); 
} 
 
1992/0318    
void 
upstream(Queue *q, ulong len) 
{ 
	Block *bl, **tail, *bp; 
	ulong l; 
1991/0521    
 
1992/0318    
	tail = &bl; 
	while(len) { 
		l = BLEN(q->first); 
		if(l > len) 
			break; 
		bp = getq(q);			/* Consume all of block */ 
		*tail = bp; 
		tail = &bp->next; 
		len -= l; 
	} 
	if(len) {				/* Consume partial block */ 
		lock(q); 
		*tail = copyb(q->first, len); 
		q->first->rptr += len; 
		q->len -= len; 
		unlock(q); 
	} 
	for(bp = bl; bp->next; bp = bp->next) 
		; 
	bp->flags |= S_DELIM; 
	PUTNEXT(q, bl); 
} 
 
1991/0521    
static void 
fcalliput(Queue *q, Block *bp) 
{ 
	Fcalld *f = (Fcalld *)((Block *)q->ptr)->base; 
	int len, n; 
1992/0318    
	ulong len, need, off; 
1991/0521    
 
	len = BLEN(bp); 
	DPRINT("fcalliput %d: blen=%d\n", f->dev, len); 
	if(bp->type != M_DATA){ 
		DPRINT("fcalliput %d: type=%d\n", f->dev, bp->type); 
1992/0318    
	if(bp->type != M_DATA) { 
1991/0521    
		PUTNEXT(q, bp); 
		return; 
	} 
	bp->flags &= ~S_DELIM; 
	if(len == 0){ 
1992/0318    
	if(BLEN(bp) == 0) { 
1991/0521    
		freeb(bp); 
		return; 
	} 
	while(len > 0)switch(f->state){ 
	case Startup: 
		if (len == 1 && bp->rptr[0] == 'O'){ 
			DPRINT("fcalliput %d: O\n", f->dev); 
			PUTNEXT(q, bp); 
			f->state = Startup1; 
			return; 
		} 
		if(bp->rptr[0] == 'O' && bp->rptr[1] == 'K'){ 
			DPRINT("fcalliput %d: OK\n", f->dev); 
			bp = putmsg(q, bp, 2); 
			len -= 2; 
		} 
		f->state = Begin; 
		break; 
 
	case Startup1: 
		if(bp->rptr[0] == 'K'){ 
			DPRINT("fcalliput %d: K\n", f->dev); 
			bp = putmsg(q, bp, 1); 
			len -= 1; 
			f->state = Begin; 
			break; 
		} 
		f->type = 'O'; 
		f->need = msglen['O']-1; 
		f->state = Data; 
		DPRINT("fcalliput %d: type=%d, need=%d\n", 
			f->dev, f->type, f->need); 
		break; 
1992/0318    
	/* Stash the data */ 
	bp->flags &= ~S_DELIM; 
	putq(q, bp); 
1991/0521    
 
	case Begin: 
		f->type = bp->rptr[0]; 
		f->need = msglen[f->type]; 
		f->nhdr = 0; 
		if(f->type == Twrite || f->type == Rread) 
			f->state = Header; 
		else 
			f->state = Data; 
		DPRINT("fcalliput %d: type=%d, need=%d\n", 
			f->dev, f->type, f->need); 
		break; 
1992/0318    
	bp = q->first; 
	switch(bp->rptr[0]) {		/* This is the type */ 
	default: 
		len = msglen[bp->rptr[0]]; 
		if(len == 0) 
			error(Emountrpc); 
		if(q->len >= len) 
			upstream(q, len); 
1991/0521    
 
	case Header: 
		n = f->need; 
		if(n > len) 
			n = len; 
		memmove(&f->hdr[f->nhdr], bp->rptr, n); 
		f->nhdr += n; 
		DPRINT("fcalliput %d: nhdr=%d\n", 
			f->dev, f->nhdr); 
		if(n == f->need){ 
			f->need += f->hdr[f->nhdr-3]; 
			f->need += f->hdr[f->nhdr-2] << 8; 
			f->state = Data; 
			DPRINT("fcalliput %d: need=%d\n", 
				f->dev, f->need); 
		} 
		/* fall through */ 
                 
	case Data: 
		if(f->need > len){ 
			f->need -= len; 
			PUTNEXT(q, bp); 
			return; 
		} 
		bp = putmsg(q, bp, f->need); 
		len -= f->need; 
		f->state = Begin; 
1992/0318    
		return; 
	case Twrite:			/* Fmt: TGGFFOOOOOOOOCC */ 
		len = Twritehdr;	/* T = type, G = tag, F = fid */ 
		off = Twritecnt;	/* O = offset, C = count */ 
1991/0521    
		break; 
1992/0318    
	case Rread:			/* Fmt: TGGFFCC */ 
		len = Rreadhdr; 
		off = Rreadcnt; 
		break; 
1991/0521    
	} 
} 
 
static Block * 
putmsg(Queue *q, Block *bp, int n) 
{ 
	Block *xbp; 
	int k; 
1992/0318    
	if(q->len < len) 
		return; 
1991/0521    
 
	DPRINT("putmsg: n=%d\n\n", n); 
	k = BLEN(bp) - n; 
	if(k == 0){ 
		bp->flags |= S_DELIM; 
		PUTNEXT(q, bp); 
		return 0; 
	} 
	if(n <= k){ 
		xbp = allocb(n); 
		memmove(xbp->wptr, bp->rptr, n); 
		xbp->wptr += n; 
		bp->rptr += n; 
		xbp->flags |= S_DELIM; 
		PUTNEXT(q, xbp); 
		return bp; 
	} 
	xbp = allocb(k); 
	memmove(xbp->wptr, bp->rptr+n, k); 
	xbp->wptr += k; 
	bp->wptr -= k; 
	bp->flags |= S_DELIM; 
	PUTNEXT(q, bp); 
	return xbp; 
1992/0318    
	pullup(q->first, len); 
	bp = q->first; 
	need = len+bp->rptr[off]+(bp->rptr[off+1]<<8); 
	if(q->len < need) 
		return; 
 
	upstream(q, need); 
1991/0521    
} 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)