|
|
1.1 ! root 1: /* ! 2: ! 3: Copyright 1991,1992 Eric R. Smith. All rights reserved. ! 4: ! 5: */ ! 6: ! 7: ! 8: ! 9: /* PROC pseudo-filesystem routines */ ! 10: ! 11: /* basically just to allow 'ls -l X:' to give a list of active processes ! 12: ! 13: * some things to note: ! 14: ! 15: * process names are given as name.XXX, where 'XXX' is the pid of the ! 16: ! 17: * process ! 18: ! 19: * process attributes depend on the run queue as follows: ! 20: ! 21: * RUNNING: 0x00 (normal) ! 22: ! 23: * READY: 0x01 (read-only) ! 24: ! 25: * WAIT: 0x20 (archive bit) ! 26: ! 27: * IOBOUND: 0x21 (archive bit+read-only) ! 28: ! 29: * ZOMBIE: 0x22 (archive+hidden) ! 30: ! 31: * TSR: 0x02 (hidden) ! 32: ! 33: * STOP: 0x24 (archive bit+system) ! 34: ! 35: * the general principle is: inactive processes have the archive bit (0x20) ! 36: ! 37: * set, terminated processes have the hidden bit (0x02) set, stopped processes ! 38: ! 39: * have the system bit (0x04) set, and the read-only bit is used to ! 40: ! 41: * otherwise distinguish states (which is unfortunate, since it would be ! 42: ! 43: * nice if this bit corresponded with file permissions). ! 44: ! 45: */ ! 46: ! 47: ! 48: ! 49: #include "mint.h" ! 50: ! 51: ! 52: ! 53: ! 54: ! 55: static long proc_root P_((int drv, fcookie *fc)); ! 56: ! 57: static long proc_lookup P_((fcookie *dir, const char *name, fcookie *fc)); ! 58: ! 59: static long proc_getxattr P_((fcookie *fc, XATTR *xattr)); ! 60: ! 61: static long proc_chattr P_((fcookie *fc, int attrib)); ! 62: ! 63: static long proc_chown P_((fcookie *fc, int uid, int gid)); ! 64: ! 65: static long proc_chmode P_((fcookie *fc, unsigned mode)); ! 66: ! 67: static long proc_rmdir P_((fcookie *dir, const char *name)); ! 68: ! 69: static long proc_remove P_((fcookie *dir, const char *name)); ! 70: ! 71: static long proc_getname P_((fcookie *root, fcookie *dir, char *pathname)); ! 72: ! 73: static long proc_rename P_((fcookie *olddir, char *oldname, ! 74: ! 75: fcookie *newdir, const char *newname)); ! 76: ! 77: static long proc_opendir P_((DIR *dirh, int flags)); ! 78: ! 79: static long proc_readdir P_((DIR *dirh, char *nm, int nmlen, fcookie *)); ! 80: ! 81: static long proc_rewinddir P_((DIR *dirh)); ! 82: ! 83: static long proc_closedir P_((DIR *dirh)); ! 84: ! 85: static long proc_pathconf P_((fcookie *dir, int which)); ! 86: ! 87: static long proc_dfree P_((fcookie *dir, long *buf)); ! 88: ! 89: static DEVDRV * proc_getdev P_((fcookie *fc, long *devsp)); ! 90: ! 91: ! 92: ! 93: static long proc_open P_((FILEPTR *f)); ! 94: ! 95: static long proc_write P_((FILEPTR *f, const char *buf, long bytes)); ! 96: ! 97: static long proc_read P_((FILEPTR *f, char *buf, long bytes)); ! 98: ! 99: static long proc_lseek P_((FILEPTR *f, long where, int whence)); ! 100: ! 101: static long proc_ioctl P_((FILEPTR *f, int mode, void *buf)); ! 102: ! 103: static long proc_datime P_((FILEPTR *f, short *time, int rwflag)); ! 104: ! 105: static long proc_close P_((FILEPTR *f, int pid)); ! 106: ! 107: ! 108: ! 109: /* dummy routines from biosfs.c */ ! 110: ! 111: extern long null_select P_((FILEPTR *f, long p, int mode)); ! 112: ! 113: extern void null_unselect P_((FILEPTR *f, long p, int mode)); ! 114: ! 115: ! 116: ! 117: static PROC * name2proc P_((const char *name)); ! 118: ! 119: ! 120: ! 121: ! 122: ! 123: DEVDRV proc_device = { ! 124: ! 125: proc_open, proc_write, proc_read, proc_lseek, proc_ioctl, proc_datime, ! 126: ! 127: proc_close, null_select, null_unselect ! 128: ! 129: }; ! 130: ! 131: ! 132: ! 133: FILESYS proc_filesys = { ! 134: ! 135: (FILESYS *)0, ! 136: ! 137: 0, ! 138: ! 139: proc_root, ! 140: ! 141: proc_lookup, nocreat, proc_getdev, proc_getxattr, ! 142: ! 143: proc_chattr, proc_chown, proc_chmode, ! 144: ! 145: nomkdir, proc_rmdir, proc_remove, proc_getname, proc_rename, ! 146: ! 147: proc_opendir, proc_readdir, proc_rewinddir, proc_closedir, ! 148: ! 149: proc_pathconf, proc_dfree, ! 150: ! 151: nowritelabel, noreadlabel, nosymlink, noreadlink, nohardlink, ! 152: ! 153: nofscntl, nodskchng ! 154: ! 155: }; ! 156: ! 157: ! 158: ! 159: long ! 160: ! 161: proc_root(drv, fc) ! 162: ! 163: int drv; ! 164: ! 165: fcookie *fc; ! 166: ! 167: { ! 168: ! 169: if (drv == PROCDRV) { ! 170: ! 171: fc->fs = &proc_filesys; ! 172: ! 173: fc->dev = drv; ! 174: ! 175: fc->index = 0L; ! 176: ! 177: return 0; ! 178: ! 179: } ! 180: ! 181: fc->fs = 0; ! 182: ! 183: return EINTRN; ! 184: ! 185: } ! 186: ! 187: ! 188: ! 189: static PROC * ! 190: ! 191: name2proc(name) ! 192: ! 193: const char *name; ! 194: ! 195: { ! 196: ! 197: const char *pstr; ! 198: ! 199: char c; ! 200: ! 201: int i; ! 202: ! 203: ! 204: ! 205: pstr = name; ! 206: ! 207: while ( (c = *name++) != 0) { ! 208: ! 209: if (c == '.') ! 210: ! 211: pstr = name; ! 212: ! 213: } ! 214: ! 215: if (!isdigit(*pstr) && *pstr != '-') ! 216: ! 217: return 0; ! 218: ! 219: i = atoi(pstr); ! 220: ! 221: if (i == -1) ! 222: ! 223: return curproc; ! 224: ! 225: else if (i == -2) ! 226: ! 227: i = curproc->ppid; ! 228: ! 229: return pid2proc(i); ! 230: ! 231: } ! 232: ! 233: ! 234: ! 235: static long ! 236: ! 237: proc_lookup(dir, name, fc) ! 238: ! 239: fcookie *dir; ! 240: ! 241: const char *name; ! 242: ! 243: fcookie *fc; ! 244: ! 245: { ! 246: ! 247: PROC *p; ! 248: ! 249: ! 250: ! 251: if (dir->index != 0) { ! 252: ! 253: DEBUG("proc_lookup: bad directory"); ! 254: ! 255: return EPTHNF; ! 256: ! 257: } ! 258: ! 259: ! 260: ! 261: /* special case: an empty name in a directory means that directory */ ! 262: ! 263: /* so does "." */ ! 264: ! 265: if (!*name || (name[0] == '.' && name[1] == 0)) { ! 266: ! 267: *fc = *dir; ! 268: ! 269: return 0; ! 270: ! 271: } ! 272: ! 273: ! 274: ! 275: /* another special case: ".." could be a mount point */ ! 276: ! 277: if (!strcmp(name, "..")) { ! 278: ! 279: *fc = *dir; ! 280: ! 281: return EMOUNT; ! 282: ! 283: } ! 284: ! 285: ! 286: ! 287: if (!(p = name2proc(name))) { ! 288: ! 289: DEBUG("proc_lookup: name not found"); ! 290: ! 291: return EFILNF; ! 292: ! 293: } else { ! 294: ! 295: fc->index = (long)p; ! 296: ! 297: fc->fs = &proc_filesys; ! 298: ! 299: fc->dev = PROC_BASE_DEV | p->pid; ! 300: ! 301: } ! 302: ! 303: return 0; ! 304: ! 305: } ! 306: ! 307: ! 308: ! 309: static int p_attr[NUM_QUEUES] = { /* attributes corresponding to queues */ ! 310: ! 311: 0, /* "RUNNING" */ ! 312: ! 313: 0x01, /* "READY" */ ! 314: ! 315: 0x20, /* "WAITING" */ ! 316: ! 317: 0x21, /* "IOBOUND" */ ! 318: ! 319: 0x22, /* "ZOMBIE" */ ! 320: ! 321: 0x02, /* "TSR" */ ! 322: ! 323: 0x24, /* "STOPPED" */ ! 324: ! 325: 0x21 /* "SELECT" (same as IOBOUND) */ ! 326: ! 327: }; ! 328: ! 329: ! 330: ! 331: static long ! 332: ! 333: proc_getxattr(fc, xattr) ! 334: ! 335: fcookie *fc; ! 336: ! 337: XATTR *xattr; ! 338: ! 339: { ! 340: ! 341: PROC *p; ! 342: ! 343: extern int proctime, procdate; /* see dosmem.c */ ! 344: ! 345: ! 346: ! 347: xattr->blksize = 1; ! 348: ! 349: if (fc->index == 0) { ! 350: ! 351: /* the root directory */ ! 352: ! 353: xattr->index = 0; ! 354: ! 355: xattr->dev = PROCDRV; ! 356: ! 357: xattr->nlink = 1; ! 358: ! 359: xattr->uid = xattr->gid = 0; ! 360: ! 361: xattr->size = xattr->nblocks = 0; ! 362: ! 363: xattr->mtime = xattr->atime = xattr->ctime = proctime; ! 364: ! 365: xattr->mdate = xattr->adate = xattr->cdate = procdate; ! 366: ! 367: xattr->mode = S_IFDIR | DEFAULT_DIRMODE; ! 368: ! 369: xattr->attr = FA_DIR; ! 370: ! 371: return 0; ! 372: ! 373: } ! 374: ! 375: ! 376: ! 377: p = (PROC *)fc->index; ! 378: ! 379: xattr->index = p->pid; ! 380: ! 381: xattr->dev = PROC_BASE_DEV | p->pid; ! 382: ! 383: xattr->nlink = 1; ! 384: ! 385: xattr->uid = p->ruid; xattr->gid = p->rgid; ! 386: ! 387: xattr->size = xattr->nblocks = memused(p); ! 388: ! 389: xattr->mtime = xattr->ctime = xattr->atime = p->starttime; ! 390: ! 391: xattr->mdate = xattr->cdate = xattr->adate = p->startdate; ! 392: ! 393: xattr->mode = S_IMEM | S_IRUSR | S_IWUSR; ! 394: ! 395: xattr->attr = p_attr[p->wait_q]; ! 396: ! 397: return 0; ! 398: ! 399: } ! 400: ! 401: ! 402: ! 403: static long ! 404: ! 405: proc_chattr(fc, attrib) ! 406: ! 407: fcookie *fc; ! 408: ! 409: int attrib; ! 410: ! 411: { ! 412: ! 413: return EACCDN; ! 414: ! 415: } ! 416: ! 417: ! 418: ! 419: static long ! 420: ! 421: proc_chown(fc, uid, gid) ! 422: ! 423: fcookie *fc; ! 424: ! 425: int uid, gid; ! 426: ! 427: { ! 428: ! 429: return EINVFN; ! 430: ! 431: } ! 432: ! 433: ! 434: ! 435: static long ! 436: ! 437: proc_chmode(fc, mode) ! 438: ! 439: fcookie *fc; ! 440: ! 441: unsigned mode; ! 442: ! 443: { ! 444: ! 445: return EINVFN; ! 446: ! 447: } ! 448: ! 449: ! 450: ! 451: static long ! 452: ! 453: proc_rmdir(dir, name) ! 454: ! 455: fcookie *dir; ! 456: ! 457: const char *name; ! 458: ! 459: { ! 460: ! 461: return EPTHNF; ! 462: ! 463: } ! 464: ! 465: ! 466: ! 467: static long ! 468: ! 469: proc_remove(dir, name) ! 470: ! 471: fcookie *dir; ! 472: ! 473: const char *name; ! 474: ! 475: { ! 476: ! 477: PROC *p; ! 478: ! 479: ! 480: ! 481: if (dir->index != 0) ! 482: ! 483: return EPTHNF; ! 484: ! 485: p = name2proc(name); ! 486: ! 487: if (!p) ! 488: ! 489: return EFILNF; ! 490: ! 491: ! 492: ! 493: post_sig(p, SIGTERM); ! 494: ! 495: check_sigs(); /* it might have been us */ ! 496: ! 497: return 0; ! 498: ! 499: } ! 500: ! 501: ! 502: ! 503: static long ! 504: ! 505: proc_getname(root, dir, pathname) ! 506: ! 507: fcookie *root, *dir; char *pathname; ! 508: ! 509: { ! 510: ! 511: PROC *p; ! 512: ! 513: ! 514: ! 515: if (dir->index == 0) ! 516: ! 517: *pathname = 0; ! 518: ! 519: else { ! 520: ! 521: p = (PROC *)dir->index; ! 522: ! 523: ksprintf(pathname, "%s.03d", p->name, p->pid); ! 524: ! 525: } ! 526: ! 527: return 0; ! 528: ! 529: } ! 530: ! 531: ! 532: ! 533: static long ! 534: ! 535: proc_rename(olddir, oldname, newdir, newname) ! 536: ! 537: fcookie *olddir; ! 538: ! 539: char *oldname; ! 540: ! 541: fcookie *newdir; ! 542: ! 543: const char *newname; ! 544: ! 545: { ! 546: ! 547: PROC *p; ! 548: ! 549: int i; ! 550: ! 551: ! 552: ! 553: if (olddir->index != 0 || newdir->index != 0) ! 554: ! 555: return EPTHNF; ! 556: ! 557: if (!(p = name2proc(oldname))) ! 558: ! 559: return EFILNF; ! 560: ! 561: ! 562: ! 563: oldname = p->name; ! 564: ! 565: for (i = 0; i < PNAMSIZ; i++) { ! 566: ! 567: if (*newname == 0 || *newname == '.') { ! 568: ! 569: *oldname = 0; break; ! 570: ! 571: } ! 572: ! 573: *oldname++ = *newname++; ! 574: ! 575: } ! 576: ! 577: return 0; ! 578: ! 579: } ! 580: ! 581: ! 582: ! 583: static long ! 584: ! 585: proc_opendir(dirh, flags) ! 586: ! 587: DIR *dirh; ! 588: ! 589: int flags; ! 590: ! 591: { ! 592: ! 593: dirh->index = 0; ! 594: ! 595: return 0; ! 596: ! 597: } ! 598: ! 599: ! 600: ! 601: static long ! 602: ! 603: proc_readdir(dirh, name, namelen, fc) ! 604: ! 605: DIR *dirh; ! 606: ! 607: char *name; ! 608: ! 609: int namelen; ! 610: ! 611: fcookie *fc; ! 612: ! 613: { ! 614: ! 615: int i; ! 616: ! 617: int giveindex = (dirh->flags == 0); ! 618: ! 619: PROC *p; ! 620: ! 621: ! 622: ! 623: do { ! 624: ! 625: i = dirh->index++; ! 626: ! 627: /* BUG: we shouldn't have the magic number "1000" for maximum proc pid */ ! 628: ! 629: if (i >= 1000) { ! 630: ! 631: p = 0; ! 632: ! 633: break; ! 634: ! 635: } ! 636: ! 637: p = pid2proc(i); ! 638: ! 639: } while (!p); ! 640: ! 641: ! 642: ! 643: if (!p) ! 644: ! 645: return ENMFIL; ! 646: ! 647: ! 648: ! 649: fc->index = (long)p; ! 650: ! 651: fc->fs = &proc_filesys; ! 652: ! 653: fc->dev = PROC_BASE_DEV | p->pid; ! 654: ! 655: ! 656: ! 657: if (giveindex) { ! 658: ! 659: namelen -= sizeof(long); ! 660: ! 661: if (namelen <= 0) return ERANGE; ! 662: ! 663: *((long *)name) = (long)p->pid; ! 664: ! 665: name += sizeof(long); ! 666: ! 667: } ! 668: ! 669: if (namelen < strlen(p->name) + 5) ! 670: ! 671: return ENAMETOOLONG; ! 672: ! 673: ! 674: ! 675: ksprintf(name, "%s.%03d", p->name, p->pid); ! 676: ! 677: return 0; ! 678: ! 679: } ! 680: ! 681: ! 682: ! 683: static long ! 684: ! 685: proc_rewinddir(dirh) ! 686: ! 687: DIR *dirh; ! 688: ! 689: { ! 690: ! 691: dirh->index = 0; ! 692: ! 693: return 0; ! 694: ! 695: } ! 696: ! 697: ! 698: ! 699: static long ! 700: ! 701: proc_closedir(dirh) ! 702: ! 703: DIR *dirh; ! 704: ! 705: { ! 706: ! 707: return 0; ! 708: ! 709: } ! 710: ! 711: static long ! 712: ! 713: proc_pathconf(dir, which) ! 714: ! 715: fcookie *dir; ! 716: ! 717: int which; ! 718: ! 719: { ! 720: ! 721: switch(which) { ! 722: ! 723: case -1: ! 724: ! 725: return DP_MAXREQ; ! 726: ! 727: case DP_IOPEN: ! 728: ! 729: return UNLIMITED; /* no internal limit on open files */ ! 730: ! 731: case DP_MAXLINKS: ! 732: ! 733: return 1; /* we don't have hard links */ ! 734: ! 735: case DP_PATHMAX: ! 736: ! 737: return PATH_MAX; /* max. path length */ ! 738: ! 739: case DP_NAMEMAX: ! 740: ! 741: return PNAMSIZ; /* max. length of individual name */ ! 742: ! 743: case DP_ATOMIC: ! 744: ! 745: return UNLIMITED; /* all writes are atomic */ ! 746: ! 747: case DP_TRUNC: ! 748: ! 749: return DP_DOSTRUNC; /* file names are truncated to 8.3 */ ! 750: ! 751: case DP_CASE: ! 752: ! 753: return DP_CASEINSENS; /* case preserved, but ignored */ ! 754: ! 755: default: ! 756: ! 757: return EINVFN; ! 758: ! 759: } ! 760: ! 761: } ! 762: ! 763: ! 764: ! 765: static long ! 766: ! 767: proc_dfree(dir, buf) ! 768: ! 769: fcookie *dir; ! 770: ! 771: long *buf; ! 772: ! 773: { ! 774: ! 775: long size; ! 776: ! 777: /* "sector" size is the size of the smallest amount of memory that can be ! 778: ! 779: allocated. see mem.h for the definition of ROUND ! 780: ! 781: */ ! 782: ! 783: long secsiz = ROUND(1); ! 784: ! 785: ! 786: ! 787: size = tot_rsize(core, 0) + tot_rsize(alt, 0); ! 788: ! 789: *buf++ = size/secsiz; /* number of free clusters */ ! 790: ! 791: size = tot_rsize(core, 1) + tot_rsize(alt, 1); ! 792: ! 793: *buf++ = size/secsiz; /* total number of clusters */ ! 794: ! 795: *buf++ = secsiz; /* sector size (bytes) */ ! 796: ! 797: *buf++ = 1; /* cluster size (in sectors) */ ! 798: ! 799: return 0; ! 800: ! 801: } ! 802: ! 803: ! 804: ! 805: static DEVDRV * ! 806: ! 807: proc_getdev(fc, devsp) ! 808: ! 809: fcookie *fc; ! 810: ! 811: long *devsp; ! 812: ! 813: { ! 814: ! 815: PROC *p; ! 816: ! 817: ! 818: ! 819: p = (PROC *)fc->index; ! 820: ! 821: ! 822: ! 823: *devsp = (long)p; ! 824: ! 825: return &proc_device; ! 826: ! 827: } ! 828: ! 829: ! 830: ! 831: /* ! 832: ! 833: * PROC device driver ! 834: ! 835: */ ! 836: ! 837: ! 838: ! 839: /* ! 840: ! 841: * BUG: file locking and the O_SHMODE restrictions are not implemented ! 842: ! 843: * for processes ! 844: ! 845: */ ! 846: ! 847: ! 848: ! 849: static long ! 850: ! 851: proc_open(f) ! 852: ! 853: FILEPTR *f; ! 854: ! 855: { ! 856: ! 857: return 0; ! 858: ! 859: } ! 860: ! 861: ! 862: ! 863: static long ! 864: ! 865: proc_write(f, buf, nbytes) ! 866: ! 867: FILEPTR *f; const char *buf; long nbytes; ! 868: ! 869: { ! 870: ! 871: PROC *p; ! 872: ! 873: char *where; ! 874: ! 875: long bytes_written = 0; ! 876: ! 877: ! 878: ! 879: p = (PROC *)f->devinfo; ! 880: ! 881: where = (char *)f->pos; ! 882: ! 883: ! 884: ! 885: /* BUG: process read/writes should check for valid addresses */ ! 886: ! 887: ! 888: ! 889: TRACE("proc_write: %ld bytes to %lx", nbytes, where); ! 890: ! 891: ! 892: ! 893: while (nbytes-- > 0) { ! 894: ! 895: *where++ = *buf++; ! 896: ! 897: bytes_written++; ! 898: ! 899: } ! 900: ! 901: f->pos += bytes_written; ! 902: ! 903: return bytes_written; ! 904: ! 905: } ! 906: ! 907: ! 908: ! 909: static long ! 910: ! 911: proc_read(f, buf, nbytes) ! 912: ! 913: FILEPTR *f; char *buf; long nbytes; ! 914: ! 915: { ! 916: ! 917: PROC *p; ! 918: ! 919: char *where; ! 920: ! 921: long bytes_read = 0; ! 922: ! 923: ! 924: ! 925: p = (PROC *)f->devinfo; ! 926: ! 927: where = (char *)f->pos; ! 928: ! 929: ! 930: ! 931: TRACE("proc_read: %ld bytes from %lx", nbytes, where); ! 932: ! 933: ! 934: ! 935: while (nbytes-- > 0) { ! 936: ! 937: *buf++ = *where++; ! 938: ! 939: bytes_read++; ! 940: ! 941: } ! 942: ! 943: f->pos += bytes_read; ! 944: ! 945: return bytes_read; ! 946: ! 947: } ! 948: ! 949: ! 950: ! 951: /* ! 952: ! 953: * proc_ioctl: currently, the only IOCTL's available are: ! 954: ! 955: * PPROCADDR: get address of PROC structure's "interesting" bits ! 956: ! 957: * PCTXTSIZE: get the size of the CONTEXT structure ! 958: ! 959: * PBASEADDR: get address of process basepage ! 960: ! 961: * PSETFLAGS: set the memory allocation flags (e.g. to malloc from fastram) ! 962: ! 963: * PGETFLAGS: get the memory allocation flags ! 964: ! 965: */ ! 966: ! 967: ! 968: ! 969: static long ! 970: ! 971: proc_ioctl(f, mode, buf) ! 972: ! 973: FILEPTR *f; int mode; void *buf; ! 974: ! 975: { ! 976: ! 977: PROC *p; ! 978: ! 979: ! 980: ! 981: p = (PROC *)f->devinfo; ! 982: ! 983: switch(mode) { ! 984: ! 985: case PPROCADDR: ! 986: ! 987: *((long *)buf) = (long)&p->magic; ! 988: ! 989: return 0; ! 990: ! 991: case PBASEADDR: ! 992: ! 993: *((long *)buf) = (long)p->base; ! 994: ! 995: return 0; ! 996: ! 997: case PCTXTSIZE: ! 998: ! 999: *((long *)buf) = sizeof(CONTEXT); ! 1000: ! 1001: return 0; ! 1002: ! 1003: case PSETFLAGS: ! 1004: ! 1005: /* note: only the low 16 bits are actually used */ ! 1006: ! 1007: p->memflags = *((long *)buf); ! 1008: ! 1009: return 0; ! 1010: ! 1011: case PGETFLAGS: ! 1012: ! 1013: *((long *)buf) = p->memflags; ! 1014: ! 1015: return 0; ! 1016: ! 1017: case FIONREAD: ! 1018: ! 1019: case FIONWRITE: ! 1020: ! 1021: *((long *)buf) = 1L; /* we're always ready for i/o */ ! 1022: ! 1023: return 0; ! 1024: ! 1025: default: ! 1026: ! 1027: DEBUG("procfs: bad Fcntl command"); ! 1028: ! 1029: } ! 1030: ! 1031: return EINVFN; ! 1032: ! 1033: } ! 1034: ! 1035: ! 1036: ! 1037: static long ! 1038: ! 1039: proc_lseek(f, where, whence) ! 1040: ! 1041: FILEPTR *f; long where; int whence; ! 1042: ! 1043: { ! 1044: ! 1045: switch(whence) { ! 1046: ! 1047: case 0: ! 1048: ! 1049: f->pos = where; ! 1050: ! 1051: break; ! 1052: ! 1053: case 1: ! 1054: ! 1055: f->pos += where; ! 1056: ! 1057: break; ! 1058: ! 1059: case 2: ! 1060: ! 1061: f->pos = -where; ! 1062: ! 1063: break; ! 1064: ! 1065: default: ! 1066: ! 1067: return EINVFN; ! 1068: ! 1069: } ! 1070: ! 1071: return f->pos; ! 1072: ! 1073: } ! 1074: ! 1075: ! 1076: ! 1077: static long ! 1078: ! 1079: proc_datime(f, timeptr, rwflag) ! 1080: ! 1081: FILEPTR *f; ! 1082: ! 1083: short *timeptr; ! 1084: ! 1085: int rwflag; ! 1086: ! 1087: { ! 1088: ! 1089: PROC *p; ! 1090: ! 1091: ! 1092: ! 1093: p = (PROC *)f->devinfo; ! 1094: ! 1095: if (rwflag) { ! 1096: ! 1097: return EACCDN; ! 1098: ! 1099: } ! 1100: ! 1101: else { ! 1102: ! 1103: *timeptr++ = p->starttime; ! 1104: ! 1105: *timeptr++ = p->startdate; ! 1106: ! 1107: } ! 1108: ! 1109: return 0; ! 1110: ! 1111: } ! 1112: ! 1113: ! 1114: ! 1115: static long ! 1116: ! 1117: proc_close(f, pid) ! 1118: ! 1119: FILEPTR *f; ! 1120: ! 1121: int pid; ! 1122: ! 1123: { ! 1124: ! 1125: return 0; ! 1126: ! 1127: } ! 1128:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.