Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/port/devpipe.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


## diffname port/devpipe.c 1990/0227
## diff -e /dev/null /n/bootesdump/1990/0227/sys/src/9/mips/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 port/devpipe.c 1990/0312
## diff -e /n/bootesdump/1990/0227/sys/src/9/mips/devpipe.c /n/bootesdump/1990/0312/sys/src/9/mips/devpipe.c
132c
	return streamwrite(c, va, n, 0);
.
## diffname port/devpipe.c 1990/0403
## diff -e /n/bootesdump/1990/0312/sys/src/9/mips/devpipe.c /n/bootesdump/1990/0403/sys/src/9/mips/devpipe.c
170a
	else{
		print("pipeoput losing block\n");
		freeb(bp);
	}
.
157c
	FLOWCTL(q);
.
14c
Qinfo pipeinfo = { pipeiput, pipeoput, 0, pipestclose, "pipe" };
.
## diffname port/devpipe.c 1990/0513
## diff -e /n/bootesdump/1990/0403/sys/src/9/mips/devpipe.c /n/bootesdump/1990/0513/sys/src/9/mips/devpipe.c
132c
	n = streamwrite(c, va, n, 0);
	poperror();
	return n;
.
## diffname port/devpipe.c 1990/0617
## diff -e /n/bootesdump/1990/0513/sys/src/9/mips/devpipe.c /n/bootesdump/1990/0617/sys/src/9/mips/devpipe.c
109,110c
	error(0, Eperm);
.
102d
95d
## diffname port/devpipe.c 1990/0629
## diff -e /n/bootesdump/1990/0617/sys/src/9/mips/devpipe.c /n/bootesdump/1990/0629/sys/src/9/mips/devpipe.c
196,220c
	bp = allocb(0);
	bp->type = M_HANGUP;
	PUTNEXT(q, bp);
.
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 */
	poperror();
.
63a

	/*
	 *  up the inuse count of each stream to reflect the
	 *  pointer from the other stream.
	 */
	if(streamenter(c->stream)<0)
		panic("pipeattach");
	if(streamenter(nc->stream)<0)
		panic("pipeattach");
.
61a
	c->stream->devq->ptr = (Stream *)nc->stream;
	nc->stream->devq->ptr = (Stream *)c->stream;
.
34a
	int i;

.
## diffname port/devpipe.c 1990/0801
## diff -e /n/bootesdump/1990/0629/sys/src/9/mips/devpipe.c /n/bootesdump/1990/0801/sys/src/9/mips/devpipe.c
90,93c
	streamstat(c, db, "pipe");
.
## diffname port/devpipe.c 1990/1009
## diff -e /n/bootesdump/1990/0801/sys/src/9/mips/devpipe.c /n/bootesdump/1990/1009/sys/src/9/mips/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 port/devpipe.c 1990/1011
## diff -e /n/bootesdump/1990/1009/sys/src/9/mips/devpipe.c /n/bootesdump/1990/1011/sys/src/9/mips/devpipe.c
234d
227,231d
223c
	 *  take care of associated streams
.
204,205c
	if(decref(p) < 0)
		panic("pipeexit");
	if(p->ref == 0){
.
## diffname port/devpipe.c 1990/1013
## diff -e /n/bootesdump/1990/1011/sys/src/9/mips/devpipe.c /n/bootesdump/1990/1013/sys/src/9/mips/devpipe.c
92c
	if(incref(p) <= 1)
		panic("pipeclone");
.
78c
	if(incref(p) != 1)
		panic("pipeattach");
.
## diffname port/devpipe.c 1990/1104
## diff -e /n/bootesdump/1990/1013/sys/src/9/mips/devpipe.c /n/bootesdump/1990/1104/sys/src/9/mips/devpipe.c
233c

	lock(p);
	if(--(p->ref) < 0)
		panic("pipeexit");
	if(p->ref == 0){
		lock(&pipealloc);
		p->next = pipealloc.free;
		pipealloc.free = p;
		unlock(&pipealloc);
	}
	unlock(p);
.
204,216d
79a
	}
.
78c
	if(++(p->ref) != 1){
		print("pipattach pipe half %d ref %d\n", p - pipealloc.pipe, p->ref);
.
## diffname port/devpipe.c 1990/1113
## diff -e /n/bootesdump/1990/1104/sys/src/9/mips/devpipe.c /n/bootesdump/1990/1113/sys/src/9/mips/devpipe.c
30c
Qinfo pipeinfo =
{
	pipeiput,
	pipeoput,
	0,
	pipestclose,
	"pipe"
};
.
## diffname port/devpipe.c 1990/1115
## diff -e /n/bootesdump/1990/1113/sys/src/9/mips/devpipe.c /n/bootesdump/1990/1115/sys/src/9/mips/devpipe.c
239a
	poperror();
	pipeexit(p);
.
229,238d
219a
	lock(p);
	if(waserror()){
		unlock(p);
		nexterror();
	}
.
212a
pipeexit(Pipe *p)
{
	if(decref(p) < 0)
		panic("pipeexit");
	if(p->ref == 0){
		lock(&pipealloc);
		p->next = pipealloc.free;
		pipealloc.free = p;
		unlock(&pipealloc);
	}
}

void
.
88d
85,86c
	if(incref(p) != 1)
.
## diffname port/devpipe.c 1990/11161
## diff -e /n/bootesdump/1990/1115/sys/src/9/mips/devpipe.c /n/bootesdump/1990/11161/sys/src/9/mips/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
181a
	} else {
		/*
		 *  increment the inuse count of the other
		 *  stream
		 */
		if(streamenter(local->devq->ptr)<0)
			panic("pipeattach2");
.
## diffname port/devpipe.c 1990/1118
## diff -e /n/bootesdump/1990/11161/sys/src/9/mips/devpipe.c /n/bootesdump/1990/1118/sys/src/9/mips/devpipe.c
330a

	/*
	 *  release stream for other half of pipe
	 */
	remote = RD(q)->ptr;
	streamexit(remote, 0);
.
315a
	Stream *remote;
.
232,233d
229,230c
	if(c->stream)
.
220,221d
181,188c
			panic("pipeopen");
.
## diffname port/devpipe.c 1990/11211
## diff -e /n/bootesdump/1990/1118/sys/src/9/mips/devpipe.c /n/bootesdump/1990/11211/sys/src/9/mips/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 port/devpipe.c 1991/0125
## diff -e /n/bootesdump/1990/1210/sys/src/9/mips/devpipe.c /n/bootesdump/1991/0125/sys/src/9/port/devpipe.c
80a
		close(c);
.
## diffname port/devpipe.c 1991/0302
## diff -e /n/bootesdump/1991/0125/sys/src/9/port/devpipe.c /n/bootesdump/1991/0302/sys/src/9/port/devpipe.c
309a
	if(q->next == 0)
		return;
.
## diffname port/devpipe.c 1991/0314
## diff -e /n/bootesdump/1991/0302/sys/src/9/port/devpipe.c /n/bootesdump/1991/0314/sys/src/9/port/devpipe.c
224,225c
		if(streamclose(c) <= 0){
			if(remote)
				streamexit(remote, 0);
		}
.
## diffname port/devpipe.c 1991/0411
## diff -e /n/bootesdump/1991/0314/sys/src/9/port/devpipe.c /n/bootesdump/1991/0411/sys/src/9/port/devpipe.c
257c
pipewrite(Chan *c, void *va, long n, ulong offset)
.
244c
piperead(Chan *c, void *va, long n, ulong offset)
.
## diffname port/devpipe.c 1991/0419
## diff -e /n/bootesdump/1991/0411/sys/src/9/port/devpipe.c /n/bootesdump/1991/0419/sys/src/9/port/devpipe.c
127a
Chan*
pipeclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

.
## diffname port/devpipe.c 1991/0427
## diff -e /n/bootesdump/1991/0419/sys/src/9/port/devpipe.c /n/bootesdump/1991/0427/sys/src/9/port/devpipe.c
128,133d
## diffname port/devpipe.c 1991/0920
## diff -e /n/bootesdump/1991/0427/sys/src/9/port/devpipe.c /n/bootesdump/1991/0920/sys/src/9/port/devpipe.c
278c
	if(bp->type != M_HANGUP)
		FLOWCTL(q);
.
## diffname port/devpipe.c 1991/1109
## diff -e /n/bootesdump/1991/0920/sys/src/9/port/devpipe.c /n/bootesdump/1991/1109/sys/src/9/port/devpipe.c
117c
	devdir(c, (Qid){STREAMQID(id, tab->qid.path),0}, tab->name, tab->length, eve, tab->perm, dp);
.
## diffname port/devpipe.c 1991/1115
## diff -e /n/bootesdump/1991/1109/sys/src/9/port/devpipe.c /n/bootesdump/1991/1115/sys/src/9/port/devpipe.c
207a
	USED(c, db);
.
201a
	USED(c);
.
195a
	USED(c, name, omode, perm);
.
## diffname port/devpipe.c 1991/1227
## diff -e /n/bootesdump/1991/1115/sys/src/9/port/devpipe.c /n/bootesdump/1991/1227/sys/src/9/port/devpipe.c
303d
287,288c
 *  send the block to the other side
.
230a
		qunlock(p);
.
227c
		if(streamclose(c) == 0){
.
225a
		qlock(p);
.
223c
	 *  take care of local and remote streams
.
184c
	qunlock(p);
.
181,182c
		streamenter(local->devq->ptr);
.
178,179c
		 *  keep other side around till last close of this side
.
176c
	} else if(local->opens == 1){
.
167c
		remote = streamnew(c->type, c->dev, STREAMID(c->qid.path)^1, &pipeinfo,1);
.
165c
		 *  first open, create the other end also
.
160c
	qlock(p);
.
155,157c
		qunlock(p);
.
153d
90a
	c->dev = 0;
.
16c
	QLock;
.
## diffname port/devpipe.c 1992/0111
## diff -e /n/bootesdump/1991/1227/sys/src/9/port/devpipe.c /n/bootesdump/1992/0111/sys/src/9/port/devpipe.c
6c
#include	"../port/error.h"
.
## diffname port/devpipe.c 1992/0114
## diff -e /n/bootesdump/1992/0111/sys/src/9/port/devpipe.c /n/bootesdump/1992/0114/sys/src/9/port/devpipe.c
82c
		exhausted("pipes");
.
## diffname port/devpipe.c 1992/0305
## diff -e /n/bootesdump/1992/0114/sys/src/9/port/devpipe.c /n/bootesdump/1992/0305/sys/src/9/port/devpipe.c
279,281c
	FLOWCTL(q, bp);
.
## diffname port/devpipe.c 1992/0321
## diff -e /n/bootesdump/1992/0305/sys/src/9/port/devpipe.c /n/bootesdump/1992/0321/sys/src/9/port/devpipe.c
2c
#include	"../port/lib.h"
.
## diffname port/devpipe.c 1992/0619
## diff -e /n/bootesdump/1992/0321/sys/src/9/port/devpipe.c /n/bootesdump/1992/0619/sys/src/9/port/devpipe.c
9d
## diffname port/devpipe.c 1992/0621
## diff -e /n/bootesdump/1992/0619/sys/src/9/port/devpipe.c /n/bootesdump/1992/0621/sys/src/9/port/devpipe.c
313a
}

Pipe*
getpipe(ulong path)
{
	Pipe *p;

	lock(&pipealloc);
	for(p = pipealloc.pipe; p; p = p->next) {
		if(path == p->path) {
			unlock(&pipealloc);
			return p;
		}
	}
	unlock(&pipealloc);
	panic("getpipe");
	return 0;
.
269,271d
259c
	if(waserror()) {
.
248,249c

	return streamread(c, va, n);
.
239,240d
237a
		free(p);
.
235,236c
		l = &pipealloc.pipe;
		for(f = *l; f; f = f->next) {
			if(f == p) {
				*l = p->next;
				break;
			}
			l = &p->next;
		}
.
215c
	p = getpipe(STREAMID(c->qid.path)/2);
.
212c
	Pipe *p, *f, **l;
.
173c
	}
	else
	if(local->opens == 1){
.
164c
		other = STREAMID(c->qid.path)^1;
		remote = streamnew(c->type, c->dev, other, &pipeinfo,1);
.
152c
	p = getpipe(STREAMID(c->qid.path)/2);
.
140a
	int other;
.
99c
	p = getpipe(STREAMID(c->qid.path)/2);
.
89c
	c->qid = (Qid){CHDIR|STREAMQID(2*p->path, 0), 0};
.
78,86c
	p->path = ++pipealloc.path;
	p->next = pipealloc.pipe;
	pipealloc.pipe = p;
.
75a
	p = smalloc(sizeof(Pipe));
	p->ref = 1;
.
57,63d
51,53d
38c
Dirtab pipedir[] =
{
.
28a

.
25a
static Pipe *getpipe(ulong);
.
22,23c
	Pipe	*pipe;
	ulong	path;
.
19c
struct
.
16a
	ulong	path;
.
11d
## diffname port/devpipe.c 1992/0623
## diff -e /n/bootesdump/1992/0621/sys/src/9/port/devpipe.c /n/bootesdump/1992/0623/sys/src/9/port/devpipe.c
324c
	error(Enonexist);
.
164,166c
	} else if(local->opens == 1){
.
## diffname port/devpipe.c 1992/0625
## diff -e /n/bootesdump/1992/0623/sys/src/9/port/devpipe.c /n/bootesdump/1992/0625/sys/src/9/port/devpipe.c
322,323c
	panic("getpipe");
	return 0;		/* not reached */
.
232c
			l = &f->next;
.
## diffname port/devpipe.c 1992/0711
## diff -e /n/bootesdump/1992/0625/sys/src/9/port/devpipe.c /n/bootesdump/1992/0711/sys/src/9/port/devpipe.c
254a
	USED(offset);
.
241a
	USED(offset);
.
216c
				streamexit(remote);
.
## diffname port/devpipe.c 1992/0714
## diff -e /n/bootesdump/1992/0711/sys/src/9/port/devpipe.c /n/bootesdump/1992/0714/sys/src/9/port/devpipe.c
258c
		postnote(u->p, 1, "sys: write on closed pipe", NUser);
.
## diffname port/devpipe.c 1992/0821
## diff -e /n/bootesdump/1992/0714/sys/src/9/port/devpipe.c /n/bootesdump/1992/0821/sys/src/9/port/devpipe.c
267,268c
 *  send a block upstream to the process.
 *  sleep until there's room upstream.
.
256a

	/* avoid notes when pipe is a mounted stream */
	if(c->flag & CMSG)
		return streamwrite(c, va, n, 0);

.
## diffname port/devpipe.c 1992/0826
## diff -e /n/bootesdump/1992/0821/sys/src/9/port/devpipe.c /n/bootesdump/1992/0826/sys/src/9/port/devpipe.c
120c
	streamstat(c, db, "pipe", 0666);
.
## diffname port/devpipe.c 1993/0324
## diff -e /n/bootesdump/1992/0826/sys/src/9/port/devpipe.c /n/bootesdump/1993/0324/sys/src/9/port/devpipe.c
173c
	c->mode = openmode(omode);
.
## diffname port/devpipe.c 1993/0501
## diff -e /n/bootesdump/1993/0324/sys/src/9/port/devpipe.c /n/fornaxdump/1993/0501/sys/src/brazil/port/devpipe.c
263c
		postnote(up, 1, "sys: write on closed pipe", NUser);
.
173c
	c->mode = omode&~OTRUNC;
.
## diffname port/devpipe.c 1993/0528
## diff -e /n/fornaxdump/1993/0501/sys/src/brazil/port/devpipe.c /n/fornaxdump/1993/0528/sys/src/brazil/port/devpipe.c
269,330d
266,267d
262,264c
	switch(NETTYPE(c->qid.path)){
	case Qdata0:
		return qwrite(p->q[1], va, n);
	case Qdata1:
		return qwrite(p->q[0], va, n);
	default:
		panic("piperead");
.
258,260c
	p = c->aux;
.
255a
	Pipe *p;

.
246c
	p = c->aux;

	switch(NETTYPE(c->qid.path)){
	case Qdir:
		return devdirread(c, va, n, pipedir, NPIPEDIR, pipegen);
	case Qdata0:
		return qread(p->q[0], va, n);
	case Qdata1:
		return qread(p->q[1], va, n);
	default:
		panic("piperead");
	}
	return -1;	/* not reached */
.
243,244d
241a
	Pipe *p;

.
236a

	qunlock(p);
.
234a
		free(p->q[0]);
		free(p->q[1]);
.
224c
	if(p->qref[0] == 0 && p->qref[1] == 0){
		qreopen(p->q[0]);
		qreopen(p->q[1]);
	}

	/*
	 *  free the structure on last close
	 */
	p->ref--;
	if(p->ref == 0){
		qunlock(p);
.
222c
	 *  if both sides are closed, they are reusable
.
218c
		break;
	case Qdata1:
		p->qref[1]--;
		if(p->qref[1] == 0){
			qclose(p->q[1]);
			qhangup(p->q[0]);
		}
		break;
.
211,216c
	switch(NETTYPE(c->qid.path)){
	case Qdata0:
		p->qref[0]--;
		if(p->qref[0] == 0){
			qclose(p->q[0]);
			qhangup(p->q[1]);
.
209c
	 *  closing either side hangs up the stream
.
206c
	p = c->aux;
	qlock(p);
.
204d
171d
148,168c
	switch(NETTYPE(c->qid.path)){
	case Qdata0:
		p->qref[0]++;
		break;
	case Qdata1:
		p->qref[1]++;
		break;
.
142,146c
	p = c->aux;
.
130,131d
120c
	Pipe *p;
	Dir dir;

	p = c->aux;

	switch(NETTYPE(c->qid.path)){
	case Qdir:
		devdir(c, c->qid, ".", 2*DIRLEN, eve, CHDIR|0555, &dir);
		break;
	case Qdata0:
		devdir(c, c->qid, "data", p->q[0]->len, eve, 0660, &dir);
		break;
	case Qdata1:
		devdir(c, c->qid, "data1", p->q[1]->len, eve, 0660, &dir);
		break;
	default:
		panic("pipestat");
	}
	convD2M(&dir, db);
.
106c
	devdir(c, (Qid){NETQID(id, tab->qid.path),0}, tab->name, tab->length, eve, tab->perm, dp);
.
100c
	id = NETID(c->qid.path);
.
90,91c
	qlock(p);
	p->ref++;
	qunlock(p);
.
88c
	p = c->aux;
.
78c
	c->qid = (Qid){CHDIR|NETQID(2*p->path, Qdir), 0};
	c->aux = p;
.
71a
	p->q[0] = qopen(64*1024, 0, 0);
	if(p->q[0] == 0){
		free(p);
		exhausted("memory");
	}
	p->q[0]->state &= ~Qmsg;
	p->q[1] = qopen(32*1024, 0, 0);
	if(p->q[1] == 0){
		free(p->q[0]);
		free(p);
		exhausted("memory");
	}
	p->q[1]->state &= ~Qmsg;

.
69c
	p = malloc(sizeof(Pipe));
	if(p == 0)
		exhausted("memory");
.
42,45c
	"data",		{Qdata0},	0,			0600,
	"data1",	{Qdata1},	0,			0600,
.
33,37c
	Qdir,
	Qdata0,
	Qdata1,
.
26,31c
enum
.
16a
	Queue	*q[2];
	int	qref[2];
.
15a
	int	ref;
.
13d
8a
#include	"netif.h"
.
## diffname port/devpipe.c 1993/0530
## diff -e /n/fornaxdump/1993/0528/sys/src/brazil/port/devpipe.c /n/fornaxdump/1993/0530/sys/src/brazil/port/devpipe.c
145c
		devdir(c, c->qid, "data1", qlen(p->q[1]), eve, 0660, &dir);
.
142c
		devdir(c, c->qid, "data", qlen(p->q[0]), eve, 0660, &dir);
.
80d
73,74c
	p->q[1] = qopen(32*1024, 0, 0, 0);
.
68c
	p->q[0] = qopen(64*1024, 0, 0, 0);
.
## diffname port/devpipe.c 1993/0601
## diff -e /n/fornaxdump/1993/0530/sys/src/brazil/port/devpipe.c /n/fornaxdump/1993/0601/sys/src/brazil/port/devpipe.c
306c
		return qwrite(p->q[0], va, n, 0);
.
304c
		return qwrite(p->q[1], va, n, 0);
.
## diffname port/devpipe.c 1993/0725
## diff -e /n/fornaxdump/1993/0601/sys/src/brazil/port/devpipe.c /n/fornaxdump/1993/0725/sys/src/brazil/port/devpipe.c
309a

	poperror();
.
306c
		n = qwrite(p->q[0], va, n, 0);
		break;

.
304c
		n = qwrite(p->q[1], va, n, 0);
		break;

.
299a
	if(waserror()) {
		postnote(up, 1, "sys: write on closed pipe", NUser);
		error(Ehungup);
	}

.
## diffname port/devpipe.c 1993/0911
## diff -e /n/fornaxdump/1993/0725/sys/src/brazil/port/devpipe.c /n/fornaxdump/1993/0911/sys/src/brazil/port/devpipe.c
301c
		/* avoid notes when pipe is a mounted queue */
		if((c->flag & CMSG) == 0)
			postnote(up, 1, "sys: write on closed pipe", NUser);
.
## diffname port/devpipe.c 1993/1106
## diff -e /n/fornaxdump/1993/0911/sys/src/brazil/port/devpipe.c /n/fornaxdump/1993/1106/sys/src/brazil/port/devpipe.c
180c
	c->mode = openmode(omode);
.
## diffname port/devpipe.c 1993/1111
## diff -e /n/fornaxdump/1993/1106/sys/src/brazil/port/devpipe.c /n/fornaxdump/1993/1111/sys/src/brazil/port/devpipe.c
234a
	
.
225,232d
215,223c
	if(c->flag & COPEN){
		/*
		 *  closing either side hangs up the stream
		 */
		switch(NETTYPE(c->qid.path)){
		case Qdata0:
			p->qref[0]--;
			if(p->qref[0] == 0){
				qclose(p->q[0]);
				qhangup(p->q[1]);
			}
			break;
		case Qdata1:
			p->qref[1]--;
			if(p->qref[1] == 0){
				qclose(p->q[1]);
				qhangup(p->q[0]);
			}
			break;
.
100a
	if(c->flag & COPEN){
		switch(NETTYPE(c->qid.path)){
		case Qdata0:
			p->qref[0]++;
			break;
		case Qdata1:
			p->qref[1]++;
			break;
		}
	}
.
68c
	p->q[0] = qopen(32*1024, 0, 0, 0);
.
## diffname port/devpipe.c 1994/0503
## diff -e /n/fornaxdump/1993/1111/sys/src/brazil/port/devpipe.c /n/fornaxdump/1994/0503/sys/src/brazil/port/devpipe.c
73c
	p->q[1] = qopen(conf.pipeqsize, 0, 0, 0);
.
68c
	p->q[0] = qopen(conf.pipeqsize, 0, 0, 0);
.
45a
	if(conf.pipeqsize == 0){
		if(conf.nmach > 1)
			conf.pipeqsize = 256*1024;
		else
			conf.pipeqsize = 32*1024;
	}
.
41c
#define NPIPEDIR 2
.
## diffname port/devpipe.c 1994/0804
## diff -e /n/fornaxdump/1994/0503/sys/src/brazil/port/devpipe.c /n/fornaxdump/1994/0804/sys/src/brazil/port/devpipe.c
281,283c
	} else
		qunlock(p);
.
268,277d
247a
				qclose(p->q[1]);
.
246d
240a
				qclose(p->q[0]);
.
239d
226c
	Pipe *p;
.
88,89d
25d
## diffname port/devpipe.c 1994/0902
## diff -e /n/fornaxdump/1994/0804/sys/src/brazil/port/devpipe.c /n/fornaxdump/1994/0902/sys/src/brazil/port/devpipe.c
320c
		n = qwrite(p->q[0], va, n);
.
316c
		n = qwrite(p->q[1], va, n);
.
## diffname port/devpipe.c 1995/0106
## diff -e /n/fornaxdump/1994/0902/sys/src/brazil/port/devpipe.c /n/fornaxdump/1995/0106/sys/src/brazil/port/devpipe.c
304a
	if((getstatus()&IE) == 0)
		print("pipewrite hi %lux\n", getcallerpc(c));
.
## diffname port/devpipe.c 1995/0108
## diff -e /n/fornaxdump/1995/0106/sys/src/brazil/port/devpipe.c /n/fornaxdump/1995/0108/sys/src/brazil/port/devpipe.c
330a
}

long
pipebwrite(Chan *c, Block *bp, ulong offset)
{
	return devbwrite(c, bp, offset);
.
293a
Block*
pipebread(Chan *c, long n, ulong offset)
{
	return devbread(c, n, offset);
}

.
## diffname port/devpipe.c 1995/0714
## diff -e /n/fornaxdump/1995/0108/sys/src/brazil/port/devpipe.c /n/fornaxdump/1995/0714/sys/src/brazil/port/devpipe.c
342c
	long n;
	Pipe *p;

	USED(offset);

	if(waserror()) {
		/* avoid notes when pipe is a mounted queue */
		if((c->flag & CMSG) == 0)
			postnote(up, 1, "sys: write on closed pipe", NUser);
		error(Ehungup);
	}

	p = c->aux;
	switch(NETTYPE(c->qid.path)){
	case Qdata0:
		n = qbwrite(p->q[1], bp);
		break;

	case Qdata1:
		n = qbwrite(p->q[0], bp);
		break;

	default:
		panic("pipebwrite");
	}

	poperror();
	return n;
.
332c
		panic("pipewrite");
.
296a
	Pipe *p;

	USED(offset);

	p = c->aux;

	switch(NETTYPE(c->qid.path)){
	case Qdata0:
		return qbread(p->q[0], n);
	case Qdata1:
		return qbread(p->q[1], n);
	}

.
## diffname port/devpipe.c 1995/0726
## diff -e /n/fornaxdump/1995/0714/sys/src/brazil/port/devpipe.c /n/fornaxdump/1995/0726/sys/src/brazil/port/devpipe.c
209d
207c
piperemove(Chan*)
.
202d
200c
pipecreate(Chan*, char*, int, ulong)
.
## diffname port/devpipe.c 1995/0804
## diff -e /n/fornaxdump/1995/0726/sys/src/brazil/port/devpipe.c /n/fornaxdump/1995/0804/sys/src/brazil/port/devpipe.c
375a
		n = 0;
.
356,357d
351c
pipebwrite(Chan *c, Block *bp, ulong)
.
320,321d
316c
pipewrite(Chan *c, void *va, long n, ulong)
.
297,298d
275,276d
271c
piperead(Chan *c, void *va, long n, ulong)
.
214d
212c
pipewstat(Chan*, char*)
.
## diffname port/devpipe.c 1996/0223
## diff -e /n/fornaxdump/1995/0804/sys/src/brazil/port/devpipe.c /n/fornaxdump/1996/0223/sys/src/brazil/port/devpipe.c
8d
## diffname port/devpipe.c 1997/0327
## diff -e /n/fornaxdump/1996/0223/sys/src/brazil/port/devpipe.c /n/emeliedump/1997/0327/sys/src/brazil/port/devpipe.c
372a

Dev pipedevtab = {
	devreset,
	pipeinit,
	pipeattach,
	pipeclone,
	pipewalk,
	pipestat,
	pipeopen,
	devcreate,
	pipeclose,
	piperead,
	pipebread,
	pipewrite,
	pipebwrite,
	devremove,
	devwstat,
};
.
342c
static long
.
314c
	if(!islo())
.
309c
static long
.
288c
static Block*
.
268c
static long
.
239c
				qhangup(p->q[0], 0);
.
232c
				qhangup(p->q[1], 0);
.
198,216c
static void
.
166c
static Chan*
.
139c
static void
.
133c
static int
.
117c
static int
.
94c
static Chan*
.
60c
static Chan*
.
52,56d
41c
static void
.
## diffname port/devpipe.c 1997/0408
## diff -e /n/emeliedump/1997/0327/sys/src/brazil/port/devpipe.c /n/emeliedump/1997/0408/sys/src/brazil/port/devpipe.c
351a
	'|',
	"pipe",

.
## diffname port/devpipe.c 1998/0319
## diff -e /n/emeliedump/1997/0408/sys/src/brazil/port/devpipe.c /n/emeliedump/1998/0319/sys/src/brazil/port/devpipe.c
287c
pipewrite(Chan *c, void *va, long n, vlong)
.
246c
piperead(Chan *c, void *va, long n, vlong)
.
## diffname port/devpipe.c 1998/0512
## diff -e /n/emeliedump/1998/0319/sys/src/brazil/port/devpipe.c /n/emeliedump/1998/0512/sys/src/brazil/port/devpipe.c
223c

.
## diffname port/devpipe.c 1999/0219
## diff -e /n/emeliedump/1998/0512/sys/src/brazil/port/devpipe.c /n/emeliedump/1999/0219/sys/src/brazil/port/devpipe.c
329c
		nexterror();
.
297c
		nexterror();
.
## diffname port/devpipe.c 1999/0501
## diff -e /n/emeliedump/1999/0219/sys/src/brazil/port/devpipe.c /n/emeliedump/1999/0501/sys/src/brazil/port/devpipe.c
292c
		print("pipewrite hi %lux\n", getcallerpc(&c));
.
## diffname port/devpipe.c 1999/1230
## diff -e /n/emeliedump/1999/0501/sys/src/brazil/port/devpipe.c /n/emeliedump/1999/1230/sys/src/9/port/devpipe.c
116a
	if(i == DEVDOTDOT){
		devdir(c, c->qid, "#|", 0, eve, CHDIR|0555, dp);
		return 1;
	}

.
## diffname port/devpipe.c 2000/0516
## diff -e /n/emeliedump/1999/1230/sys/src/9/port/devpipe.c /n/emeliedump/2000/0516/sys/src/9/port/devpipe.c
128c
	p = c->aux;
	switch(tab->qid.path){
	case Qdata0:
		len = qlen(p->q[0]);
		break;
	case Qdata1:
		len = qlen(p->q[1]);
		break;
	default:
		len = tab->length;
		break;
	}
	devdir(c, (Qid){NETQID(id, tab->qid.path),0}, tab->name, len, eve, tab->perm, dp);
.
115a
	int len;
	Pipe *p;
.
## diffname port/devpipe.c 2000/1201
## diff -e /n/emeliedump/2000/0516/sys/src/9/port/devpipe.c /n/emeliedump/2000/1201/sys/src/9/port/devpipe.c
125,126d
## diffname port/devpipe.c 2001/0527
## diff -e /n/emeliedump/2000/1201/sys/src/9/port/devpipe.c /n/emeliedump/2001/0527/sys/src/9/port/devpipe.c
375d
183c
	if(c->qid.type & QTDIR){
.
172c
	n = convD2M(&dir, db, n);
	if(n < BIT16SZ)
		error(Eshortstat);
	return n;
.
161c
		devdir(c, c->qid, ".", 0, eve, DMDIR|0555, &dir);
.
151,152c
static int
pipestat(Chan *c, uchar *db, int n)
.
148c
	Walkqid *wq;
	Pipe *p;

	wq = devwalk(c, nc, name, nname, pipedir, NPIPEDIR, pipegen);
	if(wq != nil && wq->clone != nil && wq->clone != c){
		p = c->aux;
		qlock(p);
		p->ref++;
		if(c->flag & COPEN){
			print("channel open in pipewalk\n");
			switch(NETTYPE(c->qid.path)){
			case Qdata0:
				p->qref[0]++;
				break;
			case Qdata1:
				p->qref[1]++;
				break;
			}
		}
		qunlock(p);
	}
	return wq;
.
145,146c
static Walkqid*
pipewalk(Chan *c, Chan *nc, char **name, int nname)
.
140c
	mkqid(&q, NETQID(NETID(c->qid.path), tab->qid.path), 0, QTFILE);
	devdir(c, q, tab->name, len, eve, tab->perm, dp);
.
129c
	switch((ulong)tab->qid.path){
.
126a

.
123,124d
120c
		devdir(c, c->qid, "#|", 0, eve, DMDIR|0555, dp);
.
117a
	Qid q;
.
115d
113c
pipegen(Chan *c, char*, Dirtab *tab, int ntab, int i, Dir *dp)
.
89,111d
83c
	mkqid(&c->qid, NETQID(2*p->path, Qdir), 0, QTDIR);
.
39c
#define NPIPEDIR 3
.
36,37c
	".",		{Qdir,0,QTDIR},	0,		DMDIR|0500,
	"data",		{Qdata0},	0,		0600,
	"data1",	{Qdata1},	0,		0600,
.
## diffname port/devpipe.c 2001/0813
## diff -e /n/emeliedump/2001/0527/sys/src/9/port/devpipe.c /n/emeliedump/2001/0813/sys/src/9/port/devpipe.c
95d
92a
	Qid q;
.
## diffname port/devpipe.c 2001/1017
## diff -e /n/emeliedump/2001/0813/sys/src/9/port/devpipe.c /n/emeliedump/2001/1017/sys/src/9/port/devpipe.c
100a
	i++;	/* skip . */
.
## diffname port/devpipe.c 2001/1207
## diff -e /n/emeliedump/2001/1017/sys/src/9/port/devpipe.c /n/emeliedump/2001/1207/sys/src/9/port/devpipe.c
209a
	c->iounit = qiomaxatomic;
.
## diffname port/devpipe.c 2002/0109
## diff -e /n/emeliedump/2001/1207/sys/src/9/port/devpipe.c /n/emeliedump/2002/0109/sys/src/9/port/devpipe.c
377a
	devshutdown,
.
## diffname port/devpipe.c 2002/0922
## diff -e /n/emeliedump/2002/0109/sys/src/9/port/devpipe.c /n/emeliedump/2002/0922/sys/src/9/port/devpipe.c
167c
		devdir(c, c->qid, "data1", qlen(p->q[1]), eve, 0600, &dir);
.
164c
		devdir(c, c->qid, "data", qlen(p->q[0]), eve, 0600, &dir);
.

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.