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

1997/0408/port/devsrv.c (diff list | history)

port/devsrv.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" 
1991/0828    
 
1990/0227    
 
1992/0620    
typedef struct Srv Srv; 
1992/0622    
struct Srv 
{ 
1991/1219    
	char	name[NAMELEN]; 
	char	owner[NAMELEN]; 
	ulong	perm; 
	Chan	*chan; 
1992/0622    
	Srv	*link; 
	ulong	path; 
1991/1219    
}; 
1990/0227    
 
1992/0622    
static QLock	srvlk; 
static Srv	*srv; 
1993/0501    
static int	qidpath; 
1991/1219    
 
1997/0327    
static int 
1995/0804    
srvgen(Chan *c, Dirtab*, int, int s, Dir *dp) 
1991/0828    
{ 
1991/1219    
	Srv *sp; 
 
1992/0622    
	qlock(&srvlk); 
	for(sp = srv; sp && s; sp = sp->link) 
		s--; 
1991/1219    
 
1992/0622    
	if(sp == 0) { 
		qunlock(&srvlk); 
		return -1; 
	} 
	devdir(c, (Qid){sp->path, 0}, sp->name, 0, sp->owner, sp->perm, dp); 
	qunlock(&srvlk); 
1991/0828    
	return 1; 
} 
 
1997/0327    
static void 
1990/0227    
srvinit(void) 
{ 
1993/0501    
	qidpath = 1; 
1990/0227    
} 
 
1997/0327    
static Chan* 
1990/0227    
srvattach(char *spec) 
{ 
1991/0828    
	return devattach('s', spec); 
1990/0227    
} 
 
1997/0327    
static int 
1990/0227    
srvwalk(Chan *c, char *name) 
{ 
1991/0828    
	return devwalk(c, name, 0, 0, srvgen); 
1990/0227    
} 
 
1997/0327    
static void 
1990/0227    
srvstat(Chan *c, char *db) 
{ 
1991/0828    
	devstat(c, db, 0, 0, srvgen); 
1990/0227    
} 
 
1997/0327    
static Chan* 
1990/0227    
srvopen(Chan *c, int omode) 
{ 
1992/0622    
	Srv *sp; 
1990/0227    
 
1991/0828    
	if(c->qid.path == CHDIR){ 
1990/1110    
		if(omode != OREAD) 
1990/11211    
			error(Eisdir); 
1990/0227    
		c->mode = omode; 
		c->flag |= COPEN; 
		c->offset = 0; 
		return c; 
	} 
1992/0622    
	qlock(&srvlk); 
1991/0828    
	if(waserror()){ 
1992/0622    
		qunlock(&srvlk); 
1991/0828    
		nexterror(); 
	} 
1992/0622    
 
	for(sp = srv; sp; sp = sp->link) 
		if(sp->path == c->qid.path) 
			break; 
 
	if(sp == 0 || sp->chan == 0) 
1990/11211    
		error(Eshutdown); 
1992/0622    
 
1991/0828    
	if(omode&OTRUNC) 
1990/11211    
		error(Eperm); 
1992/0622    
	if(omode!=sp->chan->mode && sp->chan->mode!=ORDWR) 
1990/11211    
		error(Eperm); 
1992/0622    
 
1997/0327    
	cclose(c); 
1992/0622    
	incref(sp->chan); 
	qunlock(&srvlk); 
1991/0828    
	poperror(); 
1992/0622    
	return sp->chan; 
1990/0227    
} 
 
1997/0327    
static void 
1990/0227    
srvcreate(Chan *c, char *name, int omode, ulong perm) 
{ 
1991/1219    
	Srv *sp; 
1990/0227    
 
1991/0828    
	if(omode != OWRITE) 
		error(Eperm); 
1991/1219    
 
1992/0622    
	sp = malloc(sizeof(Srv)); 
	if(sp == 0) 
		error(Enomem); 
 
	qlock(&srvlk); 
1991/0828    
	if(waserror()){ 
1992/0622    
		qunlock(&srvlk); 
1990/0227    
		nexterror(); 
	} 
1993/0501    
	sp->path = qidpath++; 
1992/0622    
	sp->link = srv; 
	c->qid.path = sp->path; 
	srv = sp; 
	qunlock(&srvlk); 
1990/1002    
	poperror(); 
1992/0622    
 
1991/1219    
	strncpy(sp->name, name, NAMELEN); 
1993/0501    
	strncpy(sp->owner, up->user, NAMELEN); 
1991/1219    
	sp->perm = perm&0777; 
 
1990/0227    
	c->flag |= COPEN; 
1991/0828    
	c->mode = OWRITE; 
1990/0227    
} 
 
1997/0327    
static void 
1990/0227    
srvremove(Chan *c) 
{ 
1992/0622    
	Srv *sp, **l; 
1990/0227    
 
1991/0828    
	if(c->qid.path == CHDIR) 
1990/11211    
		error(Eperm); 
1991/1219    
 
1992/0622    
	qlock(&srvlk); 
1990/1110    
	if(waserror()){ 
1992/0622    
		qunlock(&srvlk); 
1990/0227    
		nexterror(); 
	} 
1992/0622    
	l = &srv; 
	for(sp = *l; sp; sp = sp->link) { 
		if(sp->path == c->qid.path) 
			break; 
 
1993/0701    
		l = &sp->link; 
1992/0622    
	} 
	if(sp == 0) 
		error(Enonexist); 
 
	if(strcmp(sp->name, "boot") == 0) 
1991/0828    
		error(Eperm); 
1992/0622    
 
	*l = sp->link; 
	qunlock(&srvlk); 
1990/0227    
	poperror(); 
1992/0622    
 
	if(sp->chan) 
1997/0327    
		cclose(sp->chan); 
1992/0622    
	free(sp); 
1990/0227    
} 
 
1997/0327    
static void 
1990/0227    
srvwstat(Chan *c, char *dp) 
{ 
1994/1018    
	Dir d; 
	Srv *sp; 
 
	if(!iseve()) 
		error(Eperm); 
	if(CHDIR & c->qid.path) 
		error(Eperm); 
 
	qlock(&srvlk); 
	if(waserror()){ 
		qunlock(&srvlk); 
		nexterror(); 
	} 
 
	for(sp = srv; sp; sp = sp->link) 
		if(sp->path == c->qid.path) 
			break; 
	if(sp == 0 || sp->chan == 0) 
		error(Eshutdown); 
	convM2D(dp, &d); 
	d.mode &= 0777; 
	sp->perm = d.mode; 
 
	qunlock(&srvlk); 
	poperror(); 
1990/0227    
} 
 
1997/0327    
static void 
1995/0804    
srvclose(Chan*) 
1990/0227    
{ 
} 
 
1997/0327    
static long 
1995/0804    
srvread(Chan *c, void *va, long n, ulong) 
1990/0227    
{ 
1990/1002    
	isdir(c); 
1991/0828    
	return devdirread(c, va, n, 0, 0, srvgen); 
1990/0227    
} 
 
1997/0327    
static long 
1995/0804    
srvwrite(Chan *c, void *va, long n, ulong) 
1990/0227    
{ 
1992/0622    
	Srv *sp; 
	Chan *c1; 
1992/0711    
	int fd; 
1990/0227    
	char buf[32]; 
 
1990/1110    
	if(n >= sizeof buf) 
1990/11211    
		error(Egreg); 
1991/0318    
	memmove(buf, va, n);	/* so we can NUL-terminate */ 
1990/0227    
	buf[n] = 0; 
	fd = strtoul(buf, 0, 0); 
1992/0520    
 
1993/0501    
	c1 = fdtochan(fd, -1, 0, 1);	/* error check and inc ref */ 
1992/0520    
 
1992/0622    
	qlock(&srvlk); 
	if(waserror()) { 
		qunlock(&srvlk); 
1997/0327    
		cclose(c1); 
1992/0520    
		nexterror(); 
	} 
1992/0622    
	for(sp = srv; sp; sp = sp->link) 
		if(sp->path == c->qid.path) 
			break; 
1992/0620    
 
1992/0622    
	if(sp == 0) 
		error(Enonexist); 
 
	if(sp->chan) 
		panic("srvwrite"); 
 
	sp->chan = c1; 
	qunlock(&srvlk); 
1992/0226    
	poperror(); 
1990/0227    
	return n; 
1995/0108    
} 
 
1997/0327    
Dev srvdevtab = { 
1997/0408    
	's', 
	"srv", 
 
1997/0327    
	devreset, 
	srvinit, 
	srvattach, 
	devclone, 
	srvwalk, 
	srvstat, 
	srvopen, 
	srvcreate, 
	srvclose, 
	srvread, 
	devbread, 
	srvwrite, 
	devbwrite, 
	srvremove, 
	srvwstat, 
}; 
1993/0501    
 
void 
srvrecover(Chan *old, Chan *new) 
{ 
	Srv *sp; 
 
	qlock(&srvlk); 
	for(sp = srv; sp; sp = sp->link) { 
		if(sp->chan == old) { 
			sp->chan = new; 
			incref(new); 
			qunlock(&srvlk); 
1997/0327    
			cclose(old); 
1993/0501    
			return; 
		} 
	} 
	qunlock(&srvlk); 
1990/0227    
} 


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