#include <sys/types.h>
#include <sys/sysmacros.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/errno.h>
#include <sys/signal.h>
#include <sys/user.h>
#include <sys/fstyp.h>
#include <sys/stropts.h>
#include <sys/stream.h>
#include <sys/strsubr.h>
#include <sys/vnode.h>
#include <sys/file.h>
#include <sys/fs/fifonode.h>
#include <sys/debug.h>
#include <sys/ddi.h>
#include <sys/conf.h>
#include <sys/modctl.h>
extern struct streamtab conninfo;
static struct fmodsw fsw = {
"connld",
&conninfo,
D_NEW | D_MP
};
static struct modlstrmod modlstrmod = {
&mod_strmodops, "Streams-based pipes", &fsw
};
static struct modlinkage modlinkage = {
MODREV_1, (void *)&modlstrmod, NULL
};
int
_init()
{
return (mod_install(&modlinkage));
}
int
_fini()
{
return (mod_remove(&modlinkage));
}
int
_info(struct modinfo *modinfop)
{
return (mod_info(&modlinkage, modinfop));
}
int connopen(queue_t *, dev_t *, int, int, cred_t *);
int connclose(queue_t *, int, cred_t *);
int connput(queue_t *, mblk_t *);
static struct module_info conn_info = {
1003,
"connld",
0,
INFPSZ,
STRHIGH,
STRLOW
};
static struct qinit connrinit = {
connput,
NULL,
connopen,
connclose,
NULL,
&conn_info,
NULL
};
static struct qinit connwinit = {
connput,
NULL,
NULL,
NULL,
NULL,
&conn_info,
NULL
};
struct streamtab conninfo = {
&connrinit,
&connwinit
};
int
connopen(queue_t *rqp, dev_t *devp, int flag, int sflag, cred_t *crp)
{
int error = 0;
vnode_t *streamvp;
fifonode_t *streamfnp;
if ((streamvp = strq2vp(rqp)) == NULL) {
return (EINVAL);
}
if (streamvp->v_type != VFIFO) {
error = EINVAL;
goto out;
}
streamfnp = VTOF(streamvp);
if (!(streamfnp->fn_flag & ISPIPE) ||
streamfnp->fn_dest->fn_open == 0) {
error = EPIPE;
goto out;
}
if (rqp->q_ptr == 0) {
if (streamfnp->fn_flag & FIFOCONNLD) {
error = ENXIO;
goto out;
}
rqp->q_ptr = (caddr_t)1;
streamfnp->fn_flag |= FIFOCONNLD;
qprocson(rqp);
}
out:
VN_RELE(streamvp);
return (error);
}
int
connclose(queue_t *q, int cflag, cred_t *crp)
{
vnode_t *streamvp;
fifonode_t *streamfnp;
qprocsoff(q);
streamvp = strq2vp(q);
ASSERT(streamvp != NULL);
ASSERT(streamvp->v_type == VFIFO);
streamfnp = VTOF(streamvp);
streamfnp->fn_flag &= ~FIFOCONNLD;
VN_RELE(streamvp);
return (0);
}
int
connput(queue_t *q, mblk_t *bp)
{
putnext(q, bp);
return (0);
}