Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/boot/fcall.c

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


## diffname boot/fcall.c 2001/0214
## diff -e /dev/null /n/emeliedump/2001/0214/sys/src/9/boot/fcall.c
0a
#include <u.h>
#include <libc.h>
#include <auth.h>
#include <fcall.h>
#include <ip.h>

#include "boot.h"

/*
 * reassemble 9P messages for stream based protocols
 * interposed between devmnt and the network by srv for tcp connections
 * fcall expects devmnt on fd0, network fd1
 */
static uchar msglen[256] =
{
	[Tnop]		3,
	[Rnop]		3,
	[Tsession]	3+CHALLEN,
	[Rsession]	3+NAMELEN+DOMLEN+CHALLEN,
	[Terror]	0,
	[Rerror]	67,
	[Tflush]	5,
	[Rflush]	3,
	[Tattach]	5+2*NAMELEN+TICKETLEN+AUTHENTLEN,
	[Rattach]	13+AUTHENTLEN,
	[Tclone]	7,
	[Rclone]	5,
	[Twalk]		33,
	[Rwalk]		13,
	[Topen]		6,
	[Ropen]		13,
	[Tcreate]	38,
	[Rcreate]	13,
	[Tread]		15,
	[Rread]		8,
	[Twrite]	16,
	[Rwrite]	7,
	[Tclunk]	5,
	[Rclunk]	5,
	[Tremove]	5,
	[Rremove]	5,
	[Tstat]		5,
	[Rstat]		121,
	[Twstat]	121,
	[Rwstat]	5,
	[Tclwalk]	35,
	[Rclwalk]	13,
};

enum
{
	Twritehdr	= 16,	/* Min bytes for Twrite */
	Rreadhdr	= 8,	/* Min bytes for Rread */
	Twritecnt	= 13,	/* Offset in byte stream of write count */
	Rreadcnt	= 5,	/* Offset for Readcnt */
};

void
echo(int f, int t)
{
	int n;
	char buf[MAXRPC];

	for(;;) {
		n = read9p(f, buf, MAXRPC);
		if(n <= 0)
			break;
		if(write(t, buf, n) < n)
			break;
	}
}

int
mntrpclen(uchar *d, int n)
{
	uchar t;
	int len, off;

	if(n < 1)
		return 0;

	t = d[0];
	switch(t) {			/* This is the type */
	default:
		len = msglen[t];
		if(len == 0)		/* Illegal type so consume */
			return n;
		if(n < len)
			return 0;
		return len;
	case Twrite:			/* Fmt: TGGFFOOOOOOOOCC */
		len = Twritehdr;	/* T = type, G = tag, F = fid */
		off = Twritecnt;	/* O = offset, C = count */
		break;
	case Rread:			/* Fmt: TGGFFCC */
		len = Rreadhdr;
		off = Rreadcnt;
		break;
	}
	if(n < off+2)
		return 0;

	len += d[off]|(d[off+1]<<8);
	if(n < len)
		return 0;

	return len;
}

int
pushfcall(int fd)
{
	int r, n, l, pfd[2];
	uchar *p, buf[MAXRPC];

	if(pipe(pfd) < 0){
		fprint(2, "pipe: %r\n");
		exits("pipe");
	}

	/* Downstream is just a copy process */
	switch(rfork(RFPROC|RFFDG|RFMEM)){
	case 0:
		close(pfd[1]);
		echo(pfd[0], fd);
		fprint(2, "echo finished\n");
		exits("echo done");
	case -1:
		fprint(2, "fcall fork failed: %r\n");
		exits("fork");
	}

	switch(rfork(RFPROC|RFFDG|RFMEM)){
	default:
		close(pfd[0]);
		return pfd[1];
	case 0:
		close(pfd[1]);
		break;
	case -1:
		fprint(2, "fcall fork failed: %r\n");
		exits("fork");
	}

	/* Dispatch only full RPC's to the mount driver */
	l = MAXRPC;
	p = buf;
	for(;;) {
		n = read(fd, p, l);
		if(n < 0)
			break;
		p += n;
		l -= n;

		for(;;) {
			r = mntrpclen(buf, p - buf);
			if(r == 0)
				break;

			if(write(pfd[0], buf, r) < 0)
				break;

			n = (p - buf) - r;
			memmove(buf, buf+r, n);
			p = buf+n;
			l = MAXRPC - n;
		}
	}
	abort();
	return 0;
}
.
## diffname boot/fcall.c 2001/0527 # deleted
## diff -e /n/emeliedump/2001/0214/sys/src/9/boot/fcall.c /n/emeliedump/2001/0527/sys/src/9/boot/fcall.c
1,171d

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.