File:  [Plan 9 NeXT] / lucent / sys / src / 9 / port / devroot.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 18:01:03 2018 UTC (8 years, 1 month ago) by root
Branches: lucent, MAIN
CVS tags: plan9, HEAD
Plan 9 NeXT

#include	"u.h"
#include	"../port/lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"../port/error.h"
#include	"devtab.h"

enum{
	Qdir=	0,
	Qbin,
	Qdev,
	Qenv,
	Qproc,
	Qnet,
	Qboot,		/* readable files */

	Nfiles=13,	/* max root files */	
};

extern ulong	bootlen;
extern uchar	bootcode[];

Dirtab rootdir[Nfiles]={
		"bin",		{Qbin|CHDIR},	0,	0777,
		"dev",		{Qdev|CHDIR},	0,	0777,
		"env",		{Qenv|CHDIR},	0,	0777,
		"proc",		{Qproc|CHDIR},	0,	0777,
		"net",		{Qnet|CHDIR},	0,	0777,
};

static uchar	*rootdata[Nfiles];
static int	nroot = Qboot - 1;

/*
 *  add a root file
 */
void
addrootfile(char *name, uchar *contents, ulong len)
{
	Dirtab *d;
	

	if(nroot >= Nfiles)
		panic("too many root files");
	rootdata[nroot] = contents;
	d = &rootdir[nroot];
	strcpy(d->name, name);
	d->length = len;
	d->perm = 0555;
	d->qid.path = nroot+1;
	nroot++;
}

void
rootreset(void)
{
	addrootfile("boot", bootcode, bootlen);	/* always have a boot file */
}

void
rootinit(void)
{
}

Chan*
rootattach(char *spec)
{
	return devattach('/', spec);
}

Chan*
rootclone(Chan *c, Chan *nc)
{
	return devclone(c, nc);
}

int	 
rootwalk(Chan *c, char *name)
{
	if(strcmp(name, "..") == 0) {
		c->qid.path = Qdir|CHDIR;
		return 1;
	}
	if((c->qid.path & ~CHDIR) != Qdir)
		return 0;
	return devwalk(c, name, rootdir, nroot, devgen);
}

void	 
rootstat(Chan *c, char *dp)
{
	devstat(c, dp, rootdir, nroot, devgen);
}

Chan*
rootopen(Chan *c, int omode)
{
	return devopen(c, omode, rootdir, nroot, devgen);
}

void	 
rootcreate(Chan *c, char *name, int omode, ulong perm)
{
	USED(c, name, omode, perm);
	error(Eperm);
}

/*
 * sysremove() knows this is a nop
 */
void	 
rootclose(Chan *c)
{
	USED(c);
}

long	 
rootread(Chan *c, void *buf, long n, ulong offset)
{
	ulong t;
	Dirtab *d;
	uchar *data;

	t = c->qid.path & ~CHDIR;
	if(t == Qdir)
		return devdirread(c, buf, n, rootdir, nroot, devgen);
	if(t < Qboot)
		return 0;

	d = &rootdir[t-1];
	data = rootdata[t-1];
	if(offset >= d->length)
		return 0;
	if(offset+n > d->length)
		n = d->length - offset;
	memmove(buf, data+offset, n);
	return n;
}

long	 
rootwrite(Chan *c, void *buf, long n, ulong offset)
{
	USED(c, buf, n, offset);
	error(Egreg);
	return 0;	/* not reached */
}

void	 
rootremove(Chan *c)
{
	USED(c);
	error(Eperm);
}

void	 
rootwstat(Chan *c, char *dp)
{
	USED(c, dp);
	error(Eperm);
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.