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 
 
 |