]> CyberLeo.Net >> Repos - FreeBSD/stable/8.git/blob - sys/fs/fifofs/fifo_vnops.c
Copy head to stable/8 as part of 8.0 Release cycle.
[FreeBSD/stable/8.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         { 1, NULL, filt_fifordetach, filt_fiforead };
105 static struct filterops fifowrite_filtops =
106         { 1, NULL, filt_fifowdetach, filt_fifowrite };
107 static struct filterops fifo_notsup_filtops =
108         { 1, NULL, filt_fifodetach_notsup, filt_fifo_notsup };
109
110 struct vop_vector fifo_specops = {
111         .vop_default =          &default_vnodeops,
112
113         .vop_access =           VOP_EBADF,
114         .vop_advlock =          fifo_advlock,
115         .vop_close =            fifo_close,
116         .vop_create =           VOP_PANIC,
117         .vop_getattr =          VOP_EBADF,
118         .vop_ioctl =            VOP_PANIC,
119         .vop_kqfilter =         VOP_PANIC,
120         .vop_link =             VOP_PANIC,
121         .vop_mkdir =            VOP_PANIC,
122         .vop_mknod =            VOP_PANIC,
123         .vop_open =             fifo_open,
124         .vop_pathconf =         fifo_pathconf,
125         .vop_print =            fifo_print,
126         .vop_read =             VOP_PANIC,
127         .vop_readdir =          VOP_PANIC,
128         .vop_readlink =         VOP_PANIC,
129         .vop_reallocblks =      VOP_PANIC,
130         .vop_reclaim =          VOP_NULL,
131         .vop_remove =           VOP_PANIC,
132         .vop_rename =           VOP_PANIC,
133         .vop_rmdir =            VOP_PANIC,
134         .vop_setattr =          VOP_EBADF,
135         .vop_symlink =          VOP_PANIC,
136         .vop_write =            VOP_PANIC,
137 };
138
139 struct mtx fifo_mtx;
140 MTX_SYSINIT(fifo, &fifo_mtx, "fifo mutex", MTX_DEF);
141
142 /*
143  * Dispose of fifo resources.
144  */
145 static void
146 fifo_cleanup(struct vnode *vp)
147 {
148         struct fifoinfo *fip = vp->v_fifoinfo;
149
150         ASSERT_VOP_ELOCKED(vp, "fifo_cleanup");
151         if (fip->fi_readers == 0 && fip->fi_writers == 0) {
152                 vp->v_fifoinfo = NULL;
153                 (void)soclose(fip->fi_readsock);
154                 (void)soclose(fip->fi_writesock);
155                 free(fip, M_VNODE);
156         }
157 }
158
159 /*
160  * Open called to set up a new instance of a fifo or
161  * to find an active instance of a fifo.
162  */
163 /* ARGSUSED */
164 static int
165 fifo_open(ap)
166         struct vop_open_args /* {
167                 struct vnode *a_vp;
168                 int  a_mode;
169                 struct ucred *a_cred;
170                 struct thread *a_td;
171                 struct file *a_fp;
172         } */ *ap;
173 {
174         struct vnode *vp = ap->a_vp;
175         struct fifoinfo *fip;
176         struct thread *td = ap->a_td;
177         struct ucred *cred = ap->a_cred;
178         struct file *fp = ap->a_fp;
179         struct socket *rso, *wso;
180         int error;
181
182         ASSERT_VOP_ELOCKED(vp, "fifo_open");
183         if (fp == NULL)
184                 return (EINVAL);
185         if ((fip = vp->v_fifoinfo) == NULL) {
186                 fip = malloc(sizeof(*fip), M_VNODE, M_WAITOK);
187                 error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, cred, td);
188                 if (error)
189                         goto fail1;
190                 fip->fi_readsock = rso;
191                 error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0, cred, td);
192                 if (error)
193                         goto fail2;
194                 fip->fi_writesock = wso;
195                 error = soconnect2(wso, rso);
196                 if (error) {
197                         (void)soclose(wso);
198 fail2:
199                         (void)soclose(rso);
200 fail1:
201                         free(fip, M_VNODE);
202                         return (error);
203                 }
204                 fip->fi_readers = fip->fi_writers = 0;
205                 wso->so_snd.sb_lowat = PIPE_BUF;
206                 SOCKBUF_LOCK(&rso->so_rcv);
207                 rso->so_rcv.sb_state |= SBS_CANTRCVMORE;
208                 SOCKBUF_UNLOCK(&rso->so_rcv);
209                 KASSERT(vp->v_fifoinfo == NULL,
210                     ("fifo_open: v_fifoinfo race"));
211                 vp->v_fifoinfo = fip;
212         }
213
214         /*
215          * General access to fi_readers and fi_writers is protected using
216          * the vnode lock.
217          *
218          * Protect the increment of fi_readers and fi_writers and the
219          * associated calls to wakeup() with the fifo mutex in addition
220          * to the vnode lock.  This allows the vnode lock to be dropped
221          * for the msleep() calls below, and using the fifo mutex with
222          * msleep() prevents the wakeup from being missed.
223          */
224         mtx_lock(&fifo_mtx);
225         if (ap->a_mode & FREAD) {
226                 fip->fi_readers++;
227                 if (fip->fi_readers == 1) {
228                         SOCKBUF_LOCK(&fip->fi_writesock->so_snd);
229                         fip->fi_writesock->so_snd.sb_state &= ~SBS_CANTSENDMORE;
230                         SOCKBUF_UNLOCK(&fip->fi_writesock->so_snd);
231                         if (fip->fi_writers > 0) {
232                                 wakeup(&fip->fi_writers);
233                                 sowwakeup(fip->fi_writesock);
234                         }
235                 }
236                 fp->f_seqcount = fip->fi_wgen - fip->fi_writers;
237         }
238         if (ap->a_mode & FWRITE) {
239                 if ((ap->a_mode & O_NONBLOCK) && fip->fi_readers == 0) {
240                         mtx_unlock(&fifo_mtx);
241                         return (ENXIO);
242                 }
243                 fip->fi_writers++;
244                 if (fip->fi_writers == 1) {
245                         SOCKBUF_LOCK(&fip->fi_readsock->so_rcv);
246                         fip->fi_readsock->so_rcv.sb_state &= ~SBS_CANTRCVMORE;
247                         SOCKBUF_UNLOCK(&fip->fi_readsock->so_rcv);
248                         if (fip->fi_readers > 0) {
249                                 wakeup(&fip->fi_readers);
250                                 sorwakeup(fip->fi_readsock);
251                         }
252                 }
253         }
254         if ((ap->a_mode & O_NONBLOCK) == 0) {
255                 if ((ap->a_mode & FREAD) && fip->fi_writers == 0) {
256                         VOP_UNLOCK(vp, 0);
257                         error = msleep(&fip->fi_readers, &fifo_mtx,
258                             PDROP | PCATCH | PSOCK, "fifoor", 0);
259                         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
260                         if (error) {
261                                 fip->fi_readers--;
262                                 if (fip->fi_readers == 0) {
263                                         socantsendmore(fip->fi_writesock);
264                                         fifo_cleanup(vp);
265                                 }
266                                 return (error);
267                         }
268                         mtx_lock(&fifo_mtx);
269                         /*
270                          * We must have got woken up because we had a writer.
271                          * That (and not still having one) is the condition
272                          * that we must wait for.
273                          */
274                 }
275                 if ((ap->a_mode & FWRITE) && fip->fi_readers == 0) {
276                         VOP_UNLOCK(vp, 0);
277                         error = msleep(&fip->fi_writers, &fifo_mtx,
278                             PDROP | PCATCH | PSOCK, "fifoow", 0);
279                         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
280                         if (error) {
281                                 fip->fi_writers--;
282                                 if (fip->fi_writers == 0) {
283                                         socantrcvmore(fip->fi_readsock);
284                                         mtx_lock(&fifo_mtx);
285                                         fip->fi_wgen++;
286                                         mtx_unlock(&fifo_mtx);
287                                         fifo_cleanup(vp);
288                                 }
289                                 return (error);
290                         }
291                         /*
292                          * We must have got woken up because we had
293                          * a reader.  That (and not still having one)
294                          * is the condition that we must wait for.
295                          */
296                         mtx_lock(&fifo_mtx);
297                 }
298         }
299         mtx_unlock(&fifo_mtx);
300         KASSERT(fp != NULL, ("can't fifo/vnode bypass"));
301         KASSERT(fp->f_ops == &badfileops, ("not badfileops in fifo_open"));
302         finit(fp, fp->f_flag, DTYPE_FIFO, fip, &fifo_ops_f);
303         return (0);
304 }
305
306 static void
307 filt_fifordetach(struct knote *kn)
308 {
309         struct socket *so = (struct socket *)kn->kn_hook;
310
311         SOCKBUF_LOCK(&so->so_rcv);
312         knlist_remove(&so->so_rcv.sb_sel.si_note, kn, 1);
313         if (knlist_empty(&so->so_rcv.sb_sel.si_note))
314                 so->so_rcv.sb_flags &= ~SB_KNOTE;
315         SOCKBUF_UNLOCK(&so->so_rcv);
316 }
317
318 static int
319 filt_fiforead(struct knote *kn, long hint)
320 {
321         struct socket *so = (struct socket *)kn->kn_hook;
322
323         SOCKBUF_LOCK_ASSERT(&so->so_rcv);
324         kn->kn_data = so->so_rcv.sb_cc;
325         if (so->so_rcv.sb_state & SBS_CANTRCVMORE) {
326                 kn->kn_flags |= EV_EOF;
327                 return (1);
328         } else {
329                 kn->kn_flags &= ~EV_EOF;
330                 return (kn->kn_data > 0);
331         }
332 }
333
334 static void
335 filt_fifowdetach(struct knote *kn)
336 {
337         struct socket *so = (struct socket *)kn->kn_hook;
338
339         SOCKBUF_LOCK(&so->so_snd);
340         knlist_remove(&so->so_snd.sb_sel.si_note, kn, 1);
341         if (knlist_empty(&so->so_snd.sb_sel.si_note))
342                 so->so_snd.sb_flags &= ~SB_KNOTE;
343         SOCKBUF_UNLOCK(&so->so_snd);
344 }
345
346 static int
347 filt_fifowrite(struct knote *kn, long hint)
348 {
349         struct socket *so = (struct socket *)kn->kn_hook;
350
351         SOCKBUF_LOCK_ASSERT(&so->so_snd);
352         kn->kn_data = sbspace(&so->so_snd);
353         if (so->so_snd.sb_state & SBS_CANTSENDMORE) {
354                 kn->kn_flags |= EV_EOF;
355                 return (1);
356         } else {
357                 kn->kn_flags &= ~EV_EOF;
358                 return (kn->kn_data >= so->so_snd.sb_lowat);
359         }
360 }
361
362 static void
363 filt_fifodetach_notsup(struct knote *kn)
364 {
365
366 }
367
368 static int
369 filt_fifo_notsup(struct knote *kn, long hint)
370 {
371
372         return (0);
373 }
374
375 /*
376  * Device close routine
377  */
378 /* ARGSUSED */
379 static int
380 fifo_close(ap)
381         struct vop_close_args /* {
382                 struct vnode *a_vp;
383                 int  a_fflag;
384                 struct ucred *a_cred;
385                 struct thread *a_td;
386         } */ *ap;
387 {
388         struct vnode *vp = ap->a_vp;
389         struct fifoinfo *fip = vp->v_fifoinfo;
390
391         ASSERT_VOP_ELOCKED(vp, "fifo_close");
392         if (fip == NULL) {
393                 printf("fifo_close: no v_fifoinfo %p\n", vp);
394                 return (0);
395         }
396         if (ap->a_fflag & FREAD) {
397                 fip->fi_readers--;
398                 if (fip->fi_readers == 0)
399                         socantsendmore(fip->fi_writesock);
400         }
401         if (ap->a_fflag & FWRITE) {
402                 fip->fi_writers--;
403                 if (fip->fi_writers == 0) {
404                         socantrcvmore(fip->fi_readsock);
405                         mtx_lock(&fifo_mtx);
406                         fip->fi_wgen++;
407                         mtx_unlock(&fifo_mtx);
408                 }
409         }
410         fifo_cleanup(vp);
411         return (0);
412 }
413
414 /*
415  * Print out internal contents of a fifo vnode.
416  */
417 int
418 fifo_printinfo(vp)
419         struct vnode *vp;
420 {
421         register struct fifoinfo *fip = vp->v_fifoinfo;
422
423         if (fip == NULL){
424                 printf(", NULL v_fifoinfo");
425                 return (0);
426         }
427         printf(", fifo with %ld readers and %ld writers",
428                 fip->fi_readers, fip->fi_writers);
429         return (0);
430 }
431
432 /*
433  * Print out the contents of a fifo vnode.
434  */
435 static int
436 fifo_print(ap)
437         struct vop_print_args /* {
438                 struct vnode *a_vp;
439         } */ *ap;
440 {
441         printf("    ");
442         fifo_printinfo(ap->a_vp);
443         printf("\n");
444         return (0);
445 }
446
447 /*
448  * Return POSIX pathconf information applicable to fifo's.
449  */
450 static int
451 fifo_pathconf(ap)
452         struct vop_pathconf_args /* {
453                 struct vnode *a_vp;
454                 int a_name;
455                 int *a_retval;
456         } */ *ap;
457 {
458
459         switch (ap->a_name) {
460         case _PC_LINK_MAX:
461                 *ap->a_retval = LINK_MAX;
462                 return (0);
463         case _PC_PIPE_BUF:
464                 *ap->a_retval = PIPE_BUF;
465                 return (0);
466         case _PC_CHOWN_RESTRICTED:
467                 *ap->a_retval = 1;
468                 return (0);
469         default:
470                 return (EINVAL);
471         }
472         /* NOTREACHED */
473 }
474
475 /*
476  * Fifo advisory byte-level locks.
477  */
478 /* ARGSUSED */
479 static int
480 fifo_advlock(ap)
481         struct vop_advlock_args /* {
482                 struct vnode *a_vp;
483                 caddr_t  a_id;
484                 int  a_op;
485                 struct flock *a_fl;
486                 int  a_flags;
487         } */ *ap;
488 {
489
490         return (ap->a_flags & F_FLOCK ? EOPNOTSUPP : EINVAL);
491 }
492
493 static int
494 fifo_close_f(struct file *fp, struct thread *td)
495 {
496
497         return (vnops.fo_close(fp, td));
498 }
499
500 /*
501  * The implementation of ioctl() for named fifos is complicated by the fact
502  * that we permit O_RDWR fifo file descriptors, meaning that the actions of
503  * ioctls may have to be applied to both the underlying sockets rather than
504  * just one.  The original implementation simply forward the ioctl to one
505  * or both sockets based on fp->f_flag.  We now consider each ioctl
506  * separately, as the composition effect requires careful ordering.
507  *
508  * We do not blindly pass all ioctls through to the socket in order to avoid
509  * providing unnecessary ioctls that might be improperly depended on by
510  * applications (such as socket-specific, routing, and interface ioctls).
511  *
512  * Unlike sys_pipe.c, fifos do not implement the deprecated TIOCSPGRP and
513  * TIOCGPGRP ioctls.  Earlier implementations of fifos did forward SIOCSPGRP
514  * and SIOCGPGRP ioctls, so we might need to re-add those here.
515  */
516 static int
517 fifo_ioctl_f(struct file *fp, u_long com, void *data, struct ucred *cred,
518     struct thread *td)
519 {
520         struct fifoinfo *fi;
521         struct file filetmp;    /* Local, so need not be locked. */
522         int error;
523
524         error = ENOTTY;
525         fi = fp->f_data;
526
527         switch (com) {
528         case FIONBIO:
529                 /*
530                  * Non-blocking I/O is implemented at the fifo layer using
531                  * MSG_NBIO, so does not need to be forwarded down the stack.
532                  */
533                 return (0);
534
535         case FIOASYNC:
536         case FIOSETOWN:
537         case FIOGETOWN:
538                 /*
539                  * These socket ioctls don't have any ordering requirements,
540                  * so are called in an arbitrary order, and only on the
541                  * sockets indicated by the file descriptor rights.
542                  *
543                  * XXXRW: If O_RDWR and the read socket accepts an ioctl but
544                  * the write socket doesn't, the socketpair is left in an
545                  * inconsistent state.
546                  */
547                 if (fp->f_flag & FREAD) {
548                         filetmp.f_data = fi->fi_readsock;
549                         filetmp.f_cred = cred;
550                         error = soo_ioctl(&filetmp, com, data, cred, td);
551                         if (error)
552                                 return (error);
553                 }
554                 if (fp->f_flag & FWRITE) {
555                         filetmp.f_data = fi->fi_writesock;
556                         filetmp.f_cred = cred;
557                         error = soo_ioctl(&filetmp, com, data, cred, td);
558                 }
559                 return (error);
560
561         case FIONREAD:
562                 /*
563                  * FIONREAD will return 0 for non-readable descriptors, and
564                  * the results of FIONREAD on the read socket for readable
565                  * descriptors.
566                  */
567                 if (!(fp->f_flag & FREAD)) {
568                         *(int *)data = 0;
569                         return (0);
570                 }
571                 filetmp.f_data = fi->fi_readsock;
572                 filetmp.f_cred = cred;
573                 return (soo_ioctl(&filetmp, com, data, cred, td));
574
575         default:
576                 return (ENOTTY);
577         }
578 }
579
580 /*
581  * Because fifos are now a file descriptor layer object, EVFILT_VNODE is not
582  * implemented.  Likely, fifo_kqfilter() should be removed, and
583  * fifo_kqfilter_f() should know how to forward the request to the underling
584  * vnode using f_vnode in the file descriptor here.
585  */
586 static int
587 fifo_kqfilter_f(struct file *fp, struct knote *kn)
588 {
589         struct fifoinfo *fi;
590         struct socket *so;
591         struct sockbuf *sb;
592
593         fi = fp->f_data;
594
595         /*
596          * If a filter is requested that is not supported by this file
597          * descriptor, don't return an error, but also don't ever generate an
598          * event.
599          */
600         if ((kn->kn_filter == EVFILT_READ) && !(fp->f_flag & FREAD)) {
601                 kn->kn_fop = &fifo_notsup_filtops;
602                 return (0);
603         }
604
605         if ((kn->kn_filter == EVFILT_WRITE) && !(fp->f_flag & FWRITE)) {
606                 kn->kn_fop = &fifo_notsup_filtops;
607                 return (0);
608         }
609
610         switch (kn->kn_filter) {
611         case EVFILT_READ:
612                 kn->kn_fop = &fiforead_filtops;
613                 so = fi->fi_readsock;
614                 sb = &so->so_rcv;
615                 break;
616         case EVFILT_WRITE:
617                 kn->kn_fop = &fifowrite_filtops;
618                 so = fi->fi_writesock;
619                 sb = &so->so_snd;
620                 break;
621         default:
622                 return (EINVAL);
623         }
624
625         kn->kn_hook = (caddr_t)so;
626
627         SOCKBUF_LOCK(sb);
628         knlist_add(&sb->sb_sel.si_note, kn, 1);
629         sb->sb_flags |= SB_KNOTE;
630         SOCKBUF_UNLOCK(sb);
631
632         return (0);
633 }
634
635 static int
636 fifo_poll_f(struct file *fp, int events, struct ucred *cred, struct thread *td)
637 {
638         struct fifoinfo *fip;
639         struct file filetmp;
640         int levents, revents = 0;
641
642         fip = fp->f_data;
643         levents = events &
644             (POLLIN | POLLINIGNEOF | POLLPRI | POLLRDNORM | POLLRDBAND);
645         if ((fp->f_flag & FREAD) && levents) {
646                 filetmp.f_data = fip->fi_readsock;
647                 filetmp.f_cred = cred;
648                 mtx_lock(&fifo_mtx);
649                 if (fp->f_seqcount == fip->fi_wgen)
650                         levents |= POLLINIGNEOF;
651                 mtx_unlock(&fifo_mtx);
652                 revents |= soo_poll(&filetmp, levents, cred, td);
653         }
654         levents = events & (POLLOUT | POLLWRNORM | POLLWRBAND);
655         if ((fp->f_flag & FWRITE) && levents) {
656                 filetmp.f_data = fip->fi_writesock;
657                 filetmp.f_cred = cred;
658                 revents |= soo_poll(&filetmp, levents, cred, td);
659         }
660         return (revents);
661 }
662
663 static int
664 fifo_read_f(struct file *fp, struct uio *uio, struct ucred *cred, int flags, struct thread *td)
665 {
666         struct fifoinfo *fip;
667         int sflags;
668
669         fip = fp->f_data;
670         KASSERT(uio->uio_rw == UIO_READ,("fifo_read mode"));
671         if (uio->uio_resid == 0)
672                 return (0);
673         sflags = (fp->f_flag & FNONBLOCK) ? MSG_NBIO : 0;
674         return (soreceive(fip->fi_readsock, NULL, uio, NULL, NULL, &sflags));
675 }
676
677 static int
678 fifo_stat_f(struct file *fp, struct stat *sb, struct ucred *cred, struct thread *td)
679 {
680
681         return (vnops.fo_stat(fp, sb, cred, td));
682 }
683
684 static int
685 fifo_truncate_f(struct file *fp, off_t length, struct ucred *cred, struct thread *td)
686 {
687
688         return (vnops.fo_truncate(fp, length, cred, td));
689 }
690
691 static int
692 fifo_write_f(struct file *fp, struct uio *uio, struct ucred *cred, int flags, struct thread *td)
693 {
694         struct fifoinfo *fip;
695         int sflags;
696
697         fip = fp->f_data;
698         KASSERT(uio->uio_rw == UIO_WRITE,("fifo_write mode"));
699         sflags = (fp->f_flag & FNONBLOCK) ? MSG_NBIO : 0;
700         return (sosend(fip->fi_writesock, NULL, uio, 0, NULL, sflags, td));
701 }