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