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

📄 ccmd.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include "stdinc.h"#include "9.h"static struct {	VtLock*	lock;	Con*	con;	int	confd[2];	ushort	tag;} cbox;static ulongcmd9pStrtoul(char* s){	if(strcmp(s, "~0") == 0)		return ~0UL;	return strtoul(s, 0, 0);}static uvlongcmd9pStrtoull(char* s){	if(strcmp(s, "~0") == 0)		return ~0ULL;	return strtoull(s, 0, 0);}static intcmd9pTag(Fcall*, int, char **argv){	cbox.tag = strtoul(argv[0], 0, 0)-1;	return 1;}static intcmd9pTwstat(Fcall* f, int, char **argv){	Dir d;	static uchar buf[DIRMAX];	memset(&d, 0, sizeof d);	nulldir(&d);	d.name = argv[1];	d.uid = argv[2];	d.gid = argv[3];	d.mode = cmd9pStrtoul(argv[4]);	d.mtime = cmd9pStrtoul(argv[5]);	d.length = cmd9pStrtoull(argv[6]);	f->fid = strtol(argv[0], 0, 0);	f->stat = buf;	f->nstat = convD2M(&d, buf, sizeof buf);	if(f->nstat < BIT16SZ){		vtSetError("Twstat: convD2M failed (internal error)");		return 0;	}	return 1;}static intcmd9pTstat(Fcall* f, int, char** argv){	f->fid = strtol(argv[0], 0, 0);	return 1;}static intcmd9pTremove(Fcall* f, int, char** argv){	f->fid = strtol(argv[0], 0, 0);	return 1;}static intcmd9pTclunk(Fcall* f, int, char** argv){	f->fid = strtol(argv[0], 0, 0);	return 1;}static intcmd9pTwrite(Fcall* f, int, char** argv){	f->fid = strtol(argv[0], 0, 0);	f->offset = strtoll(argv[1], 0, 0);	f->data = argv[2];	f->count = strlen(argv[2]);	return 1;}static intcmd9pTread(Fcall* f, int, char** argv){	f->fid = strtol(argv[0], 0, 0);	f->offset = strtoll(argv[1], 0, 0);	f->count = strtol(argv[2], 0, 0);	return 1;}static intcmd9pTcreate(Fcall* f, int, char** argv){	f->fid = strtol(argv[0], 0, 0);	f->name = argv[1];	f->perm = strtol(argv[2], 0, 8);	f->mode = strtol(argv[3], 0, 0);	return 1;}static intcmd9pTopen(Fcall* f, int, char** argv){	f->fid = strtol(argv[0], 0, 0);	f->mode = strtol(argv[1], 0, 0);	return 1;}static intcmd9pTwalk(Fcall* f, int argc, char** argv){	int i;	if(argc < 2){		vtSetError("usage: Twalk tag fid newfid [name...]");		return 0;	}	f->fid = strtol(argv[0], 0, 0);	f->newfid = strtol(argv[1], 0, 0);	f->nwname = argc-2;	if(f->nwname > MAXWELEM){		vtSetError("Twalk: too many names");		return 0;	}	for(i = 0; i < argc-2; i++)		f->wname[i] = argv[2+i];	return 1;}static intcmd9pTflush(Fcall* f, int, char** argv){	f->oldtag = strtol(argv[0], 0, 0);	return 1;}static intcmd9pTattach(Fcall* f, int, char** argv){	f->fid = strtol(argv[0], 0, 0);	f->afid = strtol(argv[1], 0, 0);	f->uname = argv[2];	f->aname = argv[3];	return 1;}static intcmd9pTauth(Fcall* f, int, char** argv){	f->afid = strtol(argv[0], 0, 0);	f->uname = argv[1];	f->aname = argv[2];	return 1;}static intcmd9pTversion(Fcall* f, int, char** argv){	f->msize = strtoul(argv[0], 0, 0);	if(f->msize > cbox.con->msize){		vtSetError("msize too big");		return 0;	}	f->version = argv[1];	return 1;}typedef struct Cmd9p Cmd9p;struct Cmd9p {	char*	name;	int	type;	int	argc;	char*	usage;	int	(*f)(Fcall*, int, char**);};static Cmd9p cmd9pTmsg[] = {	"Tversion", Tversion, 2, "msize version", cmd9pTversion,	"Tauth", Tauth, 3, "afid uname aname", cmd9pTauth,	"Tflush", Tflush, 1, "oldtag", cmd9pTflush,	"Tattach", Tattach, 4, "fid afid uname aname", cmd9pTattach,	"Twalk", Twalk, 0, "fid newfid [name...]", cmd9pTwalk,	"Topen", Topen, 2, "fid mode", cmd9pTopen,	"Tcreate", Tcreate, 4, "fid name perm mode", cmd9pTcreate,	"Tread", Tread, 3, "fid offset count", cmd9pTread,	"Twrite", Twrite, 3, "fid offset data", cmd9pTwrite,	"Tclunk", Tclunk, 1, "fid", cmd9pTclunk,	"Tremove", Tremove, 1, "fid", cmd9pTremove,	"Tstat", Tstat, 1, "fid", cmd9pTstat,	"Twstat", Twstat, 7, "fid name uid gid mode mtime length", cmd9pTwstat,	"nexttag", 0, 0, "", cmd9pTag,};static intcmd9p(int argc, char* argv[]){	int i, n;	Fcall f, t;	uchar *buf;	char *usage;	u32int msize;	usage = "usage: 9p T-message ...";	ARGBEGIN{	default:		return cliError(usage);	}ARGEND	if(argc < 1)		return cliError(usage);	for(i = 0; i < nelem(cmd9pTmsg); i++){		if(strcmp(cmd9pTmsg[i].name, argv[0]) == 0)			break;	}	if(i == nelem(cmd9pTmsg))		return cliError(usage);	argc--;	argv++;	if(cmd9pTmsg[i].argc && argc != cmd9pTmsg[i].argc){		vtSetError("usage: %s %s",			cmd9pTmsg[i].name, cmd9pTmsg[i].usage);		return 0;	}	memset(&t, 0, sizeof(t));	t.type = cmd9pTmsg[i].type;	if(t.type == Tversion)		t.tag = NOTAG;	else		t.tag = ++cbox.tag;	msize = cbox.con->msize;	if(!cmd9pTmsg[i].f(&t, argc, argv))		return 0;	buf = vtMemAlloc(msize);	n = convS2M(&t, buf, msize);	if(n <= BIT16SZ){		vtSetError("%s: convS2M error", cmd9pTmsg[i].name);		vtMemFree(buf);		return 0;	}	if(write(cbox.confd[0], buf, n) != n){		vtSetError("%s: write error: %r", cmd9pTmsg[i].name);		vtMemFree(buf);		return 0;	}	consPrint("\t-> %F\n", &t);	if((n = read9pmsg(cbox.confd[0], buf, msize)) <= 0){		vtSetError("%s: read error: %r", cmd9pTmsg[i].name);		vtMemFree(buf);		return 0;	}	if(convM2S(buf, n, &f) == 0){		vtSetError("%s: convM2S error", cmd9pTmsg[i].name);		vtMemFree(buf);		return 0;	}	consPrint("\t<- %F\n", &f);	vtMemFree(buf);	return 1;}static intcmdDot(int argc, char* argv[]){	long l;	Dir *dir;	int fd, r;	vlong length;	char *f, *p, *s, *usage;	usage = "usage: . file";	ARGBEGIN{	default:		return cliError(usage);	}ARGEND	if(argc != 1)		return cliError(usage);	if((dir = dirstat(argv[0])) == nil)		return cliError(". dirstat %s: %r", argv[0]);	length = dir->length;	free(dir);	r = 1;	if(length != 0){		/*		 * Read the whole file in.		 */		if((fd = open(argv[0], OREAD)) < 0)			return cliError(". open %s: %r", argv[0]);		f = vtMemAlloc(dir->length+1);		if((l = read(fd, f, length)) < 0){			vtMemFree(f);			close(fd);			return cliError(". read %s: %r", argv[0]);		}		close(fd);		f[l] = '\0';		/*		 * Call cliExec() for each line.		 */		for(p = s = f; *p != '\0'; p++){			if(*p == '\n'){				*p = '\0';				if(cliExec(s) == 0){					r = 0;					consPrint("%s: %R\n", s);				}				s = p+1;			}		}		vtMemFree(f);	}	if(r == 0)		vtSetError("errors in . %#q", argv[0]);	return r;}static intcmdDflag(int argc, char* argv[]){	char *usage;	usage = "usage: dflag";	ARGBEGIN{	default:		return cliError(usage);	}ARGEND	if(argc)		return cliError(usage);	Dflag ^= 1;	consPrint("dflag %d\n", Dflag);	return 1;}static intcmdEcho(int argc, char* argv[]){	char *usage;	int i, nflag;	nflag = 0;	usage = "usage: echo [-n] ...";	ARGBEGIN{	default:		return cliError(usage);	case 'n':		nflag = 1;		break;	}ARGEND	for(i = 0; i < argc; i++){		if(i != 0)			consPrint(" %s", argv[i]);		else			consPrint(argv[i]);	}	if(!nflag)		consPrint("\n");	return 1;}static intcmdBind(int argc, char* argv[]){	ulong flag = 0;	char *usage;	usage = "usage: bind [-b|-a|-c|-bc|-ac] new old";	ARGBEGIN{	case 'a':		flag |= MAFTER;		break;	case 'b':		flag |= MBEFORE;		break;	case 'c':		flag |= MCREATE;		break;	default:		return cliError(usage);	}ARGEND	if(argc != 2 || (flag&MAFTER)&&(flag&MBEFORE))		return cliError(usage);	if(bind(argv[0], argv[1], flag) < 0){		/* try to give a less confusing error than the default */		if(access(argv[0], 0) < 0)			return cliError("bind: %s: %r", argv[0]);		else if(access(argv[1], 0) < 0)			return cliError("bind: %s: %r", argv[1]);		else			return cliError("bind %s %s: %r", argv[0], argv[1]);	}	return 1;}intcmdInit(void){	cbox.lock = vtLockAlloc();	cbox.confd[0] = cbox.confd[1] = -1;	cliAddCmd(".", cmdDot);	cliAddCmd("9p", cmd9p);	cliAddCmd("dflag", cmdDflag);	cliAddCmd("echo", cmdEcho);	cliAddCmd("bind", cmdBind);	if(pipe(cbox.confd) < 0)		return 0;	if((cbox.con = conAlloc(cbox.confd[1], "console", 0)) == nil){		close(cbox.confd[0]);		close(cbox.confd[1]);		cbox.confd[0] = cbox.confd[1] = -1;		return 0;	}	cbox.con->isconsole = 1;	return 1;}

⌨️ 快捷键说明

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