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