⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xfssrv.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <auth.h>#include <fcall.h>#include "iotrack.h"#include "dat.h"#include "dosfs.h"#include "fns.h"#include "errstr.h"#define	Reqsize	(sizeof(Fcall)+Maxfdata)Fcall	*req;Fcall	*rep;uchar	mdata[Maxiosize];char	repdata[Maxfdata];uchar	statbuf[STATMAX];int	errno;char	errbuf[ERRMAX];void	rmservice(void);char	srvfile[64];char	*deffile;int	doabort;int	trspaces;void	(*fcalls[])(void) = {	[Tversion]	rversion,	[Tflush]	rflush,	[Tauth]	rauth,	[Tattach]	rattach,	[Twalk]		rwalk,	[Topen]		ropen,	[Tcreate]	rcreate,	[Tread]		rread,	[Twrite]	rwrite,	[Tclunk]	rclunk,	[Tremove]	rremove,	[Tstat]		rstat,	[Twstat]	rwstat,};voidusage(void){	fprint(2, "usage: %s [-v] [-s] [-f devicefile] [srvname]\n", argv0);	exits("usage");}voidmain(int argc, char **argv){	int stdio, srvfd, pipefd[2];	rep = malloc(sizeof(Fcall));	req = malloc(Reqsize);	if(rep == nil || req == nil)		panic("out of memory");	stdio = 0;	ARGBEGIN{	case ':':		trspaces = 1;		break;	case 'r':		readonly = 1;		break;	case 'v':		++chatty;		break;	case 'f':		deffile = ARGF();		break;	case 's':		stdio = 1;		break;	case 'p':		doabort = 1;		break;	default:		usage();	}ARGEND	if(argc == 0)		strcpy(srvfile, "#s/dos");	else if(argc == 1)		snprint(srvfile, sizeof srvfile, "#s/%s", argv[0]);	else		usage();	if(stdio){		pipefd[0] = 0;		pipefd[1] = 1;	}else{		close(0);		close(1);		open("/dev/null", OREAD);		open("/dev/null", OWRITE);		if(pipe(pipefd) < 0)			panic("pipe");		srvfd = create(srvfile, OWRITE|ORCLOSE, 0600);		if(srvfd < 0)			panic(srvfile);		fprint(srvfd, "%d", pipefd[0]);		close(pipefd[0]);		atexit(rmservice);		fprint(2, "%s: serving %s\n", argv0, srvfile);	}	srvfd = pipefd[1];	switch(rfork(RFNOWAIT|RFNOTEG|RFFDG|RFPROC|RFNAMEG)){	case -1:		panic("fork");	default:		_exits(0);	case 0:		break;	}	iotrack_init();	if(!chatty){		close(2);		open("#c/cons", OWRITE);	}	io(srvfd);	exits(0);}voidio(int srvfd){	int n, pid;	pid = getpid();	fmtinstall('F', fcallfmt);	for(;;){		/*		 * reading from a pipe or a network device		 * will give an error after a few eof reads.		 * however, we cannot tell the difference		 * between a zero-length read and an interrupt		 * on the processes writing to us,		 * so we wait for the error.		 */		n = read9pmsg(srvfd, mdata, sizeof mdata);		if(n < 0)			break;		if(n == 0)			continue;		if(convM2S(mdata, n, req) == 0)			continue;		if(chatty)			fprint(2, "dossrv %d:<-%F\n", pid, req);		errno = 0;		if(!fcalls[req->type])			errno = Ebadfcall;		else			(*fcalls[req->type])();		if(errno){			rep->type = Rerror;			rep->ename = xerrstr(errno);		}else{			rep->type = req->type + 1;			rep->fid = req->fid;		}		rep->tag = req->tag;		if(chatty)			fprint(2, "dossrv %d:->%F\n", pid, rep);		n = convS2M(rep, mdata, sizeof mdata);		if(n == 0)			panic("convS2M error on write");		if(write(srvfd, mdata, n) != n)			panic("mount write");	}	chat("server shut down");}voidrmservice(void){	remove(srvfile);}char *xerrstr(int e){	if (e < 0 || e >= sizeof errmsg/sizeof errmsg[0])		return "no such error";	if(e == Eerrstr){		errstr(errbuf, sizeof errbuf);		return errbuf;	}	return errmsg[e];}inteqqid(Qid q1, Qid q2){	return q1.path == q2.path && q1.type == q2.type && q1.vers == q2.vers;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -