This source file includes following definitions.
- fifo_vnoperate
- fifo_lookup
- fifo_open
- fifo_read
- fifo_write
- fifo_ioctl
- fifo_poll
- fifo_inactive
- fifo_bmap
- fifo_close
- fifo_reclaim
- fifo_print
- fifo_printinfo
- fifo_pathconf
- fifo_ebadf
- fifo_advlock
- fifo_badop
- fifo_kqfilter
- filt_fifordetach
- filt_fiforead
- filt_fifowdetach
- filt_fifowrite
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 #include <sys/param.h>
36 #include <sys/proc.h>
37 #include <sys/systm.h>
38 #include <sys/time.h>
39 #include <sys/namei.h>
40 #include <sys/vnode.h>
41 #include <sys/socket.h>
42 #include <sys/socketvar.h>
43 #include <sys/stat.h>
44 #include <sys/ioctl.h>
45 #include <sys/file.h>
46 #include <sys/event.h>
47 #include <sys/errno.h>
48 #include <sys/malloc.h>
49 #include <sys/poll.h>
50 #include <sys/un.h>
51 #include <miscfs/fifofs/fifo.h>
52
53
54
55
56
57 struct fifoinfo {
58 struct socket *fi_readsock;
59 struct socket *fi_writesock;
60 long fi_readers;
61 long fi_writers;
62 };
63
64 int (**fifo_vnodeop_p)(void *);
65 struct vnodeopv_entry_desc fifo_vnodeop_entries[] = {
66 { &vop_default_desc, vn_default_error },
67 { &vop_lookup_desc, fifo_lookup },
68 { &vop_create_desc, fifo_create },
69 { &vop_mknod_desc, fifo_mknod },
70 { &vop_open_desc, fifo_open },
71 { &vop_close_desc, fifo_close },
72 { &vop_access_desc, fifo_access },
73 { &vop_getattr_desc, fifo_getattr },
74 { &vop_setattr_desc, fifo_setattr },
75 { &vop_read_desc, fifo_read },
76 { &vop_write_desc, fifo_write },
77 { &vop_ioctl_desc, fifo_ioctl },
78 { &vop_poll_desc, fifo_poll },
79 { &vop_kqfilter_desc, fifo_kqfilter },
80 { &vop_revoke_desc, fifo_revoke },
81 { &vop_fsync_desc, fifo_fsync },
82 { &vop_remove_desc, fifo_remove },
83 { &vop_link_desc, fifo_link },
84 { &vop_rename_desc, fifo_rename },
85 { &vop_mkdir_desc, fifo_mkdir },
86 { &vop_rmdir_desc, fifo_rmdir },
87 { &vop_symlink_desc, fifo_symlink },
88 { &vop_readdir_desc, fifo_readdir },
89 { &vop_readlink_desc, fifo_readlink },
90 { &vop_abortop_desc, fifo_abortop },
91 { &vop_inactive_desc, fifo_inactive },
92 { &vop_reclaim_desc, fifo_reclaim },
93 { &vop_lock_desc, fifo_lock },
94 { &vop_unlock_desc, fifo_unlock },
95 { &vop_bmap_desc, fifo_bmap },
96 { &vop_strategy_desc, fifo_strategy },
97 { &vop_print_desc, fifo_print },
98 { &vop_islocked_desc, fifo_islocked },
99 { &vop_pathconf_desc, fifo_pathconf },
100 { &vop_advlock_desc, fifo_advlock },
101 { &vop_bwrite_desc, fifo_bwrite },
102 { NULL, NULL }
103 };
104
105 struct vnodeopv_desc fifo_vnodeop_opv_desc =
106 { &fifo_vnodeop_p, fifo_vnodeop_entries };
107
108 int
109 fifo_vnoperate(void *v)
110 {
111 struct vop_generic_args *ap = v;
112
113 return (VOCALL(fifo_vnodeop_p, ap->a_desc->vdesc_offset, ap));
114 }
115
116 void filt_fifordetach(struct knote *kn);
117 int filt_fiforead(struct knote *kn, long hint);
118 void filt_fifowdetach(struct knote *kn);
119 int filt_fifowrite(struct knote *kn, long hint);
120
121 struct filterops fiforead_filtops =
122 { 1, NULL, filt_fifordetach, filt_fiforead };
123 struct filterops fifowrite_filtops =
124 { 1, NULL, filt_fifowdetach, filt_fifowrite };
125
126
127
128
129
130 int
131 fifo_lookup(void *v)
132 {
133 struct vop_lookup_args *ap = v;
134
135 *ap->a_vpp = NULL;
136 return (ENOTDIR);
137 }
138
139
140
141
142
143
144 int
145 fifo_open(void *v)
146 {
147 struct vop_open_args *ap = v;
148 struct vnode *vp = ap->a_vp;
149 struct fifoinfo *fip;
150 struct proc *p = ap->a_p;
151 struct socket *rso, *wso;
152 int error;
153
154 if ((fip = vp->v_fifoinfo) == NULL) {
155 MALLOC(fip, struct fifoinfo *, sizeof(*fip), M_VNODE, M_WAITOK);
156 vp->v_fifoinfo = fip;
157 if ((error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0)) != 0) {
158 free(fip, M_VNODE);
159 vp->v_fifoinfo = NULL;
160 return (error);
161 }
162 fip->fi_readsock = rso;
163 if ((error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0)) != 0) {
164 (void)soclose(rso);
165 free(fip, M_VNODE);
166 vp->v_fifoinfo = NULL;
167 return (error);
168 }
169 fip->fi_writesock = wso;
170 if ((error = unp_connect2(wso, rso)) != 0) {
171 (void)soclose(wso);
172 (void)soclose(rso);
173 free(fip, M_VNODE);
174 vp->v_fifoinfo = NULL;
175 return (error);
176 }
177 fip->fi_readers = fip->fi_writers = 0;
178 wso->so_snd.sb_lowat = PIPE_BUF;
179 rso->so_state |= SS_CANTRCVMORE;
180 }
181 if (ap->a_mode & FREAD) {
182 fip->fi_readers++;
183 if (fip->fi_readers == 1) {
184 fip->fi_writesock->so_state &= ~SS_CANTSENDMORE;
185 if (fip->fi_writers > 0)
186 wakeup(&fip->fi_writers);
187 }
188 }
189 if (ap->a_mode & FWRITE) {
190 fip->fi_writers++;
191 if ((ap->a_mode & O_NONBLOCK) && fip->fi_readers == 0) {
192 error = ENXIO;
193 goto bad;
194 }
195 if (fip->fi_writers == 1) {
196 fip->fi_readsock->so_state &= ~SS_CANTRCVMORE;
197 if (fip->fi_readers > 0)
198 wakeup(&fip->fi_readers);
199 }
200 }
201 if ((ap->a_mode & O_NONBLOCK) == 0) {
202 if ((ap->a_mode & FREAD) && fip->fi_writers == 0) {
203 VOP_UNLOCK(vp, 0, p);
204 error = tsleep(&fip->fi_readers,
205 PCATCH | PSOCK, "fifor", 0);
206 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
207 if (error)
208 goto bad;
209 }
210 if ((ap->a_mode & FWRITE) && fip->fi_readers == 0) {
211 VOP_UNLOCK(vp, 0, p);
212 error = tsleep(&fip->fi_writers,
213 PCATCH | PSOCK, "fifow", 0);
214 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
215 if (error)
216 goto bad;
217 }
218 }
219 return (0);
220 bad:
221 VOP_CLOSE(vp, ap->a_mode, ap->a_cred, ap->a_p);
222 return (error);
223 }
224
225
226
227
228
229 int
230 fifo_read(void *v)
231 {
232 struct vop_read_args *ap = v;
233 struct uio *uio = ap->a_uio;
234 struct socket *rso = ap->a_vp->v_fifoinfo->fi_readsock;
235 struct proc *p = uio->uio_procp;
236 int error;
237
238 #ifdef DIAGNOSTIC
239 if (uio->uio_rw != UIO_READ)
240 panic("fifo_read mode");
241 #endif
242 if (uio->uio_resid == 0)
243 return (0);
244 if (ap->a_ioflag & IO_NDELAY)
245 rso->so_state |= SS_NBIO;
246 VOP_UNLOCK(ap->a_vp, 0, p);
247 error = soreceive(rso, NULL, uio, NULL, NULL, NULL);
248 vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, p);
249 if (ap->a_ioflag & IO_NDELAY) {
250 rso->so_state &= ~SS_NBIO;
251 if (error == EWOULDBLOCK &&
252 ap->a_vp->v_fifoinfo->fi_writers == 0)
253 error = 0;
254 }
255 return (error);
256 }
257
258
259
260
261
262 int
263 fifo_write(void *v)
264 {
265 struct vop_write_args *ap = v;
266 struct socket *wso = ap->a_vp->v_fifoinfo->fi_writesock;
267 struct proc *p = ap->a_uio->uio_procp;
268 int error;
269
270 #ifdef DIAGNOSTIC
271 if (ap->a_uio->uio_rw != UIO_WRITE)
272 panic("fifo_write mode");
273 #endif
274 if (ap->a_ioflag & IO_NDELAY)
275 wso->so_state |= SS_NBIO;
276 VOP_UNLOCK(ap->a_vp, 0, p);
277 error = sosend(wso, NULL, ap->a_uio, NULL, NULL, 0);
278 vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, p);
279 if (ap->a_ioflag & IO_NDELAY)
280 wso->so_state &= ~SS_NBIO;
281 return (error);
282 }
283
284
285
286
287
288 int
289 fifo_ioctl(void *v)
290 {
291 struct vop_ioctl_args *ap = v;
292 struct file filetmp;
293 int error;
294
295 if (ap->a_command == FIONBIO)
296 return (0);
297 if (ap->a_fflag & FREAD) {
298 filetmp.f_data = ap->a_vp->v_fifoinfo->fi_readsock;
299 error = soo_ioctl(&filetmp, ap->a_command, ap->a_data, ap->a_p);
300 if (error)
301 return (error);
302 }
303 if (ap->a_fflag & FWRITE) {
304 filetmp.f_data = ap->a_vp->v_fifoinfo->fi_writesock;
305 error = soo_ioctl(&filetmp, ap->a_command, ap->a_data, ap->a_p);
306 if (error)
307 return (error);
308 }
309 return (0);
310 }
311
312
313 int
314 fifo_poll(void *v)
315 {
316 struct vop_poll_args *ap = v;
317 struct file filetmp;
318 short ostate;
319 int revents = 0;
320
321 if (ap->a_events & (POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND)) {
322
323
324
325
326
327
328 ostate = ap->a_vp->v_fifoinfo->fi_readsock->so_state;
329 if (ap->a_events & (POLLIN | POLLRDNORM))
330 ap->a_vp->v_fifoinfo->fi_readsock->so_state &=
331 ~SS_CANTRCVMORE;
332 filetmp.f_data = ap->a_vp->v_fifoinfo->fi_readsock;
333 if (filetmp.f_data)
334 revents |= soo_poll(&filetmp, ap->a_events, ap->a_p);
335 ap->a_vp->v_fifoinfo->fi_readsock->so_state = ostate;
336 }
337 if (ap->a_events & (POLLOUT | POLLWRNORM | POLLWRBAND)) {
338 filetmp.f_data = ap->a_vp->v_fifoinfo->fi_writesock;
339 if (filetmp.f_data)
340 revents |= soo_poll(&filetmp, ap->a_events, ap->a_p);
341 }
342 return (revents);
343 }
344
345 int
346 fifo_inactive(void *v)
347 {
348 struct vop_inactive_args *ap = v;
349
350 VOP_UNLOCK(ap->a_vp, 0, ap->a_p);
351 return (0);
352 }
353
354
355
356
357 int
358 fifo_bmap(void *v)
359 {
360 struct vop_bmap_args *ap = v;
361
362 if (ap->a_vpp != NULL)
363 *ap->a_vpp = ap->a_vp;
364 if (ap->a_bnp != NULL)
365 *ap->a_bnp = ap->a_bn;
366 return (0);
367 }
368
369
370
371
372
373 int
374 fifo_close(void *v)
375 {
376 struct vop_close_args *ap = v;
377 struct vnode *vp = ap->a_vp;
378 struct fifoinfo *fip = vp->v_fifoinfo;
379 int error1 = 0, error2 = 0;
380
381 if (fip == NULL)
382 return (0);
383
384 if (ap->a_fflag & FREAD) {
385 if (--fip->fi_readers == 0)
386 socantsendmore(fip->fi_writesock);
387 }
388 if (ap->a_fflag & FWRITE) {
389 if (--fip->fi_writers == 0)
390 socantrcvmore(fip->fi_readsock);
391 }
392 if (fip->fi_readers == 0 && fip->fi_writers == 0) {
393 error1 = soclose(fip->fi_readsock);
394 error2 = soclose(fip->fi_writesock);
395 FREE(fip, M_VNODE);
396 vp->v_fifoinfo = NULL;
397 }
398 return (error1 ? error1 : error2);
399 }
400
401 int
402 fifo_reclaim(void *v)
403 {
404 struct vop_reclaim_args *ap = v;
405 struct vnode *vp = ap->a_vp;
406 struct fifoinfo *fip = vp->v_fifoinfo;
407
408 if (fip == NULL)
409 return (0);
410
411 soclose(fip->fi_readsock);
412 soclose(fip->fi_writesock);
413 FREE(fip, M_VNODE);
414 vp->v_fifoinfo = NULL;
415
416 return (0);
417 }
418
419
420
421
422 int
423 fifo_print(void *v)
424 {
425 struct vop_print_args *ap = v;
426
427 printf("tag VT_NON");
428 fifo_printinfo(ap->a_vp);
429 printf("\n");
430 return 0;
431 }
432
433
434
435
436 void
437 fifo_printinfo(struct vnode *vp)
438 {
439 struct fifoinfo *fip = vp->v_fifoinfo;
440
441 printf(", fifo with %ld readers and %ld writers",
442 fip->fi_readers, fip->fi_writers);
443 }
444
445
446
447
448 int
449 fifo_pathconf(void *v)
450 {
451 struct vop_pathconf_args *ap = v;
452
453 switch (ap->a_name) {
454 case _PC_LINK_MAX:
455 *ap->a_retval = LINK_MAX;
456 return (0);
457 case _PC_PIPE_BUF:
458 *ap->a_retval = PIPE_BUF;
459 return (0);
460 case _PC_CHOWN_RESTRICTED:
461 *ap->a_retval = 1;
462 return (0);
463 default:
464 return (EINVAL);
465 }
466
467 }
468
469
470
471
472
473 int
474 fifo_ebadf(void *v)
475 {
476
477 return (EBADF);
478 }
479
480
481
482
483
484 int
485 fifo_advlock(void *v)
486 {
487 return (EOPNOTSUPP);
488 }
489
490
491
492
493
494 int
495 fifo_badop(void *v)
496 {
497
498 panic("fifo_badop called");
499
500 return(0);
501 }
502
503
504 int
505 fifo_kqfilter(void *v)
506 {
507 struct vop_kqfilter_args *ap = v;
508 struct socket *so = (struct socket *)ap->a_vp->v_fifoinfo->fi_readsock;
509 struct sockbuf *sb;
510
511 switch (ap->a_kn->kn_filter) {
512 case EVFILT_READ:
513 ap->a_kn->kn_fop = &fiforead_filtops;
514 sb = &so->so_rcv;
515 break;
516 case EVFILT_WRITE:
517 ap->a_kn->kn_fop = &fifowrite_filtops;
518 sb = &so->so_snd;
519 break;
520 default:
521 return (1);
522 }
523
524 ap->a_kn->kn_hook = so;
525
526 SLIST_INSERT_HEAD(&sb->sb_sel.si_note, ap->a_kn, kn_selnext);
527 sb->sb_flags |= SB_KNOTE;
528
529 return (0);
530 }
531
532 void
533 filt_fifordetach(struct knote *kn)
534 {
535 struct socket *so = (struct socket *)kn->kn_hook;
536
537 SLIST_REMOVE(&so->so_rcv.sb_sel.si_note, kn, knote, kn_selnext);
538 if (SLIST_EMPTY(&so->so_rcv.sb_sel.si_note))
539 so->so_rcv.sb_flags &= ~SB_KNOTE;
540 }
541
542 int
543 filt_fiforead(struct knote *kn, long hint)
544 {
545 struct socket *so = (struct socket *)kn->kn_hook;
546
547 kn->kn_data = so->so_rcv.sb_cc;
548 if (so->so_state & SS_CANTRCVMORE) {
549 kn->kn_flags |= EV_EOF;
550 return (1);
551 }
552 kn->kn_flags &= ~EV_EOF;
553 return (kn->kn_data > 0);
554 }
555
556 void
557 filt_fifowdetach(struct knote *kn)
558 {
559 struct socket *so = (struct socket *)kn->kn_hook;
560
561 SLIST_REMOVE(&so->so_snd.sb_sel.si_note, kn, knote, kn_selnext);
562 if (SLIST_EMPTY(&so->so_snd.sb_sel.si_note))
563 so->so_snd.sb_flags &= ~SB_KNOTE;
564 }
565
566 int
567 filt_fifowrite(struct knote *kn, long hint)
568 {
569 struct socket *so = (struct socket *)kn->kn_hook;
570
571 kn->kn_data = sbspace(&so->so_snd);
572 if (so->so_state & SS_CANTSENDMORE) {
573 kn->kn_flags |= EV_EOF;
574 return (1);
575 }
576 kn->kn_flags &= ~EV_EOF;
577 return (kn->kn_data >= so->so_snd.sb_lowat);
578 }