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

1990/0227/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" 
#include	"errno.h" 
 
#include	"devtab.h" 
 
typedef struct	Srv Srv; 
struct Srv{ 
	Lock; 
	char	*name; 
	Chan	**chan; 
}srv; 
 
int 
srvgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp) 
{ 
 
	if(s >= conf.nsrv) 
		return -1; 
	if(srv.chan[s] == 0) 
		return 0; 
	devdir(c, s, &srv.name[s*NAMELEN], 0, 0666, dp); 
	return 1; 
} 
 
void 
srvinit(void) 
{ 
} 
 
void 
srvreset(void) 
{ 
	srv.chan = ialloc(conf.nsrv*sizeof(Chan*), 0); 
	srv.name = ialloc(conf.nsrv*NAMELEN, 0); 
} 
 
Chan * 
srvattach(char *spec) 
{ 
	return devattach('s', spec); 
} 
 
Chan * 
srvclone(Chan *c, Chan *nc) 
{ 
	return devclone(c, nc); 
} 
 
int 
srvwalk(Chan *c, char *name) 
{ 
	return devwalk(c, name, (Dirtab *)0, 0, srvgen); 
} 
 
void 
srvstat(Chan *c, char *db) 
{ 
	devstat(c, db, (Dirtab *)0, 0L, srvgen); 
} 
 
Chan * 
srvopen(Chan *c, int omode) 
{ 
	Chan *f; 
 
	if(c->qid == CHDIR){ 
		if(omode != OREAD) 
			error(0, Eisdir); 
		c->mode = omode; 
		c->flag |= COPEN; 
		c->offset = 0; 
		return c; 
	} 
	lock(&srv); 
	if(waserror()){ 
		unlock(&srv); 
		nexterror(); 
	} 
	f = srv.chan[c->qid]; 
	if(f == 0) 
		error(0, Eshutdown); 
	if(omode&OTRUNC) 
		error(0, Eperm); 
	if(omode!=f->mode && f->mode!=ORDWR) 
		error(0, Eperm); 
	close(c); 
	incref(f); 
	unlock(&srv); 
	poperror(); 
	return f; 
} 
 
void 
srvcreate(Chan *c, char *name, int omode, ulong perm) 
{ 
	int j, i; 
 
	if(omode != OWRITE) 
		error(0, Eperm); 
	lock(&srv); 
	if(waserror()){ 
		unlock(&srv); 
		nexterror(); 
	} 
	j = -1; 
	for(i=0; i<conf.nsrv; i++){ 
		if(srv.chan[i] == 0){ 
			if(j == -1) 
				j = i; 
		}else if(strcmp(name, &srv.name[i*NAMELEN]) == 0){ 
			print("reuse of srv name\n"); 
			error(0, Einuse); 
		} 
	} 
	if(j == -1) 
		error(0, Enosrv); 
	srv.chan[j] = c; 
	unlock(&srv); 
	strcpy(&srv.name[j*NAMELEN], name); 
	c->qid = j; 
	c->flag |= COPEN; 
	c->mode = OWRITE; 
} 
 
void 
srvremove(Chan *c) 
{ 
	Chan *f; 
 
	if(c->qid == CHDIR) 
		error(0, Eperm); 
	lock(&srv); 
	if(waserror()){ 
		unlock(&srv); 
		nexterror(); 
	} 
	f = srv.chan[c->qid]; 
	if(f == 0) 
		error(0, Eshutdown); 
	if(strcmp(&srv.name[c->qid*NAMELEN], "boot") == 0) 
		error(0, Eperm); 
	srv.chan[c->qid] = 0; 
	unlock(&srv); 
	poperror(); 
	close(f); 
} 
 
void 
srvwstat(Chan *c, char *dp) 
{ 
	error(0, Egreg); 
} 
 
void 
srvclose(Chan *c) 
{ 
} 
 
long 
srvread(Chan *c, void *va, long n) 
{ 
	char *a = va; 
 
	if(c->qid != CHDIR) 
		panic("srvread"); 
	return devdirread(c, a, n, (Dirtab *)0, 0L, srvgen); 
} 
 
long 
srvwrite(Chan *c, void *va, long n) 
{ 
	int i, fd; 
	char buf[32]; 
 
	i = c->qid; 
	if(srv.chan[i] != c)	/* already been written to */ 
		error(0, Egreg); 
	if(n >= sizeof buf) 
		error(0, Egreg); 
	memcpy(buf, va, n);	/* so we can NUL-terminate */ 
	buf[n] = 0; 
	fd = strtoul(buf, 0, 0); 
	fdtochan(fd, -1);	/* error check only */ 
	srv.chan[i] = u->fd[fd]; 
	incref(u->fd[fd]); 
	return n; 
} 
 
void 
srverrstr(Error *e, char *buf) 
{ 
	rooterrstr(e, buf); 
} 
 
void 
srvuserstr(Error *e, char *buf) 
{ 
	consuserstr(e, buf); 
} 


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