xref: /freebsd/sys/fs/fifofs/fifo_vnops.c (revision 830940567b49bb0c08dfaed40418999e76616909)
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 }
702