From 3aea5ab8a883559f9385b2b366f7cb66b5ea04ec Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 21 May 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-05-21 --- port/stfcall.c | 224 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 port/stfcall.c diff --git a/port/stfcall.c b/port/stfcall.c new file mode 100644 index 0000000000000000000000000000000000000000..80e90d72e1a5a74d81b4dd14505d49cfe325c8f2 --- /dev/null +++ b/port/stfcall.c @@ -0,0 +1,224 @@ +#include "u.h" +#include "lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "errno.h" + +#include "fcall.h" + +#define DPRINT if(fcalldebug)kprint + +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]; +}; + +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 = +{ + fcalliput, + fcalloput, + fcallopen, + fcallclose, + "fcall", + fcallreset +}; + +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, + 35, 13, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; +static void +fcallreset(void) +{} + +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; +} + +static void +fcallclose(Queue * q) +{ + Fcalld *f = (Fcalld *)((Block *)q->ptr)->base; + + DPRINT("fcallstclose %d\n", f->dev); + freeb(q->ptr); + q->ptr = 0; +} + +void +fcalloput(Queue *q, Block *bp) +{ + PUTNEXT(q, bp); +} + + +static void +fcalliput(Queue *q, Block *bp) +{ + Fcalld *f = (Fcalld *)((Block *)q->ptr)->base; + int len, n; + + 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); + PUTNEXT(q, bp); + return; + } + bp->flags &= ~S_DELIM; + if(len == 0){ + 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; + + 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; + + 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; + break; + } +} + +static Block * +putmsg(Queue *q, Block *bp, int n) +{ + Block *xbp; + int k; + + 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; +}