Commit | Line | Data |
---|---|---|
984263bc MD |
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: src/sys/miscfs/fifofs/fifo_vnops.c,v 1.45.2.4 2003/04/22 10:11:24 bde Exp $ | |
3c37c940 | 35 | * $DragonFly: src/sys/vfs/fifofs/fifo_vnops.c,v 1.38 2007/05/06 19:23:33 dillon Exp $ |
984263bc MD |
36 | */ |
37 | ||
38 | #include <sys/param.h> | |
39 | #include <sys/systm.h> | |
40 | #include <sys/unistd.h> | |
41 | #include <sys/kernel.h> | |
42 | #include <sys/lock.h> | |
43 | #include <sys/malloc.h> | |
87de5057 | 44 | #include <sys/thread2.h> |
984263bc MD |
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> | |
50 | #include <sys/file.h> | |
51 | #include <sys/event.h> | |
52 | #include <sys/poll.h> | |
53 | #include <sys/un.h> | |
87de5057 MD |
54 | |
55 | #include <sys/thread2.h> | |
56 | ||
1f2de5d4 | 57 | #include "fifo.h" |
984263bc MD |
58 | |
59 | /* | |
60 | * This structure is associated with the FIFO vnode and stores | |
61 | * the state associated with the FIFO. | |
62 | */ | |
63 | struct fifoinfo { | |
64 | struct socket *fi_readsock; | |
65 | struct socket *fi_writesock; | |
66 | long fi_readers; | |
67 | long fi_writers; | |
68 | }; | |
69 | ||
a6ee311a RG |
70 | static int fifo_badop (void); |
71 | static int fifo_print (struct vop_print_args *); | |
e62afb5f | 72 | static int fifo_lookup (struct vop_old_lookup_args *); |
a6ee311a RG |
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 *); | |
984263bc MD |
84 | |
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); | |
89 | ||
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 }; | |
94 | ||
66a1ddf5 MD |
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 | |
984263bc | 125 | }; |
984263bc | 126 | |
66a1ddf5 | 127 | VNODEOP_SET(fifo_vnode_vops); |
984263bc | 128 | |
5fd012e0 MD |
129 | static MALLOC_DEFINE(M_FIFOINFO, "Fifo info", "Fifo info entries"); |
130 | ||
b5f12e21 | 131 | /* |
31bd717a | 132 | * fifo_vnoperate() |
b5f12e21 | 133 | */ |
984263bc | 134 | int |
b5f12e21 | 135 | fifo_vnoperate(struct vop_generic_args *ap) |
984263bc | 136 | { |
66a1ddf5 | 137 | return (VOCALL(&fifo_vnode_vops, ap)); |
984263bc MD |
138 | } |
139 | ||
140 | /* | |
141 | * Trivial lookup routine that always fails. | |
b5f12e21 CP |
142 | * |
143 | * fifo_lookup(struct vnode *a_dvp, struct vnode **a_vpp, | |
144 | * struct componentname *a_cnp) | |
984263bc MD |
145 | */ |
146 | /* ARGSUSED */ | |
147 | static int | |
e62afb5f | 148 | fifo_lookup(struct vop_old_lookup_args *ap) |
984263bc | 149 | { |
984263bc MD |
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. | |
b5f12e21 CP |
157 | * |
158 | * fifo_open(struct vnode *a_vp, int a_mode, struct ucred *a_cred, | |
159 | * struct thread *a_td) | |
984263bc MD |
160 | */ |
161 | /* ARGSUSED */ | |
162 | static int | |
b5f12e21 | 163 | fifo_open(struct vop_open_args *ap) |
984263bc | 164 | { |
87de5057 | 165 | struct thread *td = curthread; |
984263bc MD |
166 | struct vnode *vp = ap->a_vp; |
167 | struct fifoinfo *fip; | |
984263bc MD |
168 | struct socket *rso, *wso; |
169 | int error; | |
170 | ||
171 | if ((fip = vp->v_fifoinfo) == NULL) { | |
5fd012e0 | 172 | MALLOC(fip, struct fifoinfo *, sizeof(*fip), M_FIFOINFO, M_WAITOK); |
984263bc | 173 | vp->v_fifoinfo = fip; |
87de5057 | 174 | error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, td); |
984263bc | 175 | if (error) { |
efda3bd0 | 176 | kfree(fip, M_FIFOINFO); |
984263bc MD |
177 | vp->v_fifoinfo = NULL; |
178 | return (error); | |
179 | } | |
180 | fip->fi_readsock = rso; | |
87de5057 | 181 | error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0, td); |
984263bc | 182 | if (error) { |
9ba76b73 | 183 | soclose(rso, FNONBLOCK); |
efda3bd0 | 184 | kfree(fip, M_FIFOINFO); |
984263bc MD |
185 | vp->v_fifoinfo = NULL; |
186 | return (error); | |
187 | } | |
188 | fip->fi_writesock = wso; | |
189 | error = unp_connect2(wso, rso); | |
190 | if (error) { | |
9ba76b73 MD |
191 | soclose(wso, FNONBLOCK); |
192 | soclose(rso, FNONBLOCK); | |
efda3bd0 | 193 | kfree(fip, M_FIFOINFO); |
984263bc MD |
194 | vp->v_fifoinfo = NULL; |
195 | return (error); | |
196 | } | |
197 | fip->fi_readers = fip->fi_writers = 0; | |
6d49aa6f | 198 | wso->so_snd.ssb_lowat = PIPE_BUF; |
984263bc MD |
199 | rso->so_state |= SS_CANTRCVMORE; |
200 | } | |
201 | if (ap->a_mode & FREAD) { | |
202 | fip->fi_readers++; | |
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); | |
208 | } | |
209 | } | |
210 | } | |
211 | if (ap->a_mode & FWRITE) { | |
212 | fip->fi_writers++; | |
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); | |
218 | } | |
219 | } | |
220 | } | |
221 | if ((ap->a_mode & FREAD) && (ap->a_mode & O_NONBLOCK) == 0) { | |
222 | if (fip->fi_writers == 0) { | |
a11aaa81 | 223 | vn_unlock(vp); |
984263bc | 224 | error = tsleep((caddr_t)&fip->fi_readers, |
377d4740 | 225 | PCATCH, "fifoor", 0); |
ca466bae | 226 | vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); |
984263bc MD |
227 | if (error) |
228 | goto bad; | |
229 | /* | |
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. | |
233 | */ | |
234 | } | |
235 | } | |
236 | if (ap->a_mode & FWRITE) { | |
237 | if (ap->a_mode & O_NONBLOCK) { | |
238 | if (fip->fi_readers == 0) { | |
239 | error = ENXIO; | |
240 | goto bad; | |
241 | } | |
242 | } else { | |
243 | if (fip->fi_readers == 0) { | |
a11aaa81 | 244 | vn_unlock(vp); |
984263bc | 245 | error = tsleep((caddr_t)&fip->fi_writers, |
377d4740 | 246 | PCATCH, "fifoow", 0); |
ca466bae | 247 | vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); |
984263bc MD |
248 | if (error) |
249 | goto bad; | |
250 | /* | |
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. | |
254 | */ | |
255 | } | |
256 | } | |
257 | } | |
8ddc6004 | 258 | return (vop_stdopen(ap)); |
984263bc | 259 | bad: |
cbeb1f72 | 260 | vop_stdopen(ap); /* bump opencount/writecount as appropriate */ |
87de5057 | 261 | VOP_CLOSE(vp, ap->a_mode); |
984263bc MD |
262 | return (error); |
263 | } | |
264 | ||
265 | /* | |
266 | * Vnode op for read | |
b5f12e21 CP |
267 | * |
268 | * fifo_read(struct vnode *a_vp, struct uio *a_uio, int a_ioflag, | |
269 | * struct ucred *a_cred) | |
984263bc MD |
270 | */ |
271 | /* ARGSUSED */ | |
272 | static int | |
b5f12e21 | 273 | fifo_read(struct vop_read_args *ap) |
984263bc MD |
274 | { |
275 | struct uio *uio = ap->a_uio; | |
276 | struct socket *rso = ap->a_vp->v_fifoinfo->fi_readsock; | |
984263bc | 277 | int error, startresid; |
9ba76b73 | 278 | int flags; |
984263bc MD |
279 | |
280 | #ifdef DIAGNOSTIC | |
281 | if (uio->uio_rw != UIO_READ) | |
282 | panic("fifo_read mode"); | |
283 | #endif | |
284 | if (uio->uio_resid == 0) | |
285 | return (0); | |
286 | if (ap->a_ioflag & IO_NDELAY) | |
9ba76b73 MD |
287 | flags = MSG_FNONBLOCKING; |
288 | else | |
289 | flags = 0; | |
984263bc | 290 | startresid = uio->uio_resid; |
a11aaa81 | 291 | vn_unlock(ap->a_vp); |
d8a9a23b | 292 | error = soreceive(rso, NULL, uio, NULL, NULL, &flags); |
ca466bae | 293 | vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY); |
984263bc MD |
294 | return (error); |
295 | } | |
296 | ||
297 | /* | |
298 | * Vnode op for write | |
b5f12e21 CP |
299 | * |
300 | * fifo_write(struct vnode *a_vp, struct uio *a_uio, int a_ioflag, | |
301 | * struct ucred *a_cred) | |
984263bc MD |
302 | */ |
303 | /* ARGSUSED */ | |
304 | static int | |
b5f12e21 | 305 | fifo_write(struct vop_write_args *ap) |
984263bc MD |
306 | { |
307 | struct socket *wso = ap->a_vp->v_fifoinfo->fi_writesock; | |
dadab5e9 | 308 | struct thread *td = ap->a_uio->uio_td; |
984263bc | 309 | int error; |
9ba76b73 | 310 | int flags; |
984263bc MD |
311 | |
312 | #ifdef DIAGNOSTIC | |
313 | if (ap->a_uio->uio_rw != UIO_WRITE) | |
314 | panic("fifo_write mode"); | |
315 | #endif | |
316 | if (ap->a_ioflag & IO_NDELAY) | |
9ba76b73 MD |
317 | flags = MSG_FNONBLOCKING; |
318 | else | |
319 | flags = 0; | |
a11aaa81 | 320 | vn_unlock(ap->a_vp); |
984263bc | 321 | error = sosend(wso, (struct sockaddr *)0, ap->a_uio, 0, |
9ba76b73 | 322 | (struct mbuf *)0, flags, td); |
ca466bae | 323 | vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY); |
984263bc MD |
324 | return (error); |
325 | } | |
326 | ||
327 | /* | |
328 | * Device ioctl operation. | |
b5f12e21 CP |
329 | * |
330 | * fifo_ioctl(struct vnode *a_vp, int a_command, caddr_t a_data, int a_fflag, | |
331 | * struct ucred *a_cred, struct thread *a_td) | |
984263bc MD |
332 | */ |
333 | /* ARGSUSED */ | |
334 | static int | |
b5f12e21 | 335 | fifo_ioctl(struct vop_ioctl_args *ap) |
984263bc | 336 | { |
9443ca22 | 337 | struct file filetmp; /* Local */ |
984263bc MD |
338 | int error; |
339 | ||
984263bc | 340 | if (ap->a_fflag & FREAD) { |
fbb4eeab | 341 | filetmp.f_data = ap->a_vp->v_fifoinfo->fi_readsock; |
87de5057 | 342 | error = soo_ioctl(&filetmp, ap->a_command, ap->a_data, ap->a_cred); |
984263bc MD |
343 | if (error) |
344 | return (error); | |
345 | } | |
346 | if (ap->a_fflag & FWRITE) { | |
fbb4eeab | 347 | filetmp.f_data = ap->a_vp->v_fifoinfo->fi_writesock; |
87de5057 | 348 | error = soo_ioctl(&filetmp, ap->a_command, ap->a_data, ap->a_cred); |
984263bc MD |
349 | if (error) |
350 | return (error); | |
351 | } | |
352 | return (0); | |
353 | } | |
354 | ||
b5f12e21 CP |
355 | /* |
356 | * fifo_kqfilter(struct vnode *a_vp, struct knote *a_kn) | |
357 | */ | |
984263bc MD |
358 | /* ARGSUSED */ |
359 | static int | |
b5f12e21 | 360 | fifo_kqfilter(struct vop_kqfilter_args *ap) |
984263bc MD |
361 | { |
362 | struct fifoinfo *fi = ap->a_vp->v_fifoinfo; | |
363 | struct socket *so; | |
6d49aa6f | 364 | struct signalsockbuf *ssb; |
984263bc MD |
365 | |
366 | switch (ap->a_kn->kn_filter) { | |
367 | case EVFILT_READ: | |
368 | ap->a_kn->kn_fop = &fiforead_filtops; | |
369 | so = fi->fi_readsock; | |
6d49aa6f | 370 | ssb = &so->so_rcv; |
984263bc MD |
371 | break; |
372 | case EVFILT_WRITE: | |
373 | ap->a_kn->kn_fop = &fifowrite_filtops; | |
374 | so = fi->fi_writesock; | |
6d49aa6f | 375 | ssb = &so->so_snd; |
984263bc MD |
376 | break; |
377 | default: | |
378 | return (1); | |
379 | } | |
380 | ||
381 | ap->a_kn->kn_hook = (caddr_t)so; | |
382 | ||
6d49aa6f | 383 | ssb_insert_knote(ssb, ap->a_kn); |
984263bc MD |
384 | |
385 | return (0); | |
386 | } | |
387 | ||
388 | static void | |
389 | filt_fifordetach(struct knote *kn) | |
390 | { | |
391 | struct socket *so = (struct socket *)kn->kn_hook; | |
392 | ||
6d49aa6f | 393 | ssb_remove_knote(&so->so_rcv, kn); |
984263bc MD |
394 | } |
395 | ||
396 | static int | |
397 | filt_fiforead(struct knote *kn, long hint) | |
398 | { | |
399 | struct socket *so = (struct socket *)kn->kn_hook; | |
400 | ||
6d49aa6f | 401 | kn->kn_data = so->so_rcv.ssb_cc; |
984263bc MD |
402 | if (so->so_state & SS_CANTRCVMORE) { |
403 | kn->kn_flags |= EV_EOF; | |
404 | return (1); | |
405 | } | |
406 | kn->kn_flags &= ~EV_EOF; | |
407 | return (kn->kn_data > 0); | |
408 | } | |
409 | ||
410 | static void | |
411 | filt_fifowdetach(struct knote *kn) | |
412 | { | |
413 | struct socket *so = (struct socket *)kn->kn_hook; | |
414 | ||
6d49aa6f | 415 | ssb_remove_knote(&so->so_snd, kn); |
984263bc MD |
416 | } |
417 | ||
418 | static int | |
419 | filt_fifowrite(struct knote *kn, long hint) | |
420 | { | |
421 | struct socket *so = (struct socket *)kn->kn_hook; | |
422 | ||
6d49aa6f | 423 | kn->kn_data = ssb_space(&so->so_snd); |
984263bc MD |
424 | if (so->so_state & SS_CANTSENDMORE) { |
425 | kn->kn_flags |= EV_EOF; | |
426 | return (1); | |
427 | } | |
428 | kn->kn_flags &= ~EV_EOF; | |
6d49aa6f | 429 | return (kn->kn_data >= so->so_snd.ssb_lowat); |
984263bc MD |
430 | } |
431 | ||
b5f12e21 CP |
432 | /* |
433 | * fifo_poll(struct vnode *a_vp, int a_events, struct ucred *a_cred, | |
434 | * struct thread *a_td) | |
435 | */ | |
984263bc MD |
436 | /* ARGSUSED */ |
437 | static int | |
b5f12e21 | 438 | fifo_poll(struct vop_poll_args *ap) |
984263bc MD |
439 | { |
440 | struct file filetmp; | |
d08a3c4d HP |
441 | int events, revents = 0; |
442 | ||
630a348c | 443 | events = ap->a_events & |
9443ca22 | 444 | (POLLIN | POLLINIGNEOF | POLLPRI | POLLRDNORM | POLLRDBAND); |
d08a3c4d HP |
445 | if (events) { |
446 | /* | |
9443ca22 HP |
447 | * If POLLIN or POLLRDNORM is requested and POLLINIGNEOF is |
448 | * not, then convert the first two to the last one. This | |
449 | * tells the socket poll function to ignore EOF so that we | |
450 | * block if there is no writer (and no data). Callers can | |
451 | * set POLLINIGNEOF to get non-blocking behavior. | |
d08a3c4d | 452 | */ |
ad4bd3a5 HP |
453 | if (events & (POLLIN | POLLRDNORM) && |
454 | !(events & POLLINIGNEOF)) { | |
d08a3c4d HP |
455 | events &= ~(POLLIN | POLLRDNORM); |
456 | events |= POLLINIGNEOF; | |
457 | } | |
9443ca22 | 458 | |
fbb4eeab | 459 | filetmp.f_data = ap->a_vp->v_fifoinfo->fi_readsock; |
984263bc | 460 | if (filetmp.f_data) |
87de5057 | 461 | revents |= soo_poll(&filetmp, events, ap->a_cred); |
d08a3c4d | 462 | |
9443ca22 HP |
463 | /* Reverse the above conversion. */ |
464 | if ((revents & POLLINIGNEOF) && | |
465 | !(ap->a_events & POLLINIGNEOF)) { | |
466 | revents |= (ap->a_events & (POLLIN | POLLRDNORM)); | |
d08a3c4d | 467 | revents &= ~POLLINIGNEOF; |
d08a3c4d | 468 | } |
984263bc | 469 | } |
d08a3c4d HP |
470 | events = ap->a_events & (POLLOUT | POLLWRNORM | POLLWRBAND); |
471 | if (events) { | |
fbb4eeab | 472 | filetmp.f_data = ap->a_vp->v_fifoinfo->fi_writesock; |
984263bc | 473 | if (filetmp.f_data) |
87de5057 | 474 | revents |= soo_poll(&filetmp, events, ap->a_cred); |
984263bc MD |
475 | } |
476 | return (revents); | |
477 | } | |
478 | ||
b5f12e21 CP |
479 | /* |
480 | * fifo_inactive(struct vnode *a_vp, struct thread *a_td) | |
481 | */ | |
984263bc | 482 | static int |
b5f12e21 | 483 | fifo_inactive(struct vop_inactive_args *ap) |
984263bc | 484 | { |
984263bc MD |
485 | return (0); |
486 | } | |
487 | ||
488 | /* | |
489 | * This is a noop, simply returning what one has been given. | |
b5f12e21 | 490 | * |
54078292 MD |
491 | * fifo_bmap(struct vnode *a_vp, off_t a_loffset, struct vnode **a_vpp, |
492 | * off_t *a_doffsetp, int *a_runp, int *a_runb) | |
984263bc MD |
493 | */ |
494 | static int | |
b5f12e21 | 495 | fifo_bmap(struct vop_bmap_args *ap) |
984263bc | 496 | { |
984263bc MD |
497 | if (ap->a_vpp != NULL) |
498 | *ap->a_vpp = ap->a_vp; | |
54078292 MD |
499 | if (ap->a_doffsetp != NULL) |
500 | *ap->a_doffsetp = ap->a_loffset; | |
984263bc MD |
501 | if (ap->a_runp != NULL) |
502 | *ap->a_runp = 0; | |
503 | if (ap->a_runb != NULL) | |
504 | *ap->a_runb = 0; | |
505 | return (0); | |
506 | } | |
507 | ||
508 | /* | |
509 | * Device close routine | |
b5f12e21 CP |
510 | * |
511 | * fifo_close(struct vnode *a_vp, int a_fflag, struct ucred *a_cred, | |
512 | * struct thread *a_td) | |
984263bc MD |
513 | */ |
514 | /* ARGSUSED */ | |
515 | static int | |
b5f12e21 | 516 | fifo_close(struct vop_close_args *ap) |
984263bc | 517 | { |
0e99e805 RG |
518 | struct vnode *vp = ap->a_vp; |
519 | struct fifoinfo *fip = vp->v_fifoinfo; | |
984263bc MD |
520 | int error1, error2; |
521 | ||
522 | if (ap->a_fflag & FREAD) { | |
523 | fip->fi_readers--; | |
524 | if (fip->fi_readers == 0) | |
525 | socantsendmore(fip->fi_writesock); | |
526 | } | |
527 | if (ap->a_fflag & FWRITE) { | |
528 | fip->fi_writers--; | |
529 | if (fip->fi_writers == 0) | |
530 | socantrcvmore(fip->fi_readsock); | |
531 | } | |
3c37c940 | 532 | if (vp->v_sysref.refcnt > 1) { |
8ddc6004 | 533 | vop_stdclose(ap); |
984263bc | 534 | return (0); |
8ddc6004 | 535 | } |
9ba76b73 MD |
536 | error1 = soclose(fip->fi_readsock, FNONBLOCK); |
537 | error2 = soclose(fip->fi_writesock, FNONBLOCK); | |
5fd012e0 | 538 | FREE(fip, M_FIFOINFO); |
984263bc MD |
539 | vp->v_fifoinfo = NULL; |
540 | if (error1) | |
541 | return (error1); | |
8ddc6004 | 542 | vop_stdclose(ap); |
984263bc MD |
543 | return (error2); |
544 | } | |
545 | ||
546 | ||
547 | /* | |
548 | * Print out internal contents of a fifo vnode. | |
549 | */ | |
550 | int | |
b5f12e21 | 551 | fifo_printinfo(struct vnode *vp) |
984263bc | 552 | { |
0e99e805 | 553 | struct fifoinfo *fip = vp->v_fifoinfo; |
984263bc | 554 | |
086c1d7e | 555 | kprintf(", fifo with %ld readers and %ld writers", |
984263bc MD |
556 | fip->fi_readers, fip->fi_writers); |
557 | return (0); | |
558 | } | |
559 | ||
560 | /* | |
561 | * Print out the contents of a fifo vnode. | |
b5f12e21 CP |
562 | * |
563 | * fifo_print(struct vnode *a_vp) | |
984263bc MD |
564 | */ |
565 | static int | |
b5f12e21 | 566 | fifo_print(struct vop_print_args *ap) |
984263bc | 567 | { |
086c1d7e | 568 | kprintf("tag VT_NON"); |
984263bc | 569 | fifo_printinfo(ap->a_vp); |
086c1d7e | 570 | kprintf("\n"); |
984263bc MD |
571 | return (0); |
572 | } | |
573 | ||
574 | /* | |
575 | * Return POSIX pathconf information applicable to fifo's. | |
b5f12e21 CP |
576 | * |
577 | * fifo_pathconf(struct vnode *a_vp, int a_name, int *a_retval) | |
984263bc MD |
578 | */ |
579 | int | |
b5f12e21 | 580 | fifo_pathconf(struct vop_pathconf_args *ap) |
984263bc | 581 | { |
984263bc MD |
582 | switch (ap->a_name) { |
583 | case _PC_LINK_MAX: | |
584 | *ap->a_retval = LINK_MAX; | |
585 | return (0); | |
586 | case _PC_PIPE_BUF: | |
587 | *ap->a_retval = PIPE_BUF; | |
588 | return (0); | |
589 | case _PC_CHOWN_RESTRICTED: | |
590 | *ap->a_retval = 1; | |
591 | return (0); | |
592 | default: | |
593 | return (EINVAL); | |
594 | } | |
595 | /* NOTREACHED */ | |
596 | } | |
597 | ||
598 | /* | |
599 | * Fifo advisory byte-level locks. | |
b5f12e21 CP |
600 | * |
601 | * fifo_advlock(struct vnode *a_vp, caddr_t a_id, int a_op, struct flock *a_fl, | |
602 | * int a_flags) | |
984263bc MD |
603 | */ |
604 | /* ARGSUSED */ | |
605 | static int | |
b5f12e21 | 606 | fifo_advlock(struct vop_advlock_args *ap) |
984263bc | 607 | { |
71c18fe3 | 608 | return ((ap->a_flags & F_POSIX) ? EINVAL : EOPNOTSUPP); |
984263bc MD |
609 | } |
610 | ||
611 | /* | |
612 | * Fifo bad operation | |
613 | */ | |
614 | static int | |
b5f12e21 | 615 | fifo_badop(void) |
984263bc | 616 | { |
984263bc MD |
617 | panic("fifo_badop called"); |
618 | /* NOTREACHED */ | |
619 | } |