2 * Copyright (c) 1990, 1993, 1995
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
33 * @(#)fifo_vnops.c 8.10 (Berkeley) 5/27/95
34 * $FreeBSD: src/sys/miscfs/fifofs/fifo_vnops.c,v 1.45.2.4 2003/04/22 10:11:24 bde Exp $
35 * $DragonFly: src/sys/vfs/fifofs/fifo_vnops.c,v 1.40 2007/08/13 17:31:56 dillon Exp $
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/unistd.h>
41 #include <sys/kernel.h>
43 #include <sys/malloc.h>
44 #include <sys/thread2.h>
45 #include <sys/vnode.h>
46 #include <sys/socket.h>
47 #include <sys/socketvar.h>
48 #include <sys/filio.h>
49 #include <sys/fcntl.h>
51 #include <sys/event.h>
55 #include <sys/thread2.h>
60 * This structure is associated with the FIFO vnode and stores
61 * the state associated with the FIFO.
64 struct socket
*fi_readsock
;
65 struct socket
*fi_writesock
;
70 static int fifo_badop (void);
71 static int fifo_print (struct vop_print_args
*);
72 static int fifo_lookup (struct vop_old_lookup_args
*);
73 static int fifo_open (struct vop_open_args
*);
74 static int fifo_close (struct vop_close_args
*);
75 static int fifo_read (struct vop_read_args
*);
76 static int fifo_write (struct vop_write_args
*);
77 static int fifo_ioctl (struct vop_ioctl_args
*);
78 static int fifo_poll (struct vop_poll_args
*);
79 static int fifo_kqfilter (struct vop_kqfilter_args
*);
80 static int fifo_inactive (struct vop_inactive_args
*);
81 static int fifo_bmap (struct vop_bmap_args
*);
82 static int fifo_pathconf (struct vop_pathconf_args
*);
83 static int fifo_advlock (struct vop_advlock_args
*);
85 static void filt_fifordetach(struct knote
*kn
);
86 static int filt_fiforead(struct knote
*kn
, long hint
);
87 static void filt_fifowdetach(struct knote
*kn
);
88 static int filt_fifowrite(struct knote
*kn
, long hint
);
90 static struct filterops fiforead_filtops
=
91 { 1, NULL
, filt_fifordetach
, filt_fiforead
};
92 static struct filterops fifowrite_filtops
=
93 { 1, NULL
, filt_fifowdetach
, filt_fifowrite
};
95 struct vop_ops fifo_vnode_vops
= {
96 .vop_default
= vop_defaultop
,
97 .vop_access
= (void *)vop_ebadf
,
98 .vop_advlock
= fifo_advlock
,
99 .vop_bmap
= fifo_bmap
,
100 .vop_close
= fifo_close
,
101 .vop_old_create
= (void *)fifo_badop
,
102 .vop_getattr
= (void *)vop_ebadf
,
103 .vop_inactive
= fifo_inactive
,
104 .vop_ioctl
= fifo_ioctl
,
105 .vop_kqfilter
= fifo_kqfilter
,
106 .vop_old_link
= (void *)fifo_badop
,
107 .vop_old_lookup
= fifo_lookup
,
108 .vop_old_mkdir
= (void *)fifo_badop
,
109 .vop_old_mknod
= (void *)fifo_badop
,
110 .vop_open
= fifo_open
,
111 .vop_pathconf
= fifo_pathconf
,
112 .vop_poll
= fifo_poll
,
113 .vop_print
= fifo_print
,
114 .vop_read
= fifo_read
,
115 .vop_readdir
= (void *)fifo_badop
,
116 .vop_readlink
= (void *)fifo_badop
,
117 .vop_reallocblks
= (void *)fifo_badop
,
118 .vop_reclaim
= (void *)vop_null
,
119 .vop_old_remove
= (void *)fifo_badop
,
120 .vop_old_rename
= (void *)fifo_badop
,
121 .vop_old_rmdir
= (void *)fifo_badop
,
122 .vop_setattr
= (void *)vop_ebadf
,
123 .vop_old_symlink
= (void *)fifo_badop
,
124 .vop_write
= fifo_write
127 VNODEOP_SET(fifo_vnode_vops
);
129 static MALLOC_DEFINE(M_FIFOINFO
, "Fifo info", "Fifo info entries");
135 fifo_vnoperate(struct vop_generic_args
*ap
)
137 return (VOCALL(&fifo_vnode_vops
, ap
));
141 * Trivial lookup routine that always fails.
143 * fifo_lookup(struct vnode *a_dvp, struct vnode **a_vpp,
144 * struct componentname *a_cnp)
148 fifo_lookup(struct vop_old_lookup_args
*ap
)
155 * Open called to set up a new instance of a fifo or
156 * to find an active instance of a fifo.
158 * fifo_open(struct vnode *a_vp, int a_mode, struct ucred *a_cred,
163 fifo_open(struct vop_open_args
*ap
)
165 struct thread
*td
= curthread
;
166 struct vnode
*vp
= ap
->a_vp
;
167 struct fifoinfo
*fip
;
168 struct socket
*rso
, *wso
;
171 if ((fip
= vp
->v_fifoinfo
) == NULL
) {
172 MALLOC(fip
, struct fifoinfo
*, sizeof(*fip
), M_FIFOINFO
, M_WAITOK
);
173 vp
->v_fifoinfo
= fip
;
174 error
= socreate(AF_LOCAL
, &rso
, SOCK_STREAM
, 0, td
);
176 kfree(fip
, M_FIFOINFO
);
177 vp
->v_fifoinfo
= NULL
;
180 fip
->fi_readsock
= rso
;
181 error
= socreate(AF_LOCAL
, &wso
, SOCK_STREAM
, 0, td
);
183 soclose(rso
, FNONBLOCK
);
184 kfree(fip
, M_FIFOINFO
);
185 vp
->v_fifoinfo
= NULL
;
188 fip
->fi_writesock
= wso
;
189 error
= unp_connect2(wso
, rso
);
191 soclose(wso
, FNONBLOCK
);
192 soclose(rso
, FNONBLOCK
);
193 kfree(fip
, M_FIFOINFO
);
194 vp
->v_fifoinfo
= NULL
;
197 fip
->fi_readers
= fip
->fi_writers
= 0;
198 wso
->so_snd
.ssb_lowat
= PIPE_BUF
;
199 rso
->so_state
|= SS_CANTRCVMORE
;
201 if (ap
->a_mode
& FREAD
) {
203 if (fip
->fi_readers
== 1) {
204 fip
->fi_writesock
->so_state
&= ~SS_CANTSENDMORE
;
205 if (fip
->fi_writers
> 0) {
206 wakeup((caddr_t
)&fip
->fi_writers
);
207 sowwakeup(fip
->fi_writesock
);
211 if (ap
->a_mode
& FWRITE
) {
213 if (fip
->fi_writers
== 1) {
214 fip
->fi_readsock
->so_state
&= ~SS_CANTRCVMORE
;
215 if (fip
->fi_readers
> 0) {
216 wakeup((caddr_t
)&fip
->fi_readers
);
217 sorwakeup(fip
->fi_writesock
);
221 if ((ap
->a_mode
& FREAD
) && (ap
->a_mode
& O_NONBLOCK
) == 0) {
222 if (fip
->fi_writers
== 0) {
224 error
= tsleep((caddr_t
)&fip
->fi_readers
,
225 PCATCH
, "fifoor", 0);
226 vn_lock(vp
, LK_EXCLUSIVE
| LK_RETRY
);
230 * We must have got woken up because we had a writer.
231 * That (and not still having one) is the condition
232 * that we must wait for.
236 if (ap
->a_mode
& FWRITE
) {
237 if (ap
->a_mode
& O_NONBLOCK
) {
238 if (fip
->fi_readers
== 0) {
243 if (fip
->fi_readers
== 0) {
245 error
= tsleep((caddr_t
)&fip
->fi_writers
,
246 PCATCH
, "fifoow", 0);
247 vn_lock(vp
, LK_EXCLUSIVE
| LK_RETRY
);
251 * We must have got woken up because we had
252 * a reader. That (and not still having one)
253 * is the condition that we must wait for.
258 return (vop_stdopen(ap
));
260 vop_stdopen(ap
); /* bump opencount/writecount as appropriate */
261 VOP_CLOSE(vp
, ap
->a_mode
);
268 * fifo_read(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
269 * struct ucred *a_cred)
273 fifo_read(struct vop_read_args
*ap
)
275 struct uio
*uio
= ap
->a_uio
;
276 struct socket
*rso
= ap
->a_vp
->v_fifoinfo
->fi_readsock
;
277 int error
, startresid
;
281 if (uio
->uio_rw
!= UIO_READ
)
282 panic("fifo_read mode");
284 if (uio
->uio_resid
== 0)
286 if (ap
->a_ioflag
& IO_NDELAY
)
287 flags
= MSG_FNONBLOCKING
;
290 startresid
= uio
->uio_resid
;
292 error
= soreceive(rso
, NULL
, uio
, NULL
, NULL
, &flags
);
293 vn_lock(ap
->a_vp
, LK_EXCLUSIVE
| LK_RETRY
);
300 * fifo_write(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
301 * struct ucred *a_cred)
305 fifo_write(struct vop_write_args
*ap
)
307 struct socket
*wso
= ap
->a_vp
->v_fifoinfo
->fi_writesock
;
308 struct thread
*td
= ap
->a_uio
->uio_td
;
313 if (ap
->a_uio
->uio_rw
!= UIO_WRITE
)
314 panic("fifo_write mode");
316 if (ap
->a_ioflag
& IO_NDELAY
)
317 flags
= MSG_FNONBLOCKING
;
321 error
= sosend(wso
, (struct sockaddr
*)0, ap
->a_uio
, 0,
322 (struct mbuf
*)0, flags
, td
);
323 vn_lock(ap
->a_vp
, LK_EXCLUSIVE
| LK_RETRY
);
328 * Device ioctl operation.
330 * fifo_ioctl(struct vnode *a_vp, int a_command, caddr_t a_data, int a_fflag,
331 * struct ucred *a_cred)
335 fifo_ioctl(struct vop_ioctl_args
*ap
)
337 struct file filetmp
; /* Local */
340 if (ap
->a_fflag
& FREAD
) {
341 filetmp
.f_data
= ap
->a_vp
->v_fifoinfo
->fi_readsock
;
342 error
= soo_ioctl(&filetmp
, ap
->a_command
, ap
->a_data
, ap
->a_cred
);
346 if (ap
->a_fflag
& FWRITE
) {
347 filetmp
.f_data
= ap
->a_vp
->v_fifoinfo
->fi_writesock
;
348 error
= soo_ioctl(&filetmp
, ap
->a_command
, ap
->a_data
, ap
->a_cred
);
356 * fifo_kqfilter(struct vnode *a_vp, struct knote *a_kn)
360 fifo_kqfilter(struct vop_kqfilter_args
*ap
)
362 struct fifoinfo
*fi
= ap
->a_vp
->v_fifoinfo
;
364 struct signalsockbuf
*ssb
;
366 switch (ap
->a_kn
->kn_filter
) {
368 ap
->a_kn
->kn_fop
= &fiforead_filtops
;
369 so
= fi
->fi_readsock
;
373 ap
->a_kn
->kn_fop
= &fifowrite_filtops
;
374 so
= fi
->fi_writesock
;
381 ap
->a_kn
->kn_hook
= (caddr_t
)so
;
383 ssb_insert_knote(ssb
, ap
->a_kn
);
389 filt_fifordetach(struct knote
*kn
)
391 struct socket
*so
= (struct socket
*)kn
->kn_hook
;
393 ssb_remove_knote(&so
->so_rcv
, kn
);
397 filt_fiforead(struct knote
*kn
, long hint
)
399 struct socket
*so
= (struct socket
*)kn
->kn_hook
;
401 kn
->kn_data
= so
->so_rcv
.ssb_cc
;
402 if (so
->so_state
& SS_CANTRCVMORE
) {
403 kn
->kn_flags
|= EV_EOF
;
406 kn
->kn_flags
&= ~EV_EOF
;
407 return (kn
->kn_data
> 0);
411 filt_fifowdetach(struct knote
*kn
)
413 struct socket
*so
= (struct socket
*)kn
->kn_hook
;
415 ssb_remove_knote(&so
->so_snd
, kn
);
419 filt_fifowrite(struct knote
*kn
, long hint
)
421 struct socket
*so
= (struct socket
*)kn
->kn_hook
;
423 kn
->kn_data
= ssb_space(&so
->so_snd
);
424 if (so
->so_state
& SS_CANTSENDMORE
) {
425 kn
->kn_flags
|= EV_EOF
;
428 kn
->kn_flags
&= ~EV_EOF
;
429 return (kn
->kn_data
>= so
->so_snd
.ssb_lowat
);
433 * fifo_poll(struct vnode *a_vp, int a_events, struct ucred *a_cred)
437 fifo_poll(struct vop_poll_args
*ap
)
440 int events
, revents
= 0;
442 events
= ap
->a_events
&
443 (POLLIN
| POLLINIGNEOF
| POLLPRI
| POLLRDNORM
| POLLRDBAND
);
446 * If POLLIN or POLLRDNORM is requested and POLLINIGNEOF is
447 * not, then convert the first two to the last one. This
448 * tells the socket poll function to ignore EOF so that we
449 * block if there is no writer (and no data). Callers can
450 * set POLLINIGNEOF to get non-blocking behavior.
452 if (events
& (POLLIN
| POLLRDNORM
) &&
453 !(events
& POLLINIGNEOF
)) {
454 events
&= ~(POLLIN
| POLLRDNORM
);
455 events
|= POLLINIGNEOF
;
458 filetmp
.f_data
= ap
->a_vp
->v_fifoinfo
->fi_readsock
;
460 revents
|= soo_poll(&filetmp
, events
, ap
->a_cred
);
462 /* Reverse the above conversion. */
463 if ((revents
& POLLINIGNEOF
) &&
464 !(ap
->a_events
& POLLINIGNEOF
)) {
465 revents
|= (ap
->a_events
& (POLLIN
| POLLRDNORM
));
466 revents
&= ~POLLINIGNEOF
;
469 events
= ap
->a_events
& (POLLOUT
| POLLWRNORM
| POLLWRBAND
);
471 filetmp
.f_data
= ap
->a_vp
->v_fifoinfo
->fi_writesock
;
473 revents
|= soo_poll(&filetmp
, events
, ap
->a_cred
);
479 * fifo_inactive(struct vnode *a_vp)
482 fifo_inactive(struct vop_inactive_args
*ap
)
488 * This is a noop, simply returning what one has been given.
490 * fifo_bmap(struct vnode *a_vp, off_t a_loffset,
491 * off_t *a_doffsetp, int *a_runp, int *a_runb)
494 fifo_bmap(struct vop_bmap_args
*ap
)
496 if (ap
->a_doffsetp
!= NULL
)
497 *ap
->a_doffsetp
= ap
->a_loffset
;
498 if (ap
->a_runp
!= NULL
)
500 if (ap
->a_runb
!= NULL
)
506 * Device close routine
508 * fifo_close(struct vnode *a_vp, int a_fflag)
512 fifo_close(struct vop_close_args
*ap
)
514 struct vnode
*vp
= ap
->a_vp
;
515 struct fifoinfo
*fip
= vp
->v_fifoinfo
;
518 if (ap
->a_fflag
& FREAD
) {
520 if (fip
->fi_readers
== 0)
521 socantsendmore(fip
->fi_writesock
);
523 if (ap
->a_fflag
& FWRITE
) {
525 if (fip
->fi_writers
== 0)
526 socantrcvmore(fip
->fi_readsock
);
528 if (vp
->v_sysref
.refcnt
> 1) {
532 error1
= soclose(fip
->fi_readsock
, FNONBLOCK
);
533 error2
= soclose(fip
->fi_writesock
, FNONBLOCK
);
534 FREE(fip
, M_FIFOINFO
);
535 vp
->v_fifoinfo
= NULL
;
544 * Print out internal contents of a fifo vnode.
547 fifo_printinfo(struct vnode
*vp
)
549 struct fifoinfo
*fip
= vp
->v_fifoinfo
;
551 kprintf(", fifo with %ld readers and %ld writers",
552 fip
->fi_readers
, fip
->fi_writers
);
557 * Print out the contents of a fifo vnode.
559 * fifo_print(struct vnode *a_vp)
562 fifo_print(struct vop_print_args
*ap
)
564 kprintf("tag VT_NON");
565 fifo_printinfo(ap
->a_vp
);
571 * Return POSIX pathconf information applicable to fifo's.
573 * fifo_pathconf(struct vnode *a_vp, int a_name, int *a_retval)
576 fifo_pathconf(struct vop_pathconf_args
*ap
)
578 switch (ap
->a_name
) {
580 *ap
->a_retval
= LINK_MAX
;
583 *ap
->a_retval
= PIPE_BUF
;
585 case _PC_CHOWN_RESTRICTED
:
595 * Fifo advisory byte-level locks.
597 * fifo_advlock(struct vnode *a_vp, caddr_t a_id, int a_op, struct flock *a_fl,
602 fifo_advlock(struct vop_advlock_args
*ap
)
604 return ((ap
->a_flags
& F_POSIX
) ? EINVAL
: EOPNOTSUPP
);
613 panic("fifo_badop called");