summaryrefslogtreecommitdiff
path: root/sys/src/cmd/qi/syscall.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/qi/syscall.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/qi/syscall.c')
-rwxr-xr-xsys/src/cmd/qi/syscall.c740
1 files changed, 740 insertions, 0 deletions
diff --git a/sys/src/cmd/qi/syscall.c b/sys/src/cmd/qi/syscall.c
new file mode 100755
index 000000000..0c5a82cca
--- /dev/null
+++ b/sys/src/cmd/qi/syscall.c
@@ -0,0 +1,740 @@
+#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); }
+
+void
+sys_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;
+}
+
+void
+syserrstr(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;
+
+}
+
+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, 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[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");
+}
+
+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)", nofunc);
+
+ reg.r[REGRET] = 0;
+}
+
+void
+syssegflush(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,
+};
+
+void
+sc(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);
+}