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

📄 exec.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
			bufread(t->file, q0, r, n);			bufinsert(&snarfbuf, snarfbuf.nc, r, n);			q0 += n;		}		fbuffree(r);		putsnarf();	}	if(docut){		textdelete(t, t->q0, t->q1, TRUE);		textsetselect(t, t->q0, t->q0);		if(t->w){			textscrdraw(t);			winsettag(t->w);		}	}else if(dosnarf)	/* Snarf command */		argtext = t;	if(locked)		winunlock(t->w);}voidpaste(Text *et, Text *t, Text*, int selectall, int tobody, Rune*, int){	int c;	uint q, q0, q1, n;	Rune *r;	/* if(tobody), use body of executing window  (Paste or Send command) */	if(tobody && et!=nil && et->w!=nil){		t = &et->w->body;		filemark(t->file);	/* seq has been incremented by execute */	}	if(t == nil)		return;	getsnarf();	if(t==nil || snarfbuf.nc==0)		return;	if(t->w!=nil && et->w!=t->w){		c = 'M';		if(et->w)			c = et->w->owner;		winlock(t->w, c);	}	cut(t, t, nil, FALSE, TRUE, nil, 0);	q = 0;	q0 = t->q0;	q1 = t->q0+snarfbuf.nc;	r = fbufalloc();	while(q0 < q1){		n = q1 - q0;		if(n > RBUFSIZE)			n = RBUFSIZE;		if(r == nil)			r = runemalloc(n);		bufread(&snarfbuf, q, r, n);		textinsert(t, q0, r, n, TRUE);		q += n;		q0 += n;	}	fbuffree(r);	if(selectall)		textsetselect(t, t->q0, q1);	else		textsetselect(t, q1, q1);	if(t->w){		textscrdraw(t);		winsettag(t->w);	}	if(t->w!=nil && et->w!=t->w)		winunlock(t->w);}voidlook(Text *et, Text *t, Text *argt, int, int, Rune *arg, int narg){	Rune *r;	int n;	if(et && et->w){		t = &et->w->body;		if(narg > 0){			search(t, arg, narg);			return;		}		getarg(argt, FALSE, FALSE, &r, &n);		if(r == nil){			n = t->q1-t->q0;			r = runemalloc(n);			bufread(t->file, t->q0, r, n);		}		search(t, r, n);		free(r);	}}voidsendx(Text *et, Text *t, Text*, int, int, Rune*, int){	if(et->w==nil)		return;	t = &et->w->body;	if(t->q0 != t->q1)		cut(t, t, nil, TRUE, FALSE, nil, 0);	textsetselect(t, t->file->nc, t->file->nc);	paste(t, t, nil, TRUE, TRUE, nil, 0);	if(textreadc(t, t->file->nc-1) != '\n'){		textinsert(t, t->file->nc, L"\n", 1, TRUE);		textsetselect(t, t->file->nc, t->file->nc);	}}voidedit(Text *et, Text*, Text *argt, int, int, Rune *arg, int narg){	Rune *r;	int len;	if(et == nil)		return;	getarg(argt, FALSE, TRUE, &r, &len);	seq++;	if(r != nil){		editcmd(et, r, len);		free(r);	}else		editcmd(et, arg, narg);}voidexit(Text*, Text*, Text*, int, int, Rune*, int){	if(rowclean(&row)){		sendul(cexit, 0);		threadexits(nil);	}}voidputall(Text*, Text*, Text*, int, int, Rune*, int){	int i, j, e;	Window *w;	Column *c;	char *a;	for(i=0; i<row.ncol; i++){		c = row.col[i];		for(j=0; j<c->nw; j++){			w = c->w[j];			if(w->isscratch || w->isdir || w->body.file->nname==0)				continue;			if(w->nopen[QWevent] > 0)				continue;			a = runetobyte(w->body.file->name, w->body.file->nname);			e = access(a, 0);			if(w->body.file->mod || w->body.ncache)				if(e < 0)					warning(nil, "no auto-Put of %s: %r\n", a);				else{					wincommit(w, &w->body);					put(&w->body, nil, nil, XXX, XXX, nil, 0);				}			free(a);		}	}}voidid(Text *et, Text*, Text*, int, int, Rune*, int){	if(et && et->w)		warning(nil, "/mnt/acme/%d/\n", et->w->id);}voidlocal(Text *et, Text*, Text *argt, int, int, Rune *arg, int narg){	char *a, *aa;	Runestr dir;	aa = getbytearg(argt, TRUE, TRUE, &a);	dir = dirname(et, nil, 0);	if(dir.nr==1 && dir.r[0]=='.'){	/* sigh */		free(dir.r);		dir.r = nil;		dir.nr = 0;	}	run(nil, runetobyte(arg, narg), dir.r, dir.nr, FALSE, aa, a, FALSE);}voidkill(Text*, Text*, Text *argt, int, int, Rune *arg, int narg){	Rune *a, *cmd, *r;	int na;	getarg(argt, FALSE, FALSE, &r, &na);	if(r)		kill(nil, nil, nil, 0, 0, r, na);	/* loop condition: *arg is not a blank */	for(;;){		a = findbl(arg, narg, &na);		if(a == arg)			break;		cmd = runemalloc(narg-na+1);		runemove(cmd, arg, narg-na);		sendp(ckill, cmd);		arg = skipbl(a, na, &narg);	}}voidfontx(Text *et, Text *t, Text *argt, int, int, Rune *arg, int narg){	Rune *a, *r, *flag, *file;	int na, nf;	char *aa;	Reffont *newfont;	Dirlist *dp;	int i, fix;	if(et==nil || et->w==nil)		return;	t = &et->w->body;	flag = nil;	file = nil;	/* loop condition: *arg is not a blank */	nf = 0;	for(;;){		a = findbl(arg, narg, &na);		if(a == arg)			break;		r = runemalloc(narg-na+1);		runemove(r, arg, narg-na);		if(runeeq(r, narg-na, L"fix", 3) || runeeq(r, narg-na, L"var", 3)){			free(flag);			flag = r;		}else{			free(file);			file = r;			nf = narg-na;		}		arg = skipbl(a, na, &narg);	}	getarg(argt, FALSE, TRUE, &r, &na);	if(r)		if(runeeq(r, na, L"fix", 3) || runeeq(r, na, L"var", 3)){			free(flag);			flag = r;		}else{			free(file);			file = r;			nf = na;		}	fix = 1;	if(flag)		fix = runeeq(flag, runestrlen(flag), L"fix", 3);	else if(file == nil){		newfont = rfget(FALSE, FALSE, FALSE, nil);		if(newfont)			fix = strcmp(newfont->f->name, t->font->name)==0;	}	if(file){		aa = runetobyte(file, nf);		newfont = rfget(fix, flag!=nil, FALSE, aa);		free(aa);	}else		newfont = rfget(fix, FALSE, FALSE, nil);	if(newfont){		draw(screen, t->w->r, textcols[BACK], nil, ZP);		rfclose(t->reffont);		t->reffont = newfont;		t->font = newfont->f;		frinittick(t);		if(t->w->isdir){			t->all.min.x++;	/* force recolumnation; disgusting! */			for(i=0; i<t->w->ndl; i++){				dp = t->w->dlp[i];				aa = runetobyte(dp->r, dp->nr);				dp->wid = stringwidth(newfont->f, aa);				free(aa);			}		}		/* avoid shrinking of window due to quantization */		colgrow(t->w->col, t->w, -1);	}	free(file);	free(flag);}voidincl(Text *et, Text*, Text *argt, int, int, Rune *arg, int narg){	Rune *a, *r;	Window *w;	int na, n, len;	if(et==nil || et->w==nil)		return;	w = et->w;	n = 0;	getarg(argt, FALSE, TRUE, &r, &len);	if(r){		n++;		winaddincl(w, r, len);	}	/* loop condition: *arg is not a blank */	for(;;){		a = findbl(arg, narg, &na);		if(a == arg)			break;		r = runemalloc(narg-na+1);		runemove(r, arg, narg-na);		n++;		winaddincl(w, r, narg-na);		arg = skipbl(a, na, &narg);	}	if(n==0 && w->nincl){		for(n=w->nincl; --n>=0; )			warning(nil, "%S ", w->incl[n]);		warning(nil, "\n");	}}enum {	IGlobal = -2,	IError = -1,	Ion = 0,	Ioff = 1,};static intindentval(Rune *s, int n){	if(n < 2)		return IError;	if(runestrncmp(s, L"ON", n) == 0){		globalautoindent = TRUE;		warning(nil, "Indent ON\n");		return IGlobal;	}	if(runestrncmp(s, L"OFF", n) == 0){		globalautoindent = FALSE;		warning(nil, "Indent OFF\n");		return IGlobal;	}	return runestrncmp(s, L"on", n) == 0;}voidindent(Text *et, Text*, Text *argt, int, int, Rune *arg, int narg){	Rune *a, *r;	Window *w;	int na, len, autoindent;	w = nil;	if(et!=nil && et->w!=nil)		w = et->w;	autoindent = IError;	getarg(argt, FALSE, TRUE, &r, &len);	if(r!=nil && len>0)		autoindent = indentval(r, len);	else{		a = findbl(arg, narg, &na);		if(a != arg)			autoindent = indentval(arg, narg-na);	}	if(w != nil){		switch(autoindent){		case Ion:		case Ioff:			w->autoindent = autoindent;			break;		case IGlobal:			w->autoindent = globalautoindent;			break;		}	}}voidtab(Text *et, Text*, Text *argt, int, int, Rune *arg, int narg){	Rune *a, *r;	Window *w;	int na, len, tab;	char *p;	if(et==nil || et->w==nil)		return;	w = et->w;	getarg(argt, FALSE, TRUE, &r, &len);	tab = 0;	if(r!=nil && len>0){		p = runetobyte(r, len);		if('0'<=p[0] && p[0]<='9')			tab = atoi(p);		free(p);	}else{		a = findbl(arg, narg, &na);		if(a != arg){			p = runetobyte(arg, narg-na);			if('0'<=p[0] && p[0]<='9')				tab = atoi(p);			free(p);		}	}	if(tab > 0){		if(w->body.tabstop != tab){			w->body.tabstop = tab;			winresize(w, w->r, 1);		}	}else		warning(nil, "%.*S: Tab %d\n", w->body.file->nname, w->body.file->name, w->body.tabstop);}voidrunproc(void *argvp){	/* args: */		Window *win;		char *s;		Rune *rdir;		int ndir;		int newns;		char *argaddr;		char *arg;		Command *c;		Channel *cpid;		int iseditcmd;	/* end of args */	char *e, *t, *name, *filename, *dir, **av, *news;	Rune r, **incl;	int ac, w, inarg, i, n, fd, nincl, winid;	int pipechar;	char buf[512];	static void *parg[2];	void **argv;	argv = argvp;	win = argv[0];	s = argv[1];	rdir = argv[2];	ndir = (uintptr)argv[3];	newns = (uintptr)argv[4];	argaddr = argv[5];	arg = argv[6];	c = argv[7];	cpid = argv[8];	iseditcmd = (uintptr)argv[9];	free(argv);	t = s;	while(*t==' ' || *t=='\n' || *t=='\t')		t++;	for(e=t; *e; e++)		if(*e==' ' || *e=='\n' || *e=='\t' )			break;	name = emalloc((e-t)+2);	memmove(name, t, e-t);	name[e-t] = 0;	e = utfrrune(name, '/');	if(e)		memmove(name, e+1, strlen(e+1)+1);	/* strcpy but overlaps */	strcat(name, " ");	/* add blank here for ease in waittask */	c->name = bytetorune(name, &c->nname);	free(name);	pipechar = 0;	if(*t=='<' || *t=='|' || *t=='>')		pipechar = *t++;	c->iseditcmd = iseditcmd;	c->text = s;	if(rdir != nil){		dir = runetobyte(rdir, ndir);		chdir(dir);	/* ignore error: probably app. window */		free(dir);	}	if(newns){		nincl = 0;		incl = nil;		if(win){			filename = smprint("%.*S", win->body.file->nname, win->body.file->name);			nincl = win->nincl;			if(nincl > 0){				incl = emalloc(nincl*sizeof(Rune*));				for(i=0; i<nincl; i++){					n = runestrlen(win->incl[i]);					incl[i] = runemalloc(n+1);					runemove(incl[i], win->incl[i], n);				}			}			winid = win->id;		}else{			filename = nil;			winid = 0;			if(activewin)				winid = activewin->id;		}		rfork(RFNAMEG|RFENVG|RFFDG|RFNOTEG);		sprint(buf, "%d", winid);		putenv("winid", buf);		if(filename){			putenv("%", filename);			free(filename);		}		c->md = fsysmount(rdir, ndir, incl, nincl);		if(c->md == nil){			fprint(2, "child: can't mount /dev/cons: %r\n");			threadexits("mount");		}		close(0);		if(winid>0 && (pipechar=='|' || pipechar=='>')){			sprint(buf, "/mnt/acme/%d/rdsel", winid);			open(buf, OREAD);		}else			open("/dev/null", OREAD);		close(1);		if((winid>0 || iseditcmd) && (pipechar=='|' || pipechar=='<')){			if(iseditcmd){				if(winid > 0)					sprint(buf, "/mnt/acme/%d/editout", winid);				else					sprint(buf, "/mnt/acme/editout");			}else				sprint(buf, "/mnt/acme/%d/wrsel", winid);			open(buf, OWRITE);			close(2);			open("/dev/cons", OWRITE);		}else{			open("/dev/cons", OWRITE);			dup(1, 2);		}	}else{		rfork(RFFDG|RFNOTEG);		fsysclose();		close(0);		open("/dev/null", OREAD);		close(1);		open(acmeerrorfile, OWRITE);		dup(1, 2);	}	if(win)		winclose(win);	if(argaddr)		putenv("acmeaddr", argaddr);	if(strlen(t) > sizeof buf-10)	/* may need to print into stack */		goto Hard;	inarg = FALSE;	for(e=t; *e; e+=w){		w = chartorune(&r, e);		if(r==' ' || r=='\t')			continue;		if(r < ' ')			goto Hard;		if(utfrune("#;&|^$=`'{}()<>[]*?^~`", r))			goto Hard;		inarg = TRUE;	}	if(!inarg)		goto Fail;	ac = 0;	av = nil;	inarg = FALSE;	for(e=t; *e; e+=w){		w = chartorune(&r, e);		if(r==' ' || r=='\t'){			inarg = FALSE;			*e = 0;			continue;		}		if(!inarg){			inarg = TRUE;			av = realloc(av, (ac+1)*sizeof(char**));			av[ac++] = e;		}	}	av = realloc(av, (ac+2)*sizeof(char**));	av[ac++] = arg;	av[ac] = nil;	c->av = av;	procexec(cpid, av[0], av);	e = av[0];	if(e[0]=='/' || (e[0]=='.' && e[1]=='/'))		goto Fail;	if(cputype){		sprint(buf, "%s/%s", cputype, av[0]);		procexec(cpid, buf, av);	}	sprint(buf, "/bin/%s", av[0]);	procexec(cpid, buf, av);	goto Fail;Hard:	/*	 * ugly: set path = (. $cputype /bin)	 * should honor $path if unusual.	 */	if(cputype){		n = 0;		memmove(buf+n, ".", 2);		n += 2;		i = strlen(cputype)+1;		memmove(buf+n, cputype, i);		n += i;		memmove(buf+n, "/bin", 5);		n += 5;		fd = create("/env/path", OWRITE, 0666);		write(fd, buf, n);		close(fd);	}	if(arg){		news = emalloc(strlen(t) + 1 + 1 + strlen(arg) + 1 + 1);		if(news){			sprint(news, "%s '%s'", t, arg);	/* BUG: what if quote in arg? */			free(s);			t = news;			c->text = news;		}	}	procexecl(cpid, "/bin/rc", "rc", "-c", t, nil);   Fail:	/* procexec hasn't happened, so send a zero */	sendul(cpid, 0);	threadexits(nil);}voidrunwaittask(void *v){	Command *c;	Channel *cpid;	void **a;	threadsetname("runwaittask");	a = v;	c = a[0];	cpid = a[1];	free(a);	do		c->pid = recvul(cpid);	while(c->pid == ~0);	free(c->av);	if(c->pid != 0)	/* successful exec */		sendp(ccommand, c);	else{		if(c->iseditcmd)			sendul(cedit, 0);		free(c->name);		free(c->text);		free(c);	}	chanfree(cpid);}voidrun(Window *win, char *s, Rune *rdir, int ndir, int newns, char *argaddr, char *xarg, int iseditcmd){	void **arg;	Command *c;	Channel *cpid;	if(s == nil)		return;	arg = emalloc(10*sizeof(void*));	c = emalloc(sizeof *c);	cpid = chancreate(sizeof(ulong), 0);	arg[0] = win;	arg[1] = s;	arg[2] = rdir;	arg[3] = (void*)ndir;	arg[4] = (void*)newns;	arg[5] = argaddr;	arg[6] = xarg;	arg[7] = c;	arg[8] = cpid;	arg[9] = (void*)iseditcmd;	proccreate(runproc, arg, STACK);	/* mustn't block here because must be ready to answer mount() call in run() */	arg = emalloc(2*sizeof(void*));	arg[0] = c;	arg[1] = cpid;	threadcreate(runwaittask, arg, STACK);}

⌨️ 快捷键说明

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