xref: /plan9-contrib/sys/src/cmd/5i/syscall.c (revision a41547ffda0e0a8ab69753330f2e59eeb889e152)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <mach.h>
5 #define	EXTERN
6 #include "arm.h"
7 
8 #define	ODIRLEN	116	/* compatibility; used in _stat etc. */
9 #define	OERRLEN	64	/* compatibility; used in _stat etc. */
10 
11 char 	errbuf[ERRMAX];
12 ulong	nofunc;
13 
14 #include "/sys/src/libc/9syscall/sys.h"
15 
16 
17 char*	sysctab[] =
18 {
19 	[SYSR1]		"Running",
20 	[_ERRSTR]		"_errstr",
21 	[BIND]		"Bind",
22 	[CHDIR]		"Chdir",
23 	[CLOSE]		"Close",
24 	[DUP]		"Dup",
25 	[ALARM]		"Alarm",
26 	[EXEC]		"Exec",
27 	[EXITS]		"Exits",
28 	[_FSESSION]	"_Fsession",
29 	[FAUTH]		"Fauth",
30 	[_FSTAT]		"_fstat",
31 	[SEGBRK]		"Segbrk",
32 	[MOUNT]		"Mount",
33 	[OPEN]		"Open",
34 	[_READ]		"_Read",
35 	[OSEEK]		"Oseek",
36 	[SLEEP]		"Sleep",
37 	[_STAT]		"_Stat",
38 	[RFORK]		"Rfork",
39 	[_WRITE]		"_Write",
40 	[PIPE]		"Pipe",
41 	[CREATE]		"Create",
42 	[FD2PATH]	"Fd2path",
43 	[BRK_]		"Brk_",
44 	[REMOVE]		"Remove",
45 	[_WSTAT]		"_Wstat",
46 	[_FWSTAT]	"_Fwstat",
47 	[NOTIFY]		"Notify",
48 	[NOTED]		"Noted",
49 	[SEGATTACH]	"Segattach",
50 	[SEGDETACH]	"Segdetach",
51 	[SEGFREE]		"Segfree",
52 	[SEGFLUSH]	"Segflush",
53 	[RENDEZVOUS]	"Rendezvous",
54 	[UNMOUNT]	"Unmount",
55 	[_WAIT]		"_Wait",
56 	[SEEK]		"Seek",
57 	[FVERSION]	"Fversion",
58 	[ERRSTR]		"Errstr",
59 	[STAT]		"Stat",
60 	[FSTAT]		"Fstat",
61 	[WSTAT]		"Wstat",
62 	[FWSTAT]		"Fwstat",
63 	[PREAD]		"Pread",
64 	[PWRITE]		"Pwrite",
65 	[AWAIT]		"Await",
66 };
67 
68 void
69 sys1(void)
70 {
71 	Bprint(bioout, "no system call %s\n", sysctab[reg.r[1]]);
72 	exits(0);
73 }
74 
75 void
76 sys_errstr(void)
77 {
78 	ulong str;
79 
80 	str = getmem_w(reg.r[13]+4);
81 	if(sysdbg)
82 		itrace("errstr(0x%lux)", str);
83 
84 	memio(errbuf, str, OERRLEN, MemWrite);
85 	strcpy(errbuf, "no error");
86 	reg.r[REGRET] = 0;
87 
88 }
89 
90 void
91 syserrstr(void)
92 {
93 	ulong str;
94 	int n;
95 
96 	str = getmem_w(reg.r[13]+4);
97 	n = getmem_w(reg.r[13]+8);
98 	if(sysdbg)
99 		itrace("errstr(0x%lux, 0x%lux)", str, n);
100 
101 	if(n > strlen(errbuf)+1)
102 		n = strlen(errbuf)+1;
103 	memio(errbuf, str, n, MemWrite);
104 	strcpy(errbuf, "no error");
105 	reg.r[REGRET] = n;
106 
107 }
108 void
109 sysbind(void)
110 {
111 	ulong pname, pold, flags;
112 	char name[1024], old[1024];
113 	int n;
114 
115 	pname = getmem_w(reg.r[13]+4);
116 	pold = getmem_w(reg.r[13]+8);
117 	flags = getmem_w(reg.r[13]+12);
118 	memio(name, pname, sizeof(name), MemReadstring);
119 	memio(old, pold, sizeof(old), MemReadstring);
120 	if(sysdbg)
121 		itrace("bind(0x%lux='%s', 0x%lux='%s', 0x%lux)", name, name, old, old, flags);
122 
123 	n = bind(name, old, flags);
124 	if(n < 0)
125 		errstr(errbuf, sizeof errbuf);
126 
127 	reg.r[REGRET] = n;
128 }
129 
130 void
131 sysfd2path(void)
132 {
133 	int n;
134 	uint fd;
135 	ulong str;
136 	char buf[1024];
137 
138 	fd = getmem_w(reg.r[13]+4);
139 	str = getmem_w(reg.r[13]+8);
140 	n = getmem_w(reg.r[13]+12);
141 	if(sysdbg)
142 		itrace("fd2path(0x%lux, 0x%lux, 0x%lux)", fd, str, n);
143 	reg.r[1] = -1;
144 	if(n > sizeof buf){
145 		strcpy(errbuf, "buffer too big");
146 		return;
147 	}
148 	n = fd2path(fd, buf, sizeof buf);
149 	if(n < 0)
150 		errstr(buf, sizeof buf);
151 	else
152 		memio(errbuf, str, n, MemWrite);
153 	reg.r[REGRET] = n;
154 
155 }
156 
157 void
158 syschdir(void)
159 {
160 	char file[1024];
161 	int n;
162 	ulong name;
163 
164 	name = getmem_w(reg.r[13]+4);
165 	memio(file, name, sizeof(file), MemReadstring);
166 	if(sysdbg)
167 		itrace("chdir(0x%lux='%s', 0x%lux)", name, file);
168 
169 	n = chdir(file);
170 	if(n < 0)
171 		errstr(errbuf, sizeof errbuf);
172 
173 	reg.r[REGRET] = n;
174 }
175 
176 void
177 sysclose(void)
178 {
179 	int n;
180 	ulong fd;
181 
182 	fd = getmem_w(reg.r[13]+4);
183 	if(sysdbg)
184 		itrace("close(%d)", fd);
185 
186 	n = close(fd);
187 	if(n < 0)
188 		errstr(errbuf, sizeof errbuf);
189 	reg.r[REGRET] = n;
190 }
191 
192 void
193 sysdup(void)
194 {
195 	int oldfd, newfd;
196 	int n;
197 
198 	oldfd = getmem_w(reg.r[13]+4);
199 	newfd = getmem_w(reg.r[13]+8);
200 	if(sysdbg)
201 		itrace("dup(%d, %d)", oldfd, newfd);
202 
203 	n = dup(oldfd, newfd);
204 	if(n < 0)
205 		errstr(errbuf, sizeof errbuf);
206 	reg.r[REGRET] = n;
207 }
208 
209 void
210 sysexits(void)
211 {
212 	char buf[OERRLEN];
213 	ulong str;
214 
215 	str = getmem_w(reg.r[13]+4);
216 	if(sysdbg)
217 		itrace("exits(0x%lux)", str);
218 
219 	count = 1;
220 	if(str != 0) {
221 		memio(buf, str, sizeof buf, MemRead);
222 		Bprint(bioout, "exits(%s)\n", buf);
223 	}
224 	else
225 		Bprint(bioout, "exits(0)\n");
226 }
227 
228 void
229 sysopen(void)
230 {
231 	char file[1024];
232 	int n;
233 	ulong mode, name;
234 
235 	name = getmem_w(reg.r[13]+4);
236 	mode = getmem_w(reg.r[13]+8);
237 	memio(file, name, sizeof(file), MemReadstring);
238 
239 	n = open(file, mode);
240 	if(n < 0)
241 		errstr(errbuf, sizeof errbuf);
242 
243 	if(sysdbg)
244 		itrace("open(0x%lux='%s', 0x%lux) = %d", name, file, mode, n);
245 
246 	reg.r[REGRET] = n;
247 };
248 
249 
250 void
251 sysread(vlong offset)
252 {
253 	int fd;
254 	ulong size, a;
255 	char *buf, *p;
256 	int n, cnt, c;
257 
258 	fd = getmem_w(reg.r[13]+4);
259 	a = getmem_w(reg.r[13]+8);
260 	size = getmem_w(reg.r[13]+12);
261 
262 	buf = emalloc(size);
263 	if(fd == 0) {
264 		print("\nstdin>>");
265 		p = buf;
266 		n = 0;
267 		cnt = size;
268 		while(cnt) {
269 			c = Bgetc(bin);
270 			if(c <= 0)
271 				break;
272 			*p++ = c;
273 			n++;
274 			cnt--;
275 			if(c == '\n')
276 				break;
277 		}
278 	}
279 	else
280 		n = pread(fd, buf, size, offset);
281 
282 	if(n < 0)
283 		errstr(errbuf, sizeof errbuf);
284 	else
285 		memio(buf, a, n, MemWrite);
286 
287 	if(sysdbg)
288 		itrace("read(%d, 0x%lux, %d, 0x%llx) = %d", fd, a, size, offset, n);
289 
290 	free(buf);
291 	reg.r[REGRET] = n;
292 }
293 
294 void
295 sys_read(void)
296 {
297 	sysread(-1LL);
298 }
299 
300 void
301 syspread(void)
302 {
303 	union {
304 		vlong v;
305 		ulong u[2];
306 	} o;
307 
308 	o.u[0] = getmem_w(reg.r[13]+16);
309 	o.u[1] = getmem_w(reg.r[13]+20);
310 	sysread(o.v);
311 }
312 
313 void
314 sysseek(void)
315 {
316 	int fd;
317 	ulong mode;
318 	ulong retp;
319 	union {
320 		vlong v;
321 		ulong u[2];
322 	} o;
323 
324 	retp = getmem_w(reg.r[13]+4);
325 	fd = getmem_w(reg.r[13]+8);
326 	o.u[0] = getmem_w(reg.r[13]+12);
327 	o.u[1] = getmem_w(reg.r[13]+16);
328 	mode = getmem_w(reg.r[13]+20);
329 	if(sysdbg)
330 		itrace("seek(%d, %lld, %d)", fd, o.v, mode);
331 
332 	o.v = seek(fd, o.v, mode);
333 	if(o.v < 0)
334 		errstr(errbuf, sizeof errbuf);
335 
336 	memio((char*)o.u, retp, sizeof(vlong), MemWrite);
337 }
338 
339 void
340 sysoseek(void)
341 {
342 	int fd, n;
343 	ulong off, mode;
344 
345 	fd = getmem_w(reg.r[13]+4);
346 	off = getmem_w(reg.r[13]+8);
347 	mode = getmem_w(reg.r[13]+12);
348 	if(sysdbg)
349 		itrace("seek(%d, %lud, %d)", fd, off, mode);
350 
351 	n = seek(fd, off, mode);
352 	if(n < 0)
353 		errstr(errbuf, sizeof errbuf);
354 
355 	reg.r[REGRET] = n;
356 }
357 
358 void
359 syssleep(void)
360 {
361 	ulong len;
362 	int n;
363 
364 	len = getmem_w(reg.r[13]+4);
365 	if(sysdbg)
366 		itrace("sleep(%d)", len);
367 
368 	n = sleep(len);
369 	if(n < 0)
370 		errstr(errbuf, sizeof errbuf);
371 
372 	reg.r[REGRET] = n;
373 }
374 
375 void
376 sys_stat(void)
377 {
378 	char nambuf[1024];
379 	char buf[ODIRLEN];
380 	ulong edir, name;
381 	extern int _stat(char*, char*);	/* old system call */
382 	int n;
383 
384 	name = getmem_w(reg.r[13]+4);
385 	edir = getmem_w(reg.r[13]+8);
386 	memio(nambuf, name, sizeof(nambuf), MemReadstring);
387 	if(sysdbg)
388 		itrace("stat(0x%lux='%s', 0x%lux)", name, nambuf, edir);
389 
390 	n = _stat(nambuf, buf);
391 	if(n < 0)
392 		errstr(errbuf, sizeof errbuf);
393 	else
394 		memio(buf, edir, ODIRLEN, MemWrite);
395 
396 	reg.r[REGRET] = n;
397 }
398 
399 void
400 sysstat(void)
401 {
402 	char nambuf[1024];
403 	uchar buf[STATMAX];
404 	ulong edir, name;
405 	int n;
406 
407 	name = getmem_w(reg.r[13]+4);
408 	edir = getmem_w(reg.r[13]+8);
409 	n = getmem_w(reg.r[13]+12);
410 	memio(nambuf, name, sizeof(nambuf), MemReadstring);
411 	if(sysdbg)
412 		itrace("stat(0x%lux='%s', 0x%lux, 0x%lux)", name, nambuf, edir, n);
413 	if(n > sizeof buf)
414 		errstr(errbuf, sizeof errbuf);
415 	else{
416 		n = stat(nambuf, buf, n);
417 		if(n < 0)
418 			errstr(errbuf, sizeof errbuf);
419 		else
420 			memio((char*)buf, edir, n, MemWrite);
421 	}
422 	reg.r[REGRET] = n;
423 }
424 
425 void
426 sys_fstat(void)
427 {
428 	char buf[ODIRLEN];
429 	extern int _fstat(int, char*);	/* old system call */
430 	ulong edir;
431 	int n, fd;
432 
433 	fd = getmem_w(reg.r[13]+4);
434 	edir = getmem_w(reg.r[13]+8);
435 	if(sysdbg)
436 		itrace("fstat(%d, 0x%lux)", fd, edir);
437 
438 	n = _fstat(fd, buf);
439 	if(n < 0)
440 		errstr(errbuf, sizeof errbuf);
441 	else
442 		memio(buf, edir, ODIRLEN, MemWrite);
443 
444 	reg.r[REGRET] = n;
445 }
446 
447 void
448 sysfstat(void)
449 {
450 	uchar buf[STATMAX];
451 	ulong edir;
452 	int n, fd;
453 
454 	fd = getmem_w(reg.r[13]+4);
455 	edir = getmem_w(reg.r[13]+8);
456 	n = getmem_w(reg.r[13]+12);
457 	if(sysdbg)
458 		itrace("fstat(%d, 0x%lux, 0x%lux)", fd, edir, n);
459 
460 	reg.r[REGRET] = -1;
461 	if(n > sizeof buf){
462 		strcpy(errbuf, "stat buffer too big");
463 		return;
464 	}
465 	n = fstat(fd, buf, n);
466 	if(n < 0)
467 		errstr(errbuf, sizeof errbuf);
468 	else
469 		memio((char*)buf, edir, n, MemWrite);
470 	reg.r[REGRET] = n;
471 }
472 
473 void
474 syswrite(vlong offset)
475 {
476 	int fd;
477 	ulong size, a;
478 	char *buf;
479 	int n;
480 
481 	fd = getmem_w(reg.r[13]+4);
482 	a = getmem_w(reg.r[13]+8);
483 	size = getmem_w(reg.r[13]+12);
484 
485 	Bflush(bioout);
486 	buf = memio(0, a, size, MemRead);
487 	n = pwrite(fd, buf, size, offset);
488 	if(n < 0)
489 		errstr(errbuf, sizeof errbuf);
490 
491 	if(sysdbg)
492 		itrace("write(%d, %lux, %d, 0x%llx) = %d", fd, a, size, offset, n);
493 
494 	free(buf);
495 
496 	reg.r[REGRET] = n;
497 }
498 
499 void
500 sys_write(void)
501 {
502 	syswrite(-1LL);
503 }
504 
505 void
506 syspwrite(void)
507 {
508 	union {
509 		vlong v;
510 		ulong u[2];
511 	} o;
512 
513 	o.u[0] = getmem_w(reg.r[13]+16);
514 	o.u[1] = getmem_w(reg.r[13]+20);
515 	syswrite(o.v);
516 }
517 
518 void
519 syspipe(void)
520 {
521 	int n, p[2];
522 	ulong fd;
523 
524 	fd = getmem_w(reg.r[13]+4);
525 	if(sysdbg)
526 		itrace("pipe(%lux)", fd);
527 
528 	n = pipe(p);
529 	if(n < 0)
530 		errstr(errbuf, sizeof errbuf);
531 	else {
532 		putmem_w(fd, p[0]);
533 		putmem_w(fd+4, p[1]);
534 	}
535 	reg.r[REGRET] = n;
536 }
537 
538 void
539 syscreate(void)
540 {
541 	char file[1024];
542 	int n;
543 	ulong mode, name, perm;
544 
545 	name = getmem_w(reg.r[13]+4);
546 	mode = getmem_w(reg.r[13]+8);
547 	perm = getmem_w(reg.r[13]+12);
548 	memio(file, name, sizeof(file), MemReadstring);
549 	if(sysdbg)
550 		itrace("create(0x%lux='%s', 0x%lux, 0x%lux)", name, file, mode, perm);
551 
552 	n = create(file, mode, perm);
553 	if(n < 0)
554 		errstr(errbuf, sizeof errbuf);
555 
556 	reg.r[REGRET] = n;
557 }
558 
559 void
560 sysbrk_(void)
561 {
562 	ulong addr, osize, nsize;
563 	Segment *s;
564 
565 	addr = getmem_w(reg.r[13]+4);
566 	if(sysdbg)
567 		itrace("brk_(0x%lux)", addr);
568 
569 	reg.r[REGRET] = -1;
570 	if(addr < memory.seg[Data].base+datasize) {
571 		strcpy(errbuf, "address below segment");
572 		return;
573 	}
574 	if(addr > memory.seg[Stack].base) {
575 		strcpy(errbuf, "segment too big");
576 		return;
577 	}
578 	s = &memory.seg[Bss];
579 	if(addr > s->end) {
580 		osize = ((s->end-s->base)/BY2PG)*sizeof(uchar*);
581 		addr = ((addr)+(BY2PG-1))&~(BY2PG-1);
582 		s->end = addr;
583 		nsize = ((s->end-s->base)/BY2PG)*sizeof(uchar*);
584 		s->table = erealloc(s->table, osize, nsize);
585 	}
586 
587 	reg.r[REGRET] = 0;
588 }
589 
590 void
591 sysremove(void)
592 {
593 	char nambuf[1024];
594 	ulong name;
595 	int n;
596 
597 	name = getmem_w(reg.r[13]+4);
598 	memio(nambuf, name, sizeof(nambuf), MemReadstring);
599 	if(sysdbg)
600 		itrace("remove(0x%lux='%s')", name, nambuf);
601 
602 	n = remove(nambuf);
603 	if(n < 0)
604 		errstr(errbuf, sizeof errbuf);
605 	reg.r[REGRET] = n;
606 }
607 
608 void
609 sysnotify(void)
610 {
611 	nofunc = getmem_w(reg.r[13]+4);
612 	if(sysdbg)
613 		itrace("notify(0x%lux)\n", nofunc);
614 
615 	reg.r[REGRET] = 0;
616 }
617 
618 void
619 sys_wait(void)
620 {
621 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
622 	exits(0);
623 }
624 void
625 sysawait(void)
626 {
627 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
628 	exits(0);
629 }
630 void
631 sysrfork(void)
632 {
633 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
634 	exits(0);
635 }
636 void
637 syswstat(void)
638 {
639 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
640 	exits(0);
641 }
642 void
643 sys_wstat(void)
644 {
645 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
646 	exits(0);
647 }
648 void
649 sysfwstat(void)
650 {
651 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
652 	exits(0);
653 }
654 void
655 sys_fwstat(void)
656 {
657 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
658 	exits(0);
659 }
660 void
661 sysnoted(void)
662 {
663 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
664 	exits(0);
665 }
666 void
667 syssegattach(void)
668 {
669 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
670 	exits(0);
671 }
672 void
673 syssegdetach(void)
674 {
675 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
676 	exits(0);
677 }
678 void
679 syssegfree(void)
680 {
681 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
682 	exits(0);
683 }
684 void
685 syssegflush(void)
686 {
687 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
688 	exits(0);
689 }
690 void
691 sysrendezvous(void)
692 {
693 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
694 	exits(0);
695 }
696 void
697 sysunmount(void)
698 {
699 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
700 	exits(0);
701 }
702 void
703 sysfork(void)
704 {
705 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
706 	exits(0);
707 }
708 void
709 sysforkpgrp(void)
710 {
711 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
712 	exits(0);
713 }
714 void
715 syssegbrk(void)
716 {
717 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
718 	exits(0);
719 }
720 void
721 sysmount(void)
722 {
723 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
724 	exits(0);
725 }
726 void
727 sysalarm(void)
728 {
729 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
730 	exits(0);
731 }
732 void
733 sysexec(void)
734 {
735 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
736  	exits(0);
737 }
738 void
739 sys_fsession(void)
740 {
741 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
742  	exits(0);
743 }
744 void
745 sysfauth(void)
746 {
747 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
748  	exits(0);
749 }
750 void
751 sysfversion(void)
752 {
753 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
754  	exits(0);
755 }
756 
757 void	(*systab[])(void) =
758 {
759 	[SYSR1]		sys1,
760 	[_ERRSTR]		sys_errstr,
761 	[BIND]		sysbind,
762 	[CHDIR]		syschdir,
763 	[CLOSE]		sysclose,
764 	[DUP]		sysdup,
765 	[ALARM]		sysalarm,
766 	[EXEC]		sysexec,
767 	[EXITS]		sysexits,
768 	[_FSESSION]	sys_fsession,
769 	[FAUTH]		sysfauth,
770 	[_FSTAT]		sys_fstat,
771 	[SEGBRK]		syssegbrk,
772 	[MOUNT]		sysmount,
773 	[OPEN]		sysopen,
774 	[_READ]		sys_read,
775 	[OSEEK]		sysoseek,
776 	[SLEEP]		syssleep,
777 	[_STAT]		sys_stat,
778 	[RFORK]		sysrfork,
779 	[_WRITE]		sys_write,
780 	[PIPE]		syspipe,
781 	[CREATE]		syscreate,
782 	[FD2PATH]	sysfd2path,
783 	[BRK_]		sysbrk_,
784 	[REMOVE]		sysremove,
785 	[_WSTAT]		sys_wstat,
786 	[_FWSTAT]	sys_fwstat,
787 	[NOTIFY]		sysnotify,
788 	[NOTED]		sysnoted,
789 	[SEGATTACH]	syssegattach,
790 	[SEGDETACH]	syssegdetach,
791 	[SEGFREE]		syssegfree,
792 	[SEGFLUSH]	syssegflush,
793 	[RENDEZVOUS]	sysrendezvous,
794 	[UNMOUNT]	sysunmount,
795 	[_WAIT]		sys_wait,
796 	[SEEK]		sysseek,
797 	[FVERSION]	sysfversion,
798 	[ERRSTR]		syserrstr,
799 	[STAT]		sysstat,
800 	[FSTAT]		sysfstat,
801 	[WSTAT]		syswstat,
802 	[FWSTAT]		sysfwstat,
803 	[PREAD]		syspread,
804 	[PWRITE]		syspwrite,
805 	[AWAIT]		sysawait,
806 };
807 
808 void
809 Ssyscall(ulong)
810 {
811 	int call;
812 
813 	call = reg.r[REGARG];
814 	if(call < 0 || call > PWRITE || systab[call] == nil) {
815 		Bprint(bioout, "bad system call\n");
816 		dumpreg();
817 	}
818 
819 	if(trace)
820 		itrace("SWI\t%s", sysctab[call]);
821 	(*systab[call])();
822 	Bflush(bioout);
823 }
824