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