plan 9 kernel history: overview | file list | diff list

1999/0630/port/dev.c (diff list | history)

port/dev.c on 1990/0227
1990/0227    
#include	"u.h" 
1992/0321    
#include	"../port/lib.h" 
1990/0227    
#include	"mem.h" 
#include	"dat.h" 
#include	"fns.h" 
1992/0111    
#include	"../port/error.h" 
1990/0227    
 
1991/1220    
extern ulong	kerndate; 
 
1990/0227    
int 
devno(int c, int user) 
{ 
1992/1217    
	int i; 
1990/0227    
 
1997/0408    
	for(i = 0; devtab[i] != nil; i++) { 
		if(devtab[i]->dc == c) 
1992/1217    
			return i; 
1990/0227    
	} 
1997/0408    
	if(user == 0) 
		panic("devno %C 0x%ux", c, c); 
1992/1217    
 
1997/0408    
	return -1; 
1990/0227    
} 
 
void 
1998/0326    
devdir(Chan *c, Qid qid, char *n, vlong length, char *user, long perm, Dir *db) 
1990/0227    
{ 
	strcpy(db->name, n); 
	db->qid = qid; 
1997/0408    
	db->type = devtab[c->type]->dc; 
1990/0227    
	db->dev = c->dev; 
1990/11211    
	if(qid.path & CHDIR) 
1990/0227    
		db->mode = CHDIR|perm; 
	else 
		db->mode = perm; 
1993/0323    
	if(c->flag&CMSG) 
		db->mode |= CHMOUNT; 
1990/0227    
	db->atime = seconds(); 
1991/1220    
	db->mtime = kerndate; 
1998/0326    
	db->length = length; 
1993/1210    
	memmove(db->uid, user, NAMELEN); 
	memmove(db->gid, eve, NAMELEN); 
1990/0227    
} 
 
int 
devgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp) 
{ 
	if(tab==0 || i>=ntab) 
		return -1; 
	tab += i; 
1991/1109    
	devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp); 
1990/0227    
	return 1; 
} 
 
1997/0327    
void 
devreset(void) 
{ 
} 
 
void 
devinit(void) 
{ 
} 
 
Chan* 
1990/0227    
devattach(int tc, char *spec) 
{ 
	Chan *c; 
1993/0501    
	char buf[NAMELEN+4]; 
1990/0227    
 
	c = newchan(); 
1990/11211    
	c->qid = (Qid){CHDIR, 0}; 
1990/0227    
	c->type = devno(tc, 0); 
1999/0629    
	sprint(buf, "#%C%s", tc, spec==nil? "" : spec); 
	c->name = newcname(buf); 
1990/0227    
	return c; 
} 
 
1997/0327    
Chan* 
1990/0227    
devclone(Chan *c, Chan *nc) 
{ 
1990/0329    
	if(c->flag & COPEN) 
1997/0408    
		panic("clone of open file type %C\n", devtab[c->type]->dc); 
1993/0501    
 
1990/0227    
	if(nc == 0) 
		nc = newchan(); 
1993/0501    
 
1990/0227    
	nc->type = c->type; 
1991/0421    
	nc->dev = c->dev; 
1990/0227    
	nc->mode = c->mode; 
	nc->qid = c->qid; 
	nc->offset = c->offset; 
	nc->flag = c->flag; 
1998/0829    
	nc->mh = c->mh; 
	if(c->mh != nil) 
		incref(c->mh); 
1991/0427    
	nc->mountid = c->mountid; 
1991/0421    
	nc->aux = c->aux; 
1990/0303    
	nc->mchan = c->mchan; 
	nc->mqid = c->mqid; 
1993/1013    
	nc->mcp = c->mcp; 
1990/0227    
	return nc; 
} 
 
int 
devwalk(Chan *c, char *name, Dirtab *tab, int ntab, Devgen *gen) 
{ 
	long i; 
	Dir dir; 
 
	isdir(c); 
	if(name[0]=='.' && name[1]==0) 
		return 1; 
1993/0501    
	for(i=0;; i++) { 
1990/0227    
		switch((*gen)(c, tab, ntab, i, &dir)){ 
		case -1: 
1993/0501    
			strncpy(up->error, Enonexist, NAMELEN); 
1990/0227    
			return 0; 
		case 0: 
			continue; 
		case 1: 
			if(strcmp(name, dir.name) == 0){ 
				c->qid = dir.qid; 
				return 1; 
			} 
			continue; 
		} 
1993/0501    
	} 
1997/0327    
	return 0; 
1991/0411    
} 
 
1990/0227    
void 
devstat(Chan *c, char *db, Dirtab *tab, int ntab, Devgen *gen) 
{ 
	int i; 
	Dir dir; 
1999/0629    
	char *p, *elem; 
1990/0227    
 
1993/0330    
	for(i=0;; i++) 
1990/0227    
		switch((*gen)(c, tab, ntab, i, &dir)){ 
		case -1: 
1990/11211    
			if(c->qid.path & CHDIR){ 
1999/0629    
				if(c->name == nil) 
					elem = "???"; 
				else 
					for(elem=p=c->name->s; *p; p++) 
						if(*p = '/') 
							elem = p+1; 
				devdir(c, c->qid, elem, i*DIRLEN, eve, CHDIR|0555, &dir); 
1990/0227    
				convD2M(&dir, db); 
				return; 
			} 
1997/0327    
			print("%s %s: devstat %C %lux\n", 
				up->text, up->user, 
1997/0408    
				devtab[c->type]->dc, c->qid.path); 
1997/0327    
 
1991/0626    
			error(Enonexist); 
1993/0330    
		case 0: 
			break; 
1990/0227    
		case 1: 
1999/0122    
			if(c->qid.path == dir.qid.path) { 
1993/0323    
				if(c->flag&CMSG) 
					dir.mode |= CHMOUNT; 
1990/0227    
				convD2M(&dir, db); 
				return; 
			} 
			break; 
		} 
} 
 
long 
devdirread(Chan *c, char *d, long n, Dirtab *tab, int ntab, Devgen *gen) 
{ 
1990/0821    
	long k, m; 
1990/0227    
	Dir dir; 
 
	k = c->offset/DIRLEN; 
1993/0501    
	for(m=0; m<n; k++) { 
1990/0227    
		switch((*gen)(c, tab, ntab, k, &dir)){ 
		case -1: 
1990/0821    
			return m; 
1990/0227    
 
		case 0: 
			c->offset += DIRLEN; 
			break; 
 
		case 1: 
			convD2M(&dir, d); 
1990/0821    
			m += DIRLEN; 
1990/0227    
			d += DIRLEN; 
			break; 
		} 
1993/0501    
	} 
 
1990/0821    
	return m; 
1990/0227    
} 
 
1997/0327    
Chan* 
1990/0227    
devopen(Chan *c, int omode, Dirtab *tab, int ntab, Devgen *gen) 
{ 
	int i; 
	Dir dir; 
1991/1112    
	ulong t, mode; 
1990/0227    
	static int access[] = { 0400, 0200, 0600, 0100 }; 
 
1993/0501    
	for(i=0;; i++) { 
1990/0227    
		switch((*gen)(c, tab, ntab, i, &dir)){ 
		case -1: 
			goto Return; 
		case 0: 
			break; 
		case 1: 
1999/0122    
			if(c->qid.path == dir.qid.path) { 
1993/0501    
				if(strcmp(up->user, dir.uid) == 0) 
1991/1112    
					mode = dir.mode; 
1993/0501    
				else 
				if(strcmp(up->user, eve) == 0) 
1991/1112    
					mode = dir.mode<<3; 
				else 
1993/0501    
					mode = dir.mode<<6; 
1991/1112    
 
				t = access[omode&3]; 
				if((t & mode) == t) 
1990/0227    
					goto Return; 
1990/11211    
				error(Eperm); 
1990/0227    
			} 
			break; 
		} 
1993/0501    
	} 
Return: 
1990/0227    
	c->offset = 0; 
1990/11211    
	if((c->qid.path&CHDIR) && omode!=OREAD) 
		error(Eperm); 
1990/0227    
	c->mode = openmode(omode); 
	c->flag |= COPEN; 
	return c; 
} 
1995/0108    
 
1998/0512    
void 
1997/0327    
devcreate(Chan*, char*, int, ulong) 
{ 
	error(Eperm); 
} 
 
1995/0108    
Block* 
devbread(Chan *c, long n, ulong offset) 
{ 
	Block *bp; 
 
	bp = allocb(n); 
	if(bp == 0) 
		error(Enomem); 
	if(waserror()) { 
		freeb(bp); 
		nexterror(); 
	} 
1997/0327    
	bp->wp += devtab[c->type]->read(c, bp->wp, n, offset); 
1995/0108    
	poperror(); 
	return bp; 
} 
 
long 
devbwrite(Chan *c, Block *bp, ulong offset) 
{ 
	long n; 
 
1997/0327    
	n = devtab[c->type]->write(c, bp->rp, BLEN(bp), offset); 
1995/0108    
	freeb(bp); 
 
1998/0512    
	return n; 
1995/0108    
} 
 
1997/0327    
void 
devremove(Chan*) 
{ 
	error(Eperm); 
} 
 
void 
devwstat(Chan*, char*) 
{ 
	error(Eperm); 
} 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)