diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/vi/syscall.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/vi/syscall.c')
-rwxr-xr-x | sys/src/cmd/vi/syscall.c | 731 |
1 files changed, 731 insertions, 0 deletions
diff --git a/sys/src/cmd/vi/syscall.c b/sys/src/cmd/vi/syscall.c new file mode 100755 index 000000000..7b977dd0d --- /dev/null +++ b/sys/src/cmd/vi/syscall.c @@ -0,0 +1,731 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include <mach.h> +#define Extern extern +#include "mips.h" + +#define REGSP 29 +#define REGRET 1 + +#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); } + +void +sys_errstr(void) +{ + ulong str; + + str = getmem_w(reg.r[REGSP]+4); + if(sysdbg) + itrace("errstr(0x%lux)", str); + + memio(errbuf, str, OERRLEN, MemWrite); + strcpy(errbuf, "no error"); + reg.r[REGRET] = 0; + +} + +void +syserrstr(void) +{ + ulong str; + uint n; + + 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; + memio(errbuf, str, n, MemWrite); + strcpy(errbuf, "no error"); + reg.r[REGRET] = n; + +} + +void +sysfd2path(void) +{ + int n; + uint fd; + ulong str; + 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; + +} + +void +sysbind(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, name, old, old, flags); + + n = bind(name, old, flags); + if(n < 0) + errstr(errbuf, sizeof errbuf); + + reg.r[REGRET] = n; +} + +void +syschdir(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; +} + +void +sysclose(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; +} + +void +sysdup(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; +} + +void +sysexits(void) +{ + char buf[OERRLEN]; + 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); + Bprint(bioout, "exits(%s)\n", buf); + } + else + Bprint(bioout, "exits(0)\n"); +} + +void +sysopen(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; +}; + +void +sysread(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; +} + +void +sys_read(void) +{ + sysread(-1LL); +} + +void +syspread(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); +} + +void +sysseek(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); +} + +void +sysoseek(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; +} + +void +sysrfork(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); +} + +void +syssleep(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; +} + +void +sys_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; +} + +void +sysstat(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; +} + +void +sys_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; +} + +void +sysfstat(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; +} + +void +syswrite(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; +} + +void +sys_write(void) +{ + syswrite(-1LL); +} + +void +syspwrite(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); +} + +void +syspipe(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; +} + +void +syscreate(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; +} + +void +sysbrk_(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; +} + +void +sysremove(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; +} + +void +sysnotify(void) +{ + nofunc = getmem_w(reg.r[REGSP]+4); + if(sysdbg) + itrace("notify(0x%lux)\n", nofunc); + + reg.r[REGRET] = 0; +} + +void +syssegflush(void) +{ + int n; + ulong va; + + va = getmem_w(reg.r[REGSP]+4); + n = getmem_w(reg.r[REGSP]+8); + if(sysdbg) + itrace("segflush(va=0x%lux, n=%d)\n", va, n); + + 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, +}; + +void +Ssyscall(ulong inst) +{ + int call; + + USED(inst); + call = reg.r[REGRET]; + if(call < 0 || call > PWRITE || systab[call] == nil) { + Bprint(bioout, "Bad system call\n"); + dumpreg(); + } + if(trace) + itrace("sysc\t%s", sysctab[call]); + + (*systab[call])(); + Bflush(bioout); +} |