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