diff options
author | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
---|---|---|
committer | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
commit | 7c478bd95313f5f23a4c958a745db2134aa03244 (patch) | |
tree | c871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/uts/common/io/connld.c | |
download | illumos-joyent-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz |
OpenSolaris Launch
Diffstat (limited to 'usr/src/uts/common/io/connld.c')
-rw-r--r-- | usr/src/uts/common/io/connld.c | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/usr/src/uts/common/io/connld.c b/usr/src/uts/common/io/connld.c new file mode 100644 index 0000000000..5acc22879f --- /dev/null +++ b/usr/src/uts/common/io/connld.c @@ -0,0 +1,222 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ +/* All Rights Reserved */ + + +#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4 1.8 */ + +/* + * This module establishes a unique connection on + * a STREAMS-based pipe. + */ +#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> + +/* + * This is the loadable module wrapper. + */ +#include <sys/conf.h> +#include <sys/modctl.h> + +extern struct streamtab conninfo; + +static struct fmodsw fsw = { + "connld", + &conninfo, + D_NEW | D_MP +}; + +/* + * Module linkage information for the kernel. + */ + +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)); +} + +/* + * Define local and external routines. + */ +int connopen(queue_t *, dev_t *, int, int, cred_t *); +int connclose(queue_t *, int, cred_t *); +int connput(queue_t *, mblk_t *); + +/* + * Define STREAMS header information. + */ +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 +}; + +/* + * For each invocation of connopen(), create a new pipe. One end of the pipe + * is sent to the process on the other end of this STREAM. The vnode for + * the other end is returned to the open() system call as the vnode for + * the opened object. + * + * On the first invocation of connopen(), a flag is set and the routine + * returns 0, since the first open corresponds to the pushing of the module. + */ +/*ARGSUSED*/ +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); + } + + /* + * CONNLD is only allowed to be pushed onto a "pipe" that has both + * of its ends open. + */ + 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 this is the first time CONNLD was opened while on this stream, + * it is being pushed. Therefore, set a flag and return 0. + */ + 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); +} + +/*ARGSUSED*/ +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); +} + +/* + * Use same put procedure for write and read queues. + */ +int +connput(queue_t *q, mblk_t *bp) +{ + putnext(q, bp); + return (0); +} |