1 /*
   2  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
   3  * Use is subject to license terms.
   4  * Copyright 2015, Joyent, Inc.
   5  */
   6 
   7 /*
   8  * Copyright (c) 1983 Regents of the University of California.
   9  * All rights reserved. The Berkeley software License Agreement
  10  * specifies the terms and conditions for redistribution.
  11  */
  12 
  13 /*
  14  * PTY - Stream "pseudo-tty" device.  For each "controller" side
  15  * it connects to a "slave" side.
  16  */
  17 
  18 
  19 #include <sys/param.h>
  20 #include <sys/systm.h>
  21 #include <sys/filio.h>
  22 #include <sys/ioccom.h>
  23 #include <sys/termios.h>
  24 #include <sys/termio.h>
  25 #include <sys/ttold.h>
  26 #include <sys/stropts.h>
  27 #include <sys/stream.h>
  28 #include <sys/tty.h>
  29 #include <sys/user.h>
  30 #include <sys/conf.h>
  31 #include <sys/file.h>
  32 #include <sys/vnode.h>    /* 1/0 on the vomit meter */
  33 #include <sys/proc.h>
  34 #include <sys/uio.h>
  35 #include <sys/errno.h>
  36 #include <sys/strsubr.h>
  37 #include <sys/poll.h>
  38 #include <sys/sysmacros.h>
  39 #include <sys/debug.h>
  40 #include <sys/procset.h>
  41 #include <sys/cred.h>
  42 #include <sys/ptyvar.h>
  43 #include <sys/suntty.h>
  44 #include <sys/stat.h>
  45 
  46 #include <sys/conf.h>
  47 #include <sys/ddi.h>
  48 #include <sys/sunddi.h>
  49 
  50 extern int npty;        /* number of pseudo-ttys configured in */
  51 extern struct pty *pty_softc;
  52 extern struct pollhead  ptcph;  /* poll head for ptcpoll() use */
  53 
  54 int ptcopen(dev_t *, int, int, struct cred *);
  55 int ptcclose(dev_t, int, int, struct cred *);
  56 int ptcwrite(dev_t, struct uio *, struct cred *);
  57 int ptcread(dev_t, struct uio *, struct cred *);
  58 int ptcioctl(dev_t, int, intptr_t, int, struct cred *, int *);
  59 int ptcpoll(dev_t, short, int, short *, struct pollhead **);
  60 
  61 static int ptc_info(dev_info_t *, ddi_info_cmd_t, void *, void **);
  62 static int ptc_attach(dev_info_t *, ddi_attach_cmd_t);
  63 static dev_info_t *ptc_dip;     /* for dev-to-dip conversions */
  64 
  65 static void ptc_init(void), ptc_uninit(void);
  66 
  67 static int makemsg(ssize_t count, struct uio *uiop,
  68     struct pty *pty, mblk_t **mpp);
  69 
  70 struct cb_ops   ptc_cb_ops = {
  71         ptcopen,                /* open */
  72         ptcclose,               /* close */
  73         nodev,                  /* strategy */
  74         nodev,                  /* print */
  75         nodev,                  /* dump */
  76         ptcread,                /* read */
  77         ptcwrite,               /* write */
  78         ptcioctl,               /* ioctl */
  79         nodev,                  /* devmap */
  80         nodev,                  /* mmap */
  81         nodev,                  /* segmap */
  82         ptcpoll,                /* poll */
  83         ddi_prop_op,            /* prop_op */
  84         0,                      /* streamtab */
  85         D_NEW | D_MP            /* Driver compatibility flag */
  86 };
  87 
  88 struct dev_ops  ptc_ops = {
  89         DEVO_REV,               /* devo_rev */
  90         0,                      /* refcnt */
  91         ptc_info,               /* info */
  92         nulldev,                /* identify */
  93         nulldev,                /* probe */
  94         ptc_attach,             /* attach */
  95         nodev,                  /* detach */
  96         nodev,                  /* reset */
  97         &ptc_cb_ops,                /* driver operations */
  98         (struct bus_ops *)0,    /* bus operations */
  99         NULL,                   /* power */
 100         ddi_quiesce_not_supported,      /* devo_quiesce */
 101 };
 102 
 103 #include <sys/types.h>
 104 #include <sys/conf.h>
 105 #include <sys/param.h>
 106 #include <sys/systm.h>
 107 #include <sys/errno.h>
 108 #include <sys/modctl.h>
 109 
 110 extern int dseekneg_flag;
 111 extern struct mod_ops mod_driverops;
 112 extern struct dev_ops ptc_ops;
 113 
 114 /*
 115  * Module linkage information for the kernel.
 116  */
 117 
 118 static struct modldrv modldrv = {
 119         &mod_driverops, /* Type of module.  This one is a pseudo driver */
 120         "tty pseudo driver control 'ptc'",
 121         &ptc_ops,   /* driver ops */
 122 };
 123 
 124 static struct modlinkage modlinkage = {
 125         MODREV_1,
 126         { &modldrv, NULL }
 127 };
 128 
 129 int
 130 _init()
 131 {
 132         int rc;
 133 
 134         if ((rc = mod_install(&modlinkage)) == 0)
 135                 ptc_init();
 136         return (rc);
 137 }
 138 
 139 
 140 int
 141 _fini()
 142 {
 143         int rc;
 144 
 145         if ((rc = mod_remove(&modlinkage)) == 0)
 146                 ptc_uninit();
 147         return (rc);
 148 }
 149 
 150 int
 151 _info(struct modinfo *modinfop)
 152 {
 153         return (mod_info(&modlinkage, modinfop));
 154 }
 155 
 156 static char     *pty_banks = PTY_BANKS;
 157 static char     *pty_digits = PTY_DIGITS;
 158 
 159 /* ARGSUSED */
 160 static int
 161 ptc_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
 162 {
 163         char    name[8];
 164         int     pty_num;
 165         char    *pty_digit = pty_digits;
 166         char    *pty_bank = pty_banks;
 167 
 168         for (pty_num = 0; pty_num < npty; pty_num++) {
 169                 (void) sprintf(name, "pty%c%c", *pty_bank, *pty_digit);
 170                 if (ddi_create_minor_node(devi, name, S_IFCHR,
 171                     pty_num, DDI_PSEUDO, NULL) == DDI_FAILURE) {
 172                         ddi_remove_minor_node(devi, NULL);
 173                         return (-1);
 174                 }
 175                 if (*(++pty_digit) == '\0') {
 176                         pty_digit = pty_digits;
 177                         if (*(++pty_bank) == '\0')
 178                                 break;
 179                 }
 180         }
 181         ptc_dip = devi;
 182         return (DDI_SUCCESS);
 183 }
 184 
 185 /* ARGSUSED */
 186 static int
 187 ptc_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
 188 {
 189         int error;
 190 
 191         switch (infocmd) {
 192         case DDI_INFO_DEVT2DEVINFO:
 193                 if (ptc_dip == NULL) {
 194                         *result = (void *)NULL;
 195                         error = DDI_FAILURE;
 196                 } else {
 197                         *result = (void *) ptc_dip;
 198                         error = DDI_SUCCESS;
 199                 }
 200                 break;
 201         case DDI_INFO_DEVT2INSTANCE:
 202                 *result = (void *)0;
 203                 error = DDI_SUCCESS;
 204                 break;
 205         default:
 206                 error = DDI_FAILURE;
 207         }
 208         return (error);
 209 }
 210 
 211 static void
 212 ptc_init(void)
 213 {
 214         minor_t dev;
 215 
 216         for (dev = 0; dev < npty; dev++) {
 217                 cv_init(&pty_softc[dev].pt_cv_flags, NULL, CV_DEFAULT, NULL);
 218                 cv_init(&pty_softc[dev].pt_cv_readq, NULL, CV_DEFAULT, NULL);
 219                 cv_init(&pty_softc[dev].pt_cv_writeq, NULL, CV_DEFAULT, NULL);
 220                 mutex_init(&pty_softc[dev].ptc_lock, NULL, MUTEX_DEFAULT, NULL);
 221         }
 222 }
 223 
 224 static void
 225 ptc_uninit(void)
 226 {
 227         minor_t dev;
 228 
 229         for (dev = 0; dev < npty; dev++) {
 230                 cv_destroy(&pty_softc[dev].pt_cv_flags);
 231                 cv_destroy(&pty_softc[dev].pt_cv_readq);
 232                 cv_destroy(&pty_softc[dev].pt_cv_writeq);
 233                 mutex_destroy(&pty_softc[dev].ptc_lock);
 234         }
 235 }
 236 
 237 /*
 238  * Controller side.  This is not, alas, a streams device; there are too
 239  * many old features that we must support and that don't work well
 240  * with streams.
 241  */
 242 
 243 /*ARGSUSED*/
 244 int
 245 ptcopen(dev_t *devp, int flag, int otyp, struct cred *cred)
 246 {
 247         dev_t dev = *devp;
 248         struct pty *pty;
 249         queue_t *q;
 250 
 251         if (getminor(dev) >= npty) {
 252                 return (ENXIO);
 253         }
 254         pty = &pty_softc[getminor(dev)];
 255         mutex_enter(&pty->ptc_lock);
 256         if (pty->pt_flags & PF_CARR_ON) {
 257                 mutex_exit(&pty->ptc_lock);
 258                 return (EIO);   /* controller is exclusive use */
 259                                 /* XXX - should be EBUSY! */
 260         }
 261         if (pty->pt_flags & PF_WOPEN) {
 262                 pty->pt_flags &= ~PF_WOPEN;
 263                 cv_broadcast(&pty->pt_cv_flags);
 264         }
 265 
 266         if ((q = pty->pt_ttycommon.t_readq) != NULL) {
 267                 /*
 268                  * Send an un-hangup to the slave, since "carrier" is
 269                  * coming back up.  Make sure we're doing canonicalization.
 270                  */
 271                 (void) putctl(q, M_UNHANGUP);
 272                 (void) putctl1(q, M_CTL, MC_DOCANON);
 273         }
 274         pty->pt_flags |= PF_CARR_ON;
 275         pty->pt_send = 0;
 276         pty->pt_ucntl = 0;
 277 
 278         mutex_exit(&pty->ptc_lock);
 279         return (0);
 280 }
 281 
 282 /*ARGSUSED1*/
 283 int
 284 ptcclose(dev_t dev, int flag, int otyp, struct cred *cred)
 285 {
 286         struct pty *pty;
 287         mblk_t *bp;
 288         queue_t *q;
 289 
 290         pty = &pty_softc[getminor(dev)];
 291 
 292         mutex_enter(&pty->ptc_lock);
 293         if ((q = pty->pt_ttycommon.t_readq) != NULL) {
 294                 /*
 295                  * Send a hangup to the slave, since "carrier" is dropping.
 296                  */
 297                 (void) putctl(q, M_HANGUP);
 298         }
 299 
 300         /*
 301          * Clear out all the controller-side state.  This also
 302          * clears PF_CARR_ON, which is correct because the
 303          * "carrier" is dropping since the controller process
 304          * is going away.
 305          */
 306         pty->pt_flags &= (PF_WOPEN|PF_STOPPED|PF_NOSTOP);
 307         while ((bp = pty->pt_stuffqfirst) != NULL) {
 308                 if ((pty->pt_stuffqfirst = bp->b_next) == NULL)
 309                         pty->pt_stuffqlast = NULL;
 310                 else
 311                         pty->pt_stuffqfirst->b_prev = NULL;
 312                 pty->pt_stuffqlen--;
 313                 bp->b_next = bp->b_prev = NULL;
 314                 freemsg(bp);
 315         }
 316         mutex_exit(&pty->ptc_lock);
 317         return (0);
 318 }
 319 
 320 int
 321 ptcread(dev_t dev, struct uio *uio, struct cred *cred)
 322 {
 323         struct pty *pty = &pty_softc[getminor(dev)];
 324         mblk_t *bp, *nbp;
 325         queue_t *q;
 326         unsigned char tmp;
 327         ssize_t cc;
 328         int error;
 329         off_t off;
 330 
 331 #ifdef lint
 332         cred = cred;
 333 #endif
 334 
 335         off = uio->uio_offset;
 336 
 337         mutex_enter(&pty->ptc_lock);
 338 
 339         for (;;) {
 340                 while (pty->pt_flags & PF_READ) {
 341                         pty->pt_flags |= PF_WREAD;
 342                         cv_wait(&pty->pt_cv_flags, &pty->ptc_lock);
 343                 }
 344                 pty->pt_flags |= PF_READ;
 345 
 346                 /*
 347                  * If there's a TIOCPKT packet waiting, pass it back.
 348                  */
 349                 while (pty->pt_flags&(PF_PKT|PF_UCNTL) && pty->pt_send) {
 350                         tmp = pty->pt_send;
 351                         pty->pt_send = 0;
 352                         mutex_exit(&pty->ptc_lock);
 353                         error = ureadc((int)tmp, uio);
 354                         uio->uio_offset = off;
 355                         mutex_enter(&pty->ptc_lock);
 356                         if (error) {
 357                                 pty->pt_send |= tmp;
 358                                 goto out;
 359                         }
 360                         if (pty->pt_send == 0)
 361                                 goto out;
 362                 }
 363 
 364                 /*
 365                  * If there's a user-control packet waiting, pass the
 366                  * "ioctl" code back.
 367                  */
 368                 while ((pty->pt_flags & (PF_UCNTL|PF_43UCNTL)) &&
 369                     pty->pt_ucntl) {
 370                         tmp = pty->pt_ucntl;
 371                         pty->pt_ucntl = 0;
 372                         mutex_exit(&pty->ptc_lock);
 373                         error = ureadc((int)tmp, uio);
 374                         uio->uio_offset = off;
 375                         mutex_enter(&pty->ptc_lock);
 376                         if (error) {
 377                                 if (pty->pt_ucntl == 0)
 378                                         pty->pt_ucntl = tmp;
 379                                 goto out;
 380                         }
 381                         if (pty->pt_ucntl == 0)
 382                                 goto out;
 383                 }
 384 
 385                 /*
 386                  * If there's any data waiting, pass it back.
 387                  */
 388                 if ((q = pty->pt_ttycommon.t_writeq) != NULL &&
 389                     q->q_first != NULL &&
 390                     !(pty->pt_flags & PF_STOPPED)) {
 391                         if (pty->pt_flags & (PF_PKT|PF_UCNTL|PF_43UCNTL)) {
 392                                 /*
 393                                  * We're about to begin a move in packet or
 394                                  * user-control mode; precede the data with a
 395                                  * data header.
 396                                  */
 397                                 mutex_exit(&pty->ptc_lock);
 398                                 error = ureadc(TIOCPKT_DATA, uio);
 399                                 uio->uio_offset = off;
 400                                 mutex_enter(&pty->ptc_lock);
 401                                 if (error != 0)
 402                                         goto out;
 403                                 if ((q = pty->pt_ttycommon.t_writeq) == NULL)
 404                                         goto out;
 405                         }
 406                         if ((bp = getq(q)) == NULL)
 407                                 goto out;
 408                         while (uio->uio_resid > 0) {
 409                                 while ((cc = bp->b_wptr - bp->b_rptr) == 0) {
 410                                         nbp = bp->b_cont;
 411                                         freeb(bp);
 412                                         if ((bp = nbp) == NULL) {
 413                                                 if ((q == NULL) ||
 414                                                     (bp = getq(q)) == NULL)
 415                                                         goto out;
 416                                         }
 417                                 }
 418                                 cc = MIN(cc, uio->uio_resid);
 419                                 mutex_exit(&pty->ptc_lock);
 420                                 error = uiomove((caddr_t)bp->b_rptr,
 421                                     cc, UIO_READ, uio);
 422                                 uio->uio_offset = off;
 423                                 mutex_enter(&pty->ptc_lock);
 424                                 if (error != 0) {
 425                                         freemsg(bp);
 426                                         goto out;
 427                                 }
 428                                 q = pty->pt_ttycommon.t_writeq;
 429                                 bp->b_rptr += cc;
 430                         }
 431                         /*
 432                          * Strip off zero-length blocks from the front of
 433                          * what we're putting back on the queue.
 434                          */
 435                         while ((bp->b_wptr - bp->b_rptr) == 0) {
 436                                 nbp = bp->b_cont;
 437                                 freeb(bp);
 438                                 if ((bp = nbp) == NULL)
 439                                         goto out;       /* nothing left */
 440                         }
 441                         if (q != NULL)
 442                                 (void) putbq(q, bp);
 443                         else
 444                                 freemsg(bp);
 445                         goto out;
 446                 }
 447 
 448                 /*
 449                  * If there's any TIOCSTI-stuffed characters, pass
 450                  * them back.  (They currently arrive after all output;
 451                  * is this correct?)
 452                  */
 453                 if (pty->pt_flags&PF_UCNTL && pty->pt_stuffqfirst != NULL) {
 454                         mutex_exit(&pty->ptc_lock);
 455                         error = ureadc(TIOCSTI&0xff, uio);
 456                         mutex_enter(&pty->ptc_lock);
 457                         while (error == 0 &&
 458                             (bp = pty->pt_stuffqfirst) != NULL &&
 459                             uio->uio_resid > 0) {
 460                                 pty->pt_stuffqlen--;
 461                                 if ((pty->pt_stuffqfirst = bp->b_next) == NULL)
 462                                         pty->pt_stuffqlast = NULL;
 463                                 else
 464                                         pty->pt_stuffqfirst->b_prev = NULL;
 465                                 mutex_exit(&pty->ptc_lock);
 466                                 error = ureadc((int)*bp->b_rptr, uio);
 467                                 bp->b_next = bp->b_prev = NULL;
 468                                 freemsg(bp);
 469                                 mutex_enter(&pty->ptc_lock);
 470                         }
 471                         uio->uio_offset = off;
 472                         goto out;
 473                 }
 474 
 475                 /*
 476                  * There's no data available.
 477                  * We want to block until the slave is open, and there's
 478                  * something to read; but if we lost the slave or we're NBIO,
 479                  * then return the appropriate error instead.  POSIX-style
 480                  * non-block has top billing and gives -1 with errno = EAGAIN,
 481                  * BSD-style comes next and gives -1 with errno = EWOULDBLOCK,
 482                  * SVID-style comes last and gives 0.
 483                  */
 484                 if (pty->pt_flags & PF_SLAVEGONE) {
 485                         error = EIO;
 486                         goto out;
 487                 }
 488                 if (uio->uio_fmode & FNONBLOCK) {
 489                         error = EAGAIN;
 490                         goto out;
 491                 }
 492                 if (pty->pt_flags & PF_NBIO) {
 493                         error = EWOULDBLOCK;
 494                         goto out;
 495                 }
 496                 if (uio->uio_fmode & FNDELAY)
 497                         goto out;
 498 
 499                 if (pty->pt_flags & PF_WREAD)
 500                         cv_broadcast(&pty->pt_cv_flags);
 501 
 502                 pty->pt_flags &= ~(PF_READ | PF_WREAD);
 503 
 504 
 505                 if (!cv_wait_sig(&pty->pt_cv_writeq, &pty->ptc_lock)) {
 506                         mutex_exit(&pty->ptc_lock);
 507                         return (EINTR);
 508                 }
 509         }
 510 
 511 out:
 512         if (pty->pt_flags & PF_WREAD)
 513                 cv_broadcast(&pty->pt_cv_flags);
 514 
 515         pty->pt_flags &= ~(PF_READ | PF_WREAD);
 516 
 517         mutex_exit(&pty->ptc_lock);
 518         return (error);
 519 }
 520 
 521 int
 522 ptcwrite(dev_t dev, struct uio *uio, struct cred *cred)
 523 {
 524         struct pty *pty = &pty_softc[getminor(dev)];
 525         queue_t *q;
 526         int written;
 527         mblk_t *mp;
 528         int fmode = 0;
 529         int error = 0;
 530 
 531         off_t off;
 532         off = uio->uio_offset;
 533 
 534 #ifdef lint
 535         cred = cred;
 536 #endif
 537 
 538 
 539         mutex_enter(&pty->ptc_lock);
 540 
 541 again:
 542         while (pty->pt_flags & PF_WRITE) {
 543                 pty->pt_flags |= PF_WWRITE;
 544                 cv_wait(&pty->pt_cv_flags, &pty->ptc_lock);
 545         }
 546 
 547         pty->pt_flags |= PF_WRITE;
 548 
 549         if ((q = pty->pt_ttycommon.t_readq) == NULL) {
 550 
 551                 /*
 552                  * Wait for slave to open.
 553                  */
 554                 if (pty->pt_flags & PF_SLAVEGONE) {
 555                         error = EIO;
 556                         goto out;
 557                 }
 558                 if (uio->uio_fmode & FNONBLOCK) {
 559                         error = EAGAIN;
 560                         goto out;
 561                 }
 562                 if (pty->pt_flags & PF_NBIO) {
 563                         error = EWOULDBLOCK;
 564                         goto out;
 565                 }
 566                 if (uio->uio_fmode & FNDELAY)
 567                         goto out;
 568 
 569                 if (pty->pt_flags & PF_WWRITE)
 570                         cv_broadcast(&pty->pt_cv_flags);
 571 
 572                 pty->pt_flags &= ~(PF_WRITE | PF_WWRITE);
 573 
 574                 if (!cv_wait_sig(&pty->pt_cv_readq, &pty->ptc_lock)) {
 575                         mutex_exit(&pty->ptc_lock);
 576                         return (EINTR);
 577                 }
 578 
 579                 goto again;
 580         }
 581 
 582         /*
 583          * If in remote mode, even zero-length writes generate messages.
 584          */
 585         written = 0;
 586         if ((pty->pt_flags & PF_REMOTE) || uio->uio_resid > 0) {
 587                 do {
 588                         while (!canput(q)) {
 589                                 /*
 590                                  * Wait for slave's read queue to unclog.
 591                                  */
 592                                 if (pty->pt_flags & PF_SLAVEGONE) {
 593                                         error = EIO;
 594                                         goto out;
 595                                 }
 596                                 if (uio->uio_fmode & FNONBLOCK) {
 597                                         if (!written)
 598                                                 error = EAGAIN;
 599                                         goto out;
 600                                 }
 601                                 if (pty->pt_flags & PF_NBIO) {
 602                                         if (!written)
 603                                                 error = EWOULDBLOCK;
 604                                         goto out;
 605                                 }
 606                                 if (uio->uio_fmode & FNDELAY)
 607                                         goto out;
 608 
 609                                 if (pty->pt_flags & PF_WWRITE)
 610                                         cv_broadcast(&pty->pt_cv_flags);
 611 
 612                                 pty->pt_flags &= ~(PF_WRITE | PF_WWRITE);
 613 
 614                                 if (!cv_wait_sig(&pty->pt_cv_readq,
 615                                     &pty->ptc_lock)) {
 616                                         mutex_exit(&pty->ptc_lock);
 617                                         return (EINTR);
 618                                 }
 619 
 620                                 while (pty->pt_flags & PF_WRITE) {
 621                                         pty->pt_flags |= PF_WWRITE;
 622                                         cv_wait(&pty->pt_cv_flags,
 623                                             &pty->ptc_lock);
 624                                 }
 625 
 626                                 pty->pt_flags |= PF_WRITE;
 627                         }
 628 
 629                         if ((pty->pt_flags & PF_NBIO) &&
 630                             !(uio->uio_fmode & FNONBLOCK)) {
 631                                 fmode = uio->uio_fmode;
 632                                 uio->uio_fmode |= FNONBLOCK;
 633                         }
 634 
 635                         error = makemsg(uio->uio_resid, uio, pty, &mp);
 636                         uio->uio_offset = off;
 637                         if (fmode)
 638                                 uio->uio_fmode = fmode;
 639                         if (error != 0) {
 640                                 if (error != EAGAIN && error != EWOULDBLOCK)
 641                                         goto out;
 642                                 if (uio->uio_fmode & FNONBLOCK) {
 643                                         if (!written)
 644                                                 error = EAGAIN;
 645                                         goto out;
 646                                 }
 647                                 if (pty->pt_flags & PF_NBIO) {
 648                                         if (!written)
 649                                                 error = EWOULDBLOCK;
 650                                         goto out;
 651                                 }
 652                                 if (uio->uio_fmode & FNDELAY)
 653                                         goto out;
 654                                 cmn_err(CE_PANIC,
 655                                     "ptcwrite: non null return from"
 656                                     " makemsg");
 657                         }
 658 
 659                         /*
 660                          * Check again for safety; since "uiomove" can take a
 661                          * page fault, there's no guarantee that "pt_flags"
 662                          * didn't change while it was happening.
 663                          */
 664                         if ((q = pty->pt_ttycommon.t_readq) == NULL) {
 665                                 if (mp)
 666                                         freemsg(mp);
 667                                 error = EIO;
 668                                 goto out;
 669                         }
 670                         if (mp)
 671                                 (void) putq(q, mp);
 672                         written = 1;
 673                 } while (uio->uio_resid > 0);
 674         }
 675 out:
 676         if (pty->pt_flags & PF_WWRITE)
 677                 cv_broadcast(&pty->pt_cv_flags);
 678 
 679         pty->pt_flags &= ~(PF_WRITE | PF_WWRITE);
 680 
 681         mutex_exit(&pty->ptc_lock);
 682         return (error);
 683 }
 684 
 685 #define copy_in(data, d_arg) \
 686         if (copyin((caddr_t)data, &d_arg, sizeof (int)) != 0) \
 687                 return (EFAULT)
 688 
 689 #define copy_out(d_arg, data) \
 690         if (copyout(&d_arg, (caddr_t)data, sizeof (int)) != 0) \
 691                 return (EFAULT)
 692 
 693 int
 694 ptcioctl(dev_t dev, int cmd, intptr_t data, int flag, struct cred *cred,
 695     int *rvalp)
 696 {
 697         struct pty *pty = &pty_softc[getminor(dev)];
 698         queue_t *q;
 699         struct ttysize tty_arg;
 700         struct winsize win_arg;
 701         int d_arg;
 702         int err;
 703 
 704         switch (cmd) {
 705 
 706         case TIOCPKT:
 707                 copy_in(data, d_arg);
 708                 mutex_enter(&pty->ptc_lock);
 709                 if (d_arg) {
 710                         if (pty->pt_flags & (PF_UCNTL|PF_43UCNTL)) {
 711                                 mutex_exit(&pty->ptc_lock);
 712                                 return (EINVAL);
 713                         }
 714                         pty->pt_flags |= PF_PKT;
 715                 } else
 716                         pty->pt_flags &= ~PF_PKT;
 717                 mutex_exit(&pty->ptc_lock);
 718                 break;
 719 
 720         case TIOCUCNTL:
 721                 copy_in(data, d_arg);
 722                 mutex_enter(&pty->ptc_lock);
 723                 if (d_arg) {
 724                         if (pty->pt_flags & (PF_PKT|PF_UCNTL)) {
 725                                 mutex_exit(&pty->ptc_lock);
 726                                 return (EINVAL);
 727                         }
 728                         pty->pt_flags |= PF_43UCNTL;
 729                 } else
 730                         pty->pt_flags &= ~PF_43UCNTL;
 731                 mutex_exit(&pty->ptc_lock);
 732                 break;
 733 
 734         case TIOCTCNTL:
 735                 copy_in(data, d_arg);
 736                 mutex_enter(&pty->ptc_lock);
 737                 if (d_arg) {
 738                         if (pty->pt_flags & PF_PKT) {
 739                                 mutex_exit(&pty->ptc_lock);
 740                                 return (EINVAL);
 741                         }
 742                         pty->pt_flags |= PF_UCNTL;
 743                 } else
 744                         pty->pt_flags &= ~PF_UCNTL;
 745                 mutex_exit(&pty->ptc_lock);
 746                 break;
 747 
 748         case TIOCREMOTE:
 749                 copy_in(data, d_arg);
 750                 mutex_enter(&pty->ptc_lock);
 751                 if (d_arg) {
 752                         if ((q = pty->pt_ttycommon.t_readq) != NULL)
 753                                 (void) putctl1(q, M_CTL, MC_NOCANON);
 754                         pty->pt_flags |= PF_REMOTE;
 755                 } else {
 756                         if ((q = pty->pt_ttycommon.t_readq) != NULL)
 757                                 (void) putctl1(q, M_CTL, MC_DOCANON);
 758                         pty->pt_flags &= ~PF_REMOTE;
 759                 }
 760                 mutex_exit(&pty->ptc_lock);
 761                 break;
 762 
 763         case TIOCSIGNAL:
 764                 /*
 765                  * Blast a M_PCSIG message up the slave stream; the
 766                  * signal number is the argument to the "ioctl".
 767                  */
 768                 copy_in(data, d_arg);
 769                 mutex_enter(&pty->ptc_lock);
 770                 if ((q = pty->pt_ttycommon.t_readq) != NULL)
 771                         (void) putctl1(q, M_PCSIG, (int)d_arg);
 772                 mutex_exit(&pty->ptc_lock);
 773                 break;
 774 
 775         case FIONBIO:
 776                 copy_in(data, d_arg);
 777                 mutex_enter(&pty->ptc_lock);
 778                 if (d_arg)
 779                         pty->pt_flags |= PF_NBIO;
 780                 else
 781                         pty->pt_flags &= ~PF_NBIO;
 782                 mutex_exit(&pty->ptc_lock);
 783                 break;
 784 
 785         case FIOASYNC:
 786                 copy_in(data, d_arg);
 787                 mutex_enter(&pty->ptc_lock);
 788                 if (d_arg)
 789                         pty->pt_flags |= PF_ASYNC;
 790                 else
 791                         pty->pt_flags &= ~PF_ASYNC;
 792                 mutex_exit(&pty->ptc_lock);
 793                 break;
 794 
 795         /*
 796          * These, at least, can work on the controller-side process
 797          * group.
 798          */
 799         case FIOGETOWN:
 800                 mutex_enter(&pty->ptc_lock);
 801                 d_arg = -pty->pt_pgrp;
 802                 mutex_exit(&pty->ptc_lock);
 803                 copy_out(d_arg, data);
 804                 break;
 805 
 806         case FIOSETOWN:
 807                 copy_in(data, d_arg);
 808                 mutex_enter(&pty->ptc_lock);
 809                 pty->pt_pgrp = (short)(-d_arg);
 810                 mutex_exit(&pty->ptc_lock);
 811                 break;
 812 
 813         case FIONREAD: {
 814                 /*
 815                  * Return the total number of bytes of data in all messages
 816                  * in slave write queue, which is master read queue, unless a
 817                  * special message would be read.
 818                  */
 819                 mblk_t *mp;
 820                 size_t count = 0;
 821 
 822                 mutex_enter(&pty->ptc_lock);
 823                 if (pty->pt_flags&(PF_PKT|PF_UCNTL) && pty->pt_send)
 824                         count = 1;      /* will return 1 byte */
 825                 else if ((pty->pt_flags & (PF_UCNTL|PF_43UCNTL)) &&
 826                     pty->pt_ucntl)
 827                         count = 1;      /* will return 1 byte */
 828                 else if ((q = pty->pt_ttycommon.t_writeq) != NULL &&
 829                     q->q_first != NULL && !(pty->pt_flags & PF_STOPPED)) {
 830                         /*
 831                          * Will return whatever data is queued up.
 832                          */
 833                         for (mp = q->q_first; mp != NULL; mp = mp->b_next)
 834                                 count += msgdsize(mp);
 835                 } else if ((pty->pt_flags & PF_UCNTL) &&
 836                     pty->pt_stuffqfirst != NULL) {
 837                         /*
 838                          * Will return STI'ed data.
 839                          */
 840                         count = pty->pt_stuffqlen + 1;
 841                 }
 842 
 843                 /*
 844                  * Under LP64 we could have more than INT_MAX bytes to report,
 845                  * but the interface is defined in terms of int, so we cap it.
 846                  */
 847                 d_arg = MIN(count, INT_MAX);
 848                 mutex_exit(&pty->ptc_lock);
 849                 copy_out(d_arg, data);
 850                 break;
 851         }
 852 
 853         case TIOCSWINSZ:
 854                 /*
 855                  * Unfortunately, TIOCSWINSZ and the old TIOCSSIZE "ioctl"s
 856                  * share the same code.  If the upper 16 bits of the number
 857                  * of lines is non-zero, it was probably a TIOCSWINSZ,
 858                  * with both "ws_row" and "ws_col" non-zero.
 859                  */
 860                 if (copyin((caddr_t)data,
 861                     &tty_arg, sizeof (struct ttysize)) != 0)
 862                         return (EFAULT);
 863 
 864                 if ((tty_arg.ts_lines & 0xffff0000) != 0) {
 865                         /*
 866                          * It's a TIOCSWINSZ.
 867                          */
 868                         win_arg = *(struct winsize *)&tty_arg;
 869 
 870                         mutex_enter(&pty->ptc_lock);
 871                         /*
 872                          * If the window size changed, send a SIGWINCH.
 873                          */
 874                         if (bcmp(&pty->pt_ttycommon.t_size,
 875                             &win_arg, sizeof (struct winsize))) {
 876                                 pty->pt_ttycommon.t_size = win_arg;
 877                                 if ((q = pty->pt_ttycommon.t_readq) != NULL)
 878                                         (void) putctl1(q, M_PCSIG, SIGWINCH);
 879                         }
 880                         mutex_exit(&pty->ptc_lock);
 881                         break;
 882                 }
 883                 /* FALLTHROUGH */
 884 
 885         case TIOCSSIZE:
 886                 if (copyin((caddr_t)data,
 887                     &tty_arg, sizeof (struct ttysize)) != 0)
 888                         return (EFAULT);
 889                 mutex_enter(&pty->ptc_lock);
 890                 pty->pt_ttycommon.t_size.ws_row = (ushort_t)tty_arg.ts_lines;
 891                 pty->pt_ttycommon.t_size.ws_col = (ushort_t)tty_arg.ts_cols;
 892                 pty->pt_ttycommon.t_size.ws_xpixel = 0;
 893                 pty->pt_ttycommon.t_size.ws_ypixel = 0;
 894                 mutex_exit(&pty->ptc_lock);
 895                 break;
 896 
 897         case TIOCGWINSZ:
 898                 mutex_enter(&pty->ptc_lock);
 899                 win_arg = pty->pt_ttycommon.t_size;
 900                 mutex_exit(&pty->ptc_lock);
 901                 if (copyout(&win_arg, (caddr_t)data,
 902                     sizeof (struct winsize)) != 0)
 903                         return (EFAULT);
 904                 break;
 905 
 906         case TIOCGSIZE:
 907                 mutex_enter(&pty->ptc_lock);
 908                 tty_arg.ts_lines = pty->pt_ttycommon.t_size.ws_row;
 909                 tty_arg.ts_cols = pty->pt_ttycommon.t_size.ws_col;
 910                 mutex_exit(&pty->ptc_lock);
 911                 if (copyout(&tty_arg, (caddr_t)data,
 912                     sizeof (struct ttysize)) != 0)
 913                         return (EFAULT);
 914                 break;
 915 
 916         /*
 917          * XXX These should not be here.  The only reason why an
 918          * "ioctl" on the controller side should get the
 919          * slave side's process group is so that the process on
 920          * the controller side can send a signal to the slave
 921          * side's process group; however, this is better done
 922          * with TIOCSIGNAL, both because it doesn't require us
 923          * to know about the slave side's process group and because
 924          * the controller side process may not have permission to
 925          * send that signal to the entire process group.
 926          *
 927          * However, since vanilla 4BSD doesn't provide TIOCSIGNAL,
 928          * we can't just get rid of them.
 929          */
 930         case TIOCGPGRP:
 931         case TIOCSPGRP:
 932         /*
 933          * This is amazingly disgusting, but the stupid semantics of
 934          * 4BSD pseudo-ttys makes us do it.  If we do one of these guys
 935          * on the controller side, it really applies to the slave-side
 936          * stream.  It should NEVER have been possible to do ANY sort
 937          * of tty operations on the controller side, but it's too late
 938          * to fix that now.  However, we won't waste our time implementing
 939          * anything that the original pseudo-tty driver didn't handle.
 940          */
 941         case TIOCGETP:
 942         case TIOCSETP:
 943         case TIOCSETN:
 944         case TIOCGETC:
 945         case TIOCSETC:
 946         case TIOCGLTC:
 947         case TIOCSLTC:
 948         case TIOCLGET:
 949         case TIOCLSET:
 950         case TIOCLBIS:
 951         case TIOCLBIC:
 952                 mutex_enter(&pty->ptc_lock);
 953                 if (pty->pt_vnode == NULL) {
 954                         mutex_exit(&pty->ptc_lock);
 955                         return (EIO);
 956                 }
 957                 pty->pt_flags |= PF_IOCTL;
 958                 mutex_exit(&pty->ptc_lock);
 959                 err = strioctl(pty->pt_vnode, cmd, data, flag,
 960                     U_TO_K, cred, rvalp);
 961                 mutex_enter(&pty->ptc_lock);
 962                 if (pty->pt_flags & PF_WAIT)
 963                         cv_signal(&pty->pt_cv_flags);
 964                 pty->pt_flags &= ~(PF_IOCTL|PF_WAIT);
 965                 mutex_exit(&pty->ptc_lock);
 966                 return (err);
 967 
 968         default:
 969                 return (ENOTTY);
 970         }
 971 
 972         return (0);
 973 }
 974 
 975 
 976 int
 977 ptcpoll(dev_t dev,
 978         short events,
 979         int anyyet,
 980         short *reventsp,
 981         struct pollhead **phpp)
 982 {
 983         struct pty *pty = &pty_softc[getminor(dev)];
 984         pollhead_t *php = &ptcph;
 985         queue_t *q;
 986         int pos = 0;
 987 
 988 #ifdef lint
 989         anyyet = anyyet;
 990 #endif
 991         if (polllock(php, &pty->ptc_lock) != 0) {
 992                 *reventsp = POLLNVAL;
 993                 return (0);
 994         }
 995 
 996         ASSERT(MUTEX_HELD(&pty->ptc_lock));
 997 
 998         *reventsp = 0;
 999         if (pty->pt_flags & PF_SLAVEGONE) {
1000                 if (events & (POLLIN|POLLRDNORM))
1001                         *reventsp |= (events & (POLLIN|POLLRDNORM));
1002                 if (events & (POLLOUT|POLLWRNORM))
1003                         *reventsp |= (events & (POLLOUT|POLLWRNORM));
1004                 mutex_exit(&pty->ptc_lock);
1005                 /*
1006                  * A non NULL pollhead pointer should be returned in case
1007                  * user polls for 0 events.
1008                  */
1009                 *phpp = !anyyet && !*reventsp ? php : (struct pollhead *)NULL;
1010                 return (0);
1011         }
1012         if (events & (POLLIN|POLLRDNORM)) {
1013                 if ((q = pty->pt_ttycommon.t_writeq) != NULL &&
1014                     q->q_first != NULL && !(pty->pt_flags & PF_STOPPED)) {
1015                         /*
1016                          * Regular data is available.
1017                          */
1018                         *reventsp |= (events & (POLLIN|POLLRDNORM));
1019                         pos++;
1020                 }
1021                 if (pty->pt_flags & (PF_PKT|PF_UCNTL) && pty->pt_send) {
1022                         /*
1023                          * A control packet is available.
1024                          */
1025                         *reventsp |= (events & (POLLIN|POLLRDNORM));
1026                         pos++;
1027                 }
1028                 if ((pty->pt_flags & PF_UCNTL) &&
1029                     (pty->pt_ucntl || pty->pt_stuffqfirst != NULL)) {
1030                         /*
1031                          * "ioctl" or TIOCSTI data is available.
1032                          */
1033                         *reventsp |= (events & (POLLIN|POLLRDNORM));
1034                         pos++;
1035                 }
1036                 if ((pty->pt_flags & PF_43UCNTL) && pty->pt_ucntl) {
1037                         *reventsp |= (events & (POLLIN|POLLRDNORM));
1038                         pos++;
1039                 }
1040         }
1041         if (events & (POLLOUT|POLLWRNORM)) {
1042                 if ((q = pty->pt_ttycommon.t_readq) != NULL &&
1043                     canput(q)) {
1044                         *reventsp |= (events & (POLLOUT|POLLWRNORM));
1045                         pos++;
1046                 }
1047         }
1048         if (events & POLLERR) {
1049                 *reventsp |= POLLERR;
1050                 pos++;
1051         }
1052         if (events == 0) {      /* "exceptional conditions" */
1053                 if (((pty->pt_flags & (PF_PKT|PF_UCNTL)) && pty->pt_send) ||
1054                     ((pty->pt_flags & PF_UCNTL) &&
1055                     (pty->pt_ucntl || pty->pt_stuffqfirst != NULL))) {
1056                         pos++;
1057                 }
1058                 if ((pty->pt_flags & PF_43UCNTL) && pty->pt_ucntl) {
1059                         pos++;
1060                 }
1061         }
1062 
1063         /*
1064          * Arrange to have poll waken up when event occurs.
1065          * if (!anyyet)
1066          */
1067         if (!pos) {
1068                 *phpp = php;
1069                 *reventsp = 0;
1070         }
1071 
1072         mutex_exit(&pty->ptc_lock);
1073         return (0);
1074 }
1075 
1076 void
1077 gsignal(int pid, int sig)
1078 {
1079         procset_t set;
1080         sigsend_t v;
1081 
1082         bzero(&v, sizeof (v));
1083         v.sig = sig;
1084         v.perm = 0;
1085         v.checkperm = 1;
1086         v.value.sival_ptr = NULL;
1087 
1088         setprocset(&set, POP_AND, P_PGID, -pid, P_ALL, P_MYID);
1089         (void) sigsendset(&set, &v);
1090 }
1091 
1092 static int
1093 makemsg(ssize_t count, struct uio *uiop, struct pty *pty, mblk_t **mpp)
1094 {
1095         int pri = BPRI_LO;
1096         int error;
1097         mblk_t *bp = NULL;
1098 
1099         ASSERT(MUTEX_HELD(&pty->ptc_lock));
1100 
1101         *mpp = NULL;
1102 
1103         /*
1104          * Create data part of message, if any.
1105          */
1106         if (count >= 0) {
1107                 if ((bp = allocb(count, pri)) == NULL)
1108                         return (ENOSR);
1109 
1110                 mutex_exit(&pty->ptc_lock);
1111                 error = uiomove((caddr_t)bp->b_wptr, count, UIO_WRITE, uiop);
1112                 mutex_enter(&pty->ptc_lock);
1113                 if (error) {
1114                         freeb(bp);
1115                         return (error);
1116                 }
1117 
1118                 bp->b_wptr += count;
1119         }
1120 
1121         *mpp = bp;
1122         return (0);
1123 }