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