|
|
1.1 ! root 1: /* ! 2: ! 3: Copyright 1992 Eric R. Smith. All rights reserved. ! 4: ! 5: */ ! 6: ! 7: ! 8: ! 9: /* Shared memory file system */ ! 10: ! 11: ! 12: ! 13: #include "mint.h" ! 14: ! 15: ! 16: ! 17: ! 18: ! 19: static long shm_root P_((int drv, fcookie *fc)); ! 20: ! 21: static long shm_creat P_((fcookie *dir, const char *name, unsigned mode, ! 22: ! 23: int attrib, fcookie *fc)); ! 24: ! 25: static long shm_lookup P_((fcookie *dir, const char *name, fcookie *fc)); ! 26: ! 27: static long shm_getxattr P_((fcookie *fc, XATTR *xattr)); ! 28: ! 29: static long shm_chattr P_((fcookie *fc, int attrib)); ! 30: ! 31: static long shm_chown P_((fcookie *fc, int uid, int gid)); ! 32: ! 33: static long shm_chmode P_((fcookie *fc, unsigned mode)); ! 34: ! 35: static long shm_rmdir P_((fcookie *dir, const char *name)); ! 36: ! 37: static long shm_remove P_((fcookie *dir, const char *name)); ! 38: ! 39: static long shm_getname P_((fcookie *root, fcookie *dir, char *pathname)); ! 40: ! 41: static long shm_rename P_((fcookie *olddir, char *oldname, ! 42: ! 43: fcookie *newdir, const char *newname)); ! 44: ! 45: static long shm_opendir P_((DIR *dirh, int flags)); ! 46: ! 47: static long shm_readdir P_((DIR *dirh, char *nm, int nmlen, fcookie *)); ! 48: ! 49: static long shm_rewinddir P_((DIR *dirh)); ! 50: ! 51: static long shm_closedir P_((DIR *dirh)); ! 52: ! 53: static long shm_pathconf P_((fcookie *dir, int which)); ! 54: ! 55: static long shm_dfree P_((fcookie *dir, long *buf)); ! 56: ! 57: static DEVDRV * shm_getdev P_((fcookie *fc, long *devsp)); ! 58: ! 59: ! 60: ! 61: static long shm_open P_((FILEPTR *f)); ! 62: ! 63: static long shm_write P_((FILEPTR *f, const char *buf, long bytes)); ! 64: ! 65: static long shm_read P_((FILEPTR *f, char *buf, long bytes)); ! 66: ! 67: static long shm_lseek P_((FILEPTR *f, long where, int whence)); ! 68: ! 69: static long shm_ioctl P_((FILEPTR *f, int mode, void *buf)); ! 70: ! 71: static long shm_datime P_((FILEPTR *f, short *time, int rwflag)); ! 72: ! 73: static long shm_close P_((FILEPTR *f, int pid)); ! 74: ! 75: ! 76: ! 77: /* dummy routines from biosfs.c */ ! 78: ! 79: extern long null_select P_((FILEPTR *f, long p, int mode)); ! 80: ! 81: extern void null_unselect P_((FILEPTR *f, long p, int mode)); ! 82: ! 83: ! 84: ! 85: static short shmtime, shmdate; ! 86: ! 87: ! 88: ! 89: #define SHMNAME_MAX 15 ! 90: ! 91: ! 92: ! 93: typedef struct shmfile { ! 94: ! 95: struct shmfile *next; ! 96: ! 97: char filename[SHMNAME_MAX+1]; ! 98: ! 99: int uid, gid; ! 100: ! 101: short time, date; ! 102: ! 103: unsigned mode; ! 104: ! 105: int inuse; ! 106: ! 107: MEMREGION *reg; ! 108: ! 109: } SHMFILE; ! 110: ! 111: ! 112: ! 113: SHMFILE *shmroot = 0; ! 114: ! 115: ! 116: ! 117: DEVDRV shm_device = { ! 118: ! 119: shm_open, shm_write, shm_read, shm_lseek, shm_ioctl, shm_datime, ! 120: ! 121: shm_close, null_select, null_unselect ! 122: ! 123: }; ! 124: ! 125: ! 126: ! 127: FILESYS shm_filesys = { ! 128: ! 129: (FILESYS *)0, ! 130: ! 131: 0, ! 132: ! 133: shm_root, ! 134: ! 135: shm_lookup, shm_creat, shm_getdev, shm_getxattr, ! 136: ! 137: shm_chattr, shm_chown, shm_chmode, ! 138: ! 139: nomkdir, shm_rmdir, shm_remove, shm_getname, shm_rename, ! 140: ! 141: shm_opendir, shm_readdir, shm_rewinddir, shm_closedir, ! 142: ! 143: shm_pathconf, shm_dfree, ! 144: ! 145: nowritelabel, noreadlabel, nosymlink, noreadlink, nohardlink, ! 146: ! 147: nofscntl, nodskchng ! 148: ! 149: }; ! 150: ! 151: ! 152: ! 153: long ! 154: ! 155: shm_root(drv, fc) ! 156: ! 157: int drv; ! 158: ! 159: fcookie *fc; ! 160: ! 161: { ! 162: ! 163: if (drv == SHMDEVICE) { ! 164: ! 165: fc->fs = &shm_filesys; ! 166: ! 167: fc->dev = drv; ! 168: ! 169: fc->index = 0L; ! 170: ! 171: return 0; ! 172: ! 173: } ! 174: ! 175: fc->fs = 0; ! 176: ! 177: return EINTRN; ! 178: ! 179: } ! 180: ! 181: ! 182: ! 183: static long ! 184: ! 185: shm_lookup(dir, name, fc) ! 186: ! 187: fcookie *dir; ! 188: ! 189: const char *name; ! 190: ! 191: fcookie *fc; ! 192: ! 193: { ! 194: ! 195: SHMFILE *s; ! 196: ! 197: ! 198: ! 199: if (dir->index != 0) { ! 200: ! 201: DEBUG("shm_lookup: bad directory"); ! 202: ! 203: return EPTHNF; ! 204: ! 205: } ! 206: ! 207: ! 208: ! 209: /* special case: an empty name in a directory means that directory */ ! 210: ! 211: /* so does "." */ ! 212: ! 213: if (!*name || (name[0] == '.' && name[1] == 0)) { ! 214: ! 215: *fc = *dir; ! 216: ! 217: return 0; ! 218: ! 219: } ! 220: ! 221: ! 222: ! 223: /* another special case: ".." could be a mount point */ ! 224: ! 225: if (!strcmp(name, "..")) { ! 226: ! 227: *fc = *dir; ! 228: ! 229: return EMOUNT; ! 230: ! 231: } ! 232: ! 233: ! 234: ! 235: for (s = shmroot; s; s = s->next) { ! 236: ! 237: if (!stricmp(s->filename,name)) ! 238: ! 239: break; ! 240: ! 241: } ! 242: ! 243: ! 244: ! 245: if (!s) { ! 246: ! 247: DEBUG("shm_lookup: name not found"); ! 248: ! 249: return EFILNF; ! 250: ! 251: } else { ! 252: ! 253: fc->index = (long)s; ! 254: ! 255: fc->fs = &shm_filesys; ! 256: ! 257: fc->dev = SHMDEVICE; ! 258: ! 259: } ! 260: ! 261: return 0; ! 262: ! 263: } ! 264: ! 265: ! 266: ! 267: static long ! 268: ! 269: shm_getxattr(fc, xattr) ! 270: ! 271: fcookie *fc; ! 272: ! 273: XATTR *xattr; ! 274: ! 275: { ! 276: ! 277: SHMFILE *s; ! 278: ! 279: ! 280: ! 281: xattr->blksize = 1; ! 282: ! 283: if (fc->index == 0) { ! 284: ! 285: /* the root directory */ ! 286: ! 287: xattr->index = 0; ! 288: ! 289: xattr->dev = SHMDEVICE; ! 290: ! 291: xattr->nlink = 1; ! 292: ! 293: xattr->uid = xattr->gid = 0; ! 294: ! 295: xattr->size = xattr->nblocks = 0; ! 296: ! 297: xattr->mtime = xattr->atime = xattr->ctime = shmtime; ! 298: ! 299: xattr->mdate = xattr->adate = xattr->cdate = shmdate; ! 300: ! 301: xattr->mode = S_IFDIR | DEFAULT_DIRMODE; ! 302: ! 303: xattr->attr = FA_DIR; ! 304: ! 305: return 0; ! 306: ! 307: } ! 308: ! 309: ! 310: ! 311: s = (SHMFILE *)fc->index; ! 312: ! 313: xattr->index = (long) s; ! 314: ! 315: xattr->dev = SHMDEVICE; ! 316: ! 317: xattr->nlink = 1; ! 318: ! 319: xattr->uid = s->uid; xattr->gid = s->gid; ! 320: ! 321: if (s->reg) ! 322: ! 323: xattr->size = xattr->nblocks = s->reg->len; ! 324: ! 325: else ! 326: ! 327: xattr->size = xattr->nblocks = 0; ! 328: ! 329: ! 330: ! 331: xattr->mtime = xattr->ctime = xattr->atime = s->time; ! 332: ! 333: xattr->mdate = xattr->cdate = xattr->adate = s->date; ! 334: ! 335: xattr->mode = S_IMEM | S_IRUSR | S_IWUSR; ! 336: ! 337: xattr->attr = 0; ! 338: ! 339: return 0; ! 340: ! 341: } ! 342: ! 343: ! 344: ! 345: static long ! 346: ! 347: shm_chattr(fc, attrib) ! 348: ! 349: fcookie *fc; ! 350: ! 351: int attrib; ! 352: ! 353: { ! 354: ! 355: return 0; ! 356: ! 357: } ! 358: ! 359: ! 360: ! 361: static long ! 362: ! 363: shm_chown(fc, uid, gid) ! 364: ! 365: fcookie *fc; ! 366: ! 367: int uid, gid; ! 368: ! 369: { ! 370: ! 371: SHMFILE *s; ! 372: ! 373: ! 374: ! 375: s = (SHMFILE *)fc->index; ! 376: ! 377: if (!s) ! 378: ! 379: return EINVFN; ! 380: ! 381: s->uid = uid; ! 382: ! 383: s->gid = gid; ! 384: ! 385: return 0; ! 386: ! 387: } ! 388: ! 389: ! 390: ! 391: static long ! 392: ! 393: shm_chmode(fc, mode) ! 394: ! 395: fcookie *fc; ! 396: ! 397: unsigned mode; ! 398: ! 399: { ! 400: ! 401: SHMFILE *s; ! 402: ! 403: ! 404: ! 405: s = (SHMFILE *)fc->index; ! 406: ! 407: if (!s) ! 408: ! 409: return EINVFN; ! 410: ! 411: s->mode = mode; ! 412: ! 413: return 0; ! 414: ! 415: } ! 416: ! 417: ! 418: ! 419: static long ! 420: ! 421: shm_rmdir(dir, name) ! 422: ! 423: fcookie *dir; ! 424: ! 425: const char *name; ! 426: ! 427: { ! 428: ! 429: return EPTHNF; ! 430: ! 431: } ! 432: ! 433: ! 434: ! 435: static long ! 436: ! 437: shm_remove(dir, name) ! 438: ! 439: fcookie *dir; ! 440: ! 441: const char *name; ! 442: ! 443: { ! 444: ! 445: SHMFILE *s, **old; ! 446: ! 447: ! 448: ! 449: if (dir->index != 0) ! 450: ! 451: return EPTHNF; ! 452: ! 453: ! 454: ! 455: old = &shmroot; ! 456: ! 457: for (s = shmroot; s; s = s->next) { ! 458: ! 459: if (!stricmp(s->filename, name)) ! 460: ! 461: break; ! 462: ! 463: old = &s->next; ! 464: ! 465: } ! 466: ! 467: if (!s) ! 468: ! 469: return EFILNF; ! 470: ! 471: if (s->inuse) ! 472: ! 473: return EACCDN; ! 474: ! 475: *old = s->next; ! 476: ! 477: ! 478: ! 479: s->reg->links--; ! 480: ! 481: if (s->reg->links <= 0) { ! 482: ! 483: free_region(s->reg); ! 484: ! 485: } ! 486: ! 487: kfree(s); ! 488: ! 489: shmtime = timestamp; ! 490: ! 491: shmdate = datestamp; ! 492: ! 493: return 0; ! 494: ! 495: } ! 496: ! 497: ! 498: ! 499: static long ! 500: ! 501: shm_getname(root, dir, pathname) ! 502: ! 503: fcookie *root, *dir; char *pathname; ! 504: ! 505: { ! 506: ! 507: *pathname = 0; ! 508: ! 509: return 0; ! 510: ! 511: } ! 512: ! 513: ! 514: ! 515: static long ! 516: ! 517: shm_rename(olddir, oldname, newdir, newname) ! 518: ! 519: fcookie *olddir; ! 520: ! 521: char *oldname; ! 522: ! 523: fcookie *newdir; ! 524: ! 525: const char *newname; ! 526: ! 527: { ! 528: ! 529: SHMFILE *s; ! 530: ! 531: ! 532: ! 533: if (olddir->index != 0 || newdir->index != 0) ! 534: ! 535: return EPTHNF; ! 536: ! 537: ! 538: ! 539: /* verify that "newname" doesn't exist */ ! 540: ! 541: for (s = shmroot; s; s = s->next) ! 542: ! 543: if (!stricmp(s->filename, newname)) ! 544: ! 545: return EACCDN; ! 546: ! 547: ! 548: ! 549: for (s = shmroot; s; s = s->next) ! 550: ! 551: if (!stricmp(s->filename, oldname)) ! 552: ! 553: break; ! 554: ! 555: if (!s) ! 556: ! 557: return EFILNF; ! 558: ! 559: ! 560: ! 561: strncpy(s->filename, newname, SHMNAME_MAX); ! 562: ! 563: shmtime = timestamp; ! 564: ! 565: shmdate = datestamp; ! 566: ! 567: return 0; ! 568: ! 569: } ! 570: ! 571: ! 572: ! 573: static long ! 574: ! 575: shm_opendir(dirh, flags) ! 576: ! 577: DIR *dirh; ! 578: ! 579: int flags; ! 580: ! 581: { ! 582: ! 583: dirh->index = 0; ! 584: ! 585: return 0; ! 586: ! 587: } ! 588: ! 589: ! 590: ! 591: static long ! 592: ! 593: shm_readdir(dirh, name, namelen, fc) ! 594: ! 595: DIR *dirh; ! 596: ! 597: char *name; ! 598: ! 599: int namelen; ! 600: ! 601: fcookie *fc; ! 602: ! 603: { ! 604: ! 605: int i; ! 606: ! 607: int giveindex = (dirh->flags == 0); ! 608: ! 609: SHMFILE *s; ! 610: ! 611: ! 612: ! 613: s = shmroot; ! 614: ! 615: i = dirh->index++; ! 616: ! 617: while (i > 0 && s != 0) { ! 618: ! 619: s = s->next; ! 620: ! 621: --i; ! 622: ! 623: } ! 624: ! 625: if (!s) ! 626: ! 627: return ENMFIL; ! 628: ! 629: ! 630: ! 631: fc->index = (long)s; ! 632: ! 633: fc->fs = &shm_filesys; ! 634: ! 635: fc->dev = SHMDEVICE; ! 636: ! 637: ! 638: ! 639: if (giveindex) { ! 640: ! 641: namelen -= sizeof(long); ! 642: ! 643: if (namelen <= 0) return ERANGE; ! 644: ! 645: *((long *)name) = (long)s; ! 646: ! 647: name += sizeof(long); ! 648: ! 649: } ! 650: ! 651: if (namelen < strlen(s->filename)) ! 652: ! 653: return ENAMETOOLONG; ! 654: ! 655: strcpy(name, s->filename); ! 656: ! 657: return 0; ! 658: ! 659: } ! 660: ! 661: ! 662: ! 663: static long ! 664: ! 665: shm_rewinddir(dirh) ! 666: ! 667: DIR *dirh; ! 668: ! 669: { ! 670: ! 671: dirh->index = 0; ! 672: ! 673: return 0; ! 674: ! 675: } ! 676: ! 677: ! 678: ! 679: static long ! 680: ! 681: shm_closedir(dirh) ! 682: ! 683: DIR *dirh; ! 684: ! 685: { ! 686: ! 687: return 0; ! 688: ! 689: } ! 690: ! 691: ! 692: ! 693: static long ! 694: ! 695: shm_pathconf(dir, which) ! 696: ! 697: fcookie *dir; ! 698: ! 699: int which; ! 700: ! 701: { ! 702: ! 703: switch(which) { ! 704: ! 705: case -1: ! 706: ! 707: return DP_MAXREQ; ! 708: ! 709: case DP_IOPEN: ! 710: ! 711: return UNLIMITED; /* no internal limit on open files */ ! 712: ! 713: case DP_MAXLINKS: ! 714: ! 715: return 1; /* we don't have hard links */ ! 716: ! 717: case DP_PATHMAX: ! 718: ! 719: return PATH_MAX; /* max. path length */ ! 720: ! 721: case DP_NAMEMAX: ! 722: ! 723: return SHMNAME_MAX; /* max. length of individual name */ ! 724: ! 725: case DP_ATOMIC: ! 726: ! 727: return UNLIMITED; /* all writes are atomic */ ! 728: ! 729: case DP_TRUNC: ! 730: ! 731: return DP_AUTOTRUNC; /* file names are truncated */ ! 732: ! 733: case DP_CASE: ! 734: ! 735: return DP_CASEINSENS; /* case preserved, but ignored */ ! 736: ! 737: default: ! 738: ! 739: return EINVFN; ! 740: ! 741: } ! 742: ! 743: } ! 744: ! 745: ! 746: ! 747: static long ! 748: ! 749: shm_dfree(dir, buf) ! 750: ! 751: fcookie *dir; ! 752: ! 753: long *buf; ! 754: ! 755: { ! 756: ! 757: long size; ! 758: ! 759: /* "sector" size is the size of the smallest amount of memory that can be ! 760: ! 761: allocated. see mem.h for the definition of ROUND ! 762: ! 763: */ ! 764: ! 765: long secsiz = ROUND(1); ! 766: ! 767: ! 768: ! 769: size = tot_rsize(core, 0) + tot_rsize(alt, 0); ! 770: ! 771: *buf++ = size/secsiz; /* number of free clusters */ ! 772: ! 773: size = tot_rsize(core, 1) + tot_rsize(alt, 1); ! 774: ! 775: *buf++ = size/secsiz; /* total number of clusters */ ! 776: ! 777: *buf++ = secsiz; /* sector size (bytes) */ ! 778: ! 779: *buf++ = 1; /* cluster size (in sectors) */ ! 780: ! 781: return 0; ! 782: ! 783: } ! 784: ! 785: ! 786: ! 787: static DEVDRV * ! 788: ! 789: shm_getdev(fc, devsp) ! 790: ! 791: fcookie *fc; ! 792: ! 793: long *devsp; ! 794: ! 795: { ! 796: ! 797: SHMFILE *s; ! 798: ! 799: ! 800: ! 801: s = (SHMFILE *)fc->index; ! 802: ! 803: ! 804: ! 805: *devsp = (long)s; ! 806: ! 807: return &shm_device; ! 808: ! 809: } ! 810: ! 811: ! 812: ! 813: /* ! 814: ! 815: * create a shared memory region ! 816: ! 817: */ ! 818: ! 819: ! 820: ! 821: static long ! 822: ! 823: shm_creat(dir, name, mode, attrib, fc) ! 824: ! 825: fcookie *dir; ! 826: ! 827: const char *name; ! 828: ! 829: unsigned mode; ! 830: ! 831: int attrib; ! 832: ! 833: fcookie *fc; ! 834: ! 835: { ! 836: ! 837: SHMFILE *s; ! 838: ! 839: ! 840: ! 841: /* ! 842: ! 843: * see if the name already exists ! 844: ! 845: */ ! 846: ! 847: for (s = shmroot; s; s = s->next) { ! 848: ! 849: if (!stricmp(s->filename, name)) { ! 850: ! 851: DEBUG("shm_creat: file exists"); ! 852: ! 853: return EACCDN; ! 854: ! 855: } ! 856: ! 857: } ! 858: ! 859: ! 860: ! 861: s = (SHMFILE *)kmalloc(SIZEOF(SHMFILE)); ! 862: ! 863: if (!s) ! 864: ! 865: return ENSMEM; ! 866: ! 867: ! 868: ! 869: s->inuse = 0; ! 870: ! 871: strncpy(s->filename, name, SHMNAME_MAX); ! 872: ! 873: s->filename[SHMNAME_MAX] = 0; ! 874: ! 875: s->uid = curproc->ruid; ! 876: ! 877: s->gid = curproc->rgid; ! 878: ! 879: s->mode = mode; ! 880: ! 881: s->next = shmroot; ! 882: ! 883: s->reg = 0; ! 884: ! 885: s->time = shmtime = timestamp; ! 886: ! 887: s->date = shmdate = datestamp; ! 888: ! 889: shmroot = s; ! 890: ! 891: ! 892: ! 893: fc->fs = &shm_filesys; ! 894: ! 895: fc->index = (long)s; ! 896: ! 897: fc->dev = dir->dev; ! 898: ! 899: ! 900: ! 901: return 0; ! 902: ! 903: } ! 904: ! 905: ! 906: ! 907: /* ! 908: ! 909: * Shared memory device driver ! 910: ! 911: */ ! 912: ! 913: ! 914: ! 915: /* ! 916: ! 917: * BUG: file locking and the O_SHMODE restrictions are not implemented ! 918: ! 919: * for shared memory ! 920: ! 921: */ ! 922: ! 923: ! 924: ! 925: static long ! 926: ! 927: shm_open(f) ! 928: ! 929: FILEPTR *f; ! 930: ! 931: { ! 932: ! 933: SHMFILE *s; ! 934: ! 935: ! 936: ! 937: s = (SHMFILE *)f->devinfo; ! 938: ! 939: s->inuse++; ! 940: ! 941: return 0; ! 942: ! 943: } ! 944: ! 945: ! 946: ! 947: static long ! 948: ! 949: shm_write(f, buf, nbytes) ! 950: ! 951: FILEPTR *f; const char *buf; long nbytes; ! 952: ! 953: { ! 954: ! 955: SHMFILE *s; ! 956: ! 957: char *where; ! 958: ! 959: long bytes_written = 0; ! 960: ! 961: ! 962: ! 963: s = (SHMFILE *)f->devinfo; ! 964: ! 965: if (!s->reg) ! 966: ! 967: return 0; ! 968: ! 969: ! 970: ! 971: if (nbytes + f->pos > s->reg->len) ! 972: ! 973: nbytes = s->reg->len - f->pos; ! 974: ! 975: ! 976: ! 977: where = (char *)s->reg->loc + f->pos; ! 978: ! 979: ! 980: ! 981: /* BUG: memory read/writes should check for valid addresses */ ! 982: ! 983: ! 984: ! 985: TRACE("shm_write: %ld bytes to %lx", nbytes, where); ! 986: ! 987: ! 988: ! 989: while (nbytes-- > 0) { ! 990: ! 991: *where++ = *buf++; ! 992: ! 993: bytes_written++; ! 994: ! 995: } ! 996: ! 997: f->pos += bytes_written; ! 998: ! 999: s->time = timestamp; ! 1000: ! 1001: s->date = datestamp; ! 1002: ! 1003: return bytes_written; ! 1004: ! 1005: } ! 1006: ! 1007: ! 1008: ! 1009: static long ! 1010: ! 1011: shm_read(f, buf, nbytes) ! 1012: ! 1013: FILEPTR *f; char *buf; long nbytes; ! 1014: ! 1015: { ! 1016: ! 1017: SHMFILE *s; ! 1018: ! 1019: char *where; ! 1020: ! 1021: long bytes_read = 0; ! 1022: ! 1023: ! 1024: ! 1025: s = (SHMFILE *)f->devinfo; ! 1026: ! 1027: if (!(s->reg)) ! 1028: ! 1029: return 0; ! 1030: ! 1031: ! 1032: ! 1033: if (nbytes + f->pos > s->reg->len) ! 1034: ! 1035: nbytes = s->reg->len - f->pos; ! 1036: ! 1037: ! 1038: ! 1039: where = (char *)s->reg->loc + f->pos; ! 1040: ! 1041: ! 1042: ! 1043: TRACE("shm_read: %ld bytes from %lx", nbytes, where); ! 1044: ! 1045: ! 1046: ! 1047: while (nbytes-- > 0) { ! 1048: ! 1049: *buf++ = *where++; ! 1050: ! 1051: bytes_read++; ! 1052: ! 1053: } ! 1054: ! 1055: f->pos += bytes_read; ! 1056: ! 1057: return bytes_read; ! 1058: ! 1059: } ! 1060: ! 1061: ! 1062: ! 1063: /* ! 1064: ! 1065: * shm_ioctl: currently, the only IOCTL's available are: ! 1066: ! 1067: * SHMSETBLK: set the address of the shared memory file. This ! 1068: ! 1069: * call may only be made once per region, and then only ! 1070: ! 1071: * if the region is open for writing. ! 1072: ! 1073: * SHMGETBLK: get the address of the shared memory region. This ! 1074: ! 1075: * call fails (returns 0) if SHMSETBLK has not been ! 1076: ! 1077: * called yet for this shared memory file. ! 1078: ! 1079: */ ! 1080: ! 1081: ! 1082: ! 1083: static long ! 1084: ! 1085: shm_ioctl(f, mode, buf) ! 1086: ! 1087: FILEPTR *f; int mode; void *buf; ! 1088: ! 1089: { ! 1090: ! 1091: SHMFILE *s; ! 1092: ! 1093: MEMREGION *m; ! 1094: ! 1095: int i; ! 1096: ! 1097: long r; ! 1098: ! 1099: ! 1100: ! 1101: s = (SHMFILE *)f->devinfo; ! 1102: ! 1103: switch(mode) { ! 1104: ! 1105: case SHMSETBLK: ! 1106: ! 1107: if (s->reg) { ! 1108: ! 1109: DEBUG("Fcntl: SHMSETBLK already performed for %s", ! 1110: ! 1111: s->filename); ! 1112: ! 1113: return ERANGE; ! 1114: ! 1115: } ! 1116: ! 1117: if ((f->flags & O_RWMODE) == O_RDONLY) { ! 1118: ! 1119: DEBUG("Fcntl: SHMSETBLK: %s was opened read-only", ! 1120: ! 1121: s->filename); ! 1122: ! 1123: return EACCDN; ! 1124: ! 1125: } ! 1126: ! 1127: /* find the memory region to be attached */ ! 1128: ! 1129: m = 0; ! 1130: ! 1131: for (i = curproc->num_reg - 1; i >= 0; i--) { ! 1132: ! 1133: if (curproc->addr[i] == (virtaddr)buf) { ! 1134: ! 1135: m = curproc->mem[i]; ! 1136: ! 1137: break; ! 1138: ! 1139: } ! 1140: ! 1141: } ! 1142: ! 1143: if (!m || !buf) { ! 1144: ! 1145: DEBUG("Fcntl: SHMSETBLK: bad address %lx", buf); ! 1146: ! 1147: return EIMBA; ! 1148: ! 1149: } ! 1150: ! 1151: m->links++; ! 1152: ! 1153: s->reg = m; ! 1154: ! 1155: return 0; ! 1156: ! 1157: case SHMGETBLK: ! 1158: ! 1159: if (!(m = s->reg)) { ! 1160: ! 1161: DEBUG("Fcntl: no address for SHMGETBLK"); ! 1162: ! 1163: return 0; ! 1164: ! 1165: } ! 1166: ! 1167: /* check for memory limits */ ! 1168: ! 1169: if (curproc->maxmem) { ! 1170: ! 1171: if (m->len > curproc->maxmem - memused(curproc)) { ! 1172: ! 1173: DEBUG("Fcntl: SHMGETBLK would violate memory limits"); ! 1174: ! 1175: return 0; ! 1176: ! 1177: } ! 1178: ! 1179: } ! 1180: ! 1181: return (long)attach_region(curproc, m); ! 1182: ! 1183: case FIONREAD: ! 1184: ! 1185: case FIONWRITE: ! 1186: ! 1187: if (s->reg == 0) { ! 1188: ! 1189: r = 0; ! 1190: ! 1191: } else { ! 1192: ! 1193: r = s->reg->len - f->pos; ! 1194: ! 1195: if (r < 0) r = 0; ! 1196: ! 1197: } ! 1198: ! 1199: *((long *)buf) = r; ! 1200: ! 1201: return 0; ! 1202: ! 1203: default: ! 1204: ! 1205: DEBUG("shmfs: bad Fcntl command"); ! 1206: ! 1207: } ! 1208: ! 1209: return EINVFN; ! 1210: ! 1211: } ! 1212: ! 1213: ! 1214: ! 1215: static long ! 1216: ! 1217: shm_lseek(f, where, whence) ! 1218: ! 1219: FILEPTR *f; long where; int whence; ! 1220: ! 1221: { ! 1222: ! 1223: long newpos = 0, maxpos; ! 1224: ! 1225: SHMFILE *s; ! 1226: ! 1227: ! 1228: ! 1229: s = (SHMFILE *)f->devinfo; ! 1230: ! 1231: ! 1232: ! 1233: if (s->reg) ! 1234: ! 1235: maxpos = s->reg->len; ! 1236: ! 1237: else ! 1238: ! 1239: maxpos = 0; ! 1240: ! 1241: ! 1242: ! 1243: switch(whence) { ! 1244: ! 1245: case 0: ! 1246: ! 1247: newpos = where; ! 1248: ! 1249: break; ! 1250: ! 1251: case 1: ! 1252: ! 1253: newpos = f->pos + where; ! 1254: ! 1255: break; ! 1256: ! 1257: case 2: ! 1258: ! 1259: newpos = maxpos - where; ! 1260: ! 1261: break; ! 1262: ! 1263: default: ! 1264: ! 1265: return EINVFN; ! 1266: ! 1267: } ! 1268: ! 1269: ! 1270: ! 1271: if (newpos < 0 || newpos > maxpos) ! 1272: ! 1273: return ERANGE; ! 1274: ! 1275: ! 1276: ! 1277: f->pos = newpos; ! 1278: ! 1279: return newpos; ! 1280: ! 1281: } ! 1282: ! 1283: ! 1284: ! 1285: static long ! 1286: ! 1287: shm_datime(f, timeptr, rwflag) ! 1288: ! 1289: FILEPTR *f; ! 1290: ! 1291: short *timeptr; ! 1292: ! 1293: int rwflag; ! 1294: ! 1295: { ! 1296: ! 1297: SHMFILE *s; ! 1298: ! 1299: ! 1300: ! 1301: s = (SHMFILE *)f->devinfo; ! 1302: ! 1303: if (rwflag) { ! 1304: ! 1305: s->time = *timeptr++; ! 1306: ! 1307: s->date = *timeptr; ! 1308: ! 1309: } else { ! 1310: ! 1311: *timeptr++ = s->time; ! 1312: ! 1313: *timeptr++ = s->date; ! 1314: ! 1315: } ! 1316: ! 1317: return 0; ! 1318: ! 1319: } ! 1320: ! 1321: ! 1322: ! 1323: static long ! 1324: ! 1325: shm_close(f, pid) ! 1326: ! 1327: FILEPTR *f; ! 1328: ! 1329: int pid; ! 1330: ! 1331: { ! 1332: ! 1333: SHMFILE *s; ! 1334: ! 1335: ! 1336: ! 1337: if (f->links <= 0) { ! 1338: ! 1339: s = (SHMFILE *)f->devinfo; ! 1340: ! 1341: s->inuse--; ! 1342: ! 1343: } ! 1344: ! 1345: return 0; ! 1346: ! 1347: } ! 1348: ! 1349: ! 1350:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.