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

1992/0226/port/devsrv.c (diff list | history)

port/devsrv.c on 1990/0227
1990/0227    
#include	"u.h" 
#include	"lib.h" 
#include	"mem.h" 
#include	"dat.h" 
#include	"fns.h" 
1992/0111    
#include	"../port/error.h" 
1991/0828    
 
1990/0227    
#include	"devtab.h" 
 
1991/0828    
typedef struct	Srv Srv; 
struct Srv{ 
1991/1219    
	char	name[NAMELEN]; 
	char	owner[NAMELEN]; 
	ulong	perm; 
	Chan	*chan; 
}; 
1990/0227    
 
1991/1219    
Lock	srvlk; 
Srv	*srv; 
 
1991/0828    
int 
srvgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp) 
{ 
1991/1219    
	Srv *sp; 
 
1991/0828    
	if(s >= conf.nsrv) 
		return -1; 
1991/1219    
 
	sp = &srv[s]; 
	if(sp->chan == 0) 
1991/0828    
		return 0; 
1991/1219    
	devdir(c, (Qid){s, 0}, sp->name, 0, sp->owner, sp->perm, dp); 
1991/0828    
	return 1; 
} 
 
1990/0227    
void 
srvinit(void) 
{ 
} 
 
void 
srvreset(void) 
{ 
1991/1219    
	srv = ialloc(conf.nsrv*sizeof(Srv), 0); 
1990/0227    
} 
 
Chan * 
srvattach(char *spec) 
{ 
1991/0828    
	return devattach('s', spec); 
1990/0227    
} 
 
Chan * 
srvclone(Chan *c, Chan *nc) 
{ 
1991/0828    
	return devclone(c, nc); 
1990/0227    
} 
 
int 
srvwalk(Chan *c, char *name) 
{ 
1991/0828    
	return devwalk(c, name, 0, 0, srvgen); 
1990/0227    
} 
 
void 
srvstat(Chan *c, char *db) 
{ 
1991/0828    
	devstat(c, db, 0, 0, srvgen); 
1990/0227    
} 
 
Chan * 
srvopen(Chan *c, int omode) 
{ 
	Chan *f; 
 
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; 
	} 
1991/1219    
	lock(&srvlk); 
1991/0828    
	if(waserror()){ 
1991/1219    
		unlock(&srvlk); 
1991/0828    
		nexterror(); 
	} 
1991/1219    
	f = srv[c->qid.path].chan; 
1991/0828    
	if(f == 0) 
1990/11211    
		error(Eshutdown); 
1991/0828    
	if(omode&OTRUNC) 
1990/11211    
		error(Eperm); 
1990/1110    
	if(omode!=f->mode && f->mode!=ORDWR) 
1990/11211    
		error(Eperm); 
1990/0227    
	close(c); 
	incref(f); 
1991/1219    
	unlock(&srvlk); 
1991/0828    
	poperror(); 
1990/0227    
	return f; 
} 
 
void 
srvcreate(Chan *c, char *name, int omode, ulong perm) 
{ 
1991/0828    
	int j, i; 
1991/1219    
	Srv *sp; 
1990/0227    
 
1991/0828    
	if(omode != OWRITE) 
		error(Eperm); 
1991/1219    
 
	lock(&srvlk); 
1991/0828    
	if(waserror()){ 
1991/1219    
		unlock(&srvlk); 
1990/0227    
		nexterror(); 
	} 
1991/0828    
	j = -1; 
	for(i=0; i<conf.nsrv; i++){ 
1991/1219    
		if(srv[i].chan == 0){ 
1991/0828    
			if(j == -1) 
				j = i; 
1991/1219    
		} 
		else if(strcmp(name, srv[i].name) == 0) 
1990/11211    
			error(Einuse); 
1991/0828    
	} 
	if(j == -1) 
1992/0114    
		exhausted("server slots"); 
1991/1219    
	sp = &srv[j]; 
	sp->chan = c; 
	unlock(&srvlk); 
1990/1002    
	poperror(); 
1991/1219    
	strncpy(sp->name, name, NAMELEN); 
	strncpy(sp->owner, u->p->user, NAMELEN); 
	sp->perm = perm&0777; 
 
1991/0828    
	c->qid.path = j; 
1990/0227    
	c->flag |= COPEN; 
1991/0828    
	c->mode = OWRITE; 
1990/0227    
} 
 
void 
srvremove(Chan *c) 
{ 
1991/0828    
	Chan *f; 
1990/0227    
 
1991/0828    
	if(c->qid.path == CHDIR) 
1990/11211    
		error(Eperm); 
1991/1219    
 
	lock(&srvlk); 
1990/1110    
	if(waserror()){ 
1991/1219    
		unlock(&srvlk); 
1990/0227    
		nexterror(); 
	} 
1991/1219    
	f = srv[c->qid.path].chan; 
1991/0828    
	if(f == 0) 
		error(Eshutdown); 
1991/1219    
	if(strcmp(srv[c->qid.path].name, "boot") == 0) 
1991/0828    
		error(Eperm); 
1991/1219    
	srv[c->qid.path].chan = 0; 
	unlock(&srvlk); 
1990/0227    
	poperror(); 
1991/0828    
	close(f); 
1990/0227    
} 
 
void 
srvwstat(Chan *c, char *dp) 
{ 
1991/1115    
	USED(c, dp); 
1990/11211    
	error(Egreg); 
1990/0227    
} 
 
void 
srvclose(Chan *c) 
{ 
1991/1115    
	USED(c); 
1990/0227    
} 
 
long 
1991/0411    
srvread(Chan *c, void *va, long n, ulong offset) 
1990/0227    
{ 
1990/1002    
	isdir(c); 
1991/0828    
	return devdirread(c, va, n, 0, 0, srvgen); 
1990/0227    
} 
 
long 
1991/0411    
srvwrite(Chan *c, void *va, long n, ulong offset) 
1990/0227    
{ 
1991/1127    
	Fgrp *f; 
1990/0227    
	int i, fd; 
	char buf[32]; 
 
1991/0828    
	i = c->qid.path; 
1991/1219    
	if(srv[i].chan != c)	/* already been written to */ 
1990/11211    
		error(Egreg); 
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); 
1991/1127    
	f = u->p->fgrp; 
	lock(f); 
1992/0226    
	if(waserror()){ 
		unlock(f); 
		nexterror(); 
	} 
1991/1011    
	fdtochan(fd, -1, 0);	/* error check only */ 
1991/1219    
	srv[i].chan = f->fd[fd]; 
	incref(srv[i].chan); 
1991/1127    
	unlock(f); 
1992/0226    
	poperror(); 
1990/0227    
	return n; 
} 


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