]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/fs/fifofs/fifo_vnops.c
Merge ACPICA 20091013.
[FreeBSD/FreeBSD.git] / sys / fs / fifofs / fifo_vnops.c
1 /*-
2  * Copyright (c) 1990, 1993, 1995
3  *      The Regents of the University of California.
4  * Copyright (c) 2005 Robert N. M. Watson
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 4. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  *      @(#)fifo_vnops.c        8.10 (Berkeley) 5/27/95
32  * $FreeBSD$
33  */
34
35 #include <sys/param.h>
36 #include <sys/event.h>
37 #include <sys/file.h>
38 #include <sys/filedesc.h>
39 #include <sys/filio.h>
40 #include <sys/fcntl.h>
41 #include <sys/kernel.h>
42 #include <sys/lock.h>
43 #include <sys/mutex.h>
44 #include <sys/malloc.h>
45 #include <sys/poll.h>
46 #include <sys/proc.h>
47 #include <sys/signalvar.h>
48 #include <sys/socket.h>
49 #include <sys/socketvar.h>
50 #include <sys/sx.h>
51 #include <sys/systm.h>
52 #include <sys/un.h>
53 #include <sys/unistd.h>
54 #include <sys/vnode.h>
55 #include <fs/fifofs/fifo.h>
56
57 static fo_rdwr_t        fifo_read_f;
58 static fo_rdwr_t        fifo_write_f;
59 static fo_ioctl_t       fifo_ioctl_f;
60 static fo_poll_t        fifo_poll_f;
61 static fo_kqfilter_t    fifo_kqfilter_f;
62 static fo_stat_t        fifo_stat_f;
63 static fo_close_t       fifo_close_f;
64 static fo_truncate_t    fifo_truncate_f;
65
66 struct fileops fifo_ops_f = {
67         .fo_read =      fifo_read_f,
68         .fo_write =     fifo_write_f,
69         .fo_truncate =  fifo_truncate_f,
70         .fo_ioctl =     fifo_ioctl_f,
71         .fo_poll =      fifo_poll_f,
72         .fo_kqfilter =  fifo_kqfilter_f,
73         .fo_stat =      fifo_stat_f,
74         .fo_close =     fifo_close_f,
75         .fo_flags =     DFLAG_PASSABLE
76 };
77
78 /*
79  * This structure is associated with the FIFO vnode and stores
80  * the state associated with the FIFO.
81  */
82 struct fifoinfo {
83         struct socket   *fi_readsock;
84         struct socket   *fi_writesock;
85         long            fi_readers;
86         long            fi_writers;
87         int             fi_wgen;
88 };
89
90 static vop_print_t      fifo_print;
91 static vop_open_t       fifo_open;
92 static vop_close_t      fifo_close;
93 static vop_pathconf_t   fifo_pathconf;
94 static vop_advlock_t    fifo_advlock;
95
96 static void     filt_fifordetach(struct knote *kn);
97 static int      filt_fiforead(struct knote *kn, long hint);
98 static void     filt_fifowdetach(struct knote *kn);
99 static int      filt_fifowrite(struct knote *kn, long hint);
100 static void     filt_fifodetach_notsup(struct knote *kn);
101 static int      filt_fifo_notsup(struct knote *kn, long hint);
102
103 static struct filterops fiforead_filtops = {
104         .f_isfd = 1,
105         .f_detach = filt_fifordetach,
106         .f_event = filt_fiforead,
107 };
108 static struct filterops fifowrite_filtops = {
109         .f_isfd = 1,
110         .f_detach = filt_fifowdetach,
111         .f_event = filt_fifowrite,
112 };
113 static struct filterops fifo_notsup_filtops = {
114         .f_isfd = 1,
115         .f_detach = filt_fifodetach_notsup,
116         .f_event = filt_fifo_notsup,
117 };
118
119 struct vop_vector fifo_specops = {
120         .vop_default =          &default_vnodeops,
121
122         .vop_advlock =          fifo_advlock,
123         .vop_close =            fifo_close,
124         .vop_create =           VOP_PANIC,
125         .vop_getattr =          VOP_EBADF,
126         .vop_ioctl =            VOP_PANIC,
127         .vop_kqfilter =         VOP_PANIC,
128         .vop_link =             VOP_PANIC,
129         .vop_mkdir =            VOP_PANIC,
130         .vop_mknod =            VOP_PANIC,
131         .vop_open =             fifo_open,
132         .vop_pathconf =         fifo_pathconf,
133         .vop_print =            fifo_print,
134         .vop_read =             VOP_PANIC,
135         .vop_readdir =          VOP_PANIC,
136         .vop_readlink =         VOP_PANIC,
137         .vop_reallocblks =      VOP_PANIC,
138         .vop_reclaim =          VOP_NULL,
139         .vop_remove =           VOP_PANIC,
140         .vop_rename =           VOP_PANIC,
141         .vop_rmdir =            VOP_PANIC,
142         .vop_setattr =          VOP_EBADF,
143         .vop_symlink =          VOP_PANIC,
144         .vop_write =            VOP_PANIC,
145 };
146
147 struct mtx fifo_mtx;
148 MTX_SYSINIT(fifo, &fifo_mtx, "fifo mutex", MTX_DEF);
149
150 /*
151  * Dispose of fifo resources.
152  */
153 static void
154 fifo_cleanup(struct vnode *vp)
155 {
156         struct fifoinfo *fip = vp->v_fifoinfo;
157
158         ASSERT_VOP_ELOCKED(vp, "fifo_cleanup");
159         if (fip->fi_readers == 0 && fip->fi_writers == 0) {
160                 vp->v_fifoinfo = NULL;
161                 (void)soclose(fip->fi_readsock);
162                 (void)soclose(fip->fi_writesock);
163                 free(fip, M_VNODE);
164         }
165 }
166
167 /*
168  * Open called to set up a new instance of a fifo or
169  * to find an active instance of a fifo.
170  */
171 /* ARGSUSED */
172 static int
173 fifo_open(ap)
174         struct vop_open_args /* {
175                 struct vnode *a_vp;
176                 int  a_mode;
177                 struct ucred *a_cred;
178                 struct thread *a_td;
179                 struct file *a_fp;
180         } */ *ap;
181 {
182         struct vnode *vp = ap->a_vp;
183         struct fifoinfo *fip;
184         struct thread *td = ap->a_td;
185         struct ucred *cred = ap->a_cred;
186         struct file *fp = ap->a_fp;
187         struct socket *rso, *wso;
188         int error;
189
190         ASSERT_VOP_ELOCKED(vp, "fifo_open");
191         if (fp == NULL)
192                 return (EINVAL);
193         if ((fip = vp->v_fifoinfo) == NULL) {
194                 fip = malloc(sizeof(*fip), M_VNODE, M_WAITOK);
195                 error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, cred, td);
196                 if (error)
197                         goto fail1;
198                 fip->fi_readsock = rso;
199                 error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0, cred, td);
200                 if (error)
201                         goto fail2;
202                 fip->fi_writesock = wso;
203                 error = soconnect2(wso, rso);
204                 /* Close the direction we do not use, so we can get POLLHUP. */
205                 if (error == 0)
206                         error = soshutdown(rso, SHUT_WR);
207                 if (error) {
208                         (void)soclose(wso);
209 fail2:
210                         (void)soclose(rso);
211 fail1:
212                         free(fip, M_VNODE);
213                         return (error);
214                 }
215                 fip->fi_readers = fip->fi_writers = 0;
216                 wso->so_snd.sb_lowat = PIPE_BUF;
217                 SOCKBUF_LOCK(&rso->so_rcv);
218                 rso->so_rcv.sb_state |= SBS_CANTRCVMORE;
219                 SOCKBUF_UNLOCK(&rso->so_rcv);
220                 KASSERT(vp->v_fifoinfo == NULL,
221                     ("fifo_open: v_fifoinfo race"));
222                 vp->v_fifoinfo = fip;
223         }
224
225         /*
226          * General access to fi_readers and fi_writers is protected using
227          * the vnode lock.
228          *
229          * Protect the increment of fi_readers and fi_writers and the
230          * associated calls to wakeup() with the fifo mutex in addition
231          * to the vnode lock.  This allows the vnode lock to be dropped
232          * for the msleep() calls below, and using the fifo mutex with
233          * msleep() prevents the wakeup from being missed.
234          */
235         mtx_lock(&fifo_mtx);
236         if (ap->a_mode & FREAD) {
237                 fip->fi_readers++;
238                 if (fip->fi_readers == 1) {
239                         SOCKBUF_LOCK(&fip->fi_writesock->so_snd);
240                         fip->fi_writesock->so_snd.sb_state &= ~SBS_CANTSENDMORE;
241                         SOCKBUF_UNLOCK(&fip->fi_writesock->so_snd);
242                         if (fip->fi_writers > 0) {
243                                 wakeup(&fip->fi_writers);
244                                 sowwakeup(fip->fi_writesock);
245                         }
246                 }
247                 fp->f_seqcount = fip->fi_wgen - fip->fi_writers;
248         }
249         if (ap->a_mode & FWRITE) {
250                 if ((ap->a_mode & O_NONBLOCK) && fip->fi_readers == 0) {
251                         mtx_unlock(&fifo_mtx);
252                         return (ENXIO);
253                 }
254                 fip->fi_writers++;
255                 if (fip->fi_writers == 1) {
256                         SOCKBUF_LOCK(&fip->fi_readsock->so_rcv);
257                         fip->fi_readsock->so_rcv.sb_state &= ~SBS_CANTRCVMORE;
258                         SOCKBUF_UNLOCK(&fip->fi_readsock->so_rcv);
259                         if (fip->fi_readers > 0) {
260                                 wakeup(&fip->fi_readers);
261                                 sorwakeup(fip->fi_readsock);
262                         }
263                 }
264         }
265         if ((ap->a_mode & O_NONBLOCK) == 0) {
266                 if ((ap->a_mode & FREAD) && fip->fi_writers == 0) {
267                         VOP_UNLOCK(vp, 0);
268                         error = msleep(&fip->fi_readers, &fifo_mtx,
269                             PDROP | PCATCH | PSOCK, "fifoor", 0);
270                         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
271                         if (error) {
272                                 fip->fi_readers--;
273                                 if (fip->fi_readers == 0) {
274                                         socantsendmore(fip->fi_writesock);
275                                         fifo_cleanup(vp);
276                                 }
277                                 return (error);
278                         }
279                         mtx_lock(&fifo_mtx);
280                         /*
281                          * We must have got woken up because we had a writer.
282                          * That (and not still having one) is the condition
283                          * that we must wait for.
284                          */
285                 }
286                 if ((ap->a_mode & FWRITE) && fip->fi_readers == 0) {
287                         VOP_UNLOCK(vp, 0);
288                         error = msleep(&fip->fi_writers, &fifo_mtx,
289                             PDROP | PCATCH | PSOCK, "fifoow", 0);
290                         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
291                         if (error) {
292                                 fip->fi_writers--;
293                                 if (fip->fi_writers == 0) {
294                                         socantrcvmore(fip->fi_readsock);
295                                         mtx_lock(&fifo_mtx);
296                                         fip->fi_wgen++;
297                                         mtx_unlock(&fifo_mtx);
298                                         fifo_cleanup(vp);
299                                 }
300                                 return (error);
301                         }
302                         /*
303                          * We must have got woken up because we had
304                          * a reader.  That (and not still having one)
305                          * is the condition that we must wait for.
306                          */
307                         mtx_lock(&fifo_mtx);
308                 }
309         }
310         mtx_unlock(&fifo_mtx);
311         KASSERT(fp != NULL, ("can't fifo/vnode bypass"));
312         KASSERT(fp->f_ops == &badfileops, ("not badfileops in fifo_open"));
313         finit(fp, fp->f_flag, DTYPE_FIFO, fip, &fifo_ops_f);
314         return (0);
315 }
316
317 static void
318 filt_fifordetach(struct knote *kn)
319 {
320         struct socket *so = (struct socket *)kn->kn_hook;
321
322         SOCKBUF_LOCK(&so->so_rcv);
323         knlist_remove(&so->so_rcv.sb_sel.si_note, kn, 1);
324         if (knlist_empty(&so->so_rcv.sb_sel.si_note))
325                 so->so_rcv.sb_flags &= ~SB_KNOTE;
326         SOCKBUF_UNLOCK(&so->so_rcv);
327 }
328
329 static int
330 filt_fiforead(struct knote *kn, long hint)
331 {
332         struct socket *so = (struct socket *)kn->kn_hook;
333
334         SOCKBUF_LOCK_ASSERT(&so->so_rcv);
335         kn->kn_data = so->so_rcv.sb_cc;
336         if (so->so_rcv.sb_state & SBS_CANTRCVMORE) {
337                 kn->kn_flags |= EV_EOF;
338                 return (1);
339         } else {
340                 kn->kn_flags &= ~EV_EOF;
341                 return (kn->kn_data > 0);
342         }
343 }
344
345 static void
346 filt_fifowdetach(struct knote *kn)
347 {
348         struct socket *so = (struct socket *)kn->kn_hook;
349
350         SOCKBUF_LOCK(&so->so_snd);
351         knlist_remove(&so->so_snd.sb_sel.si_note, kn, 1);
352         if (knlist_empty(&so->so_snd.sb_sel.si_note))
353                 so->so_snd.sb_flags &= ~SB_KNOTE;
354         SOCKBUF_UNLOCK(&so->so_snd);
355 }
356
357 static int
358 filt_fifowrite(struct knote *kn, long hint)
359 {
360         struct socket *so = (struct socket *)kn->kn_hook;
361
362         SOCKBUF_LOCK_ASSERT(&so->so_snd);
363         kn->kn_data = sbspace(&so->so_snd);
364         if (so->so_snd.sb_state & SBS_CANTSENDMORE) {
365                 kn->kn_flags |= EV_EOF;
366                 return (1);
367         } else {
368                 kn->kn_flags &= ~EV_EOF;
369                 return (kn->kn_data >= so->so_snd.sb_lowat);
370         }
371 }
372
373 static void
374 filt_fifodetach_notsup(struct knote *kn)
375 {
376
377 }
378
379 static int
380 filt_fifo_notsup(struct knote *kn, long hint)
381 {
382
383         return (0);
384 }
385
386 /*
387  * Device close routine
388  */
389 /* ARGSUSED */
390 static int
391 fifo_close(ap)
392         struct vop_close_args /* {
393                 struct vnode *a_vp;
394                 int  a_fflag;
395                 struct ucred *a_cred;
396                 struct thread *a_td;
397         } */ *ap;
398 {
399         struct vnode *vp = ap->a_vp;
400         struct fifoinfo *fip = vp->v_fifoinfo;
401
402         ASSERT_VOP_ELOCKED(vp, "fifo_close");
403         if (fip == NULL) {
404                 printf("fifo_close: no v_fifoinfo %p\n", vp);
405                 return (0);
406         }
407         if (ap->a_fflag & FREAD) {
408                 fip->fi_readers--;
409                 if (fip->fi_readers == 0)
410                         socantsendmore(fip->fi_writesock);
411         }
412         if (ap->a_fflag & FWRITE) {
413                 fip->fi_writers--;
414                 if (fip->fi_writers == 0) {
415                         socantrcvmore(fip->fi_readsock);
416                         mtx_lock(&fifo_mtx);
417                         fip->fi_wgen++;
418                         mtx_unlock(&fifo_mtx);
419                 }
420         }
421         fifo_cleanup(vp);
422         return (0);
423 }
424
425 /*
426  * Print out internal contents of a fifo vnode.
427  */
428 int
429 fifo_printinfo(vp)
430         struct vnode *vp;
431 {
432         register struct fifoinfo *fip = vp->v_fifoinfo;
433
434         if (fip == NULL){
435                 printf(", NULL v_fifoinfo");
436                 return (0);
437         }
438         printf(", fifo with %ld readers and %ld writers",
439                 fip->fi_readers, fip->fi_writers);
440         return (0);
441 }
442
443 /*
444  * Print out the contents of a fifo vnode.
445  */
446 static int
447 fifo_print(ap)
448         struct vop_print_args /* {
449                 struct vnode *a_vp;
450         } */ *ap;
451 {
452         printf("    ");
453         fifo_printinfo(ap->a_vp);
454         printf("\n");
455         return (0);
456 }
457
458 /*
459  * Return POSIX pathconf information applicable to fifo's.
460  */
461 static int
462 fifo_pathconf(ap)
463         struct vop_pathconf_args /* {
464                 struct vnode *a_vp;
465                 int a_name;
466                 int *a_retval;
467         } */ *ap;
468 {
469
470         switch (ap->a_name) {
471         case _PC_LINK_MAX:
472                 *ap->a_retval = LINK_MAX;
473                 return (0);
474         case _PC_PIPE_BUF:
475                 *ap->a_retval = PIPE_BUF;
476                 return (0);
477         case _PC_CHOWN_RESTRICTED:
478                 *ap->a_retval = 1;
479                 return (0);
480         default:
481                 return (EINVAL);
482         }
483         /* NOTREACHED */
484 }
485
486 /*
487  * Fifo advisory byte-level locks.
488  */
489 /* ARGSUSED */
490 static int
491 fifo_advlock(ap)
492         struct vop_advlock_args /* {
493                 struct vnode *a_vp;
494                 caddr_t  a_id;
495                 int  a_op;
496                 struct flock *a_fl;
497                 int  a_flags;
498         } */ *ap;
499 {
500
501         return (ap->a_flags & F_FLOCK ? EOPNOTSUPP : EINVAL);
502 }
503
504 static int
505 fifo_close_f(struct file *fp, struct thread *td)
506 {
507
508         return (vnops.fo_close(fp, td));
509 }
510
511 /*
512  * The implementation of ioctl() for named fifos is complicated by the fact
513  * that we permit O_RDWR fifo file descriptors, meaning that the actions of
514  * ioctls may have to be applied to both the underlying sockets rather than
515  * just one.  The original implementation simply forward the ioctl to one
516  * or both sockets based on fp->f_flag.  We now consider each ioctl
517  * separately, as the composition effect requires careful ordering.
518  *
519  * We do not blindly pass all ioctls through to the socket in order to avoid
520  * providing unnecessary ioctls that might be improperly depended on by
521  * applications (such as socket-specific, routing, and interface ioctls).
522  *
523  * Unlike sys_pipe.c, fifos do not implement the deprecated TIOCSPGRP and
524  * TIOCGPGRP ioctls.  Earlier implementations of fifos did forward SIOCSPGRP
525  * and SIOCGPGRP ioctls, so we might need to re-add those here.
526  */
527 static int
528 fifo_ioctl_f(struct file *fp, u_long com, void *data, struct ucred *cred,
529     struct thread *td)
530 {
531         struct fifoinfo *fi;
532         struct file filetmp;    /* Local, so need not be locked. */
533         int error;
534
535         error = ENOTTY;
536         fi = fp->f_data;
537
538         switch (com) {
539         case FIONBIO:
540                 /*
541                  * Non-blocking I/O is implemented at the fifo layer using
542                  * MSG_NBIO, so does not need to be forwarded down the stack.
543                  */
544                 return (0);
545
546         case FIOASYNC:
547         case FIOSETOWN:
548         case FIOGETOWN:
549                 /*
550                  * These socket ioctls don't have any ordering requirements,
551                  * so are called in an arbitrary order, and only on the
552                  * sockets indicated by the file descriptor rights.
553                  *
554                  * XXXRW: If O_RDWR and the read socket accepts an ioctl but
555                  * the write socket doesn't, the socketpair is left in an
556                  * inconsistent state.
557                  */
558                 if (fp->f_flag & FREAD) {
559                         filetmp.f_data = fi->fi_readsock;
560                         filetmp.f_cred = cred;
561                         error = soo_ioctl(&filetmp, com, data, cred, td);
562                         if (error)
563                                 return (error);
564                 }
565                 if (fp->f_flag & FWRITE) {
566                         filetmp.f_data = fi->fi_writesock;
567                         filetmp.f_cred = cred;
568                         error = soo_ioctl(&filetmp, com, data, cred, td);
569                 }
570                 return (error);
571
572         case FIONREAD:
573                 /*
574                  * FIONREAD will return 0 for non-readable descriptors, and
575                  * the results of FIONREAD on the read socket for readable
576                  * descriptors.
577                  */
578                 if (!(fp->f_flag & FREAD)) {
579                         *(int *)data = 0;
580                         return (0);
581                 }
582                 filetmp.f_data = fi->fi_readsock;
583                 filetmp.f_cred = cred;
584                 return (soo_ioctl(&filetmp, com, data, cred, td));
585
586         default:
587                 return (ENOTTY);
588         }
589 }
590
591 /*
592  * Because fifos are now a file descriptor layer object, EVFILT_VNODE is not
593  * implemented.  Likely, fifo_kqfilter() should be removed, and
594  * fifo_kqfilter_f() should know how to forward the request to the underling
595  * vnode using f_vnode in the file descriptor here.
596  */
597 static int
598 fifo_kqfilter_f(struct file *fp, struct knote *kn)
599 {
600         struct fifoinfo *fi;
601         struct socket *so;
602         struct sockbuf *sb;
603
604         fi = fp->f_data;
605
606         /*
607          * If a filter is requested that is not supported by this file
608          * descriptor, don't return an error, but also don't ever generate an
609          * event.
610          */
611         if ((kn->kn_filter == EVFILT_READ) && !(fp->f_flag & FREAD)) {
612                 kn->kn_fop = &fifo_notsup_filtops;
613                 return (0);
614         }
615
616         if ((kn->kn_filter == EVFILT_WRITE) && !(fp->f_flag & FWRITE)) {
617                 kn->kn_fop = &fifo_notsup_filtops;
618                 return (0);
619         }
620
621         switch (kn->kn_filter) {
622         case EVFILT_READ:
623                 kn->kn_fop = &fiforead_filtops;
624                 so = fi->fi_readsock;
625                 sb = &so->so_rcv;
626                 break;
627         case EVFILT_WRITE:
628                 kn->kn_fop = &fifowrite_filtops;
629                 so = fi->fi_writesock;
630                 sb = &so->so_snd;
631                 break;
632         default:
633                 return (EINVAL);
634         }
635
636         kn->kn_hook = (caddr_t)so;
637
638         SOCKBUF_LOCK(sb);
639         knlist_add(&sb->sb_sel.si_note, kn, 1);
640         sb->sb_flags |= SB_KNOTE;
641         SOCKBUF_UNLOCK(sb);
642
643         return (0);
644 }
645
646 static int
647 fifo_poll_f(struct file *fp, int events, struct ucred *cred, struct thread *td)
648 {
649         struct fifoinfo *fip;
650         struct file filetmp;
651         int levents, revents = 0;
652
653         fip = fp->f_data;
654         levents = events &
655             (POLLIN | POLLINIGNEOF | POLLPRI | POLLRDNORM | POLLRDBAND);
656         if ((fp->f_flag & FREAD) && levents) {
657                 filetmp.f_data = fip->fi_readsock;
658                 filetmp.f_cred = cred;
659                 mtx_lock(&fifo_mtx);
660                 if (fp->f_seqcount == fip->fi_wgen)
661                         levents |= POLLINIGNEOF;
662                 mtx_unlock(&fifo_mtx);
663                 revents |= soo_poll(&filetmp, levents, cred, td);
664         }
665         levents = events & (POLLOUT | POLLWRNORM | POLLWRBAND);
666         if ((fp->f_flag & FWRITE) && levents) {
667                 filetmp.f_data = fip->fi_writesock;
668                 filetmp.f_cred = cred;
669                 revents |= soo_poll(&filetmp, levents, cred, td);
670         }
671         return (revents);
672 }
673
674 static int
675 fifo_read_f(struct file *fp, struct uio *uio, struct ucred *cred, int flags, struct thread *td)
676 {
677         struct fifoinfo *fip;
678         int sflags;
679
680         fip = fp->f_data;
681         KASSERT(uio->uio_rw == UIO_READ,("fifo_read mode"));
682         if (uio->uio_resid == 0)
683                 return (0);
684         sflags = (fp->f_flag & FNONBLOCK) ? MSG_NBIO : 0;
685         return (soreceive(fip->fi_readsock, NULL, uio, NULL, NULL, &sflags));
686 }
687
688 static int
689 fifo_stat_f(struct file *fp, struct stat *sb, struct ucred *cred, struct thread *td)
690 {
691
692         return (vnops.fo_stat(fp, sb, cred, td));
693 }
694
695 static int
696 fifo_truncate_f(struct file *fp, off_t length, struct ucred *cred, struct thread *td)
697 {
698
699         return (vnops.fo_truncate(fp, length, cred, td));
700 }
701
702 static int
703 fifo_write_f(struct file *fp, struct uio *uio, struct ucred *cred, int flags, struct thread *td)
704 {
705         struct fifoinfo *fip;
706         int sflags;
707
708         fip = fp->f_data;
709         KASSERT(uio->uio_rw == UIO_WRITE,("fifo_write mode"));
710         sflags = (fp->f_flag & FNONBLOCK) ? MSG_NBIO : 0;
711         return (sosend(fip->fi_writesock, NULL, uio, 0, NULL, sflags, td));
712 }