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 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)fifo_vnops.c 8.10 (Berkeley) 5/27/95
| 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 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)fifo_vnops.c 8.10 (Berkeley) 5/27/95
|
34 * $FreeBSD: head/sys/fs/fifofs/fifo_vnops.c 87725 2001-12-12 09:35:33Z alfred $
| 34 * $FreeBSD: head/sys/fs/fifofs/fifo_vnops.c 88739 2001-12-31 17:45:16Z rwatson $
|
35 */ 36 37#include <sys/param.h> 38#include <sys/systm.h> 39#include <sys/unistd.h> 40#include <sys/kernel.h> 41#include <sys/lock.h> 42#include <sys/malloc.h> 43#include <sys/vnode.h> 44#include <sys/proc.h> /* XXXKSE */ 45#include <sys/socket.h> 46#include <sys/socketvar.h> 47#include <sys/filio.h> 48#include <sys/fcntl.h> 49#include <sys/file.h> 50#include <sys/event.h> 51#include <sys/poll.h> 52#include <sys/un.h> 53#include <fs/fifofs/fifo.h> 54 55/* 56 * This structure is associated with the FIFO vnode and stores 57 * the state associated with the FIFO. 58 */ 59struct fifoinfo { 60 struct socket *fi_readsock; 61 struct socket *fi_writesock; 62 long fi_readers; 63 long fi_writers; 64}; 65 66static int fifo_badop __P((void)); 67static int fifo_print __P((struct vop_print_args *)); 68static int fifo_lookup __P((struct vop_lookup_args *)); 69static int fifo_open __P((struct vop_open_args *)); 70static int fifo_close __P((struct vop_close_args *)); 71static int fifo_read __P((struct vop_read_args *)); 72static int fifo_write __P((struct vop_write_args *)); 73static int fifo_ioctl __P((struct vop_ioctl_args *)); 74static int fifo_poll __P((struct vop_poll_args *)); 75static int fifo_kqfilter __P((struct vop_kqfilter_args *)); 76static int fifo_pathconf __P((struct vop_pathconf_args *)); 77static int fifo_advlock __P((struct vop_advlock_args *)); 78 79static void filt_fifordetach(struct knote *kn); 80static int filt_fiforead(struct knote *kn, long hint); 81static void filt_fifowdetach(struct knote *kn); 82static int filt_fifowrite(struct knote *kn, long hint); 83 84static struct filterops fiforead_filtops = 85 { 1, NULL, filt_fifordetach, filt_fiforead }; 86static struct filterops fifowrite_filtops = 87 { 1, NULL, filt_fifowdetach, filt_fifowrite }; 88 89vop_t **fifo_vnodeop_p; 90static struct vnodeopv_entry_desc fifo_vnodeop_entries[] = { 91 { &vop_default_desc, (vop_t *) vop_defaultop }, 92 { &vop_access_desc, (vop_t *) vop_ebadf }, 93 { &vop_advlock_desc, (vop_t *) fifo_advlock }, 94 { &vop_close_desc, (vop_t *) fifo_close }, 95 { &vop_create_desc, (vop_t *) fifo_badop }, 96 { &vop_getattr_desc, (vop_t *) vop_ebadf }, 97 { &vop_getwritemount_desc, (vop_t *) vop_stdgetwritemount }, 98 { &vop_ioctl_desc, (vop_t *) fifo_ioctl }, 99 { &vop_kqfilter_desc, (vop_t *) fifo_kqfilter }, 100 { &vop_lease_desc, (vop_t *) vop_null }, 101 { &vop_link_desc, (vop_t *) fifo_badop }, 102 { &vop_lookup_desc, (vop_t *) fifo_lookup }, 103 { &vop_mkdir_desc, (vop_t *) fifo_badop }, 104 { &vop_mknod_desc, (vop_t *) fifo_badop }, 105 { &vop_open_desc, (vop_t *) fifo_open }, 106 { &vop_pathconf_desc, (vop_t *) fifo_pathconf }, 107 { &vop_poll_desc, (vop_t *) fifo_poll }, 108 { &vop_print_desc, (vop_t *) fifo_print }, 109 { &vop_read_desc, (vop_t *) fifo_read }, 110 { &vop_readdir_desc, (vop_t *) fifo_badop }, 111 { &vop_readlink_desc, (vop_t *) fifo_badop }, 112 { &vop_reallocblks_desc, (vop_t *) fifo_badop }, 113 { &vop_reclaim_desc, (vop_t *) vop_null }, 114 { &vop_remove_desc, (vop_t *) fifo_badop }, 115 { &vop_rename_desc, (vop_t *) fifo_badop }, 116 { &vop_rmdir_desc, (vop_t *) fifo_badop }, 117 { &vop_setattr_desc, (vop_t *) vop_ebadf }, 118 { &vop_symlink_desc, (vop_t *) fifo_badop }, 119 { &vop_write_desc, (vop_t *) fifo_write }, 120 { NULL, NULL } 121}; 122static struct vnodeopv_desc fifo_vnodeop_opv_desc = 123 { &fifo_vnodeop_p, fifo_vnodeop_entries }; 124 125VNODEOP_SET(fifo_vnodeop_opv_desc); 126 127int 128fifo_vnoperate(ap) 129 struct vop_generic_args /* { 130 struct vnodeop_desc *a_desc; 131 <other random data follows, presumably> 132 } */ *ap; 133{ 134 return (VOCALL(fifo_vnodeop_p, ap->a_desc->vdesc_offset, ap)); 135} 136 137/* 138 * Trivial lookup routine that always fails. 139 */ 140/* ARGSUSED */ 141static int 142fifo_lookup(ap) 143 struct vop_lookup_args /* { 144 struct vnode * a_dvp; 145 struct vnode ** a_vpp; 146 struct componentname * a_cnp; 147 } */ *ap; 148{ 149 150 *ap->a_vpp = NULL; 151 return (ENOTDIR); 152} 153 154/* 155 * Open called to set up a new instance of a fifo or 156 * to find an active instance of a fifo. 157 */ 158/* ARGSUSED */ 159static int 160fifo_open(ap) 161 struct vop_open_args /* { 162 struct vnode *a_vp; 163 int a_mode; 164 struct ucred *a_cred; 165 struct thread *a_td; 166 } */ *ap; 167{ 168 struct vnode *vp = ap->a_vp; 169 struct fifoinfo *fip; 170 struct thread *td = ap->a_td; 171 struct socket *rso, *wso; 172 int error; 173 174 if ((fip = vp->v_fifoinfo) == NULL) { 175 MALLOC(fip, struct fifoinfo *, sizeof(*fip), M_VNODE, M_WAITOK); 176 vp->v_fifoinfo = fip;
| 35 */ 36 37#include <sys/param.h> 38#include <sys/systm.h> 39#include <sys/unistd.h> 40#include <sys/kernel.h> 41#include <sys/lock.h> 42#include <sys/malloc.h> 43#include <sys/vnode.h> 44#include <sys/proc.h> /* XXXKSE */ 45#include <sys/socket.h> 46#include <sys/socketvar.h> 47#include <sys/filio.h> 48#include <sys/fcntl.h> 49#include <sys/file.h> 50#include <sys/event.h> 51#include <sys/poll.h> 52#include <sys/un.h> 53#include <fs/fifofs/fifo.h> 54 55/* 56 * This structure is associated with the FIFO vnode and stores 57 * the state associated with the FIFO. 58 */ 59struct fifoinfo { 60 struct socket *fi_readsock; 61 struct socket *fi_writesock; 62 long fi_readers; 63 long fi_writers; 64}; 65 66static int fifo_badop __P((void)); 67static int fifo_print __P((struct vop_print_args *)); 68static int fifo_lookup __P((struct vop_lookup_args *)); 69static int fifo_open __P((struct vop_open_args *)); 70static int fifo_close __P((struct vop_close_args *)); 71static int fifo_read __P((struct vop_read_args *)); 72static int fifo_write __P((struct vop_write_args *)); 73static int fifo_ioctl __P((struct vop_ioctl_args *)); 74static int fifo_poll __P((struct vop_poll_args *)); 75static int fifo_kqfilter __P((struct vop_kqfilter_args *)); 76static int fifo_pathconf __P((struct vop_pathconf_args *)); 77static int fifo_advlock __P((struct vop_advlock_args *)); 78 79static void filt_fifordetach(struct knote *kn); 80static int filt_fiforead(struct knote *kn, long hint); 81static void filt_fifowdetach(struct knote *kn); 82static int filt_fifowrite(struct knote *kn, long hint); 83 84static struct filterops fiforead_filtops = 85 { 1, NULL, filt_fifordetach, filt_fiforead }; 86static struct filterops fifowrite_filtops = 87 { 1, NULL, filt_fifowdetach, filt_fifowrite }; 88 89vop_t **fifo_vnodeop_p; 90static struct vnodeopv_entry_desc fifo_vnodeop_entries[] = { 91 { &vop_default_desc, (vop_t *) vop_defaultop }, 92 { &vop_access_desc, (vop_t *) vop_ebadf }, 93 { &vop_advlock_desc, (vop_t *) fifo_advlock }, 94 { &vop_close_desc, (vop_t *) fifo_close }, 95 { &vop_create_desc, (vop_t *) fifo_badop }, 96 { &vop_getattr_desc, (vop_t *) vop_ebadf }, 97 { &vop_getwritemount_desc, (vop_t *) vop_stdgetwritemount }, 98 { &vop_ioctl_desc, (vop_t *) fifo_ioctl }, 99 { &vop_kqfilter_desc, (vop_t *) fifo_kqfilter }, 100 { &vop_lease_desc, (vop_t *) vop_null }, 101 { &vop_link_desc, (vop_t *) fifo_badop }, 102 { &vop_lookup_desc, (vop_t *) fifo_lookup }, 103 { &vop_mkdir_desc, (vop_t *) fifo_badop }, 104 { &vop_mknod_desc, (vop_t *) fifo_badop }, 105 { &vop_open_desc, (vop_t *) fifo_open }, 106 { &vop_pathconf_desc, (vop_t *) fifo_pathconf }, 107 { &vop_poll_desc, (vop_t *) fifo_poll }, 108 { &vop_print_desc, (vop_t *) fifo_print }, 109 { &vop_read_desc, (vop_t *) fifo_read }, 110 { &vop_readdir_desc, (vop_t *) fifo_badop }, 111 { &vop_readlink_desc, (vop_t *) fifo_badop }, 112 { &vop_reallocblks_desc, (vop_t *) fifo_badop }, 113 { &vop_reclaim_desc, (vop_t *) vop_null }, 114 { &vop_remove_desc, (vop_t *) fifo_badop }, 115 { &vop_rename_desc, (vop_t *) fifo_badop }, 116 { &vop_rmdir_desc, (vop_t *) fifo_badop }, 117 { &vop_setattr_desc, (vop_t *) vop_ebadf }, 118 { &vop_symlink_desc, (vop_t *) fifo_badop }, 119 { &vop_write_desc, (vop_t *) fifo_write }, 120 { NULL, NULL } 121}; 122static struct vnodeopv_desc fifo_vnodeop_opv_desc = 123 { &fifo_vnodeop_p, fifo_vnodeop_entries }; 124 125VNODEOP_SET(fifo_vnodeop_opv_desc); 126 127int 128fifo_vnoperate(ap) 129 struct vop_generic_args /* { 130 struct vnodeop_desc *a_desc; 131 <other random data follows, presumably> 132 } */ *ap; 133{ 134 return (VOCALL(fifo_vnodeop_p, ap->a_desc->vdesc_offset, ap)); 135} 136 137/* 138 * Trivial lookup routine that always fails. 139 */ 140/* ARGSUSED */ 141static int 142fifo_lookup(ap) 143 struct vop_lookup_args /* { 144 struct vnode * a_dvp; 145 struct vnode ** a_vpp; 146 struct componentname * a_cnp; 147 } */ *ap; 148{ 149 150 *ap->a_vpp = NULL; 151 return (ENOTDIR); 152} 153 154/* 155 * Open called to set up a new instance of a fifo or 156 * to find an active instance of a fifo. 157 */ 158/* ARGSUSED */ 159static int 160fifo_open(ap) 161 struct vop_open_args /* { 162 struct vnode *a_vp; 163 int a_mode; 164 struct ucred *a_cred; 165 struct thread *a_td; 166 } */ *ap; 167{ 168 struct vnode *vp = ap->a_vp; 169 struct fifoinfo *fip; 170 struct thread *td = ap->a_td; 171 struct socket *rso, *wso; 172 int error; 173 174 if ((fip = vp->v_fifoinfo) == NULL) { 175 MALLOC(fip, struct fifoinfo *, sizeof(*fip), M_VNODE, M_WAITOK); 176 vp->v_fifoinfo = fip;
|
177 error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, ap->a_td);
| 177 error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, 178 ap->a_td->td_proc->p_ucred, ap->a_td);
|
178 if (error) { 179 free(fip, M_VNODE); 180 vp->v_fifoinfo = NULL; 181 return (error); 182 } 183 fip->fi_readsock = rso;
| 179 if (error) { 180 free(fip, M_VNODE); 181 vp->v_fifoinfo = NULL; 182 return (error); 183 } 184 fip->fi_readsock = rso;
|
184 error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0, ap->a_td);
| 185 error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0, 186 ap->a_td->td_proc->p_ucred, ap->a_td);
|
185 if (error) { 186 (void)soclose(rso); 187 free(fip, M_VNODE); 188 vp->v_fifoinfo = NULL; 189 return (error); 190 } 191 fip->fi_writesock = wso; 192 error = unp_connect2(wso, rso); 193 if (error) { 194 (void)soclose(wso); 195 (void)soclose(rso); 196 free(fip, M_VNODE); 197 vp->v_fifoinfo = NULL; 198 return (error); 199 } 200 fip->fi_readers = fip->fi_writers = 0; 201 wso->so_snd.sb_lowat = PIPE_BUF; 202 } 203 if (ap->a_mode & FREAD) { 204 fip->fi_readers++; 205 if (fip->fi_readers == 1) { 206 fip->fi_writesock->so_state &= ~SS_CANTSENDMORE; 207 if (fip->fi_writers > 0) { 208 wakeup((caddr_t)&fip->fi_writers); 209 sowwakeup(fip->fi_writesock); 210 } 211 } 212 } 213 if (ap->a_mode & FWRITE) { 214 fip->fi_writers++; 215 if (fip->fi_writers == 1) { 216 fip->fi_readsock->so_state &= ~SS_CANTRCVMORE; 217 if (fip->fi_readers > 0) { 218 wakeup((caddr_t)&fip->fi_readers); 219 sorwakeup(fip->fi_writesock); 220 } 221 } 222 } 223 if ((ap->a_mode & FREAD) && (ap->a_mode & O_NONBLOCK) == 0) { 224 while (fip->fi_writers == 0) { 225 VOP_UNLOCK(vp, 0, td); 226 error = tsleep((caddr_t)&fip->fi_readers, 227 PCATCH | PSOCK, "fifoor", 0); 228 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 229 if (error) 230 goto bad; 231 } 232 } 233 if (ap->a_mode & FWRITE) { 234 if (ap->a_mode & O_NONBLOCK) { 235 if (fip->fi_readers == 0) { 236 error = ENXIO; 237 goto bad; 238 } 239 } else { 240 while (fip->fi_readers == 0) { 241 VOP_UNLOCK(vp, 0, td); 242 error = tsleep((caddr_t)&fip->fi_writers, 243 PCATCH | PSOCK, "fifoow", 0); 244 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 245 if (error) 246 goto bad; 247 } 248 } 249 } 250 return (0); 251bad: 252 VOP_CLOSE(vp, ap->a_mode, ap->a_cred, td); 253 return (error); 254} 255 256/* 257 * Vnode op for read 258 */ 259/* ARGSUSED */ 260static int 261fifo_read(ap) 262 struct vop_read_args /* { 263 struct vnode *a_vp; 264 struct uio *a_uio; 265 int a_ioflag; 266 struct ucred *a_cred; 267 } */ *ap; 268{ 269 struct uio *uio = ap->a_uio; 270 struct socket *rso = ap->a_vp->v_fifoinfo->fi_readsock; 271 struct thread *td = uio->uio_td; 272 int error, startresid; 273 274#ifdef DIAGNOSTIC 275 if (uio->uio_rw != UIO_READ) 276 panic("fifo_read mode"); 277#endif 278 if (uio->uio_resid == 0) 279 return (0); 280 if (ap->a_ioflag & IO_NDELAY) 281 rso->so_state |= SS_NBIO; 282 startresid = uio->uio_resid; 283 VOP_UNLOCK(ap->a_vp, 0, td); 284 error = soreceive(rso, (struct sockaddr **)0, uio, (struct mbuf **)0, 285 (struct mbuf **)0, (int *)0); 286 /* 287 * Clear EOF indication after first such return. 288 */ 289 if (uio->uio_resid == startresid) 290 rso->so_state &= ~SS_CANTRCVMORE; 291 vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, td); 292 if (ap->a_ioflag & IO_NDELAY) 293 rso->so_state &= ~SS_NBIO; 294 return (error); 295} 296 297/* 298 * Vnode op for write 299 */ 300/* ARGSUSED */ 301static int 302fifo_write(ap) 303 struct vop_write_args /* { 304 struct vnode *a_vp; 305 struct uio *a_uio; 306 int a_ioflag; 307 struct ucred *a_cred; 308 } */ *ap; 309{ 310 struct socket *wso = ap->a_vp->v_fifoinfo->fi_writesock; 311 struct thread *td = ap->a_uio->uio_td; 312 int error; 313 314#ifdef DIAGNOSTIC 315 if (ap->a_uio->uio_rw != UIO_WRITE) 316 panic("fifo_write mode"); 317#endif 318 if (ap->a_ioflag & IO_NDELAY) 319 wso->so_state |= SS_NBIO; 320 VOP_UNLOCK(ap->a_vp, 0, td); 321 error = sosend(wso, (struct sockaddr *)0, ap->a_uio, 0, 322 (struct mbuf *)0, 0, td); 323 vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, td); 324 if (ap->a_ioflag & IO_NDELAY) 325 wso->so_state &= ~SS_NBIO; 326 return (error); 327} 328 329/* 330 * Device ioctl operation. 331 */ 332/* ARGSUSED */ 333static int 334fifo_ioctl(ap) 335 struct vop_ioctl_args /* { 336 struct vnode *a_vp; 337 int a_command; 338 caddr_t a_data; 339 int a_fflag; 340 struct ucred *a_cred; 341 struct thread *a_td; 342 } */ *ap; 343{ 344 struct file filetmp; 345 int error; 346 347 if (ap->a_command == FIONBIO) 348 return (0); 349 if (ap->a_fflag & FREAD) { 350 filetmp.f_data = (caddr_t)ap->a_vp->v_fifoinfo->fi_readsock; 351 error = soo_ioctl(&filetmp, ap->a_command, ap->a_data, ap->a_td); 352 if (error) 353 return (error); 354 } 355 if (ap->a_fflag & FWRITE) { 356 filetmp.f_data = (caddr_t)ap->a_vp->v_fifoinfo->fi_writesock; 357 error = soo_ioctl(&filetmp, ap->a_command, ap->a_data, ap->a_td); 358 if (error) 359 return (error); 360 } 361 return (0); 362} 363 364/* ARGSUSED */ 365static int 366fifo_kqfilter(ap) 367 struct vop_kqfilter_args /* { 368 struct vnode *a_vp; 369 struct knote *a_kn; 370 } */ *ap; 371{ 372 struct fifoinfo *fi = ap->a_vp->v_fifoinfo; 373 struct socket *so; 374 struct sockbuf *sb; 375 376 switch (ap->a_kn->kn_filter) { 377 case EVFILT_READ: 378 ap->a_kn->kn_fop = &fiforead_filtops; 379 so = fi->fi_readsock; 380 sb = &so->so_rcv; 381 break; 382 case EVFILT_WRITE: 383 ap->a_kn->kn_fop = &fifowrite_filtops; 384 so = fi->fi_writesock; 385 sb = &so->so_snd; 386 break; 387 default: 388 return (1); 389 } 390 391 ap->a_kn->kn_hook = (caddr_t)so; 392 393 SLIST_INSERT_HEAD(&sb->sb_sel.si_note, ap->a_kn, kn_selnext); 394 sb->sb_flags |= SB_KNOTE; 395 396 return (0); 397} 398 399static void 400filt_fifordetach(struct knote *kn) 401{ 402 struct socket *so = (struct socket *)kn->kn_hook; 403 404 SLIST_REMOVE(&so->so_rcv.sb_sel.si_note, kn, knote, kn_selnext); 405 if (SLIST_EMPTY(&so->so_rcv.sb_sel.si_note)) 406 so->so_rcv.sb_flags &= ~SB_KNOTE; 407} 408 409static int 410filt_fiforead(struct knote *kn, long hint) 411{ 412 struct socket *so = (struct socket *)kn->kn_hook; 413 414 kn->kn_data = so->so_rcv.sb_cc; 415 if (so->so_state & SS_CANTRCVMORE) { 416 kn->kn_flags |= EV_EOF; 417 return (1); 418 } 419 kn->kn_flags &= ~EV_EOF; 420 return (kn->kn_data > 0); 421} 422 423static void 424filt_fifowdetach(struct knote *kn) 425{ 426 struct socket *so = (struct socket *)kn->kn_hook; 427 428 SLIST_REMOVE(&so->so_snd.sb_sel.si_note, kn, knote, kn_selnext); 429 if (SLIST_EMPTY(&so->so_snd.sb_sel.si_note)) 430 so->so_snd.sb_flags &= ~SB_KNOTE; 431} 432 433static int 434filt_fifowrite(struct knote *kn, long hint) 435{ 436 struct socket *so = (struct socket *)kn->kn_hook; 437 438 kn->kn_data = sbspace(&so->so_snd); 439 if (so->so_state & SS_CANTSENDMORE) { 440 kn->kn_flags |= EV_EOF; 441 return (1); 442 } 443 kn->kn_flags &= ~EV_EOF; 444 return (kn->kn_data >= so->so_snd.sb_lowat); 445} 446 447/* ARGSUSED */ 448static int 449fifo_poll(ap) 450 struct vop_poll_args /* { 451 struct vnode *a_vp; 452 int a_events; 453 struct ucred *a_cred; 454 struct thread *a_td; 455 } */ *ap; 456{ 457 struct file filetmp; 458 int revents = 0; 459 460 if (ap->a_events & (POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND)) { 461 filetmp.f_data = (caddr_t)ap->a_vp->v_fifoinfo->fi_readsock; 462 if (filetmp.f_data) 463 revents |= soo_poll(&filetmp, ap->a_events, ap->a_cred, 464 ap->a_td); 465 } 466 if (ap->a_events & (POLLOUT | POLLWRNORM | POLLWRBAND)) { 467 filetmp.f_data = (caddr_t)ap->a_vp->v_fifoinfo->fi_writesock; 468 if (filetmp.f_data) 469 revents |= soo_poll(&filetmp, ap->a_events, ap->a_cred, 470 ap->a_td); 471 } 472 return (revents); 473} 474 475/* 476 * Device close routine 477 */ 478/* ARGSUSED */ 479static int 480fifo_close(ap) 481 struct vop_close_args /* { 482 struct vnode *a_vp; 483 int a_fflag; 484 struct ucred *a_cred; 485 struct thread *a_td; 486 } */ *ap; 487{ 488 register struct vnode *vp = ap->a_vp; 489 register struct fifoinfo *fip = vp->v_fifoinfo; 490 int error1, error2; 491 492 if (ap->a_fflag & FREAD) { 493 fip->fi_readers--; 494 if (fip->fi_readers == 0) 495 socantsendmore(fip->fi_writesock); 496 } 497 if (ap->a_fflag & FWRITE) { 498 fip->fi_writers--; 499 if (fip->fi_writers == 0) 500 socantrcvmore(fip->fi_readsock); 501 } 502 if (vp->v_usecount > 1) 503 return (0); 504 error1 = soclose(fip->fi_readsock); 505 error2 = soclose(fip->fi_writesock); 506 FREE(fip, M_VNODE); 507 vp->v_fifoinfo = NULL; 508 if (error1) 509 return (error1); 510 return (error2); 511} 512 513 514/* 515 * Print out internal contents of a fifo vnode. 516 */ 517int 518fifo_printinfo(vp) 519 struct vnode *vp; 520{ 521 register struct fifoinfo *fip = vp->v_fifoinfo; 522 523 printf(", fifo with %ld readers and %ld writers", 524 fip->fi_readers, fip->fi_writers); 525 return (0); 526} 527 528/* 529 * Print out the contents of a fifo vnode. 530 */ 531static int 532fifo_print(ap) 533 struct vop_print_args /* { 534 struct vnode *a_vp; 535 } */ *ap; 536{ 537 538 printf("tag VT_NON"); 539 fifo_printinfo(ap->a_vp); 540 printf("\n"); 541 return (0); 542} 543 544/* 545 * Return POSIX pathconf information applicable to fifo's. 546 */ 547int 548fifo_pathconf(ap) 549 struct vop_pathconf_args /* { 550 struct vnode *a_vp; 551 int a_name; 552 int *a_retval; 553 } */ *ap; 554{ 555 556 switch (ap->a_name) { 557 case _PC_LINK_MAX: 558 *ap->a_retval = LINK_MAX; 559 return (0); 560 case _PC_PIPE_BUF: 561 *ap->a_retval = PIPE_BUF; 562 return (0); 563 case _PC_CHOWN_RESTRICTED: 564 *ap->a_retval = 1; 565 return (0); 566 default: 567 return (EINVAL); 568 } 569 /* NOTREACHED */ 570} 571 572/* 573 * Fifo advisory byte-level locks. 574 */ 575/* ARGSUSED */ 576static int 577fifo_advlock(ap) 578 struct vop_advlock_args /* { 579 struct vnode *a_vp; 580 caddr_t a_id; 581 int a_op; 582 struct flock *a_fl; 583 int a_flags; 584 } */ *ap; 585{ 586 587 return (ap->a_flags & F_FLOCK ? EOPNOTSUPP : EINVAL); 588} 589 590/* 591 * Fifo bad operation 592 */ 593static int 594fifo_badop() 595{ 596 597 panic("fifo_badop called"); 598 /* NOTREACHED */ 599}
| 187 if (error) { 188 (void)soclose(rso); 189 free(fip, M_VNODE); 190 vp->v_fifoinfo = NULL; 191 return (error); 192 } 193 fip->fi_writesock = wso; 194 error = unp_connect2(wso, rso); 195 if (error) { 196 (void)soclose(wso); 197 (void)soclose(rso); 198 free(fip, M_VNODE); 199 vp->v_fifoinfo = NULL; 200 return (error); 201 } 202 fip->fi_readers = fip->fi_writers = 0; 203 wso->so_snd.sb_lowat = PIPE_BUF; 204 } 205 if (ap->a_mode & FREAD) { 206 fip->fi_readers++; 207 if (fip->fi_readers == 1) { 208 fip->fi_writesock->so_state &= ~SS_CANTSENDMORE; 209 if (fip->fi_writers > 0) { 210 wakeup((caddr_t)&fip->fi_writers); 211 sowwakeup(fip->fi_writesock); 212 } 213 } 214 } 215 if (ap->a_mode & FWRITE) { 216 fip->fi_writers++; 217 if (fip->fi_writers == 1) { 218 fip->fi_readsock->so_state &= ~SS_CANTRCVMORE; 219 if (fip->fi_readers > 0) { 220 wakeup((caddr_t)&fip->fi_readers); 221 sorwakeup(fip->fi_writesock); 222 } 223 } 224 } 225 if ((ap->a_mode & FREAD) && (ap->a_mode & O_NONBLOCK) == 0) { 226 while (fip->fi_writers == 0) { 227 VOP_UNLOCK(vp, 0, td); 228 error = tsleep((caddr_t)&fip->fi_readers, 229 PCATCH | PSOCK, "fifoor", 0); 230 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 231 if (error) 232 goto bad; 233 } 234 } 235 if (ap->a_mode & FWRITE) { 236 if (ap->a_mode & O_NONBLOCK) { 237 if (fip->fi_readers == 0) { 238 error = ENXIO; 239 goto bad; 240 } 241 } else { 242 while (fip->fi_readers == 0) { 243 VOP_UNLOCK(vp, 0, td); 244 error = tsleep((caddr_t)&fip->fi_writers, 245 PCATCH | PSOCK, "fifoow", 0); 246 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 247 if (error) 248 goto bad; 249 } 250 } 251 } 252 return (0); 253bad: 254 VOP_CLOSE(vp, ap->a_mode, ap->a_cred, td); 255 return (error); 256} 257 258/* 259 * Vnode op for read 260 */ 261/* ARGSUSED */ 262static int 263fifo_read(ap) 264 struct vop_read_args /* { 265 struct vnode *a_vp; 266 struct uio *a_uio; 267 int a_ioflag; 268 struct ucred *a_cred; 269 } */ *ap; 270{ 271 struct uio *uio = ap->a_uio; 272 struct socket *rso = ap->a_vp->v_fifoinfo->fi_readsock; 273 struct thread *td = uio->uio_td; 274 int error, startresid; 275 276#ifdef DIAGNOSTIC 277 if (uio->uio_rw != UIO_READ) 278 panic("fifo_read mode"); 279#endif 280 if (uio->uio_resid == 0) 281 return (0); 282 if (ap->a_ioflag & IO_NDELAY) 283 rso->so_state |= SS_NBIO; 284 startresid = uio->uio_resid; 285 VOP_UNLOCK(ap->a_vp, 0, td); 286 error = soreceive(rso, (struct sockaddr **)0, uio, (struct mbuf **)0, 287 (struct mbuf **)0, (int *)0); 288 /* 289 * Clear EOF indication after first such return. 290 */ 291 if (uio->uio_resid == startresid) 292 rso->so_state &= ~SS_CANTRCVMORE; 293 vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, td); 294 if (ap->a_ioflag & IO_NDELAY) 295 rso->so_state &= ~SS_NBIO; 296 return (error); 297} 298 299/* 300 * Vnode op for write 301 */ 302/* ARGSUSED */ 303static int 304fifo_write(ap) 305 struct vop_write_args /* { 306 struct vnode *a_vp; 307 struct uio *a_uio; 308 int a_ioflag; 309 struct ucred *a_cred; 310 } */ *ap; 311{ 312 struct socket *wso = ap->a_vp->v_fifoinfo->fi_writesock; 313 struct thread *td = ap->a_uio->uio_td; 314 int error; 315 316#ifdef DIAGNOSTIC 317 if (ap->a_uio->uio_rw != UIO_WRITE) 318 panic("fifo_write mode"); 319#endif 320 if (ap->a_ioflag & IO_NDELAY) 321 wso->so_state |= SS_NBIO; 322 VOP_UNLOCK(ap->a_vp, 0, td); 323 error = sosend(wso, (struct sockaddr *)0, ap->a_uio, 0, 324 (struct mbuf *)0, 0, td); 325 vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, td); 326 if (ap->a_ioflag & IO_NDELAY) 327 wso->so_state &= ~SS_NBIO; 328 return (error); 329} 330 331/* 332 * Device ioctl operation. 333 */ 334/* ARGSUSED */ 335static int 336fifo_ioctl(ap) 337 struct vop_ioctl_args /* { 338 struct vnode *a_vp; 339 int a_command; 340 caddr_t a_data; 341 int a_fflag; 342 struct ucred *a_cred; 343 struct thread *a_td; 344 } */ *ap; 345{ 346 struct file filetmp; 347 int error; 348 349 if (ap->a_command == FIONBIO) 350 return (0); 351 if (ap->a_fflag & FREAD) { 352 filetmp.f_data = (caddr_t)ap->a_vp->v_fifoinfo->fi_readsock; 353 error = soo_ioctl(&filetmp, ap->a_command, ap->a_data, ap->a_td); 354 if (error) 355 return (error); 356 } 357 if (ap->a_fflag & FWRITE) { 358 filetmp.f_data = (caddr_t)ap->a_vp->v_fifoinfo->fi_writesock; 359 error = soo_ioctl(&filetmp, ap->a_command, ap->a_data, ap->a_td); 360 if (error) 361 return (error); 362 } 363 return (0); 364} 365 366/* ARGSUSED */ 367static int 368fifo_kqfilter(ap) 369 struct vop_kqfilter_args /* { 370 struct vnode *a_vp; 371 struct knote *a_kn; 372 } */ *ap; 373{ 374 struct fifoinfo *fi = ap->a_vp->v_fifoinfo; 375 struct socket *so; 376 struct sockbuf *sb; 377 378 switch (ap->a_kn->kn_filter) { 379 case EVFILT_READ: 380 ap->a_kn->kn_fop = &fiforead_filtops; 381 so = fi->fi_readsock; 382 sb = &so->so_rcv; 383 break; 384 case EVFILT_WRITE: 385 ap->a_kn->kn_fop = &fifowrite_filtops; 386 so = fi->fi_writesock; 387 sb = &so->so_snd; 388 break; 389 default: 390 return (1); 391 } 392 393 ap->a_kn->kn_hook = (caddr_t)so; 394 395 SLIST_INSERT_HEAD(&sb->sb_sel.si_note, ap->a_kn, kn_selnext); 396 sb->sb_flags |= SB_KNOTE; 397 398 return (0); 399} 400 401static void 402filt_fifordetach(struct knote *kn) 403{ 404 struct socket *so = (struct socket *)kn->kn_hook; 405 406 SLIST_REMOVE(&so->so_rcv.sb_sel.si_note, kn, knote, kn_selnext); 407 if (SLIST_EMPTY(&so->so_rcv.sb_sel.si_note)) 408 so->so_rcv.sb_flags &= ~SB_KNOTE; 409} 410 411static int 412filt_fiforead(struct knote *kn, long hint) 413{ 414 struct socket *so = (struct socket *)kn->kn_hook; 415 416 kn->kn_data = so->so_rcv.sb_cc; 417 if (so->so_state & SS_CANTRCVMORE) { 418 kn->kn_flags |= EV_EOF; 419 return (1); 420 } 421 kn->kn_flags &= ~EV_EOF; 422 return (kn->kn_data > 0); 423} 424 425static void 426filt_fifowdetach(struct knote *kn) 427{ 428 struct socket *so = (struct socket *)kn->kn_hook; 429 430 SLIST_REMOVE(&so->so_snd.sb_sel.si_note, kn, knote, kn_selnext); 431 if (SLIST_EMPTY(&so->so_snd.sb_sel.si_note)) 432 so->so_snd.sb_flags &= ~SB_KNOTE; 433} 434 435static int 436filt_fifowrite(struct knote *kn, long hint) 437{ 438 struct socket *so = (struct socket *)kn->kn_hook; 439 440 kn->kn_data = sbspace(&so->so_snd); 441 if (so->so_state & SS_CANTSENDMORE) { 442 kn->kn_flags |= EV_EOF; 443 return (1); 444 } 445 kn->kn_flags &= ~EV_EOF; 446 return (kn->kn_data >= so->so_snd.sb_lowat); 447} 448 449/* ARGSUSED */ 450static int 451fifo_poll(ap) 452 struct vop_poll_args /* { 453 struct vnode *a_vp; 454 int a_events; 455 struct ucred *a_cred; 456 struct thread *a_td; 457 } */ *ap; 458{ 459 struct file filetmp; 460 int revents = 0; 461 462 if (ap->a_events & (POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND)) { 463 filetmp.f_data = (caddr_t)ap->a_vp->v_fifoinfo->fi_readsock; 464 if (filetmp.f_data) 465 revents |= soo_poll(&filetmp, ap->a_events, ap->a_cred, 466 ap->a_td); 467 } 468 if (ap->a_events & (POLLOUT | POLLWRNORM | POLLWRBAND)) { 469 filetmp.f_data = (caddr_t)ap->a_vp->v_fifoinfo->fi_writesock; 470 if (filetmp.f_data) 471 revents |= soo_poll(&filetmp, ap->a_events, ap->a_cred, 472 ap->a_td); 473 } 474 return (revents); 475} 476 477/* 478 * Device close routine 479 */ 480/* ARGSUSED */ 481static int 482fifo_close(ap) 483 struct vop_close_args /* { 484 struct vnode *a_vp; 485 int a_fflag; 486 struct ucred *a_cred; 487 struct thread *a_td; 488 } */ *ap; 489{ 490 register struct vnode *vp = ap->a_vp; 491 register struct fifoinfo *fip = vp->v_fifoinfo; 492 int error1, error2; 493 494 if (ap->a_fflag & FREAD) { 495 fip->fi_readers--; 496 if (fip->fi_readers == 0) 497 socantsendmore(fip->fi_writesock); 498 } 499 if (ap->a_fflag & FWRITE) { 500 fip->fi_writers--; 501 if (fip->fi_writers == 0) 502 socantrcvmore(fip->fi_readsock); 503 } 504 if (vp->v_usecount > 1) 505 return (0); 506 error1 = soclose(fip->fi_readsock); 507 error2 = soclose(fip->fi_writesock); 508 FREE(fip, M_VNODE); 509 vp->v_fifoinfo = NULL; 510 if (error1) 511 return (error1); 512 return (error2); 513} 514 515 516/* 517 * Print out internal contents of a fifo vnode. 518 */ 519int 520fifo_printinfo(vp) 521 struct vnode *vp; 522{ 523 register struct fifoinfo *fip = vp->v_fifoinfo; 524 525 printf(", fifo with %ld readers and %ld writers", 526 fip->fi_readers, fip->fi_writers); 527 return (0); 528} 529 530/* 531 * Print out the contents of a fifo vnode. 532 */ 533static int 534fifo_print(ap) 535 struct vop_print_args /* { 536 struct vnode *a_vp; 537 } */ *ap; 538{ 539 540 printf("tag VT_NON"); 541 fifo_printinfo(ap->a_vp); 542 printf("\n"); 543 return (0); 544} 545 546/* 547 * Return POSIX pathconf information applicable to fifo's. 548 */ 549int 550fifo_pathconf(ap) 551 struct vop_pathconf_args /* { 552 struct vnode *a_vp; 553 int a_name; 554 int *a_retval; 555 } */ *ap; 556{ 557 558 switch (ap->a_name) { 559 case _PC_LINK_MAX: 560 *ap->a_retval = LINK_MAX; 561 return (0); 562 case _PC_PIPE_BUF: 563 *ap->a_retval = PIPE_BUF; 564 return (0); 565 case _PC_CHOWN_RESTRICTED: 566 *ap->a_retval = 1; 567 return (0); 568 default: 569 return (EINVAL); 570 } 571 /* NOTREACHED */ 572} 573 574/* 575 * Fifo advisory byte-level locks. 576 */ 577/* ARGSUSED */ 578static int 579fifo_advlock(ap) 580 struct vop_advlock_args /* { 581 struct vnode *a_vp; 582 caddr_t a_id; 583 int a_op; 584 struct flock *a_fl; 585 int a_flags; 586 } */ *ap; 587{ 588 589 return (ap->a_flags & F_FLOCK ? EOPNOTSUPP : EINVAL); 590} 591 592/* 593 * Fifo bad operation 594 */ 595static int 596fifo_badop() 597{ 598 599 panic("fifo_badop called"); 600 /* NOTREACHED */ 601}
|