1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 #include <mach.h> 5 #define Extern extern 6 #include "mips.h" 7 8 #define REGSP 29 9 #define REGRET 1 10 11 #define ODIRLEN 116 /* compatibility; used in _stat etc. */ 12 #define OERRLEN 64 /* compatibility; used in _stat etc. */ 13 14 char errbuf[ERRMAX]; 15 ulong nofunc; 16 17 #include "/sys/src/libc/9syscall/sys.h" 18 19 char *sysctab[]={ 20 [SYSR1] "SYSR1", 21 [_ERRSTR] "_errstr", 22 [BIND] "Bind", 23 [CHDIR] "Chdir", 24 [CLOSE] "Close", 25 [DUP] "Dup", 26 [ALARM] "Alarm", 27 [EXEC] "Exec", 28 [EXITS] "Exits", 29 [_FSESSION] "_Fsession", 30 [FAUTH] "Fauth", 31 [_FSTAT] "_fstat", 32 [SEGBRK] "Segbrk", 33 [_MOUNT] "_Mount", 34 [OPEN] "Open", 35 [_READ] "_Read", 36 [OSEEK] "Oseek", 37 [SLEEP] "Sleep", 38 [_STAT] "_Stat", 39 [RFORK] "Rfork", 40 [_WRITE] "_Write", 41 [PIPE] "Pipe", 42 [CREATE] "Create", 43 [FD2PATH] "Fd2path", 44 [BRK_] "Brk_", 45 [REMOVE] "Remove", 46 [_WSTAT] "_Wstat", 47 [_FWSTAT] "_Fwstat", 48 [NOTIFY] "Notify", 49 [NOTED] "Noted", 50 [SEGATTACH] "Segattach", 51 [SEGDETACH] "Segdetach", 52 [SEGFREE] "Segfree", 53 [SEGFLUSH] "Segflush", 54 [RENDEZVOUS] "Rendezvous", 55 [UNMOUNT] "Unmount", 56 [_WAIT] "Wait", 57 [SEEK] "Seek", 58 [FVERSION] "Fversion", 59 [ERRSTR] "Errstr", 60 [STAT] "Stat", 61 [FSTAT] "Fstat", 62 [WSTAT] "Wstat", 63 [FWSTAT] "Fwstat", 64 [MOUNT] "Mount", 65 [AWAIT] "Await", 66 [PREAD] "Pread", 67 [PWRITE] "Pwrite", 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 sysfversion(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGRET]]); exits(0); } 642 void sysfsession(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 syswait(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 void sysmount(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGRET]]); exits(0);} 662 void sysawait(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGRET]]); exits(0);} 663 664 void (*systab[])(void) ={ 665 [SYSR1] sys1, 666 [_ERRSTR] sys_errstr, 667 [BIND] sysbind, 668 [CHDIR] syschdir, 669 [CLOSE] sysclose, 670 [DUP] sysdup, 671 [ALARM] sysalarm, 672 [EXEC] sysexec, 673 [EXITS] sysexits, 674 [_FSESSION] sysfsession, 675 [FAUTH] sysfauth, 676 [_FSTAT] sys_fstat, 677 [SEGBRK] syssegbrk, 678 [_MOUNT] _sysmount, 679 [OPEN] sysopen, 680 [_READ] sys_read, 681 [OSEEK] sysoseek, 682 [SLEEP] syssleep, 683 [_STAT] sys_stat, 684 [RFORK] sysrfork, 685 [_WRITE] sys_write, 686 [PIPE] syspipe, 687 [CREATE] syscreate, 688 [FD2PATH] sysfd2path, 689 [BRK_] sysbrk_, 690 [REMOVE] sysremove, 691 [_WSTAT] sys_wstat, 692 [_FWSTAT] sys_fwstat, 693 [NOTIFY] sysnotify, 694 [NOTED] sysnoted, 695 [SEGATTACH] syssegattach, 696 [SEGDETACH] syssegdetach, 697 [SEGFREE] syssegfree, 698 [SEGFLUSH] syssegflush, 699 [RENDEZVOUS] sysrendezvous, 700 [UNMOUNT] sysunmount, 701 [_WAIT] syswait, 702 [SEEK] sysseek, 703 [FVERSION] sysfversion, 704 [ERRSTR] syserrstr, 705 [STAT] sysstat, 706 [FSTAT] sysfstat, 707 [WSTAT] syswstat, 708 [FWSTAT] sysfwstat, 709 [MOUNT] sysmount, 710 [AWAIT] sysawait, 711 [PREAD] syspread, 712 [PWRITE] syspwrite, 713 }; 714 715 void 716 Ssyscall(ulong inst) 717 { 718 int call; 719 720 USED(inst); 721 call = reg.r[REGRET]; 722 if(call < 0 || call > PWRITE || systab[call] == nil) { 723 Bprint(bioout, "Bad system call\n"); 724 dumpreg(); 725 } 726 if(trace) 727 itrace("sysc\t%s", sysctab[call]); 728 729 (*systab[call])(); 730 Bflush(bioout); 731 } 732