| plan 9 kernel history: overview | file list | diff list |
1992/0111/port/stfcall.c (diff list | history)
| port/stfcall.c on 1991/0521 | ||
| 1991/0521 | #include "u.h" #include "lib.h" #include "mem.h" #include "dat.h" #include "fns.h" | |
| 1992/0111 | #include "../port/error.h" | |
| 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]; }; 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, | |
| 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) {} 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; } | |