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