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

📄 syscall.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include <mach.h>#define	EXTERN#include "arm.h"#define	ODIRLEN	116	/* compatibility; used in _stat etc. */#define	OERRLEN	64	/* compatibility; used in _stat etc. */char 	errbuf[ERRMAX];ulong	nofunc;#include "/sys/src/libc/9syscall/sys.h"char*	sysctab[] ={	[SYSR1]		"Running",	[_ERRSTR]		"_errstr",	[BIND]		"Bind",	[CHDIR]		"Chdir",	[CLOSE]		"Close",	[DUP]		"Dup",	[ALARM]		"Alarm",	[EXEC]		"Exec",	[EXITS]		"Exits",	[_FSESSION]	"_Fsession",	[FAUTH]		"Fauth",	[_FSTAT]		"_fstat",	[SEGBRK]		"Segbrk",	[MOUNT]		"Mount",	[OPEN]		"Open",	[_READ]		"_Read",	[OSEEK]		"Oseek",	[SLEEP]		"Sleep",	[_STAT]		"_Stat",	[RFORK]		"Rfork",	[_WRITE]		"_Write",	[PIPE]		"Pipe",	[CREATE]		"Create",	[FD2PATH]	"Fd2path",	[BRK_]		"Brk_",	[REMOVE]		"Remove",	[_WSTAT]		"_Wstat",	[_FWSTAT]	"_Fwstat",	[NOTIFY]		"Notify",	[NOTED]		"Noted",	[SEGATTACH]	"Segattach",	[SEGDETACH]	"Segdetach",	[SEGFREE]		"Segfree",	[SEGFLUSH]	"Segflush",	[RENDEZVOUS]	"Rendezvous",	[UNMOUNT]	"Unmount",	[_WAIT]		"_Wait",	[SEEK]		"Seek",	[FVERSION]	"Fversion",	[ERRSTR]		"Errstr",	[STAT]		"Stat",	[FSTAT]		"Fstat",	[WSTAT]		"Wstat",	[FWSTAT]		"Fwstat",	[PREAD]		"Pread",	[PWRITE]		"Pwrite",	[AWAIT]		"Await",};voidsys1(void){	Bprint(bioout, "no system call %s\n", sysctab[reg.r[1]]);	exits(0);}voidsys_errstr(void){	ulong str;	str = getmem_w(reg.r[13]+4);	if(sysdbg)		itrace("errstr(0x%lux)", str);	memio(errbuf, str, OERRLEN, MemWrite);	strcpy(errbuf, "no error");	reg.r[REGRET] = 0;	}voidsyserrstr(void){	ulong str;	int n;	str = getmem_w(reg.r[13]+4);	n = getmem_w(reg.r[13]+8);	if(sysdbg)		itrace("errstr(0x%lux, 0x%lux)", str, n);	if(n > strlen(errbuf)+1)		n = strlen(errbuf)+1;	memio(errbuf, str, n, MemWrite);	strcpy(errbuf, "no error");	reg.r[REGRET] = n;	}voidsysbind(void){ 	ulong pname, pold, flags;	char name[1024], old[1024];	int n;	pname = getmem_w(reg.r[13]+4);	pold = getmem_w(reg.r[13]+8);	flags = getmem_w(reg.r[13]+12);	memio(name, pname, sizeof(name), MemReadstring);	memio(old, pold, sizeof(old), MemReadstring);	if(sysdbg)		itrace("bind(0x%lux='%s', 0x%lux='%s', 0x%lux)", name, name, old, old, flags);	n = bind(name, old, flags);	if(n < 0)		errstr(errbuf, sizeof errbuf);	reg.r[REGRET] = n;}voidsysfd2path(void){	ulong str;	uint fd, n;	char buf[1024];	fd = getmem_w(reg.r[13]+4);	str = getmem_w(reg.r[13]+8);	n = getmem_w(reg.r[13]+12);	if(sysdbg)		itrace("fd2path(0x%lux, 0x%lux, 0x%lux)", fd, str, n);	reg.r[1] = -1;	if(n > sizeof buf){		strcpy(errbuf, "buffer too big");		return;	}	n = fd2path(fd, buf, sizeof buf);	if(n < 0)		errstr(buf, sizeof buf);	else		memio(errbuf, str, n, MemWrite);	reg.r[REGRET] = n;	}voidsyschdir(void){ 	char file[1024];	int n;	ulong name;	name = getmem_w(reg.r[13]+4);	memio(file, name, sizeof(file), MemReadstring);	if(sysdbg)		itrace("chdir(0x%lux='%s', 0x%lux)", name, file);		n = chdir(file);	if(n < 0)		errstr(errbuf, sizeof errbuf);	reg.r[REGRET] = n;}voidsysclose(void){	int n;	ulong fd;	fd = getmem_w(reg.r[13]+4);	if(sysdbg)		itrace("close(%d)", fd);	n = close(fd);	if(n < 0)		errstr(errbuf, sizeof errbuf);	reg.r[REGRET] = n;}voidsysdup(void){	int oldfd, newfd;	int n;	oldfd = getmem_w(reg.r[13]+4);	newfd = getmem_w(reg.r[13]+8);	if(sysdbg)		itrace("dup(%d, %d)", oldfd, newfd);	n = dup(oldfd, newfd);	if(n < 0)		errstr(errbuf, sizeof errbuf);	reg.r[REGRET] = n;}voidsysexits(void){	char buf[OERRLEN];	ulong str;	str = getmem_w(reg.r[13]+4);	if(sysdbg)		itrace("exits(0x%lux)", str);	count = 1;	if(str != 0) {		memio(buf, str, sizeof buf, MemRead);		Bprint(bioout, "exits(%s)\n", buf);	}	else		Bprint(bioout, "exits(0)\n");}voidsysopen(void){	char file[1024];	int n;	ulong mode, name;	name = getmem_w(reg.r[13]+4);	mode = getmem_w(reg.r[13]+8);	memio(file, name, sizeof(file), MemReadstring);		n = open(file, mode);	if(n < 0)		errstr(errbuf, sizeof errbuf);	if(sysdbg)		itrace("open(0x%lux='%s', 0x%lux) = %d", name, file, mode, n);	reg.r[REGRET] = n;};voidsysread(vlong offset){	int fd;	ulong size, a;	char *buf, *p;	int n, cnt, c;	fd = getmem_w(reg.r[13]+4);	a = getmem_w(reg.r[13]+8);	size = getmem_w(reg.r[13]+12);	buf = emalloc(size);	if(fd == 0) {		print("\nstdin>>");		p = buf;		n = 0;		cnt = size;		while(cnt) {			c = Bgetc(bin);			if(c <= 0)				break;			*p++ = c;			n++;			cnt--;			if(c == '\n')				break;		}	}	else		n = pread(fd, buf, size, offset);	if(n < 0)		errstr(errbuf, sizeof errbuf);	else		memio(buf, a, n, MemWrite);	if(sysdbg)		itrace("read(%d, 0x%lux, %d, 0x%llx) = %d", fd, a, size, offset, n);	free(buf);	reg.r[REGRET] = n;}voidsys_read(void){	sysread(-1LL);}voidsyspread(void){	union {		vlong v;		ulong u[2];	} o;	o.u[0] = getmem_w(reg.r[13]+16);	o.u[1] = getmem_w(reg.r[13]+20);	sysread(o.v);}voidsysseek(void){	int fd;	ulong mode;	ulong retp;	union {		vlong v;		ulong u[2];	} o;	retp = getmem_w(reg.r[13]+4);	fd = getmem_w(reg.r[13]+8);	o.u[0] = getmem_w(reg.r[13]+12);	o.u[1] = getmem_w(reg.r[13]+16);	mode = getmem_w(reg.r[13]+20);	if(sysdbg)		itrace("seek(%d, %lld, %d)", fd, o.v, mode);	o.v = seek(fd, o.v, mode);	if(o.v < 0)		errstr(errbuf, sizeof errbuf);		memio((char*)o.u, retp, sizeof(vlong), MemWrite);}voidsysoseek(void){	int fd, n;	ulong off, mode;	fd = getmem_w(reg.r[13]+4);	off = getmem_w(reg.r[13]+8);	mode = getmem_w(reg.r[13]+12);	if(sysdbg)		itrace("seek(%d, %lud, %d)", fd, off, mode);	n = seek(fd, off, mode);	if(n < 0)		errstr(errbuf, sizeof errbuf);		reg.r[REGRET] = n;}voidsyssleep(void){	ulong len;	int n;	len = getmem_w(reg.r[13]+4);	if(sysdbg)		itrace("sleep(%d)", len);	n = sleep(len);	if(n < 0)		errstr(errbuf, sizeof errbuf);		reg.r[REGRET] = n;}voidsys_stat(void){	char nambuf[1024];	char buf[ODIRLEN];	ulong edir, name;	extern int _stat(char*, char*);	/* old system call */	int n;	name = getmem_w(reg.r[13]+4);	edir = getmem_w(reg.r[13]+8);	memio(nambuf, name, sizeof(nambuf), MemReadstring);	if(sysdbg)		itrace("stat(0x%lux='%s', 0x%lux)", name, nambuf, edir);	n = _stat(nambuf, buf);	if(n < 0)		errstr(errbuf, sizeof errbuf);	else		memio(buf, edir, ODIRLEN, MemWrite);	reg.r[REGRET] = n;}voidsysstat(void){	char nambuf[1024];	uchar buf[STATMAX];	ulong edir, name;	int n;	name = getmem_w(reg.r[13]+4);	edir = getmem_w(reg.r[13]+8);	n = getmem_w(reg.r[13]+12);	memio(nambuf, name, sizeof(nambuf), MemReadstring);	if(sysdbg)		itrace("stat(0x%lux='%s', 0x%lux, 0x%lux)", name, nambuf, edir, n);	if(n > sizeof buf)		errstr(errbuf, sizeof errbuf);	else{			n = stat(nambuf, buf, n);		if(n < 0)			errstr(errbuf, sizeof errbuf);		else			memio((char*)buf, edir, n, MemWrite);	}	reg.r[REGRET] = n;}voidsys_fstat(void){	char buf[ODIRLEN];	extern int _fstat(int, char*);	/* old system call */	ulong edir;	int n, fd;	fd = getmem_w(reg.r[13]+4);	edir = getmem_w(reg.r[13]+8);	if(sysdbg)		itrace("fstat(%d, 0x%lux)", fd, edir);	n = _fstat(fd, buf);	if(n < 0)		errstr(errbuf, sizeof errbuf);	else		memio(buf, edir, ODIRLEN, MemWrite);	reg.r[REGRET] = n;}voidsysfstat(void){	uchar buf[STATMAX];	ulong edir;	int n, fd;	fd = getmem_w(reg.r[13]+4);	edir = getmem_w(reg.r[13]+8);	n = getmem_w(reg.r[13]+12);	if(sysdbg)		itrace("fstat(%d, 0x%lux, 0x%lux)", fd, edir, n);	reg.r[REGRET] = -1;	if(n > sizeof buf){		strcpy(errbuf, "stat buffer too big");		return;	}	n = fstat(fd, buf, n);	if(n < 0)		errstr(errbuf, sizeof errbuf);	else		memio((char*)buf, edir, n, MemWrite);	reg.r[REGRET] = n;}voidsyswrite(vlong offset){	int fd;	ulong size, a;	char *buf;	int n;	fd = getmem_w(reg.r[13]+4);	a = getmem_w(reg.r[13]+8);	size = getmem_w(reg.r[13]+12);	Bflush(bioout);	buf = memio(0, a, size, MemRead);	n = pwrite(fd, buf, size, offset);	if(n < 0)		errstr(errbuf, sizeof errbuf);		if(sysdbg)		itrace("write(%d, %lux, %d, 0x%llx) = %d", fd, a, size, offset, n);	free(buf);	reg.r[REGRET] = n;}voidsys_write(void){	syswrite(-1LL);}voidsyspwrite(void){	union {		vlong v;		ulong u[2];	} o;	o.u[0] = getmem_w(reg.r[13]+16);	o.u[1] = getmem_w(reg.r[13]+20);	syswrite(o.v);}voidsyspipe(void){	int n, p[2];	ulong fd;	fd = getmem_w(reg.r[13]+4);	if(sysdbg)		itrace("pipe(%lux)", fd);	n = pipe(p);	if(n < 0)		errstr(errbuf, sizeof errbuf);	else {		putmem_w(fd, p[0]);		putmem_w(fd+4, p[1]);	}	reg.r[REGRET] = n;}voidsyscreate(void){	char file[1024];	int n;	ulong mode, name, perm;	name = getmem_w(reg.r[13]+4);	mode = getmem_w(reg.r[13]+8);	perm = getmem_w(reg.r[13]+12);	memio(file, name, sizeof(file), MemReadstring);	if(sysdbg)		itrace("create(0x%lux='%s', 0x%lux, 0x%lux)", name, file, mode, perm);		n = create(file, mode, perm);	if(n < 0)		errstr(errbuf, sizeof errbuf);	reg.r[REGRET] = n;}voidsysbrk_(void){	ulong addr, osize, nsize;	Segment *s;	addr = getmem_w(reg.r[13]+4);	if(sysdbg)		itrace("brk_(0x%lux)", addr);	reg.r[REGRET] = -1;	if(addr < memory.seg[Data].base+datasize) {		strcpy(errbuf, "address below segment");		return;	}	if(addr > memory.seg[Stack].base) {		strcpy(errbuf, "segment too big");		return;	}	s = &memory.seg[Bss];	if(addr > s->end) {		osize = ((s->end-s->base)/BY2PG)*sizeof(uchar*);		addr = ((addr)+(BY2PG-1))&~(BY2PG-1);		s->end = addr;		nsize = ((s->end-s->base)/BY2PG)*sizeof(uchar*);		s->table = erealloc(s->table, osize, nsize);	}		reg.r[REGRET] = 0;	}voidsysremove(void){	char nambuf[1024];	ulong name;	int n;	name = getmem_w(reg.r[13]+4);	memio(nambuf, name, sizeof(nambuf), MemReadstring);	if(sysdbg)		itrace("remove(0x%lux='%s')", name, nambuf);	n = remove(nambuf);	if(n < 0)		errstr(errbuf, sizeof errbuf);	reg.r[REGRET] = n;}voidsysnotify(void){	nofunc = getmem_w(reg.r[13]+4);	if(sysdbg)		itrace("notify(0x%lux)\n", nofunc);	reg.r[REGRET] = 0;}voidsys_wait(void){	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);	exits(0);}voidsysawait(void){	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);	exits(0);}voidsysrfork(void){	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);	exits(0);}voidsyswstat(void){	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);	exits(0);}voidsys_wstat(void){	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);	exits(0);}voidsysfwstat(void){	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);	exits(0);}voidsys_fwstat(void){	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);	exits(0);}voidsysnoted(void){	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);	exits(0);}voidsyssegattach(void){	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);	exits(0);}voidsyssegdetach(void){	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);	exits(0);}voidsyssegfree(void){	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);	exits(0);}voidsyssegflush(void){	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);	exits(0);}voidsysrendezvous(void){	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);	exits(0);}voidsysunmount(void){	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);	exits(0);}voidsysfork(void){	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);	exits(0);}voidsysforkpgrp(void){	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);	exits(0);}voidsyssegbrk(void){	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);	exits(0);}voidsysmount(void){	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);	exits(0);}voidsysalarm(void){	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);	exits(0);}voidsysexec(void){	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]); 	exits(0);}voidsys_fsession(void){	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]); 	exits(0);}voidsysfauth(void){	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]); 	exits(0);}voidsysfversion(void){	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]); 	exits(0);}void	(*systab[])(void) ={	[SYSR1]		sys1,	[_ERRSTR]		sys_errstr,	[BIND]		sysbind,	[CHDIR]		syschdir,	[CLOSE]		sysclose,	[DUP]		sysdup,	[ALARM]		sysalarm,	[EXEC]		sysexec,	[EXITS]		sysexits,	[_FSESSION]	sys_fsession,	[FAUTH]		sysfauth,	[_FSTAT]		sys_fstat,	[SEGBRK]		syssegbrk,	[MOUNT]		sysmount,	[OPEN]		sysopen,	[_READ]		sys_read,	[OSEEK]		sysoseek,	[SLEEP]		syssleep,	[_STAT]		sys_stat,	[RFORK]		sysrfork,	[_WRITE]		sys_write,	[PIPE]		syspipe,	[CREATE]		syscreate,	[FD2PATH]	sysfd2path,	[BRK_]		sysbrk_,	[REMOVE]		sysremove,	[_WSTAT]		sys_wstat,	[_FWSTAT]	sys_fwstat,	[NOTIFY]		sysnotify,	[NOTED]		sysnoted,	[SEGATTACH]	syssegattach,	[SEGDETACH]	syssegdetach,	[SEGFREE]		syssegfree,	[SEGFLUSH]	syssegflush,	[RENDEZVOUS]	sysrendezvous,	[UNMOUNT]	sysunmount,	[_WAIT]		sys_wait,	[SEEK]		sysseek,	[FVERSION]	sysfversion,	[ERRSTR]		syserrstr,	[STAT]		sysstat,	[FSTAT]		sysfstat,	[WSTAT]		syswstat,	[FWSTAT]		sysfwstat,	[PREAD]		syspread,	[PWRITE]		syspwrite,	[AWAIT]		sysawait,};voidSsyscall(ulong){	int call;	call = reg.r[REGARG];	if(call < 0 || call > PWRITE || systab[call] == nil) {		Bprint(bioout, "bad system call\n");		dumpreg();	}	if(trace)		itrace("SWI\t%s", sysctab[call]);	(*systab[call])();	Bflush(bioout);}

⌨️ 快捷键说明

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