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