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