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