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