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