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 } 730