|
|
1.1 root 1: /*
2:
1.1.1.3 root 3: Copyright 1991,1992 Eric R. Smith.
4:
1.1.1.4 ! root 5: Copyright 1992,1993,1994 Atari Corporation.
1.1.1.3 root 6:
7: All rights reserved.
1.1 root 8:
9: */
10:
11:
12:
13: /* simple pipefs.c */
14:
15:
16:
17: #include "mint.h"
18:
19:
20:
21: static int pipetime, pipedate; /* root directory time/date stamp */
22:
23:
24:
1.1.1.2 root 25: static long ARGS_ON_STACK pipe_root P_((int drv, fcookie *fc));
1.1 root 26:
1.1.1.2 root 27: static long ARGS_ON_STACK pipe_lookup P_((fcookie *dir, const char *name, fcookie *fc));
1.1 root 28:
1.1.1.2 root 29: static long ARGS_ON_STACK pipe_getxattr P_((fcookie *file, XATTR *xattr));
1.1 root 30:
1.1.1.2 root 31: static long ARGS_ON_STACK pipe_chattr P_((fcookie *file, int attrib));
1.1 root 32:
1.1.1.2 root 33: static long ARGS_ON_STACK pipe_chown P_((fcookie *file, int uid, int gid));
1.1 root 34:
1.1.1.2 root 35: static long ARGS_ON_STACK pipe_chmode P_((fcookie *file, unsigned mode));
1.1 root 36:
1.1.1.2 root 37: static long ARGS_ON_STACK pipe_rmdir P_((fcookie *dir, const char *name));
1.1 root 38:
1.1.1.2 root 39: static long ARGS_ON_STACK pipe_remove P_((fcookie *dir, const char *name));
1.1 root 40:
1.1.1.3 root 41: static long ARGS_ON_STACK pipe_getname P_((fcookie *root, fcookie *dir,
42:
43: char *pathname, int size));
1.1 root 44:
1.1.1.2 root 45: static long ARGS_ON_STACK pipe_rename P_((fcookie *olddir, char *oldname,
1.1 root 46:
47: fcookie *newdir, const char *newname));
48:
1.1.1.2 root 49: static long ARGS_ON_STACK pipe_opendir P_((DIR *dirh, int flags));
1.1 root 50:
1.1.1.2 root 51: static long ARGS_ON_STACK pipe_readdir P_((DIR *dirh, char *nm, int nmlen, fcookie *));
1.1 root 52:
1.1.1.2 root 53: static long ARGS_ON_STACK pipe_rewinddir P_((DIR *dirh));
1.1 root 54:
1.1.1.2 root 55: static long ARGS_ON_STACK pipe_closedir P_((DIR *dirh));
1.1 root 56:
1.1.1.2 root 57: static long ARGS_ON_STACK pipe_pathconf P_((fcookie *dir, int which));
1.1 root 58:
1.1.1.2 root 59: static long ARGS_ON_STACK pipe_dfree P_((fcookie *dir, long *buf));
1.1 root 60:
1.1.1.2 root 61: static long ARGS_ON_STACK pipe_creat P_((fcookie *dir, const char *name, unsigned mode,
1.1 root 62:
63: int attrib, fcookie *fc));
64:
1.1.1.2 root 65: static DEVDRV * ARGS_ON_STACK pipe_getdev P_((fcookie *fc, long *devsp));
1.1 root 66:
67:
68:
1.1.1.2 root 69: static long ARGS_ON_STACK pipe_open P_((FILEPTR *f));
1.1 root 70:
1.1.1.2 root 71: static long ARGS_ON_STACK pipe_write P_((FILEPTR *f, const char *buf, long bytes));
1.1 root 72:
1.1.1.2 root 73: static long ARGS_ON_STACK pipe_read P_((FILEPTR *f, char *buf, long bytes));
1.1 root 74:
1.1.1.2 root 75: static long ARGS_ON_STACK pipe_lseek P_((FILEPTR *f, long where, int whence));
1.1 root 76:
1.1.1.2 root 77: static long ARGS_ON_STACK pipe_ioctl P_((FILEPTR *f, int mode, void *buf));
1.1 root 78:
1.1.1.2 root 79: static long ARGS_ON_STACK pipe_datime P_((FILEPTR *f, short *time, int rwflag));
1.1 root 80:
1.1.1.2 root 81: static long ARGS_ON_STACK pipe_close P_((FILEPTR *f, int pid));
1.1 root 82:
1.1.1.2 root 83: static long ARGS_ON_STACK pipe_select P_((FILEPTR *f, long p, int mode));
1.1 root 84:
1.1.1.2 root 85: static void ARGS_ON_STACK pipe_unselect P_((FILEPTR *f, long p, int mode));
1.1 root 86:
87:
88:
89: DEVDRV pipe_device = {
90:
91: pipe_open, pipe_write, pipe_read, pipe_lseek, pipe_ioctl, pipe_datime,
92:
93: pipe_close, pipe_select, pipe_unselect
94:
95: };
96:
97:
98:
99: /* ptys and pipes can share the same driver, for now */
100:
101: #define pty_device pipe_device
102:
103:
104:
105: FILESYS pipe_filesys = {
106:
107: (FILESYS *)0,
108:
109: 0,
110:
111: pipe_root,
112:
113: pipe_lookup, pipe_creat, pipe_getdev, pipe_getxattr,
114:
115: pipe_chattr, pipe_chown, pipe_chmode,
116:
117: nomkdir, pipe_rmdir, pipe_remove, pipe_getname, pipe_rename,
118:
119: pipe_opendir, pipe_readdir, pipe_rewinddir, pipe_closedir,
120:
121: pipe_pathconf, pipe_dfree,
122:
123: nowritelabel, noreadlabel, nosymlink, noreadlink,
124:
125: nohardlink, nofscntl, nodskchng
126:
127: };
128:
129:
130:
131: /* size of pipes */
132:
133: #define PIPESIZ 4096 /* MUST be a multiple of 4 */
134:
135:
136:
137: /* writes smaller than this are atomic */
138:
139: #define PIPE_BUF 1024 /* should be a multiple of 4 */
140:
141:
142:
143: /* magic flag: indicates that nobody but the creator has opened this pipe */
144:
145: /* note: if this many processes open the pipe, we lose :-( */
146:
147: #define VIRGIN_PIPE 0x7fff
148:
149:
150:
151: struct pipe {
152:
153: int readers; /* number of readers of this pipe */
154:
155: int writers; /* number of writers of this pipe */
156:
157: int head, tail; /* pipe head, tail (head == tail for empty) */
158:
159: long rsel; /* process that did select() for reads */
160:
161: long wsel; /* process that did select() for writes */
162:
163: char buf[PIPESIZ]; /* pipe data */
164:
165: };
166:
167:
168:
169: struct fifo {
170:
171: char name[NAME_MAX+1]; /* FIFO's name */
172:
173: short date, time; /* date & time of last write */
174:
175: short dosflags; /* DOS flags, e.g. FA_RDONLY, FA_HIDDEN */
176:
177: ushort mode; /* file access mode, for XATTR */
178:
179: ushort uid, gid; /* file owner; uid and gid */
180:
181: short flags; /* various other flags (e.g. O_TTY) */
182:
183: short lockpid; /* pid of locking process */
184:
1.1.1.2 root 185: short cursrate; /* cursor flash rate for pseudo TTY's */
186:
1.1 root 187: struct tty *tty; /* tty struct for pseudo TTY's */
188:
189: struct pipe *inp; /* pipe for reads */
190:
191: struct pipe *outp; /* pipe for writes (0 if unidirectional) */
192:
193: struct fifo *next; /* link to next FIFO in list */
194:
195: FILEPTR *open; /* open file pointers for this fifo */
196:
197: } *rootlist;
198:
199:
200:
201:
202:
1.1.1.2 root 203: static long ARGS_ON_STACK
1.1 root 204:
205: pipe_root(drv, fc)
206:
207: int drv;
208:
209: fcookie *fc;
210:
211: {
212:
213: if (drv == PIPEDRV) {
214:
215: fc->fs = &pipe_filesys;
216:
217: fc->dev = drv;
218:
219: fc->index = 0L;
220:
221: return 0;
222:
223: }
224:
225: fc->fs = 0;
226:
227: return EINTRN;
228:
229: }
230:
231:
232:
1.1.1.2 root 233: static long ARGS_ON_STACK
1.1 root 234:
235: pipe_lookup(dir, name, fc)
236:
237: fcookie *dir;
238:
239: const char *name;
240:
241: fcookie *fc;
242:
243: {
244:
245: struct fifo *b;
246:
247:
248:
1.1.1.2 root 249: TRACE(("pipe_lookup(%s)", name));
1.1 root 250:
251:
252:
253: if (dir->index != 0) {
254:
1.1.1.2 root 255: DEBUG(("pipe_lookup(%s): bad directory", name));
1.1 root 256:
257: return EPTHNF;
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: for (b = rootlist; b; b = b->next) {
288:
1.1.1.3 root 289: if (!strnicmp(b->name, name, NAME_MAX)) {
1.1 root 290:
291: fc->fs = &pipe_filesys;
292:
293: fc->index = (long)b;
294:
295: fc->dev = dir->dev;
296:
297: return 0;
298:
299: }
300:
301: }
302:
1.1.1.2 root 303: DEBUG(("pipe_lookup: name `%s' not found", name));
1.1 root 304:
305: return EFILNF;
306:
307: }
308:
309:
310:
1.1.1.2 root 311: static long ARGS_ON_STACK
1.1 root 312:
313: pipe_getxattr(fc, xattr)
314:
315: fcookie *fc;
316:
317: XATTR *xattr;
318:
319: {
320:
321: struct fifo *this;
322:
323:
324:
325: xattr->index = fc->index;
326:
327: xattr->dev = fc->dev;
328:
1.1.1.4 ! root 329: xattr->rdev = fc->dev;
! 330:
1.1 root 331: xattr->nlink = 1;
332:
333: xattr->blksize = 1;
334:
335:
336:
337: if (fc->index == 0) { /* root directory? */
338:
339: xattr->uid = xattr->gid = 0;
340:
341: xattr->mtime = xattr->atime = xattr->ctime = pipetime;
342:
343: xattr->mdate = xattr->adate = xattr->cdate = pipedate;
344:
345: xattr->mode = S_IFDIR | DEFAULT_DIRMODE;
346:
347: xattr->attr = FA_DIR;
348:
349: xattr->size = xattr->nblocks = 0;
350:
351: } else {
352:
353: this = (struct fifo *)fc->index;
354:
355: xattr->uid = this->uid;
356:
357: xattr->gid = this->gid;
358:
359: xattr->mtime = xattr->atime = xattr->ctime = this->time;
360:
361: xattr->mdate = xattr->adate = xattr->cdate = this->date;
362:
363: xattr->mode = this->mode;
364:
365: xattr->attr = this->dosflags;
366:
367: /* note: fifo's that haven't been opened yet can be written to */
368:
369: if (this->flags & O_HEAD) {
370:
371: xattr->attr &= ~FA_RDONLY;
372:
373: }
374:
375:
376:
377: xattr->nblocks = PIPESIZ;
378:
379: if (this->dosflags & FA_SYSTEM) { /* pseudo-tty */
380:
381: xattr->size = PIPESIZ/4;
382:
1.1.1.4 ! root 383: xattr->rdev = PIPE_RDEV|1;
! 384:
1.1 root 385: } else {
386:
387: xattr->size = PIPESIZ;
388:
1.1.1.4 ! root 389: xattr->rdev = PIPE_RDEV|0;
! 390:
1.1 root 391: }
392:
393: }
394:
395: return 0;
396:
397: }
398:
399:
400:
1.1.1.2 root 401: static long ARGS_ON_STACK
1.1 root 402:
403: pipe_chattr(fc, attrib)
404:
405: fcookie *fc;
406:
407: int attrib;
408:
409: {
410:
1.1.1.2 root 411: UNUSED(fc); UNUSED(attrib);
412:
1.1 root 413: return EACCDN;
414:
415: }
416:
417:
418:
1.1.1.2 root 419: static long ARGS_ON_STACK
1.1 root 420:
421: pipe_chown(fc, uid, gid)
422:
423: fcookie *fc;
424:
425: int uid, gid;
426:
427: {
428:
429: struct fifo *this;
430:
431:
432:
1.1.1.2 root 433: if ((this = (struct fifo *)fc->index) == 0)
434:
435: return EACCDN;
1.1 root 436:
437:
438:
439: this->uid = uid;
440:
441: this->gid = gid;
442:
443: return 0;
444:
445: }
446:
447:
448:
1.1.1.2 root 449: static long ARGS_ON_STACK
1.1 root 450:
451: pipe_chmode(fc, mode)
452:
453: fcookie *fc;
454:
455: unsigned mode;
456:
457: {
458:
459: struct fifo *this;
460:
461:
462:
1.1.1.2 root 463: if ((this = (struct fifo *)fc->index) == 0)
464:
465: return EACCDN;
1.1 root 466:
467:
468:
469: this->mode = (this->mode & S_IFMT) | (mode & ~S_IFMT);
470:
471: return 0;
472:
473: }
474:
475:
476:
1.1.1.2 root 477: static long ARGS_ON_STACK
1.1 root 478:
479: pipe_rmdir(dir, name)
480:
481: fcookie *dir;
482:
483: const char *name;
484:
485: {
486:
1.1.1.2 root 487: UNUSED(dir); UNUSED(name);
488:
489:
490:
1.1 root 491: /* the kernel already checked to see if the file exists */
492:
493: return EACCDN;
494:
495: }
496:
497:
498:
1.1.1.2 root 499: static long ARGS_ON_STACK
1.1 root 500:
501: pipe_remove(dir, name)
502:
503: fcookie *dir;
504:
505: const char *name;
506:
507: {
508:
1.1.1.2 root 509: UNUSED(dir); UNUSED(name);
510:
511:
512:
1.1 root 513: /* the kernel already checked to see if the file exists */
514:
515: return EACCDN;
516:
517: }
518:
519:
520:
1.1.1.2 root 521: static long ARGS_ON_STACK
1.1 root 522:
1.1.1.3 root 523: pipe_getname(root, dir, pathname, size)
1.1 root 524:
525: fcookie *root, *dir; char *pathname;
526:
1.1.1.3 root 527: int size;
528:
1.1 root 529: {
530:
1.1.1.2 root 531: UNUSED(root);
532:
1.1.1.3 root 533: UNUSED(size); /* BUG: we should support 'size' */
534:
1.1.1.2 root 535:
536:
1.1 root 537: if (dir->index == 0)
538:
539: *pathname = 0;
540:
541: else
542:
543: strcpy(pathname, ((struct fifo *)dir->index)->name);
544:
545: return 0;
546:
547: }
548:
549:
550:
1.1.1.2 root 551: static long ARGS_ON_STACK
1.1 root 552:
553: pipe_rename(olddir, oldname, newdir, newname)
554:
555: fcookie *olddir;
556:
557: char *oldname;
558:
559: fcookie *newdir;
560:
561: const char *newname;
562:
563: {
564:
1.1.1.2 root 565: UNUSED(olddir); UNUSED(oldname);
566:
567: UNUSED(newdir); UNUSED(newname);
568:
569:
570:
1.1 root 571: return EACCDN;
572:
573: }
574:
575:
576:
1.1.1.2 root 577: static long ARGS_ON_STACK
1.1 root 578:
579: pipe_opendir(dirh, flags)
580:
581: DIR *dirh;
582:
583: int flags;
584:
585: {
586:
1.1.1.2 root 587: UNUSED(flags);
588:
589:
590:
1.1 root 591: if (dirh->fc.index != 0) {
592:
1.1.1.2 root 593: DEBUG(("pipe_opendir: bad directory"));
1.1 root 594:
595: return EPTHNF;
596:
597: }
598:
599: dirh->index = 0;
600:
601: return 0;
602:
603: }
604:
605:
606:
1.1.1.2 root 607: static long ARGS_ON_STACK
1.1 root 608:
609: pipe_readdir(dirh, name, namelen, fc)
610:
611: DIR *dirh;
612:
613: char *name;
614:
615: int namelen;
616:
617: fcookie *fc;
618:
619: {
620:
621: struct fifo *this;
622:
623: int i;
624:
625: int giveindex = dirh->flags == 0;
626:
627:
628:
629: i = dirh->index++;
630:
631: this = rootlist;
632:
633: while (i > 0 && this) {
634:
635: --i; this = this->next;
636:
637: }
638:
639: if (!this)
640:
641: return ENMFIL;
642:
643:
644:
645: fc->fs = &pipe_filesys;
646:
647: fc->index = (long)this;
648:
649: fc->dev = dirh->fc.dev;
650:
651: if (giveindex) {
652:
1.1.1.2 root 653: namelen -= (int) sizeof(long);
1.1 root 654:
655: if (namelen <= 0) return ERANGE;
656:
657: *((long *)name) = (long)this;
658:
659: name += sizeof(long);
660:
661: }
662:
663: strncpy(name, this->name, namelen-1);
664:
665: if (strlen(this->name) >= namelen)
666:
667: return ENAMETOOLONG;
668:
669: return 0;
670:
671: }
672:
673:
674:
1.1.1.2 root 675: static long ARGS_ON_STACK
1.1 root 676:
677: pipe_rewinddir(dirh)
678:
679: DIR *dirh;
680:
681: {
682:
683: dirh->index = 0;
684:
685: return 0;
686:
687: }
688:
689:
690:
1.1.1.2 root 691: static long ARGS_ON_STACK
1.1 root 692:
693: pipe_closedir(dirh)
694:
695: DIR *dirh;
696:
697: {
698:
1.1.1.2 root 699: UNUSED(dirh);
700:
1.1 root 701: return 0;
702:
703: }
704:
705:
706:
1.1.1.2 root 707: static long ARGS_ON_STACK
1.1 root 708:
709: pipe_pathconf(dir, which)
710:
711: fcookie *dir;
712:
713: int which;
714:
715: {
716:
1.1.1.2 root 717: UNUSED(dir);
718:
719:
720:
1.1 root 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; /* no hard links */
734:
735: case DP_PATHMAX:
736:
737: return PATH_MAX;
738:
739: case DP_NAMEMAX:
740:
741: return NAME_MAX;
742:
743: case DP_ATOMIC:
744:
745: /* BUG: for pty's, this should actually be PIPE_BUF/4 */
746:
747: return PIPE_BUF;
748:
749: case DP_TRUNC:
750:
751: return DP_AUTOTRUNC;
752:
753: case DP_CASE:
754:
755: return DP_CASEINSENS;
756:
757: default:
758:
759: return EINVFN;
760:
761: }
762:
763: }
764:
765:
766:
1.1.1.2 root 767: static long ARGS_ON_STACK
1.1 root 768:
769: pipe_dfree(dir, buf)
770:
771: fcookie *dir;
772:
773: long *buf;
774:
775: {
776:
777: int i;
778:
779: struct fifo *b;
780:
781: long freemem;
782:
783:
784:
1.1.1.2 root 785: UNUSED(dir);
786:
787:
788:
1.1 root 789: /* the "sector" size is the number of bytes per pipe */
790:
791: /* so we get the total number of sectors used by counting pipes */
792:
793:
794:
795: i = 0;
796:
797: for (b = rootlist; b; b = b->next) {
798:
799: if (b->inp) i++;
800:
801: if (b->outp) i++;
802:
803: }
804:
805:
806:
807: freemem = tot_rsize(core, 0) + tot_rsize(alt, 0);
808:
809:
810:
811: /* note: the "free clusters" isn't quite accurate, since there's overhead
812:
813: * in the fifo structure; but we're not looking for 100% accuracy here
814:
815: */
816:
817: buf[0] = freemem/PIPESIZ; /* number of free clusters */
818:
819: buf[1] = buf[0]+i; /* total number of clusters */
820:
821: buf[2] = PIPESIZ; /* sector size (bytes) */
822:
823: buf[3] = 1; /* cluster size (sectors) */
824:
825: return 0;
826:
827: }
828:
829:
830:
831: /* create a new pipe.
832:
833: * this only gets called by the kernel if a lookup already failed,
834:
835: * so we know that the new pipe creation is OK
836:
837: */
838:
839:
840:
1.1.1.2 root 841: static long ARGS_ON_STACK
1.1 root 842:
843: pipe_creat(dir, name, mode, attrib, fc)
844:
845: fcookie *dir;
846:
847: const char *name;
848:
849: unsigned mode;
850:
851: int attrib;
852:
853: fcookie *fc;
854:
855: {
856:
857: struct pipe *inp, *outp;
858:
859: struct tty *tty;
860:
861: struct fifo *b;
862:
863: /* selfread == 1 if we want reads to wait even if no other processes
864:
865: have currently opened the file, and writes to succeed in the same
866:
867: event. This is useful for servers who want to wait for requests.
868:
869: Pipes should always have selfread == 0.
870:
871: */
872:
873: int selfread = (attrib & FA_HIDDEN) ? 0 : 1;
874:
875:
876:
877:
878:
879: /* create the new pipe */
880:
1.1.1.2 root 881: if (0 == (inp = (struct pipe *)kmalloc(SIZEOF(struct pipe)))) {
1.1 root 882:
883: return ENSMEM;
884:
885: }
886:
887: if (attrib & FA_RDONLY) { /* read only FIFOs are unidirectional */
888:
889: outp = 0;
890:
891: } else {
892:
893: outp = (struct pipe *)kmalloc(SIZEOF(struct pipe));
894:
895: if (!outp) {
896:
897: kfree(inp);
898:
899: return ENSMEM;
900:
901: }
902:
903: }
904:
905: b = (struct fifo *)kmalloc(SIZEOF(struct fifo));
906:
907: if (!b) {
908:
909: kfree(inp);
910:
911: if (outp) kfree(outp);
912:
913: return ENSMEM;
914:
915: }
916:
917: if (attrib & FA_SYSTEM) { /* pseudo-tty */
918:
919: tty = (struct tty *)kmalloc(SIZEOF(struct tty));
920:
921: if (!tty) {
922:
923: kfree(inp);
924:
925: kfree(b);
926:
927: if (outp) kfree(outp);
928:
929: return ENSMEM;
930:
931: }
932:
933: tty->use_cnt = 0;
934:
935: /* do_open does the rest of tty initialization */
936:
937: } else tty = 0;
938:
939:
940:
941: /* set up the pipes appropriately */
942:
943: inp->head = inp->tail = 0;
944:
945: inp->readers = selfread ? 1 : VIRGIN_PIPE; inp->writers = 1;
946:
947: inp->rsel = inp->wsel = 0;
948:
949: if (outp) {
950:
951: outp->head = outp->tail = 0;
952:
953: outp->readers = 1; outp->writers = selfread ? 1 : VIRGIN_PIPE;
954:
955: outp->wsel = outp->rsel = 0;
956:
957: }
958:
959: strncpy(b->name, name, NAME_MAX);
960:
961: b->time = timestamp;
962:
963: b->date = datestamp;
964:
965: b->dosflags = attrib;
966:
967: b->mode = ((attrib & FA_SYSTEM) ? S_IFCHR : S_IFIFO) | mode;
968:
969: b->uid = curproc->ruid;
970:
971: b->gid = curproc->rgid;
972:
973:
974:
975: /* the O_HEAD flag indicates that the file hasn't actually been opened
976:
977: * yet; the next open gets to be the pty master. pipe_open will
978:
979: * clear the flag when this happens.
980:
981: */
982:
983: b->flags = ((attrib & FA_SYSTEM) ? O_TTY : 0) | O_HEAD;
984:
985: b->inp = inp; b->outp = outp; b->tty = tty;
986:
987:
988:
989: b->next = rootlist;
990:
991: b->open = (FILEPTR *)0;
992:
993: rootlist = b;
994:
995:
996:
997: /* we have to return a file cookie as well */
998:
999: fc->fs = &pipe_filesys;
1000:
1001: fc->index = (long)b;
1002:
1003: fc->dev = dir->dev;
1004:
1005:
1006:
1007: /* update time/date stamps for u:\pipe */
1008:
1009: pipetime = timestamp;
1010:
1011: pipedate = datestamp;
1012:
1013:
1014:
1015: return 0;
1016:
1017: }
1018:
1019:
1020:
1.1.1.2 root 1021: static DEVDRV * ARGS_ON_STACK
1.1 root 1022:
1023: pipe_getdev(fc, devsp)
1024:
1025: fcookie *fc;
1026:
1027: long *devsp;
1028:
1029: {
1030:
1031: struct fifo *b = (struct fifo *)fc->index;
1032:
1033:
1034:
1.1.1.2 root 1035: UNUSED(devsp);
1036:
1.1 root 1037: return (b->flags & O_TTY) ? &pty_device : &pipe_device;
1038:
1039: }
1040:
1041:
1042:
1043: /*
1044:
1045: * PIPE device driver
1046:
1047: */
1048:
1049:
1050:
1.1.1.2 root 1051: static long ARGS_ON_STACK
1.1 root 1052:
1053: pipe_open(f)
1054:
1055: FILEPTR *f;
1056:
1057: {
1058:
1059: struct fifo *p;
1060:
1061: int rwmode = f->flags & O_RWMODE;
1062:
1063:
1064:
1065: p = (struct fifo *)f->fc.index;
1066:
1067: f->flags |= p->flags;
1068:
1069: /*
1070:
1071: * if this is the first open for this file, then the O_HEAD flag is
1072:
1073: * set in p->flags. If not, and someone was trying to create the file,
1074:
1075: * return an error
1076:
1077: */
1078:
1079: if (p->flags & O_HEAD) {
1080:
1081: if (!(f->flags & O_CREAT)) {
1082:
1.1.1.2 root 1083: DEBUG(("pipe_open: file hasn't been created yet"));
1.1 root 1084:
1085: return EINTRN;
1086:
1087: }
1088:
1089: p->flags &= ~O_HEAD;
1090:
1091: } else {
1092:
1093: if (f->flags & O_CREAT) {
1094:
1.1.1.2 root 1095: DEBUG(("pipe_open: fifo already exists"));
1.1 root 1096:
1097: return EACCDN;
1098:
1099: }
1100:
1101: }
1102:
1103: /*
1104:
1105: * check for file sharing compatibility. note that O_COMPAT gets mutated
1106:
1107: * into O_DENYNONE, because any old programs that know about pipes will
1108:
1109: * already handle multitasking correctly
1110:
1111: */
1112:
1113: if ( (f->flags & O_SHMODE) == O_COMPAT ) {
1114:
1115: f->flags = (f->flags & ~O_SHMODE) | O_DENYNONE;
1116:
1117: }
1118:
1119: if (denyshare(p->open, f))
1120:
1121: return EACCDN;
1122:
1123: f->next = p->open; /* add this open fileptr to the list */
1124:
1125: p->open = f;
1126:
1127:
1128:
1129: /*
1130:
1131: * add readers/writers to the list
1132:
1133: */
1134:
1135: if (!(f->flags & O_HEAD)) {
1136:
1137: if (rwmode == O_RDONLY || rwmode == O_RDWR) {
1138:
1139: if (p->inp->readers == VIRGIN_PIPE)
1140:
1141: p->inp->readers = 1;
1142:
1143: else
1144:
1145: p->inp->readers++;
1146:
1147: }
1148:
1149: if ((rwmode == O_WRONLY || rwmode == O_RDWR) && p->outp) {
1150:
1151: if (p->outp->writers == VIRGIN_PIPE)
1152:
1153: p->outp->writers = 1;
1154:
1155: else
1156:
1157: p->outp->writers++;
1158:
1159: }
1160:
1161: }
1162:
1163:
1164:
1165: /* TTY devices need a tty structure in f->devinfo */
1166:
1167: f->devinfo = (long)p->tty;
1168:
1169:
1170:
1171: return 0;
1172:
1173: }
1174:
1175:
1176:
1.1.1.2 root 1177: static long ARGS_ON_STACK
1.1 root 1178:
1179: pipe_write(f, buf, nbytes)
1180:
1181: FILEPTR *f; const char *buf; long nbytes;
1182:
1183: {
1184:
1185: int ptail, phead, j;
1186:
1187: char *pbuf;
1188:
1189: struct pipe *p;
1190:
1191: struct fifo *this;
1192:
1193: long bytes_written = 0;
1194:
1195: long r;
1196:
1197:
1198:
1199: this = (struct fifo *)f->fc.index;
1200:
1201: p = (f->flags & O_HEAD) ? this->inp : this->outp;
1202:
1203: if (!p) {
1204:
1.1.1.2 root 1205: DEBUG(("pipe_write: write on wrong end of pipe"));
1.1 root 1206:
1207: return EACCDN;
1208:
1209: }
1210:
1211:
1212:
1213: if (nbytes > 0 && nbytes <= PIPE_BUF) {
1214:
1215: check_atomicity:
1216:
1217: r = p->tail - p->head;
1218:
1219: if (r < 0) r += PIPESIZ;
1220:
1221: r = (PIPESIZ-1) - r; /* r is the number of bytes we can write */
1222:
1223: if (r < nbytes) {
1224:
1225: /* check for broken pipes */
1226:
1227: if (p->readers == 0 || p->readers == VIRGIN_PIPE) {
1228:
1229: check_sigs();
1230:
1.1.1.2 root 1231: DEBUG(("pipe_write: broken pipe"));
1.1 root 1232:
1233: raise(SIGPIPE);
1234:
1.1.1.3 root 1235: return EPIPE;
1.1 root 1236:
1237: }
1238:
1239: /* wake up any readers, and wait for them to gobble some data */
1240:
1241: if (p->rsel) {
1242:
1243: wakeselect(p->rsel);
1244:
1245: p->rsel = 0;
1246:
1247: }
1248:
1249: wake(IO_Q, (long)p);
1250:
1251: sleep(IO_Q, (long)p);
1252:
1253: goto check_atomicity;
1254:
1255: }
1256:
1257: }
1258:
1259:
1260:
1261: while (nbytes > 0) {
1262:
1263: ptail = p->tail; phead = p->head;
1264:
1265: j = ptail+1;
1266:
1267: if (j >= PIPESIZ) j = 0;
1268:
1269: if (j != phead) {
1270:
1271: pbuf = &p->buf[ptail];
1272:
1273: do {
1274:
1275: *pbuf++ = *buf++;
1276:
1277: nbytes--; bytes_written++;
1278:
1279: if ( (ptail = j) == 0 )
1280:
1281: pbuf = &p->buf[0];
1282:
1283: j++;
1284:
1285: if (j >= PIPESIZ) j = 0;
1286:
1287: } while ( (nbytes > 0) && (j != phead) );
1288:
1289: p->tail = ptail;
1290:
1291: } else { /* pipe full */
1292:
1293: if (p->readers == 0 || p->readers == VIRGIN_PIPE) {
1294:
1295: /* maybe some other signal is waiting for us? */
1296:
1297: check_sigs();
1298:
1.1.1.2 root 1299: DEBUG(("pipe_write: broken pipe"));
1.1 root 1300:
1301: raise(SIGPIPE);
1302:
1.1.1.3 root 1303: return EPIPE;
1.1 root 1304:
1305: }
1306:
1307: if (f->flags & O_NDELAY) {
1308:
1309: break;
1310:
1311: }
1312:
1313: /* is someone select()ing the other end of the pipe for reading? */
1314:
1315: if (p->rsel) {
1316:
1317: wakeselect(p->rsel);
1318:
1319: p->rsel = 0;
1320:
1321: }
1322:
1323: wake(IO_Q, (long)p); /* readers may continue */
1324:
1.1.1.2 root 1325: DEBUG(("pipe_write: sleep on %lx", p));
1.1 root 1326:
1327: sleep(IO_Q, (long)p);
1328:
1329: }
1330:
1331: }
1332:
1333: this->time = timestamp;
1334:
1335: this->date = datestamp;
1336:
1337: if (bytes_written > 0) {
1338:
1339: if (p->rsel) {
1340:
1341: wakeselect(p->rsel);
1342:
1343: p->rsel = 0;
1344:
1345: }
1346:
1347: wake(IO_Q, (long)p); /* maybe someone wants this data */
1348:
1349: }
1350:
1351:
1352:
1353: return bytes_written;
1354:
1355: }
1356:
1357:
1358:
1.1.1.2 root 1359: static long ARGS_ON_STACK
1.1 root 1360:
1361: pipe_read(f, buf, nbytes)
1362:
1363: FILEPTR *f; char *buf; long nbytes;
1364:
1365: {
1366:
1367: int phead, ptail;
1368:
1369: struct fifo *this;
1370:
1371: struct pipe *p;
1372:
1373: long bytes_read = 0;
1374:
1375: char *pbuf;
1376:
1377:
1378:
1379: this = (struct fifo *)f->fc.index;
1380:
1381: p = (f->flags & O_HEAD) ? this->outp : this->inp;
1382:
1383: if (!p) {
1384:
1.1.1.2 root 1385: DEBUG(("pipe_read: read on the wrong end of a pipe"));
1.1 root 1386:
1387: return EACCDN;
1388:
1389: }
1390:
1391:
1392:
1393: while (nbytes > 0) {
1394:
1395: phead = p->head; ptail = p->tail;
1396:
1397: if (ptail != phead) {
1398:
1399: pbuf = &p->buf[phead];
1400:
1401: do {
1402:
1403: *buf++ = *pbuf++;
1404:
1405: nbytes--; bytes_read++;
1406:
1407: phead++;
1408:
1409: if (phead >= PIPESIZ) {
1410:
1411: phead = 0;
1412:
1413: pbuf = &p->buf[phead];
1414:
1415: }
1416:
1417: } while ( (nbytes > 0) && (phead != ptail) );
1418:
1419: p->head = phead;
1420:
1421: }
1422:
1423: else if (p->writers <= 0 || p->writers == VIRGIN_PIPE) {
1424:
1.1.1.2 root 1425: TRACE(("pipe_read: no more writers"));
1.1 root 1426:
1427: break;
1428:
1429: }
1430:
1.1.1.2 root 1431: else if ((f->flags & O_NDELAY) ||
1432:
1433: ((this->dosflags & FA_CHANGED) && bytes_read > 0) )
1434:
1435: {
1.1 root 1436:
1437: break;
1438:
1439: }
1440:
1441: else {
1442:
1443: /* is someone select()ing the other end of the pipe for writing? */
1444:
1445: if (p->wsel) {
1446:
1447: wakeselect(p->wsel);
1448:
1449: p->wsel = 0;
1450:
1451: }
1452:
1453: wake(IO_Q, (long)p); /* writers may continue */
1454:
1455: sleep(IO_Q, (long)p);
1456:
1457: }
1458:
1459: }
1460:
1461: if (bytes_read > 0) {
1462:
1463: if (p->wsel) {
1464:
1465: wakeselect(p->wsel);
1466:
1467: p->wsel = 0;
1468:
1469: }
1470:
1471: wake(IO_Q, (long)p); /* wake writers */
1472:
1473: }
1474:
1475: return bytes_read;
1476:
1477: }
1478:
1479:
1480:
1.1.1.2 root 1481: static long ARGS_ON_STACK
1.1 root 1482:
1483: pipe_ioctl(f, mode, buf)
1484:
1485: FILEPTR *f; int mode; void *buf;
1486:
1487: {
1488:
1489: struct pipe *p;
1490:
1491: struct fifo *this;
1492:
1493: struct flock *lck;
1494:
1495:
1496:
1497: long r;
1498:
1499:
1500:
1501: this = (struct fifo *)f->fc.index;
1502:
1503:
1504:
1505: if (mode == FIONREAD) {
1506:
1507: p = (f->flags & O_HEAD) ? this->outp : this->inp;
1508:
1509: assert(p != 0);
1510:
1511: if (p->writers <= 0 || p->writers == VIRGIN_PIPE) {
1512:
1.1.1.2 root 1513: DEBUG(("pipe FIONREAD: no writers"));
1.1 root 1514:
1515: r = -1;
1516:
1517: } else {
1518:
1519: r = p->tail - p->head;
1520:
1521: if (r < 0) r += PIPESIZ;
1522:
1523: if (is_terminal(f))
1524:
1525: r = r >> 2; /* r /= 4 */
1526:
1527: }
1528:
1529: *((long *) buf) = r;
1530:
1531: }
1532:
1533: else if (mode == FIONWRITE) {
1534:
1535: p = (f->flags & O_HEAD) ? this->inp : this->outp;
1536:
1537: assert(p != 0);
1538:
1539: if (p->readers <= 0) {
1540:
1541: r = -1;
1542:
1543: } else {
1544:
1545: r = p->tail - p->head;
1546:
1547: if (r < 0) r += PIPESIZ;
1548:
1549: r = (PIPESIZ-1) - r;
1550:
1551: if (is_terminal(f))
1552:
1553: r = r >> 2; /* r /= 4 */
1554:
1555: }
1556:
1557: *((long *) buf) = r;
1558:
1559: }
1560:
1.1.1.2 root 1561: else if (mode == F_SETLK || mode == F_SETLKW) {
1.1 root 1562:
1563: lck = (struct flock *)buf;
1564:
1.1.1.2 root 1565: while (this->flags & O_LOCK) {
1.1 root 1566:
1567: if (this->lockpid != curproc->pid) {
1568:
1.1.1.2 root 1569: DEBUG(("pipe_ioctl: pipe already locked"));
1.1 root 1570:
1.1.1.2 root 1571: if (mode == F_SETLKW && lck->l_type != F_UNLCK) {
1.1 root 1572:
1.1.1.2 root 1573: sleep(IO_Q, (long)this); /* sleep a while */
1574:
1575: }
1576:
1577: else
1578:
1579: return ELOCKED;
1580:
1581: } else
1582:
1583: break;
1.1 root 1584:
1585: }
1586:
1587: if (lck->l_type == F_UNLCK) {
1588:
1589: if (!(f->flags & O_LOCK)) {
1590:
1.1.1.2 root 1591: DEBUG(("pipe_ioctl: wrong file descriptor for UNLCK"));
1.1 root 1592:
1593: return ENSLOCK;
1594:
1595: }
1596:
1597: this->flags &= ~O_LOCK;
1598:
1599: this->lockpid = 0;
1600:
1601: f->flags &= ~O_LOCK;
1602:
1.1.1.2 root 1603: wake(IO_Q, (long)this); /* wake up anyone waiting on the lock */
1604:
1.1 root 1605: }
1606:
1607: else {
1608:
1609: this->flags |= O_LOCK;
1610:
1611: this->lockpid = curproc->pid;
1612:
1613: f->flags |= O_LOCK;
1614:
1615: }
1616:
1617: }
1618:
1619: else if (mode == F_GETLK) {
1620:
1621: lck = (struct flock *)buf;
1622:
1623: if (this->flags & O_LOCK) {
1624:
1625: lck->l_type = F_WRLCK;
1626:
1627: lck->l_start = lck->l_len = 0;
1628:
1629: lck->l_pid = this->lockpid;
1630:
1631: }
1632:
1633: else
1634:
1635: lck->l_type = F_UNLCK;
1636:
1637: }
1638:
1639: else if (mode == TIOCFLUSH) {
1640:
1.1.1.4 ! root 1641: long flushtype;
! 1642:
! 1643: long *which;
! 1644:
! 1645:
! 1646:
! 1647: which = (long *)buf;
! 1648:
! 1649: if (!which || !(*which & 3))
! 1650:
! 1651: flushtype = 3;
! 1652:
! 1653: else
! 1654:
! 1655: flushtype = *which;
! 1656:
! 1657:
! 1658:
! 1659: if ((flushtype & 1) && this->inp) {
1.1 root 1660:
1661: this->inp->head = this->inp->tail;
1662:
1663: wake(IO_Q, (long)this->inp);
1664:
1665: }
1666:
1.1.1.4 ! root 1667: if ((flushtype & 2) && this->outp) {
1.1 root 1668:
1669: this->outp->head = this->outp->tail;
1670:
1671: wake(IO_Q, (long)this->outp);
1672:
1673: }
1674:
1.1.1.4 ! root 1675: } else if (mode == TIOCOUTQ) {
! 1676:
! 1677: p = (f->flags & O_HEAD) ? this->inp : this->outp;
! 1678:
! 1679: assert(p != 0);
! 1680:
! 1681: if (p->readers <= 0) {
! 1682:
! 1683: r = -1;
! 1684:
! 1685: } else {
! 1686:
! 1687: r = p->tail - p->head;
! 1688:
! 1689: if (r < 0) r += PIPESIZ;
! 1690:
! 1691: if (is_terminal(f))
! 1692:
! 1693: r = r >> 2; /* r /= 4 */
! 1694:
! 1695: }
! 1696:
! 1697: *((long *) buf) = r;
! 1698:
1.1 root 1699: } else if (mode == TIOCIBAUD || mode == TIOCOBAUD) {
1700:
1701: *(long *)buf = -1L;
1702:
1703: } else if (mode == TIOCGFLAGS) {
1704:
1705: *((unsigned short *)buf) = 0;
1706:
1.1.1.2 root 1707: } else if (mode >= TCURSOFF && mode <= TCURSGRATE) {
1708:
1709: /* kludge: this assumes TOSWIN style escape sequences */
1710:
1711: tty_putchar(f, (long)'\033', RAW);
1712:
1713: switch (mode) {
1714:
1715: case TCURSOFF:
1716:
1717: tty_putchar(f, (long)'f', RAW);
1718:
1719: break;
1720:
1721: case TCURSON:
1722:
1723: tty_putchar(f, (long)'e', RAW);
1724:
1725: break;
1726:
1727: case TCURSSRATE:
1728:
1729: this->cursrate = *((int *)buf);
1730:
1731: /* fall through */
1732:
1733: case TCURSBLINK:
1734:
1735: tty_putchar(f, (long)'t', RAW);
1736:
1737: tty_putchar(f, (long)this->cursrate+32, RAW);
1738:
1739: break;
1740:
1741: case TCURSSTEADY:
1742:
1743: tty_putchar(f, (long)'t', RAW);
1744:
1745: tty_putchar(f, (long)32, RAW);
1746:
1747: break;
1748:
1749: case TCURSGRATE:
1750:
1751: return this->cursrate;
1752:
1753: }
1754:
1.1 root 1755: } else {
1756:
1757: /* if the file is a terminal, Fcntl will automatically
1758:
1759: * call tty_ioctl for us to handle 'generic' terminal
1760:
1761: * functions
1762:
1763: */
1764:
1765: return EINVFN;
1766:
1767: }
1768:
1769:
1770:
1771: return 0;
1772:
1773: }
1774:
1775:
1776:
1.1.1.2 root 1777: static long ARGS_ON_STACK
1.1 root 1778:
1779: pipe_lseek(f, where, whence)
1780:
1781: FILEPTR *f; long where; int whence;
1782:
1783: {
1784:
1.1.1.2 root 1785: UNUSED(f); UNUSED(where); UNUSED(whence);
1786:
1.1 root 1787: return EACCDN;
1788:
1789: }
1790:
1791:
1792:
1.1.1.2 root 1793: static long ARGS_ON_STACK
1.1 root 1794:
1795: pipe_datime(f, timeptr, rwflag)
1796:
1797: FILEPTR *f;
1798:
1799: short *timeptr;
1800:
1801: int rwflag;
1802:
1803: {
1804:
1805: struct fifo *this;
1806:
1807:
1808:
1809: this = (struct fifo *)f->fc.index;
1810:
1811: if (rwflag) {
1812:
1813: this->time = timeptr[0];
1814:
1815: this->date = timeptr[1];
1816:
1817: }
1818:
1819: else {
1820:
1821: timeptr[0] = this->time;
1822:
1823: timeptr[1] = this->date;
1824:
1825: }
1826:
1827: return 0;
1828:
1829: }
1830:
1831:
1832:
1.1.1.2 root 1833: static long ARGS_ON_STACK
1.1 root 1834:
1835: pipe_close(f, pid)
1836:
1837: FILEPTR *f;
1838:
1839: int pid;
1840:
1841: {
1842:
1843: struct fifo *this, *old;
1844:
1845: struct pipe *p;
1846:
1847: int rwmode;
1848:
1849: FILEPTR **old_x, *x;
1850:
1851:
1852:
1853: this = (struct fifo *)f->fc.index;
1854:
1855:
1856:
1857: /* wake any processes waiting on this pipe */
1858:
1859: wake(IO_Q, (long)this->inp);
1860:
1861: if (this->inp->rsel)
1862:
1863: wakeselect(this->inp->rsel);
1864:
1865: if (this->inp->wsel)
1866:
1867: wakeselect(this->inp->wsel);
1868:
1869:
1870:
1871: if (this->outp) {
1872:
1873: wake(IO_Q, (long)this->outp);
1874:
1875: if (this->outp->wsel)
1876:
1877: wakeselect(this->outp->wsel);
1878:
1879: if (this->outp->rsel)
1880:
1881: wakeselect(this->outp->rsel);
1882:
1883: }
1884:
1885:
1886:
1887: if (f->links <= 0) {
1888:
1889: /* remove the file pointer from the list of open file pointers
1890:
1891: * of this pipe
1892:
1893: */
1894:
1895: old_x = &this->open;
1896:
1897: x = this->open;
1898:
1899: while (x && x != f) {
1900:
1901: old_x = &x->next;
1902:
1903: x = x->next;
1904:
1905: }
1906:
1907: assert(x);
1908:
1909: *old_x = f->next;
1910:
1911: /* f->next = 0; */
1912:
1913:
1914:
1915: rwmode = f->flags & O_RWMODE;
1916:
1917: if (rwmode == O_RDONLY || rwmode == O_RDWR) {
1918:
1919: p = (f->flags & O_HEAD) ? this->outp : this->inp;
1920:
1921: /* note that this can never be a virgin pipe, since we had a handle
1922:
1923: * on it!
1924:
1925: */ if (p)
1926:
1927: p->readers--;
1928:
1929: }
1930:
1931: if (rwmode == O_WRONLY || rwmode == O_RDWR) {
1932:
1933: p = (f->flags & O_HEAD) ? this->inp : this->outp;
1934:
1935: if (p) p->writers--;
1936:
1937: }
1938:
1939:
1940:
1941: /* correct for the "selfread" flag (see pipe_creat) */
1942:
1943: if ((f->flags & O_HEAD) && !(this->dosflags & 0x02))
1944:
1945: this->inp->readers--;
1946:
1947:
1948:
1949: /* check for locks */
1950:
1951: if ((f->flags & O_LOCK) && (this->lockpid == pid)) {
1952:
1953: this->flags &= ~O_LOCK;
1954:
1.1.1.2 root 1955: wake(IO_Q, (long)this); /* wake up anyone waiting on the lock */
1956:
1.1 root 1957: }
1958:
1959: }
1960:
1961:
1962:
1963: /* see if we're finished with the pipe */
1964:
1965: if (this->inp->readers == VIRGIN_PIPE)
1966:
1967: this->inp->readers = 0;
1968:
1969: if (this->inp->writers == VIRGIN_PIPE)
1970:
1971: this->inp->writers = 0;
1972:
1973:
1974:
1975: if (this->inp->readers <= 0 && this->inp->writers <= 0) {
1976:
1.1.1.2 root 1977: TRACE(("disposing of closed fifo"));
1.1 root 1978:
1979: /* unlink from list of FIFOs */
1980:
1981: if (rootlist == this)
1982:
1983: rootlist = this->next;
1984:
1985: else {
1986:
1987: for (old = rootlist; old->next != this;
1988:
1989: old = old->next) {
1990:
1991: if (!old) {
1992:
1993: ALERT("fifo not on list???");
1994:
1995: return EINTRN;
1996:
1997: }
1998:
1999: }
2000:
2001: old->next = this->next;
2002:
2003: }
2004:
2005: kfree(this->inp);
2006:
2007: if (this->outp) kfree(this->outp);
2008:
1.1.1.4 ! root 2009: if (this->tty) kfree(this->tty);
! 2010:
1.1 root 2011: kfree(this);
2012:
2013: pipetime = timestamp;
2014:
2015: pipedate = datestamp;
2016:
2017: }
2018:
2019:
2020:
2021: return 0;
2022:
2023: }
2024:
2025:
2026:
1.1.1.2 root 2027: static long ARGS_ON_STACK
1.1 root 2028:
2029: pipe_select(f, proc, mode)
2030:
2031: FILEPTR *f;
2032:
2033: long proc;
2034:
2035: int mode;
2036:
2037: {
2038:
2039: struct fifo *this;
2040:
2041: struct pipe *p;
2042:
2043: int j;
2044:
2045:
2046:
2047: this = (struct fifo *)f->fc.index;
2048:
2049:
2050:
2051: if (mode == O_RDONLY) {
2052:
2053: p = (f->flags & O_HEAD) ? this->outp : this->inp;
2054:
2055: if (!p) {
2056:
1.1.1.2 root 2057: DEBUG(("read select on wrong end of pipe"));
1.1 root 2058:
2059: return 0;
2060:
2061: }
2062:
2063:
2064:
2065: /* NOTE: if p->writers <= 0 then reads won't block (they'll fail) */
2066:
2067: if (p->tail != p->head || p->writers <= 0) {
2068:
2069: return 1;
2070:
2071: }
2072:
2073:
2074:
1.1.1.4 ! root 2075: if (p->rsel)
1.1 root 2076:
1.1.1.4 ! root 2077: return 2; /* collision */
1.1 root 2078:
1.1.1.4 ! root 2079: p->rsel = proc;
1.1 root 2080:
2081: return 0;
2082:
2083: } else if (mode == O_WRONLY) {
2084:
2085: p = (f->flags & O_HEAD) ? this->inp : this->outp;
2086:
2087: if (!p) {
2088:
1.1.1.2 root 2089: DEBUG(("write select on wrong end of pipe"));
1.1 root 2090:
2091: return 0;
2092:
2093: }
2094:
2095: j = p->tail+1;
2096:
2097: if (j >= PIPESIZ) j = 0;
2098:
2099: if (j != p->head || p->readers <= 0)
2100:
2101: return 1; /* data may be written */
2102:
1.1.1.4 ! root 2103: if (p->wsel)
! 2104:
! 2105: return 2; /* collision */
1.1 root 2106:
1.1.1.4 ! root 2107: p->wsel = proc;
1.1 root 2108:
2109: return 0;
2110:
2111: }
2112:
2113: return 0;
2114:
2115: }
2116:
2117:
2118:
1.1.1.2 root 2119: static void ARGS_ON_STACK
1.1 root 2120:
2121: pipe_unselect(f, proc, mode)
2122:
2123: FILEPTR *f;
2124:
2125: long proc;
2126:
2127: int mode;
2128:
2129: {
2130:
2131: struct fifo *this;
2132:
2133: struct pipe *p;
2134:
2135:
2136:
2137: this = (struct fifo *)f->fc.index;
2138:
2139:
2140:
2141: if (mode == O_RDONLY) {
2142:
2143: p = (f->flags & O_HEAD) ? this->outp : this->inp;
2144:
2145: if (!p) {
2146:
2147: return;
2148:
2149: }
2150:
2151: if (p->rsel == proc)
2152:
2153: p->rsel = 0;
2154:
2155: } else if (mode == O_WRONLY) {
2156:
2157: p = (f->flags & O_HEAD) ? this->inp : this->outp;
2158:
2159: if (!p) {
2160:
2161: return;
2162:
2163: }
2164:
2165: if (p->wsel == proc)
2166:
2167: p->wsel = 0;
2168:
2169: }
2170:
2171: }
2172:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.