## 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
|