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

📄 builtin.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include <ctype.h>#include <mach.h>#include <regexp.h>#define Extern extern#include "acid.h"#include "y.tab.h"void	cvtatof(Node*, Node*);void	cvtatoi(Node*, Node*);void	cvtitoa(Node*, Node*);void	bprint(Node*, Node*);void	funcbound(Node*, Node*);void	printto(Node*, Node*);void	getfile(Node*, Node*);void	fmt(Node*, Node*);void	pcfile(Node*, Node*);void	pcline(Node*, Node*);void	setproc(Node*, Node*);void	strace(Node*, Node*);void	follow(Node*, Node*);void	reason(Node*, Node*);void	newproc(Node*, Node*);void	startstop(Node*, Node*);void	match(Node*, Node*);void	status(Node*, Node*);void	kill(Node*,Node*);void	waitstop(Node*, Node*);void	stop(Node*, Node*);void	start(Node*, Node*);void	filepc(Node*, Node*);void	doerror(Node*, Node*);void	rc(Node*, Node*);void	doaccess(Node*, Node*);void	map(Node*, Node*);void	readfile(Node*, Node*);void	interpret(Node*, Node*);void	include(Node*, Node*);void	regexp(Node*, Node*);void	dosysr1(Node*, Node*);typedef struct Btab Btab;struct Btab{	char	*name;	void	(*fn)(Node*, Node*);} tab[] ={	"atof",		cvtatof,	"atoi",		cvtatoi,	"error",	doerror,	"file",		getfile,	"readfile",	readfile,	"access",	doaccess,	"filepc",	filepc,	"fnbound",	funcbound,	"fmt",		fmt,	"follow",	follow,	"itoa",		cvtitoa,	"kill",		kill,	"match",	match,	"newproc",	newproc,	"pcfile",	pcfile,	"pcline",	pcline,	"print",	bprint,	"printto",	printto,	"rc",		rc,	"reason",	reason,	"setproc",	setproc,	"start",	start,	"startstop",	startstop,	"status",	status,	"stop",		stop,	"strace",	strace,	"sysr1",	dosysr1,	"waitstop",	waitstop,	"map",		map,	"interpret",	interpret,	"include",	include,	"regexp",	regexp,	0};char vfmt[] = "aBbcCdDfFgGiIoOqQrRsSuUVWxXYZ";voidmkprint(Lsym *s){	prnt = malloc(sizeof(Node));	memset(prnt, 0, sizeof(Node));	prnt->op = OCALL;	prnt->left = malloc(sizeof(Node));	memset(prnt->left, 0, sizeof(Node));	prnt->left->sym = s;}voidinstallbuiltin(void){	Btab *b;	Lsym *s;	b = tab;	while(b->name) {		s = look(b->name);		if(s == 0)			s = enter(b->name, Tid);		s->builtin = b->fn;		if(b->fn == bprint)			mkprint(s);		b++;	}}voiddosysr1(Node *r, Node*){	extern int sysr1(void);		r->op = OCONST;	r->type = TINT;	r->fmt = 'D';	r->ival = sysr1();}voidmatch(Node *r, Node *args){	int i;	List *f;	Node *av[Maxarg];	Node resi, resl;	na = 0;	flatten(av, args);	if(na != 2)		error("match(obj, list): arg count");	expr(av[1], &resl);	if(resl.type != TLIST)		error("match(obj, list): need list");	expr(av[0], &resi);	r->op = OCONST;	r->type = TINT;	r->fmt = 'D';	r->ival = -1;	i = 0;	for(f = resl.l; f; f = f->next) {		if(resi.type == f->type) {			switch(resi.type) {			case TINT:				if(resi.ival == f->ival) {					r->ival = i;					return;				}				break;			case TFLOAT:				if(resi.fval == f->fval) {					r->ival = i;					return;				}				break;			case TSTRING:				if(scmp(resi.string, f->string)) {					r->ival = i;					return;				}				break;			case TLIST:				error("match(obj, list): not defined for list");			}		}		i++;	}}voidnewproc(Node *r, Node *args){	int i;	Node res;	char *p, *e;	char *argv[Maxarg], buf[Strsize];	i = 1;	argv[0] = aout;	if(args) {		expr(args, &res);		if(res.type != TSTRING)			error("newproc(): arg not string");		if(res.string->len >= sizeof(buf))			error("newproc(): too many arguments");		memmove(buf, res.string->string, res.string->len);		buf[res.string->len] = '\0';		p = buf;		e = buf+res.string->len;		for(;;) {			while(p < e && (*p == '\t' || *p == ' '))				*p++ = '\0';			if(p >= e)				break;			argv[i++] = p;			if(i >= Maxarg)				error("newproc: too many arguments");			while(p < e && *p != '\t' && *p != ' ')				p++;		}	}	argv[i] = 0;	r->op = OCONST;	r->type = TINT;	r->fmt = 'D';	r->ival = nproc(argv);}voidstartstop(Node *r, Node *args){	Node res;	USED(r);	if(args == 0)		error("startstop(pid): no pid");	expr(args, &res);	if(res.type != TINT)		error("startstop(pid): arg type");	msg(res.ival, "startstop");	notes(res.ival);	dostop(res.ival);}voidwaitstop(Node *r, Node *args){	Node res;	USED(r);	if(args == 0)		error("waitstop(pid): no pid");	expr(args, &res);	if(res.type != TINT)		error("waitstop(pid): arg type");	Bflush(bout);	msg(res.ival, "waitstop");	notes(res.ival);	dostop(res.ival);}voidstart(Node *r, Node *args){	Node res;	USED(r);	if(args == 0)		error("start(pid): no pid");	expr(args, &res);	if(res.type != TINT)		error("start(pid): arg type");	msg(res.ival, "start");}voidstop(Node *r, Node *args){	Node res;	USED(r);	if(args == 0)		error("stop(pid): no pid");	expr(args, &res);	if(res.type != TINT)		error("stop(pid): arg type");	Bflush(bout);	msg(res.ival, "stop");	notes(res.ival);	dostop(res.ival);}voidkill(Node *r, Node *args){	Node res;	USED(r);	if(args == 0)		error("kill(pid): no pid");	expr(args, &res);	if(res.type != TINT)		error("kill(pid): arg type");	msg(res.ival, "kill");	deinstall(res.ival);}voidstatus(Node *r, Node *args){	Node res;	char *p;	USED(r);	if(args == 0)		error("status(pid): no pid");	expr(args, &res);	if(res.type != TINT)		error("status(pid): arg type");	p = getstatus(res.ival);	r->string = strnode(p);	r->op = OCONST;	r->fmt = 's';	r->type = TSTRING;}voidreason(Node *r, Node *args){	Node res;	if(args == 0)		error("reason(cause): no cause");	expr(args, &res);	if(res.type != TINT)		error("reason(cause): arg type");	r->op = OCONST;	r->type = TSTRING;	r->fmt = 's';	r->string = strnode((*machdata->excep)(cormap, rget));}voidfollow(Node *r, Node *args){	int n, i;	Node res;	uvlong f[10];	List **tail, *l;	if(args == 0)		error("follow(addr): no addr");	expr(args, &res);	if(res.type != TINT)		error("follow(addr): arg type");	n = (*machdata->foll)(cormap, res.ival, rget, f);	if (n < 0)		error("follow(addr): %r");	tail = &r->l;	for(i = 0; i < n; i++) {		l = al(TINT);		l->ival = f[i];		l->fmt = 'X';		*tail = l;		tail = &l->next;	}}voidfuncbound(Node *r, Node *args){	int n;	Node res;	uvlong bounds[2];	List *l;	if(args == 0)		error("fnbound(addr): no addr");	expr(args, &res);	if(res.type != TINT)		error("fnbound(addr): arg type");	n = fnbound(res.ival, bounds);	if (n != 0) {		r->l = al(TINT);		l = r->l;		l->ival = bounds[0];		l->fmt = 'X';		l->next = al(TINT);		l = l->next;		l->ival = bounds[1];		l->fmt = 'X';	}}voidsetproc(Node *r, Node *args){	Node res;	USED(r);	if(args == 0)		error("setproc(pid): no pid");	expr(args, &res);	if(res.type != TINT)		error("setproc(pid): arg type");	sproc(res.ival);}voidfilepc(Node *r, Node *args){	Node res;	char *p, c;	if(args == 0)		error("filepc(filename:line): arg count");	expr(args, &res);	if(res.type != TSTRING)		error("filepc(filename:line): arg type");	p = strchr(res.string->string, ':');	if(p == 0)		error("filepc(filename:line): bad arg format");	c = *p;	*p++ = '\0';	r->ival = file2pc(res.string->string, strtol(p, 0, 0));	p[-1] = c;	if(r->ival == ~0)		error("filepc(filename:line): can't find address");	r->op = OCONST;	r->type = TINT;	r->fmt = 'V';}voidinterpret(Node *r, Node *args){	Node res;	int isave;	if(args == 0)		error("interpret(string): arg count");	expr(args, &res);	if(res.type != TSTRING)		error("interpret(string): arg type");	pushstr(&res);	isave = interactive;	interactive = 0;	r->ival = yyparse();	interactive = isave;	popio();	r->op = OCONST;	r->type = TINT;	r->fmt = 'D';}voidinclude(Node *r, Node *args){	Node res;	int isave;	if(args == 0)		error("include(string): arg count");	expr(args, &res);	if(res.type != TSTRING)		error("include(string): arg type");	pushfile(res.string->string);	isave = interactive;	interactive = 0;	r->ival = yyparse();	interactive = isave;	popio();	r->op = OCONST;	r->type = TINT;	r->fmt = 'D';}voidrc(Node *r, Node *args){	Node res;	int pid;	char *p, *q, *argv[4];	Waitmsg *w;	USED(r);	if(args == 0)		error("error(string): arg count");	expr(args, &res);	if(res.type != TSTRING)		error("error(string): arg type");	argv[0] = "/bin/rc";	argv[1] = "-c";	argv[2] = res.string->string;	argv[3] = 0;	pid = fork();	switch(pid) {	case -1:		error("fork %r");	case 0:		exec("/bin/rc", argv);		exits(0);	default:		w = waitfor(pid);		break;	}	p = w->msg;	q = strrchr(p, ':');	if (q)		p = q+1;	r->op = OCONST;	r->type = TSTRING;	r->string = strnode(p);	free(w);	r->fmt = 's';}voiddoerror(Node *r, Node *args){	Node res;	USED(r);	if(args == 0)		error("error(string): arg count");	expr(args, &res);	if(res.type != TSTRING)		error("error(string): arg type");	error(res.string->string);}voiddoaccess(Node *r, Node *args){	Node res;	if(args == 0)		error("access(filename): arg count");	expr(args, &res);	if(res.type != TSTRING)		error("access(filename): arg type");	r->op = OCONST;	r->type = TINT;	r->ival = 0;			if(access(res.string->string, 4) == 0)		r->ival = 1;}voidreadfile(Node *r, Node *args){	Node res;	int n, fd;	char *buf;	Dir *db;	if(args == 0)		error("readfile(filename): arg count");	expr(args, &res);	if(res.type != TSTRING)		error("readfile(filename): arg type");	fd = open(res.string->string, OREAD);	if(fd < 0)		return;	db = dirfstat(fd);	if(db == nil || db->length == 0)		n = 8192;	else		n = db->length;	free(db);	buf = malloc(n);	n = read(fd, buf, n);	if(n > 0) {		r->op = OCONST;		r->type = TSTRING;		r->string = strnodlen(buf, n);		r->fmt = 's';	}	free(buf);	close(fd);}voidgetfile(Node *r, Node *args){	int n;	char *p;	Node res;	String *s;	Biobuf *bp;	List **l, *new;	if(args == 0)		error("file(filename): arg count");	expr(args, &res);	if(res.type != TSTRING)		error("file(filename): arg type");	r->op = OCONST;	r->type = TLIST;	r->l = 0;	p = res.string->string;	bp = Bopen(p, OREAD);	if(bp == 0)		return;	l = &r->l;	for(;;) {		p = Brdline(bp, '\n');		n = Blinelen(bp);		if(p == 0) {			if(n == 0)				break;

⌨️ 快捷键说明

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