Print this page
MFV: illumos-gate@39cc040ff7c0c62aae858381f21d0567dd60042e
9967 dflt_termios and base_termios need update
Reviewed by: Andy Fiddaman <omnios@citrus-it.net>
Reviewed by: Jason King <jason.king@joyent.com>
Approved by: Dan McDonald <danmcd@joyent.com>
Author: Toomas Soome <tsoome@me.com>
9042 multiples of tty streams modules cause weirdness
Reviewed by: Randy Fishel <randyf@sibernet.com>
Reviewed by: Carlos Neira <cneirabustos@gmail.com>
Approved by: Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   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 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.

  24  */
  25 
  26 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  27 /*        All Rights Reserved   */
  28 
  29 /*
  30  * University Copyright- Copyright (c) 1982, 1986, 1988
  31  * The Regents of the University of California
  32  * All Rights Reserved
  33  *
  34  * University Acknowledgment- Portions of this document are derived from
  35  * software developed by the University of California, Berkeley, and its
  36  * contributors.
  37  */
  38 
  39 /*
  40  * Module to intercept old V7 and 4BSD "ioctl" calls.
  41  */
  42 
  43 #include <sys/types.h>


  56 #include <sys/ttcompat.h>
  57 #include <sys/ddi.h>
  58 #include <sys/sunddi.h>
  59 #include <sys/kmem.h>
  60 #include <sys/policy.h>
  61 
  62 /*
  63  * This is the loadable module wrapper.
  64  */
  65 #include <sys/conf.h>
  66 #include <sys/modctl.h>
  67 
  68 /* See os/streamio.c */
  69 extern int sgttyb_handling;
  70 
  71 static struct streamtab ttcoinfo;
  72 
  73 static struct fmodsw fsw = {
  74         "ttcompat",
  75         &ttcoinfo,
  76         D_MTQPAIR | D_MP
  77 };
  78 
  79 /*
  80  * Module linkage information for the kernel.
  81  */
  82 
  83 static struct modlstrmod modlstrmod = {
  84         &mod_strmodops,
  85         "alt ioctl calls",
  86         &fsw
  87 };
  88 
  89 static struct modlinkage modlinkage = {
  90         MODREV_1, &modlstrmod, NULL
  91 };
  92 
  93 int
  94 _init(void)
  95 {
  96         return (mod_install(&modlinkage));


 139         300,
 140         200
 141 };
 142 
 143 static struct qinit ttycompatwinit = {
 144         (int (*)())ttcompatwput,
 145         NULL,
 146         ttcompatopen,
 147         ttcompatclose,
 148         NULL,
 149         &ttycompatmoinfo
 150 };
 151 
 152 static struct streamtab ttcoinfo = {
 153         &ttycompatrinit,
 154         &ttycompatwinit,
 155         NULL,
 156         NULL
 157 };
 158 
 159 /*
 160  * This is the termios structure that is used to reset terminal settings
 161  * when the underlying device is an instance of zcons.  It came from
 162  * cmd/init/init.c and should be kept in-sync with dflt_termios found therein.
 163  */
 164 static const struct termios base_termios = {
 165         BRKINT|ICRNL|IXON|IMAXBEL,                              /* iflag */
 166         OPOST|ONLCR|TAB3,                                       /* oflag */
 167         CS8|CREAD|B9600,                                        /* cflag */
 168         ISIG|ICANON|ECHO|ECHOE|ECHOK|ECHOCTL|ECHOKE|IEXTEN,     /* lflag */
 169         CINTR, CQUIT, CERASE, CKILL, CEOF, 0, 0, 0, 0, 0, 0, 0, /* c_cc vals */
 170         0, 0, 0, 0, 0, 0, 0
 171 };
 172 
 173 
 174 static void ttcompat_do_ioctl(ttcompat_state_t *, queue_t *, mblk_t *);
 175 static void ttcompat_ioctl_ack(queue_t *, mblk_t *);
 176 static void ttcopyout(queue_t *, mblk_t *);
 177 static void ttcompat_ioctl_nak(queue_t *, mblk_t *);
 178 static void from_compat(compat_state_t *, struct termios *);
 179 static void to_compat(struct termios *, compat_state_t *);
 180 
 181 /*
 182  * Open - get the current modes and translate them to the V7/4BSD equivalent.
 183  */
 184 /*ARGSUSED*/
 185 static int
 186 ttcompatopen(queue_t *q, dev_t *devp, int oflag, int sflag, cred_t *crp)
 187 {
 188         ttcompat_state_t *tp;
 189         mblk_t *mp;
 190         mblk_t *datamp;
 191         struct iocblk *iocb;
 192         int error;
 193 
 194         if (q->q_ptr != NULL)  {
 195                 tp = (ttcompat_state_t *)q->q_ptr;
 196                 /* fail open if TIOCEXCL was done and its not privileged */
 197                 if ((tp->t_new_lflags & XCLUDE) &&
 198                     secpolicy_excl_open(crp) != 0) {
 199                         return (EBUSY);
 200                 }
 201                 return (0);             /* already attached */
 202         }
 203         tp = kmem_zalloc(sizeof (ttcompat_state_t), KM_SLEEP);
 204         tp->t_iocpending = NULL;
 205         tp->t_state = 0;
 206         tp->t_iocid = 0;
 207         tp->t_ioccmd = 0;
 208         tp->t_new_lflags = 0;
 209         tp->t_curstate.t_flags = 0;
 210         tp->t_curstate.t_ispeed = B0;
 211         tp->t_curstate.t_ospeed = B0;
 212         tp->t_curstate.t_erase = '\0';
 213         tp->t_curstate.t_kill = '\0';
 214         tp->t_curstate.t_intrc = '\0';
 215         tp->t_curstate.t_quitc = '\0';
 216         tp->t_curstate.t_startc = '\0';
 217         tp->t_curstate.t_stopc = '\0';
 218         tp->t_curstate.t_eofc = '\0';
 219         tp->t_curstate.t_brkc = '\0';
 220         tp->t_curstate.t_suspc = '\0';
 221         tp->t_curstate.t_dsuspc = '\0';
 222         tp->t_curstate.t_rprntc = '\0';
 223         tp->t_curstate.t_flushc = '\0';
 224         tp->t_curstate.t_werasc = '\0';
 225         tp->t_curstate.t_lnextc = '\0';
 226         tp->t_curstate.t_xflags = 0;
 227         tp->t_bufcallid = 0;
 228         tp->t_arg = 0;
 229 
 230         q->q_ptr = tp;
 231         WR(q)->q_ptr = tp;
 232         qprocson(q);
 233 
 234         /*
 235          * Determine if the underlying device is a zcons instance.  If so,
 236          * then issue a termios ioctl to reset the terminal settings.
 237          */
 238         if (getmajor(q->q_stream->sd_vnode->v_rdev) !=
 239             ddi_name_to_major("zcons"))
 240                 return (0);
 241 
 242         /*
 243          * Create the ioctl message.
 244          */
 245         if ((mp = mkiocb(TCSETSF)) == NULL) {
 246                 error = ENOMEM;
 247                 goto common_error;
 248         }
 249         if ((datamp = allocb(sizeof (struct termios), BPRI_HI)) == NULL) {
 250                 freemsg(mp);
 251                 error = ENOMEM;
 252                 goto common_error;
 253         }
 254         iocb = (struct iocblk *)mp->b_rptr;
 255         iocb->ioc_count = sizeof (struct termios);
 256         bcopy(&base_termios, datamp->b_rptr, sizeof (struct termios));
 257         datamp->b_wptr += sizeof (struct termios);
 258         mp->b_cont = datamp;
 259 
 260         /*
 261          * Send the ioctl message on its merry way toward the driver.
 262          * Set some state beforehand so we can properly wait for
 263          * an acknowledgement.
 264          */
 265         tp->t_state |= TS_IOCWAIT | TS_TIOCNAK;
 266         tp->t_iocid = iocb->ioc_id;
 267         tp->t_ioccmd = TCSETSF;
 268         putnext(WR(q), mp);
 269 
 270         /*
 271          * Wait for an acknowledgement.  A NAK is treated as an error.
 272          * The presence of the TS_TIOCNAK flag indicates that a NAK was
 273          * received.
 274          */
 275         while (tp->t_state & TS_IOCWAIT) {
 276                 if (qwait_sig(q) == 0) {
 277                         error = EINTR;
 278                         goto common_error;
 279                 }
 280         }
 281         if (!(tp->t_state & TS_TIOCNAK))
 282                 return (0);
 283         error = ENOTTY;
 284 
 285 common_error:
 286         qprocsoff(q);
 287         kmem_free(tp, sizeof (ttcompat_state_t));
 288         q->q_ptr = NULL;
 289         WR(q)->q_ptr = NULL;
 290         return (error);
 291 }
 292 
 293 /* ARGSUSED1 */
 294 static int
 295 ttcompatclose(queue_t *q, int flag, cred_t *crp)
 296 {
 297         ttcompat_state_t *tp = (ttcompat_state_t *)q->q_ptr;
 298         mblk_t *mp;
 299 
 300         /* Dump the state structure, then unlink it */
 301         qprocsoff(q);
 302         if (tp->t_bufcallid != 0) {
 303                 qunbufcall(q, tp->t_bufcallid);
 304                 tp->t_bufcallid = 0;
 305         }
 306         if ((mp = tp->t_iocpending) != NULL)
 307                 freemsg(mp);
 308         kmem_free(tp, sizeof (ttcompat_state_t));
 309         q->q_ptr = NULL;
 310 




   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   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 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
  25  */
  26 
  27 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  28 /*        All Rights Reserved   */
  29 
  30 /*
  31  * University Copyright- Copyright (c) 1982, 1986, 1988
  32  * The Regents of the University of California
  33  * All Rights Reserved
  34  *
  35  * University Acknowledgment- Portions of this document are derived from
  36  * software developed by the University of California, Berkeley, and its
  37  * contributors.
  38  */
  39 
  40 /*
  41  * Module to intercept old V7 and 4BSD "ioctl" calls.
  42  */
  43 
  44 #include <sys/types.h>


  57 #include <sys/ttcompat.h>
  58 #include <sys/ddi.h>
  59 #include <sys/sunddi.h>
  60 #include <sys/kmem.h>
  61 #include <sys/policy.h>
  62 
  63 /*
  64  * This is the loadable module wrapper.
  65  */
  66 #include <sys/conf.h>
  67 #include <sys/modctl.h>
  68 
  69 /* See os/streamio.c */
  70 extern int sgttyb_handling;
  71 
  72 static struct streamtab ttcoinfo;
  73 
  74 static struct fmodsw fsw = {
  75         "ttcompat",
  76         &ttcoinfo,
  77         D_MTQPAIR | D_MP | _D_SINGLE_INSTANCE
  78 };
  79 
  80 /*
  81  * Module linkage information for the kernel.
  82  */
  83 
  84 static struct modlstrmod modlstrmod = {
  85         &mod_strmodops,
  86         "alt ioctl calls",
  87         &fsw
  88 };
  89 
  90 static struct modlinkage modlinkage = {
  91         MODREV_1, &modlstrmod, NULL
  92 };
  93 
  94 int
  95 _init(void)
  96 {
  97         return (mod_install(&modlinkage));


 140         300,
 141         200
 142 };
 143 
 144 static struct qinit ttycompatwinit = {
 145         (int (*)())ttcompatwput,
 146         NULL,
 147         ttcompatopen,
 148         ttcompatclose,
 149         NULL,
 150         &ttycompatmoinfo
 151 };
 152 
 153 static struct streamtab ttcoinfo = {
 154         &ttycompatrinit,
 155         &ttycompatwinit,
 156         NULL,
 157         NULL
 158 };
 159 















 160 static void ttcompat_do_ioctl(ttcompat_state_t *, queue_t *, mblk_t *);
 161 static void ttcompat_ioctl_ack(queue_t *, mblk_t *);
 162 static void ttcopyout(queue_t *, mblk_t *);
 163 static void ttcompat_ioctl_nak(queue_t *, mblk_t *);
 164 static void from_compat(compat_state_t *, struct termios *);
 165 static void to_compat(struct termios *, compat_state_t *);
 166 
 167 /*
 168  * Open - get the current modes and translate them to the V7/4BSD equivalent.
 169  */
 170 /*ARGSUSED*/
 171 static int
 172 ttcompatopen(queue_t *q, dev_t *devp, int oflag, int sflag, cred_t *crp)
 173 {
 174         ttcompat_state_t *tp;




 175 
 176         if (q->q_ptr != NULL)  {
 177                 tp = (ttcompat_state_t *)q->q_ptr;
 178                 /* fail open if TIOCEXCL was done and its not privileged */
 179                 if ((tp->t_new_lflags & XCLUDE) &&
 180                     secpolicy_excl_open(crp) != 0) {
 181                         return (EBUSY);
 182                 }
 183                 return (0);             /* already attached */
 184         }
 185         tp = kmem_zalloc(sizeof (ttcompat_state_t), KM_SLEEP);


























 186         q->q_ptr = tp;
 187         WR(q)->q_ptr = tp;
 188         qprocson(q);
 189 






 190         return (0);


















































 191 }
 192 
 193 /* ARGSUSED1 */
 194 static int
 195 ttcompatclose(queue_t *q, int flag, cred_t *crp)
 196 {
 197         ttcompat_state_t *tp = (ttcompat_state_t *)q->q_ptr;
 198         mblk_t *mp;
 199 
 200         /* Dump the state structure, then unlink it */
 201         qprocsoff(q);
 202         if (tp->t_bufcallid != 0) {
 203                 qunbufcall(q, tp->t_bufcallid);
 204                 tp->t_bufcallid = 0;
 205         }
 206         if ((mp = tp->t_iocpending) != NULL)
 207                 freemsg(mp);
 208         kmem_free(tp, sizeof (ttcompat_state_t));
 209         q->q_ptr = NULL;
 210