]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/5i/syscall.c
git/branch: somewhere in the syncing, the fix for junk files was lost
[plan9front.git] / sys / src / cmd / 5i / syscall.c
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         sysread(getmem_v(reg.r[13]+16));
304 }
305
306 void
307 sysseek(void)
308 {
309         int fd;
310         ulong mode;
311         ulong retp;
312         vlong v;
313
314         retp = getmem_w(reg.r[13]+4);
315         fd = getmem_w(reg.r[13]+8);
316         v = getmem_v(reg.r[13]+16);
317         mode = getmem_w(reg.r[13]+20);
318         if(sysdbg)
319                 itrace("seek(%d, %lld, %d)", fd, v, mode);
320
321         v = seek(fd, v, mode);
322         if(v < 0)
323                 errstr(errbuf, sizeof errbuf);  
324
325         putmem_v(retp, v);
326 }
327
328 void
329 sysoseek(void)
330 {
331         int fd, n;
332         ulong off, mode;
333
334         fd = getmem_w(reg.r[13]+4);
335         off = getmem_w(reg.r[13]+8);
336         mode = getmem_w(reg.r[13]+12);
337         if(sysdbg)
338                 itrace("seek(%d, %lud, %d)", fd, off, mode);
339
340         n = seek(fd, off, mode);
341         if(n < 0)
342                 errstr(errbuf, sizeof errbuf);  
343
344         reg.r[REGRET] = n;
345 }
346
347 void
348 syssleep(void)
349 {
350         ulong len;
351         int n;
352
353         len = getmem_w(reg.r[13]+4);
354         if(sysdbg)
355                 itrace("sleep(%d)", len);
356
357         n = sleep(len);
358         if(n < 0)
359                 errstr(errbuf, sizeof errbuf);  
360
361         reg.r[REGRET] = n;
362 }
363
364 void
365 sys_stat(void)
366 {
367         char nambuf[1024];
368         char buf[ODIRLEN];
369         ulong edir, name;
370         extern int _stat(char*, char*); /* old system call */
371         int n;
372
373         name = getmem_w(reg.r[13]+4);
374         edir = getmem_w(reg.r[13]+8);
375         memio(nambuf, name, sizeof(nambuf), MemReadstring);
376         if(sysdbg)
377                 itrace("stat(0x%lux='%s', 0x%lux)", name, nambuf, edir);
378
379         n = _stat(nambuf, buf);
380         if(n < 0)
381                 errstr(errbuf, sizeof errbuf);
382         else
383                 memio(buf, edir, ODIRLEN, MemWrite);
384
385         reg.r[REGRET] = n;
386 }
387
388 void
389 sysstat(void)
390 {
391         char nambuf[1024];
392         uchar buf[STATMAX];
393         ulong edir, name;
394         int n;
395
396         name = getmem_w(reg.r[13]+4);
397         edir = getmem_w(reg.r[13]+8);
398         n = getmem_w(reg.r[13]+12);
399         memio(nambuf, name, sizeof(nambuf), MemReadstring);
400         if(sysdbg)
401                 itrace("stat(0x%lux='%s', 0x%lux, 0x%lux)", name, nambuf, edir, n);
402         if(n > sizeof buf)
403                 errstr(errbuf, sizeof errbuf);
404         else{   
405                 n = stat(nambuf, buf, n);
406                 if(n < 0)
407                         errstr(errbuf, sizeof errbuf);
408                 else
409                         memio((char*)buf, edir, n, MemWrite);
410         }
411         reg.r[REGRET] = n;
412 }
413
414 void
415 sys_fstat(void)
416 {
417         char buf[ODIRLEN];
418         extern int _fstat(int, char*);  /* old system call */
419         ulong edir;
420         int n, fd;
421
422         fd = getmem_w(reg.r[13]+4);
423         edir = getmem_w(reg.r[13]+8);
424         if(sysdbg)
425                 itrace("fstat(%d, 0x%lux)", fd, edir);
426
427         n = _fstat(fd, buf);
428         if(n < 0)
429                 errstr(errbuf, sizeof errbuf);
430         else
431                 memio(buf, edir, ODIRLEN, MemWrite);
432
433         reg.r[REGRET] = n;
434 }
435
436 void
437 sysfstat(void)
438 {
439         uchar buf[STATMAX];
440         ulong edir;
441         int n, fd;
442
443         fd = getmem_w(reg.r[13]+4);
444         edir = getmem_w(reg.r[13]+8);
445         n = getmem_w(reg.r[13]+12);
446         if(sysdbg)
447                 itrace("fstat(%d, 0x%lux, 0x%lux)", fd, edir, n);
448
449         reg.r[REGRET] = -1;
450         if(n > sizeof buf){
451                 strcpy(errbuf, "stat buffer too big");
452                 return;
453         }
454         n = fstat(fd, buf, n);
455         if(n < 0)
456                 errstr(errbuf, sizeof errbuf);
457         else
458                 memio((char*)buf, edir, n, MemWrite);
459         reg.r[REGRET] = n;
460 }
461
462 void
463 syswrite(vlong offset)
464 {
465         int fd;
466         ulong size, a;
467         char *buf;
468         int n;
469
470         fd = getmem_w(reg.r[13]+4);
471         a = getmem_w(reg.r[13]+8);
472         size = getmem_w(reg.r[13]+12);
473
474         Bflush(bioout);
475         buf = memio(0, a, size, MemRead);
476         n = pwrite(fd, buf, size, offset);
477         if(n < 0)
478                 errstr(errbuf, sizeof errbuf);  
479
480         if(sysdbg)
481                 itrace("write(%d, %lux, %d, 0x%llx) = %d", fd, a, size, offset, n);
482
483         free(buf);
484
485         reg.r[REGRET] = n;
486 }
487
488 void
489 sys_write(void)
490 {
491         syswrite(-1LL);
492 }
493
494 void
495 syspwrite(void)
496 {
497         syswrite(getmem_v(reg.r[13]+16));
498 }
499
500 void
501 syspipe(void)
502 {
503         int n, p[2];
504         ulong fd;
505
506         fd = getmem_w(reg.r[13]+4);
507         if(sysdbg)
508                 itrace("pipe(%lux)", fd);
509
510         n = pipe(p);
511         if(n < 0)
512                 errstr(errbuf, sizeof errbuf);
513         else {
514                 putmem_w(fd, p[0]);
515                 putmem_w(fd+4, p[1]);
516         }
517         reg.r[REGRET] = n;
518 }
519
520 void
521 syscreate(void)
522 {
523         char file[1024];
524         int n;
525         ulong mode, name, perm;
526
527         name = getmem_w(reg.r[13]+4);
528         mode = getmem_w(reg.r[13]+8);
529         perm = getmem_w(reg.r[13]+12);
530         memio(file, name, sizeof(file), MemReadstring);
531         if(sysdbg)
532                 itrace("create(0x%lux='%s', 0x%lux, 0x%lux)", name, file, mode, perm);
533         
534         n = create(file, mode, perm);
535         if(n < 0)
536                 errstr(errbuf, sizeof errbuf);
537
538         reg.r[REGRET] = n;
539 }
540
541 void
542 sysbrk_(void)
543 {
544         ulong addr, osize, nsize;
545         Segment *s;
546
547         addr = getmem_w(reg.r[13]+4);
548         if(sysdbg)
549                 itrace("brk_(0x%lux)", addr);
550
551         reg.r[REGRET] = -1;
552         if(addr < memory.seg[Data].base+datasize) {
553                 strcpy(errbuf, "address below segment");
554                 return;
555         }
556         if(addr > memory.seg[Stack].base) {
557                 strcpy(errbuf, "segment too big");
558                 return;
559         }
560         s = &memory.seg[Bss];
561         if(addr > s->end) {
562                 osize = ((s->end-s->base)/BY2PG)*sizeof(uchar*);
563                 addr = ((addr)+(BY2PG-1))&~(BY2PG-1);
564                 s->end = addr;
565                 nsize = ((s->end-s->base)/BY2PG)*sizeof(uchar*);
566                 s->table = erealloc(s->table, osize, nsize);
567         }       
568
569         reg.r[REGRET] = 0;      
570 }
571
572 void
573 sysremove(void)
574 {
575         char nambuf[1024];
576         ulong name;
577         int n;
578
579         name = getmem_w(reg.r[13]+4);
580         memio(nambuf, name, sizeof(nambuf), MemReadstring);
581         if(sysdbg)
582                 itrace("remove(0x%lux='%s')", name, nambuf);
583
584         n = remove(nambuf);
585         if(n < 0)
586                 errstr(errbuf, sizeof errbuf);
587         reg.r[REGRET] = n;
588 }
589
590 void
591 sysnotify(void)
592 {
593         nofunc = getmem_w(reg.r[13]+4);
594         if(sysdbg)
595                 itrace("notify(0x%lux)\n", nofunc);
596
597         reg.r[REGRET] = 0;
598 }
599
600 void
601 sys_wait(void)
602 {
603         Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
604         exits(0);
605 }
606 void
607 sysawait(void)
608 {
609         Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
610         exits(0);
611 }
612 void
613 sysrfork(void)
614 {
615         Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
616         exits(0);
617 }
618 void
619 syswstat(void)
620 {
621         Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
622         exits(0);
623 }
624 void
625 sys_wstat(void)
626 {
627         Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
628         exits(0);
629 }
630 void
631 sysfwstat(void)
632 {
633         Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
634         exits(0);
635 }
636 void
637 sys_fwstat(void)
638 {
639         Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
640         exits(0);
641 }
642 void
643 sysnoted(void)
644 {
645         Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
646         exits(0);
647 }
648 void
649 syssegattach(void)
650 {
651         Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
652         exits(0);
653 }
654 void
655 syssegdetach(void)
656 {
657         Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
658         exits(0);
659 }
660 void
661 syssegfree(void)
662 {
663         Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
664         exits(0);
665 }
666 void
667 syssegflush(void)
668 {
669         Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
670         exits(0);
671 }
672 void
673 sysrendezvous(void)
674 {
675         Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
676         exits(0);
677 }
678 void
679 sysunmount(void)
680 {
681         Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
682         exits(0);
683 }
684 void
685 sysfork(void)
686 {
687         Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
688         exits(0);
689 }
690 void
691 sysforkpgrp(void)
692 {
693         Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
694         exits(0);
695 }
696 void
697 syssegbrk(void)
698 {
699         Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
700         exits(0);
701 }
702 void
703 sysmount(void)
704 {
705         Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
706         exits(0);
707 }
708 void
709 sysalarm(void)
710 {
711         Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
712         exits(0);
713 }
714 void
715 sysexec(void)
716 {
717         Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
718         exits(0);
719 }
720 void
721 sys_fsession(void)
722 {
723         Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
724         exits(0);
725 }
726 void
727 sysfauth(void)
728 {
729         Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
730         exits(0);
731 }
732 void
733 sysfversion(void)
734 {
735         Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
736         exits(0);
737 }
738
739 void    (*systab[])(void) =
740 {
741         [SYSR1]         sys1,
742         [_ERRSTR]               sys_errstr,
743         [BIND]          sysbind,
744         [CHDIR]         syschdir,
745         [CLOSE]         sysclose,
746         [DUP]           sysdup,
747         [ALARM]         sysalarm,
748         [EXEC]          sysexec,
749         [EXITS]         sysexits,
750         [_FSESSION]     sys_fsession,
751         [FAUTH]         sysfauth,
752         [_FSTAT]                sys_fstat,
753         [SEGBRK]                syssegbrk,
754         [MOUNT]         sysmount,
755         [OPEN]          sysopen,
756         [_READ]         sys_read,
757         [OSEEK]         sysoseek,
758         [SLEEP]         syssleep,
759         [_STAT]         sys_stat,
760         [RFORK]         sysrfork,
761         [_WRITE]                sys_write,
762         [PIPE]          syspipe,
763         [CREATE]                syscreate,
764         [FD2PATH]       sysfd2path,
765         [BRK_]          sysbrk_,
766         [REMOVE]                sysremove,
767         [_WSTAT]                sys_wstat,
768         [_FWSTAT]       sys_fwstat,
769         [NOTIFY]                sysnotify,
770         [NOTED]         sysnoted,
771         [SEGATTACH]     syssegattach,
772         [SEGDETACH]     syssegdetach,
773         [SEGFREE]               syssegfree,
774         [SEGFLUSH]      syssegflush,
775         [RENDEZVOUS]    sysrendezvous,
776         [UNMOUNT]       sysunmount,
777         [_WAIT]         sys_wait,
778         [SEEK]          sysseek,
779         [FVERSION]      sysfversion,
780         [ERRSTR]                syserrstr,
781         [STAT]          sysstat,
782         [FSTAT]         sysfstat,
783         [WSTAT]         syswstat,
784         [FWSTAT]                sysfwstat,
785         [PREAD]         syspread,
786         [PWRITE]                syspwrite,
787         [AWAIT]         sysawait,
788 };
789
790 void
791 Ssyscall(ulong)
792 {
793         int call;
794
795         call = reg.r[REGARG];
796         if(call < 0 || call >= nelem(systab) || systab[call] == nil) {
797                 Bprint(bioout, "bad system call %d (%#ux)\n", call, call);
798                 dumpreg();
799                 Bflush(bioout);
800                 return;
801         }
802
803         if(trace)
804                 itrace("SWI\t%s", sysctab[call]);
805         (*systab[call])();
806         Bflush(bioout);
807 }