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