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