8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
22 /* All Rights Reserved */
23
24
25 /*
26 * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
27 * Copyright 2017 Joyent, Inc.
28 */
29
30 #include <sys/types.h>
31 #include <sys/sysmacros.h>
32 #include <sys/param.h>
33 #include <sys/errno.h>
34 #include <sys/signal.h>
35 #include <sys/stat.h>
36 #include <sys/proc.h>
37 #include <sys/cred.h>
38 #include <sys/user.h>
39 #include <sys/vnode.h>
40 #include <sys/file.h>
41 #include <sys/stream.h>
42 #include <sys/strsubr.h>
43 #include <sys/stropts.h>
44 #include <sys/tihdr.h>
45 #include <sys/var.h>
46 #include <sys/poll.h>
47 #include <sys/termio.h>
3766 dev_t dummydev;
3767
3768 if (stp->sd_flag & STRHUP)
3769 return (ENXIO);
3770
3771 /*
3772 * Get module name and look up in fmodsw.
3773 */
3774 error = (copyflag & U_TO_K ? copyinstr : copystr)((void *)arg,
3775 mname, FMNAMESZ + 1, NULL);
3776 if (error)
3777 return ((error == ENAMETOOLONG) ? EINVAL : EFAULT);
3778
3779 if ((fp = fmodsw_find(mname, FMODSW_HOLD | FMODSW_LOAD)) ==
3780 NULL)
3781 return (EINVAL);
3782
3783 TRACE_2(TR_FAC_STREAMS_FR, TR_I_PUSH,
3784 "I_PUSH:fp %p stp %p", fp, stp);
3785
3786 if (error = strstartplumb(stp, flag, cmd)) {
3787 fmodsw_rele(fp);
3788 return (error);
3789 }
3790
3791 /*
3792 * See if any more modules can be pushed on this stream.
3793 * Note that this check must be done after strstartplumb()
3794 * since otherwise multiple threads issuing I_PUSHes on
3795 * the same stream will be able to exceed nstrpush.
3796 */
3797 mutex_enter(&stp->sd_lock);
3798 if (stp->sd_pushcnt >= nstrpush) {
3799 fmodsw_rele(fp);
3800 strendplumb(stp);
3801 mutex_exit(&stp->sd_lock);
3802 return (EINVAL);
3803 }
3804 mutex_exit(&stp->sd_lock);
3805
|
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
22 /* All Rights Reserved */
23
24
25 /*
26 * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
27 * Copyright 2017 Joyent, Inc.
28 * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
29 */
30
31 #include <sys/types.h>
32 #include <sys/sysmacros.h>
33 #include <sys/param.h>
34 #include <sys/errno.h>
35 #include <sys/signal.h>
36 #include <sys/stat.h>
37 #include <sys/proc.h>
38 #include <sys/cred.h>
39 #include <sys/user.h>
40 #include <sys/vnode.h>
41 #include <sys/file.h>
42 #include <sys/stream.h>
43 #include <sys/strsubr.h>
44 #include <sys/stropts.h>
45 #include <sys/tihdr.h>
46 #include <sys/var.h>
47 #include <sys/poll.h>
48 #include <sys/termio.h>
3767 dev_t dummydev;
3768
3769 if (stp->sd_flag & STRHUP)
3770 return (ENXIO);
3771
3772 /*
3773 * Get module name and look up in fmodsw.
3774 */
3775 error = (copyflag & U_TO_K ? copyinstr : copystr)((void *)arg,
3776 mname, FMNAMESZ + 1, NULL);
3777 if (error)
3778 return ((error == ENAMETOOLONG) ? EINVAL : EFAULT);
3779
3780 if ((fp = fmodsw_find(mname, FMODSW_HOLD | FMODSW_LOAD)) ==
3781 NULL)
3782 return (EINVAL);
3783
3784 TRACE_2(TR_FAC_STREAMS_FR, TR_I_PUSH,
3785 "I_PUSH:fp %p stp %p", fp, stp);
3786
3787 /*
3788 * If the module is flagged as single-instance, then check
3789 * to see if the module is already pushed. If it is, return
3790 * as if the push was successful.
3791 */
3792 if (fp->f_qflag & _QSINGLE_INSTANCE) {
3793 queue_t *q;
3794
3795 claimstr(stp->sd_wrq);
3796 for (q = stp->sd_wrq->q_next; q; q = q->q_next) {
3797 if (q->q_flag & QREADR) {
3798 q = NULL;
3799 break;
3800 }
3801 if (strcmp(mname, Q2NAME(q)) == 0)
3802 break;
3803 }
3804 releasestr(stp->sd_wrq);
3805 if (q != NULL) {
3806 fmodsw_rele(fp);
3807 return (0);
3808 }
3809 }
3810
3811 if (error = strstartplumb(stp, flag, cmd)) {
3812 fmodsw_rele(fp);
3813 return (error);
3814 }
3815
3816 /*
3817 * See if any more modules can be pushed on this stream.
3818 * Note that this check must be done after strstartplumb()
3819 * since otherwise multiple threads issuing I_PUSHes on
3820 * the same stream will be able to exceed nstrpush.
3821 */
3822 mutex_enter(&stp->sd_lock);
3823 if (stp->sd_pushcnt >= nstrpush) {
3824 fmodsw_rele(fp);
3825 strendplumb(stp);
3826 mutex_exit(&stp->sd_lock);
3827 return (EINVAL);
3828 }
3829 mutex_exit(&stp->sd_lock);
3830
|