* Copyright (c) 1990 The Regents of the University of California.
* %sccs.include.redist.c%
* @(#)fifo_vnops.c 7.10 (Berkeley) %G%
* This structure is associated with the FIFO vnode and stores
* the state associated with the FIFO.
struct socket
*fi_readsock
;
struct socket
*fi_writesock
;
struct vnodeops fifo_vnodeops
= {
fifo_lookup
, /* lookup */
fifo_create
, /* create */
fifo_access
, /* access */
fifo_getattr
, /* getattr */
fifo_setattr
, /* setattr */
fifo_select
, /* select */
fifo_remove
, /* remove */
fifo_rename
, /* rename */
fifo_symlink
, /* symlink */
fifo_readdir
, /* readdir */
fifo_readlink
, /* readlink */
fifo_abortop
, /* abortop */
fifo_inactive
, /* inactive */
fifo_reclaim
, /* reclaim */
fifo_unlock
, /* unlock */
fifo_strategy
, /* strategy */
fifo_islocked
, /* islocked */
fifo_advlock
, /* advlock */
fifo_blkatoff
, /* blkatoff */
fifo_valloc
, /* valloc */
fifo_truncate
, /* truncate */
fifo_update
, /* update */
fifo_bwrite
, /* bwrite */
* Trivial lookup routine that always fails.
fifo_lookup(dvp
, vpp
, cnp
)
struct componentname
*cnp
;
* Open called to set up a new instance of a fifo or
* to find an active instance of a fifo.
fifo_open(vp
, mode
, cred
, p
)
register struct vnode
*vp
;
register struct fifoinfo
*fip
;
struct socket
*rso
, *wso
;
static char openstr
[] = "fifo";
if ((mode
& (FREAD
|FWRITE
)) == (FREAD
|FWRITE
))
if ((fip
= vp
->v_fifoinfo
) == NULL
) {
MALLOC(fip
, struct fifoinfo
*, sizeof(*fip
), M_VNODE
, M_WAITOK
);
if (error
= socreate(AF_UNIX
, &rso
, SOCK_STREAM
, 0)) {
if (error
= socreate(AF_UNIX
, &wso
, SOCK_STREAM
, 0)) {
if (error
= unp_connect2(wso
, rso
)) {
wso
->so_state
|= SS_CANTRCVMORE
;
rso
->so_state
|= SS_CANTSENDMORE
;
if (fip
->fi_readers
== 1) {
fip
->fi_writesock
->so_state
&= ~SS_CANTSENDMORE
;
wakeup((caddr_t
)&fip
->fi_writers
);
while (fip
->fi_writers
== 0)
if (error
= tsleep((caddr_t
)&fip
->fi_readers
, PSOCK
,
if (fip
->fi_readers
== 0 && (mode
& O_NONBLOCK
)) {
if (fip
->fi_writers
== 1) {
fip
->fi_readsock
->so_state
&= ~SS_CANTRCVMORE
;
wakeup((caddr_t
)&fip
->fi_readers
);
while (fip
->fi_readers
== 0)
if (error
= tsleep((caddr_t
)&fip
->fi_writers
,
fifo_close(vp
, mode
, cred
, p
);
fifo_read(vp
, uio
, ioflag
, cred
)
register struct uio
*uio
;
register struct socket
*rso
= vp
->v_fifoinfo
->fi_readsock
;
if (uio
->uio_rw
!= UIO_READ
)
rso
->so_state
|= SS_NBIO
;
startresid
= uio
->uio_resid
;
error
= soreceive(rso
, (struct mbuf
**)0, uio
, (int *)0,
(struct mbuf
**)0, (struct mbuf
**)0);
* Clear EOF indication after first such return.
if (uio
->uio_resid
== startresid
)
rso
->so_state
&= ~SS_CANTRCVMORE
;
rso
->so_state
&= ~SS_NBIO
;
fifo_write(vp
, uio
, ioflag
, cred
)
register struct uio
*uio
;
struct socket
*wso
= vp
->v_fifoinfo
->fi_writesock
;
if (uio
->uio_rw
!= UIO_WRITE
)
panic("fifo_write mode");
wso
->so_state
|= SS_NBIO
;
error
= sosend(wso
, (struct mbuf
*)0, uio
, 0, (struct mbuf
*)0);
wso
->so_state
&= ~SS_NBIO
;
* Device ioctl operation.
fifo_ioctl(vp
, com
, data
, fflag
, cred
, p
)
filetmp
.f_data
= (caddr_t
)vp
->v_fifoinfo
->fi_readsock
;
filetmp
.f_data
= (caddr_t
)vp
->v_fifoinfo
->fi_writesock
;
return (soo_ioctl(&filetmp
, com
, data
, p
));
fifo_select(vp
, which
, fflag
, cred
, p
)
filetmp
.f_data
= (caddr_t
)vp
->v_fifoinfo
->fi_readsock
;
filetmp
.f_data
= (caddr_t
)vp
->v_fifoinfo
->fi_writesock
;
return (soo_select(&filetmp
, which
, p
));
* This is a noop, simply returning what one has been given.
fifo_bmap(vp
, bn
, vpp
, bnp
)
* At the moment we do not do any locking.
fifo_close(vp
, fflag
, cred
, p
)
register struct vnode
*vp
;
register struct fifoinfo
*fip
= vp
->v_fifoinfo
;
if (fip
->fi_writers
== 0)
socantrcvmore(fip
->fi_readsock
);
if (fip
->fi_readers
== 0)
socantsendmore(fip
->fi_writesock
);
error1
= soclose(fip
->fi_readsock
);
error2
= soclose(fip
->fi_writesock
);
* Print out the contents of a fifo vnode.
* Print out internal contents of a fifo vnode.
register struct fifoinfo
*fip
= vp
->v_fifoinfo
;
printf(", fifo with %d readers and %d writers",
fip
->fi_readers
, fip
->fi_writers
);
* Fifo advisory byte-level locks.
fifo_advlock(vp
, id
, op
, fl
, flags
)
panic("fifo_badop called");