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