## diffname gnot/devpipe.c 1990/03091 ## diff -e /dev/null /n/bootesdump/1990/03091/sys/src/9/68020/devpipe.c 0a #include "u.h" #include "lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "errno.h" #include "devtab.h" #include "fcall.h" static void pipeiput(Queue*, Block*); static void pipeoput(Queue*, Block*); static void pipestclose(Queue *); Qinfo pipeinfo = { pipeiput, pipeoput, 0, pipestclose, "process" }; void pipeinit(void) { } void pipereset(void) { } /* * allocate both streams * * a subsequent clone will get them the second stream */ Chan* pipeattach(char *spec) { Chan *c; /* * make the first stream */ c = devattach('|', spec); c->qid = STREAMQID(0, Sdataqid); streamnew(c, &pipeinfo); return c; } Chan* pipeclone(Chan *c, Chan *nc) { /* * make the second stream */ nc = devclone(c, nc); if(waserror()){ close(nc); nexterror(); } nc->qid = STREAMQID(1, Sdataqid); streamnew(nc, &pipeinfo); poperror(); /* * attach it to the first */ c->stream->devq->other->next = nc->stream->devq; nc->stream->devq->other->next = c->stream->devq; return nc; } int pipewalk(Chan *c, char *name) { print("pipewalk\n"); error(0, Egreg); } void pipestat(Chan *c, char *db) { Dir dir; devdir(c, c->qid, "pipe", 0, 0, &dir); convD2M(&dir, db); } Chan * pipeopen(Chan *c, int omode) { c->mode = omode; c->flag |= COPEN; c->offset = 0; return c; } void pipecreate(Chan *c, char *name, int omode, ulong perm) { print("pipecreate\n"); error(0, Egreg); } void piperemove(Chan *c) { print("piperemove\n"); error(0, Egreg); } void pipewstat(Chan *c, char *db) { print("pipewstat\n"); error(0, Egreg); } void pipeclose(Chan *c) { streamclose(c); } long piperead(Chan *c, void *va, long n) { return streamread(c, va, n); } long pipewrite(Chan *c, void *va, long n) { if(waserror()){ postnote(u->p, 1, "sys: write on closed pipe", NExit); error(0, Egreg); } return streamwrite(c, va, n); } void pipeuserstr(Error *e, char *buf) { consuserstr(e, buf); } void pipeerrstr(Error *e, char *buf) { rooterrstr(e, buf); } /* * stream stuff */ /* * send a block up stream to the process. * sleep untill there's room upstream. */ static void pipeiput(Queue *q, Block *bp) { flowctl(q); PUTNEXT(q, bp); } /* * send the block to the other side without letting the connection * disappear in mid put. */ static void pipeoput(Queue *q, Block *bp) { lock(q); if(q->next) pipeiput(q->next, bp); unlock(q); } /* * send a hangup and disconnect the streams */ static void pipestclose(Queue *q) { Block *bp; /* * point to the bit-bucket and let any in-progress * write's finish. */ q->put = nullput; wakeup(&q->r); /* * send a hangup */ q = q->other; lock(q); if(q->next){ bp = allocb(0); bp->type = M_HANGUP; pipeiput(q->next, bp); } unlock(q); /* * disconnect (possible livelock?) */ for(;;){ lock(q); if(q->next){ if(!canlock(q->next->other)){ unlock(q); continue; } q->next->other->next = 0; unlock(q->next->other); q->next = 0; } unlock(q); break; } } . ## diffname gnot/devpipe.c 1990/0312 ## diff -e /n/bootesdump/1990/03091/sys/src/9/68020/devpipe.c /n/bootesdump/1990/0312/sys/src/9/68020/devpipe.c 132c return streamwrite(c, va, n, 0); . ## diffname gnot/devpipe.c 1990/0331 ## diff -e /n/bootesdump/1990/0312/sys/src/9/68020/devpipe.c /n/bootesdump/1990/0331/sys/src/9/68020/devpipe.c 170a else{ print("pipeoput losing block\n"); freeb(bp); } . 157c if(q->next->len >= Streamhi) flowctl(q); . 14c Qinfo pipeinfo = { pipeiput, pipeoput, 0, pipestclose, "pipe" }; . ## diffname gnot/devpipe.c 1990/0403 ## diff -e /n/bootesdump/1990/0331/sys/src/9/68020/devpipe.c /n/bootesdump/1990/0403/sys/src/9/68020/devpipe.c 157,158c FLOWCTL(q); . ## diffname gnot/devpipe.c 1990/0513 ## diff -e /n/bootesdump/1990/0403/sys/src/9/68020/devpipe.c /n/bootesdump/1990/0513/sys/src/9/68020/devpipe.c 132c n = streamwrite(c, va, n, 0); poperror(); return n; . ## diffname gnot/devpipe.c 1990/0617 ## diff -e /n/bootesdump/1990/0513/sys/src/9/68020/devpipe.c /n/bootesdump/1990/0617/sys/src/9/68020/devpipe.c 109,110c error(0, Eperm); . 102d 95d ## diffname gnot/devpipe.c 1990/0620 ## diff -e /n/bootesdump/1990/0617/sys/src/9/68020/devpipe.c /n/bootesdump/1990/0620/sys/src/9/68020/devpipe.c 201,219d 196d 167,174c PUTNEXT(q, bp); . 113c Stream *other; other = (Stream *)c->stream->devq->ptr; if(waserror()){ streamexit(other, 0); nexterror(); } streamclose(c); /* close this stream */ streamexit(other, 0); /* release stream for other half of pipe */ . 63a /* * up the inuse count of each stream to reflect the * pointer from the other stream. */ streamenter(c->stream); streamenter(nc->stream); . 61a c->stream->devq->ptr = (Stream *)nc->stream; nc->stream->devq->ptr = (Stream *)c->stream; . 34a int i; . ## diffname gnot/devpipe.c 1990/0621 ## diff -e /n/bootesdump/1990/0620/sys/src/9/68020/devpipe.c /n/bootesdump/1990/0621/sys/src/9/68020/devpipe.c 209,213c bp = allocb(0); bp->type = M_HANGUP; PUTNEXT(q, bp); . 133a poperror(); . 73,74c if(streamenter(c->stream)<0) panic("pipeattach"); if(streamenter(nc->stream)<0) panic("pipeattach"); . ## diffname gnot/devpipe.c 1990/0801 ## diff -e /n/bootesdump/1990/0621/sys/src/9/68020/devpipe.c /n/bootesdump/1990/0801/sys/src/9/68020/devpipe.c 90,93c streamstat(c, db, "pipe"); . ## diffname gnot/devpipe.c 1990/1009 ## diff -e /n/bootesdump/1990/0801/sys/src/9/68020/devpipe.c /n/bootesdump/1990/1009/sys/src/9/68020/devpipe.c 141a /* * a write to a closed pipe causes a note to be sent to * the process. */ . 139c if(CHDIR&c->qid) return devdirread(c, va, n, pipedir, NPIPEDIR, pipegen); else return streamread(c, va, n); . 131,133c pipeexit(p); . 127,129c /* * take care of assosiated streams */ if(local = c->stream){ remote = (Stream *)c->stream->devq->ptr; if(waserror()){ streamexit(remote, 0); pipeexit(p); nexterror(); } streamclose(c); /* close this stream */ streamexit(remote, 0); /* release stream for other half of pipe */ poperror(); . 125c p = &pipealloc.pipe[STREAMID(c->qid)/2]; . 123c Stream *remote; Stream *local; Pipe *p; . 120a pipeexit(Pipe *p) { decref(p); if(p->ref <= 0){ lock(&pipealloc); p->next = pipealloc.free; pipealloc.free = p; unlock(&pipealloc); } } void . 96c Pipe *p; Stream *local, *remote; if(CHDIR & c->qid){ if(omode != OREAD) error(0, Ebadarg); c->mode = omode; c->flag |= COPEN; c->offset = 0; return c; } p = &pipealloc.pipe[STREAMID(c->qid)/2]; remote = 0; if(waserror()){ unlock(p); if(remote) streamclose1(remote); nexterror(); } lock(p); streamopen(c, &pipeinfo); local = c->stream; if(local->devq->ptr == 0){ /* * First stream opened, create the other end also */ remote = streamnew(c->type, c->dev, STREAMID(c->qid)^1, &pipeinfo, 1); /* * connect the device ends of both streams */ local->devq->ptr = remote; remote->devq->ptr = local; local->devq->other->next = remote->devq; remote->devq->other->next = local->devq; /* * increment the inuse count to reflect the * pointer from the other stream. */ if(streamenter(local)<0) panic("pipeattach"); } unlock(p); poperror(); c->mode = omode&~OTRUNC; . 92a /* * if the stream doesn't exist, create it */ . 83,84c return devwalk(c, name, pipedir, NPIPEDIR, pipegen); . 79a . 69,77c id = STREAMID(c->qid); if(i > 1) id++; if(tab==0 || i>=ntab) return -1; tab += i; devdir(c, STREAMQID(id, tab->qid), tab->name, tab->length, tab->perm, dp); return 1; . 61,67c int pipegen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp) { int id; . 53,59c incref(p); return nc; } . 49,51c Pipe *p; p = &pipealloc.pipe[STREAMID(c->qid)/2]; . 41,42c lock(&pipealloc); if(pipealloc.free == 0){ unlock(&pipealloc); error(0, Enopipe); } p = pipealloc.free; pipealloc.free = p->next; p->ref = 1; unlock(&pipealloc); c->qid = CHDIR|STREAMQID(2*(p - pipealloc.pipe), 0); . 37,39d 35d 33a Pipe *p; . 27,29c * create a pipe, no streams are created until an open . 23a Pipe *p, *ep; pipealloc.pipe = ialloc(conf.npipe * sizeof(Pipe), 0); ep = &pipealloc.pipe[conf.npipe-1]; for(p = pipealloc.pipe; p < ep; p++) p->next = p+1; pipealloc.free = pipealloc.pipe; . 20a /* * allocate structures for conf.npipe pipes */ . 15a Dirtab pipedir[]={ "data", Sdataqid, 0, 0600, "ctl", Sctlqid, 0, 0600, "data1", Sdataqid, 0, 0600, "ctl1", Sctlqid, 0, 0600, }; #define NPIPEDIR 4 . 10a typedef struct Pipe Pipe; struct Pipe { Ref; int debug; Pipe *next; }; struct Pipealloc { Lock; Pipe *pipe; Pipe *free; } pipealloc; . ## diffname gnot/devpipe.c 1990/1011 ## diff -e /n/bootesdump/1990/1009/sys/src/9/68020/devpipe.c /n/bootesdump/1990/1011/sys/src/9/68020/devpipe.c 234d 227,231d 223c * take care of associated streams . 204,205c if(decref(p) < 0) panic("pipeexit"); if(p->ref == 0){ . ## diffname gnot/devpipe.c 1990/1013 ## diff -e /n/bootesdump/1990/1011/sys/src/9/68020/devpipe.c /n/bootesdump/1990/1013/sys/src/9/68020/devpipe.c 92c if(incref(p) <= 1) panic("pipeclone"); . 78c if(incref(p) != 1) panic("pipeattach"); . ## diffname gnot/devpipe.c 1990/1115 ## diff -e /n/bootesdump/1990/1013/sys/src/9/68020/devpipe.c /n/bootesdump/1990/1115/sys/src/9/68020/devpipe.c 232a unlock(p); poperror(); . 223a lock(p); if(waserror()){ unlock(p); nexterror(); } . 174c panic("pipeopen"); . 30c Qinfo pipeinfo = { pipeiput, pipeoput, 0, pipestclose, "pipe" }; . ## diffname gnot/devpipe.c 1990/11151 ## diff -e /n/bootesdump/1990/1115/sys/src/9/68020/devpipe.c /n/bootesdump/1990/11151/sys/src/9/68020/devpipe.c 181c panic("pipeattach"); . ## diffname gnot/devpipe.c 1990/11161 ## diff -e /n/bootesdump/1990/11151/sys/src/9/68020/devpipe.c /n/bootesdump/1990/11161/sys/src/9/68020/devpipe.c 245,247c /* * free the structure */ if(decref(p) == 0){ lock(&pipealloc); p->next = pipealloc.free; pipealloc.free = p; unlock(&pipealloc); } if(p->ref < 0) panic("pipeexit"); . 231,235d 211,223d ## diffname gnot/devpipe.c 1990/1118 ## diff -e /n/bootesdump/1990/11161/sys/src/9/68020/devpipe.c /n/bootesdump/1990/1118/sys/src/9/68020/devpipe.c 323a /* * release stream for other half of pipe */ remote = RD(q)->ptr; streamexit(remote, 0); . 308a Stream *remote; . 225,226d 222,223c if(c->stream) . 213,214d 181c panic("pipeopen"); . ## diffname gnot/devpipe.c 1990/11211 ## diff -e /n/bootesdump/1990/1118/sys/src/9/68020/devpipe.c /n/bootesdump/1990/11211/sys/src/9/68020/devpipe.c 320,325d 261,272d 254c error(Egreg); . 239c if(c->qid.path & CHDIR) . 220,221c if(c->stream){ remote = c->stream->devq->ptr; if(streamclose(c) <= 0) streamexit(remote, 0); } . 215c p = &pipealloc.pipe[STREAMID(c->qid.path)/2]; . 213a Stream *remote; . 207c error(Eperm); . 201c error(Egreg); . 195c error(Egreg); . 166c remote = streamnew(c->type, c->dev, STREAMID(c->qid.path)^1, &pipeinfo, 1); . 151c p = &pipealloc.pipe[STREAMID(c->qid.path)/2]; . 144c error(Ebadarg); . 142c if(c->qid.path & CHDIR){ . 116c devdir(c, (Qid){STREAMQID(id, tab->qid.path),0}, tab->name, tab->length, tab->perm, dp); . 110c id = STREAMID(c->qid.path); . 98c p = &pipealloc.pipe[STREAMID(c->qid.path)/2]; . 89c c->qid = (Qid){CHDIR|STREAMQID(2*(p - pipealloc.pipe), 0), 0}; . 81c error(Enopipe); . 40,43c "data", {Sdataqid}, 0, 0600, "ctl", {Sctlqid}, 0, 0600, "data1", {Sdataqid}, 0, 0600, "ctl1", {Sctlqid}, 0, 0600, . ## diffname gnot/devpipe.c 1990/1210 # deleted ## diff -e /n/bootesdump/1990/11211/sys/src/9/68020/devpipe.c /n/bootesdump/1990/1210/sys/src/9/68020/devpipe.c 1,312d