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

📄 syscall.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <auth.h>#include <bio.h>#include <mach.h>#define Extern extern#include "power.h"#define	REGSP	1#define	REGRET	3#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]		"SYSR1",	[_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",	[MOUNT]		"Mount",	[AWAIT]		"Await",	[PREAD]		"Pread",	[PWRITE]	"Pwrite",};void sys1(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGRET]]); exits(0); }voidsys_errstr(void){	ulong str;	char tmp[OERRLEN];	str = getmem_w(reg.r[REGSP]+4);	if(sysdbg)		itrace("errstr(0x%lux)", str);	memio(tmp, str, OERRLEN, MemRead);	memio(errbuf, str, OERRLEN, MemWrite);	memmove(errbuf, tmp, OERRLEN);	errbuf[OERRLEN-1] = 0;	reg.r[REGRET] = 0;}voidsyserrstr(void){	ulong str;	uint n;	char tmp[ERRMAX];	str = getmem_w(reg.r[REGSP]+4);	n = getmem_w(reg.r[REGSP]+8);	if(sysdbg)		itrace("errstr(0x%lux, 0x%lux)", str, n);	if(n > strlen(errbuf)+1)		n = strlen(errbuf)+1;	if(n > ERRMAX)		n = ERRMAX;	memio(tmp, str, n, MemRead);	memio(errbuf, str, n, MemWrite);	memmove(errbuf, tmp, n);	errbuf[ERRMAX-1] = 0;	reg.r[REGRET] = n;	}voidsysfd2path(void){	ulong str;	uint fd, n;	char buf[1024];	fd = getmem_w(reg.r[REGSP]+4);	str = getmem_w(reg.r[REGSP]+8);	n = getmem_w(reg.r[REGSP]+12);	if(sysdbg)		itrace("fd2path(0x%lux, 0x%lux, 0x%lux)", fd, str, n);	reg.r[REGRET] = -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;	}voidsysbind(void){	ulong pname, pold, flags;	char name[1024], old[1024];	int n;	pname = getmem_w(reg.r[REGSP]+4);	pold = getmem_w(reg.r[REGSP]+8);	flags = getmem_w(reg.r[REGSP]+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, old, flags);	n = bind(name, old, flags);	if(n < 0)		errstr(errbuf, sizeof errbuf);	reg.r[REGRET] = n;}voidsyschdir(void){ 	char file[1024];	int n;	ulong name;	name = getmem_w(reg.r[REGSP]+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[REGSP]+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[REGSP]+4);	newfd = getmem_w(reg.r[REGSP]+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[ERRMAX];	ulong str;	str = getmem_w(reg.r[REGSP]+4);	if(sysdbg)		itrace("exits(0x%lux)", str);	count = 1;	if(str != 0) {		memio(buf, str, sizeof buf, MemRead);		buf[ERRMAX-1] = 0;		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[REGSP]+4);	mode = getmem_w(reg.r[REGSP]+8);	memio(file, name, sizeof(file), MemReadstring);	if(sysdbg)		itrace("open(0x%lux='%s', 0x%lux)", name, file, mode);		n = open(file, mode);	if(n < 0)		errstr(errbuf, sizeof errbuf);	reg.r[REGRET] = n;};voidsysread(vlong offset){	int fd;	ulong size, a;	char *buf, *p;	int n, cnt, c;	fd = getmem_w(reg.r[REGSP]+4);	a = getmem_w(reg.r[REGSP]+8);	size = getmem_w(reg.r[REGSP]+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[REGSP]+16);	o.u[1] = getmem_w(reg.r[REGSP]+20);	sysread(o.v);}voidsysseek(void){	int fd;	ulong mode;	ulong retp;	union {		vlong v;		ulong u[2];	} o;	retp = getmem_w(reg.r[REGSP]+4);	fd = getmem_w(reg.r[REGSP]+8);	o.u[0] = getmem_w(reg.r[REGSP]+12);	o.u[1] = getmem_w(reg.r[REGSP]+16);	mode = getmem_w(reg.r[REGSP]+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[REGSP]+4);	off = getmem_w(reg.r[REGSP]+8);	mode = getmem_w(reg.r[REGSP]+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;}voidsysrfork(void){	int flag;	flag = getmem_w(reg.r[REGSP]+4);	if(sysdbg)		itrace("rfork(%d)", flag);	if(flag & RFPROC) {		Bprint(bioout, "rfork: cannot create process, rfork(0x%.8ux)\n", flag);		exits(0);	}	reg.r[REGRET] = rfork(flag);}voidsyssleep(void){	ulong len;	int n;	len = getmem_w(reg.r[REGSP]+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[REGSP]+4);	edir = getmem_w(reg.r[REGSP]+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[REGSP]+4);	edir = getmem_w(reg.r[REGSP]+8);	n = getmem_w(reg.r[REGSP]+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];	ulong edir;	extern int _fstat(int, char*);	/* old system call */	int n, fd;	fd = getmem_w(reg.r[REGSP]+4);	edir = getmem_w(reg.r[REGSP]+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[REGSP]+4);	edir = getmem_w(reg.r[REGSP]+8);	n = getmem_w(reg.r[REGSP]+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[REGSP]+4);	a = getmem_w(reg.r[REGSP]+8);	size = getmem_w(reg.r[REGSP]+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, 0xllx) = %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[REGSP]+16);	o.u[1] = getmem_w(reg.r[REGSP]+20);	syswrite(o.v);}voidsyspipe(void){	int n, p[2];	ulong fd;	fd = getmem_w(reg.r[REGSP]+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[REGSP]+4);	mode = getmem_w(reg.r[REGSP]+8);	perm = getmem_w(reg.r[REGSP]+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[REGSP]+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[REGSP]+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[REGSP]+4);	if(sysdbg)		itrace("notify(0x%lux)", nofunc);	reg.r[REGRET] = 0;}voidsyssegflush(void){	ulong start, len;	start = getmem_w(reg.r[REGSP]+4);	len = getmem_w(reg.r[REGSP]+8);	if(sysdbg)		itrace("segflush(va=0x%lux, n=%lud)", start, len);	reg.r[REGRET] = 0;}void sysfversion(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGRET]]); exits(0); }void sysfsession(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGRET]]); exits(0); }void sysfauth(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGRET]]); exits(0); }void syswait(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGRET]]); exits(0); }void syswstat(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGRET]]); exits(0);}void sys_wstat(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGRET]]); exits(0);}void sysfwstat(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGRET]]); exits(0);}void sys_fwstat(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGRET]]); exits(0);}void sysnoted(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGRET]]); exits(0);}void syssegattach(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGRET]]); exits(0);}void syssegdetach(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGRET]]); exits(0);}void syssegfree(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGRET]]); exits(0);}void sysrendezvous(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGRET]]); exits(0);}void sysunmount(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGRET]]); exits(0);}void sysfork(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGRET]]); exits(0);}void sysforkpgrp(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGRET]]); exits(0);}void syssegbrk(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGRET]]); exits(0);}void _sysmount(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGRET]]); exits(0);}void sysalarm(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGRET]]); exits(0);}void sysexec(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGRET]]); exits(0);}void sysmount(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGRET]]); exits(0);}void sysawait(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGRET]]); 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]	sysfsession,	[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]		syswait,	[SEEK]		sysseek,	[FVERSION]	sysfversion,	[ERRSTR]	syserrstr,	[STAT]		sysstat,	[FSTAT]		sysfstat,	[WSTAT]		syswstat,	[FWSTAT]	sysfwstat,	[MOUNT]		sysmount,	[AWAIT]		sysawait,	[PREAD]		syspread,	[PWRITE]	syspwrite,};voidsc(ulong inst){	int call;	if(inst != ((17<<26)|2))		undef(inst);	call = reg.r[REGRET];	if(call < 0 || call > PWRITE || systab[call] == nil) {		Bprint(bioout, "Bad system call\n");		dumpreg();	}	if(trace)		itrace("sc\t(%s)", sysctab[call]);	(*systab[call])();	Bflush(bioout);}

⌨️ 快捷键说明

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