Print this page
14249 pseudo-terminal nomenclature should reflect POSIX
Change-Id: Ib4a3cef899ff4c71b09cb0dc6878863c5e8357bc

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/ptm.c
          +++ new/usr/src/uts/common/io/ptm.c
↓ open down ↓ 18 lines elided ↑ open up ↑
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
  23   23   */
  24   24  /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
  25   25  /*        All Rights Reserved   */
  26   26  
  27   27  /*
  28   28   * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
       29 + * Copyright 2021 Oxide Computer Company
  29   30   */
  30   31  
  31   32  /*
  32      - * Pseudo Terminal Master Driver.
       33 + * PSEUDO-TERMINAL MANAGER DRIVER (PTM)
  33   34   *
  34      - * The pseudo-tty subsystem simulates a terminal connection, where the master
  35      - * side represents the terminal and the slave represents the user process's
  36      - * special device end point. The master device is set up as a cloned device
  37      - * where its major device number is the major for the clone device and its minor
  38      - * device number is the major for the ptm driver. There are no nodes in the file
  39      - * system for master devices. The master pseudo driver is opened using the
  40      - * open(2) system call with /dev/ptmx as the device parameter.  The clone open
  41      - * finds the next available minor device for the ptm major device.
       35 + * The pseudo-terminal subsystem simulates a terminal connection, where the
       36 + * manager side represents the terminal and the subsidiary represents the user
       37 + * process's special device end point.  The manager device is set up as a
       38 + * cloned device where its major device number is the major for the clone
       39 + * device and its minor device number is the major for the ptm driver.  There
       40 + * are no nodes in the file system for manager devices.  The manager pseudo
       41 + * driver is opened using the open(2) system call with /dev/ptmx as the device
       42 + * parameter.  The clone open finds the next available minor device for the ptm
       43 + * major device.
  42   44   *
  43      - * A master device is available only if it and its corresponding slave device
  44      - * are not already open. When the master device is opened, the corresponding
  45      - * slave device is automatically locked out. Only one open is allowed on a
  46      - * master device.  Multiple opens are allowed on the slave device.  After both
  47      - * the master and slave have been opened, the user has two file descriptors
  48      - * which are the end points of a full duplex connection composed of two streams
  49      - * which are automatically connected at the master and slave drivers. The user
  50      - * may then push modules onto either side of the stream pair.
       45 + * A manager device is available only if it and its corresponding subsidiary
       46 + * device are not already open.  When the manager device is opened, the
       47 + * corresponding subsidiary device is automatically locked out.  Only one open
       48 + * is allowed on a manager device.  Multiple opens are allowed on the
       49 + * subsidiary device.  After both the manager and subsidiary have been opened,
       50 + * the user has two file descriptors which are the end points of a full duplex
       51 + * connection composed of two streams which are automatically connected at the
       52 + * manager and subsidiary drivers.  The user may then push modules onto either
       53 + * side of the stream pair.
  51   54   *
  52      - * The master and slave drivers pass all messages to their adjacent queues.
  53      - * Only the M_FLUSH needs some processing.  Because the read queue of one side
  54      - * is connected to the write queue of the other, the FLUSHR flag is changed to
  55      - * the FLUSHW flag and vice versa. When the master device is closed an M_HANGUP
  56      - * message is sent to the slave device which will render the device
  57      - * unusable. The process on the slave side gets the EIO when attempting to write
  58      - * on that stream but it will be able to read any data remaining on the stream
  59      - * head read queue.  When all the data has been read, read() returns 0
  60      - * indicating that the stream can no longer be used.  On the last close of the
  61      - * slave device, a 0-length message is sent to the master device. When the
  62      - * application on the master side issues a read() or getmsg() and 0 is returned,
  63      - * the user of the master device decides whether to issue a close() that
  64      - * dismantles the pseudo-terminal subsystem. If the master device is not closed,
  65      - * the pseudo-tty subsystem will be available to another user to open the slave
  66      - * device.
       55 + * The manager and subsidiary drivers pass all messages to their adjacent
       56 + * queues.  Only the M_FLUSH needs some processing.  Because the read queue of
       57 + * one side is connected to the write queue of the other, the FLUSHR flag is
       58 + * changed to the FLUSHW flag and vice versa.  When the manager device is
       59 + * closed an M_HANGUP message is sent to the subsidiary device which will
       60 + * render the device unusable.  The process on the subsidiary side gets an EIO
       61 + * error when attempting to write on that stream but it will be able to read
       62 + * any data remaining on the stream head read queue.  When all the data has
       63 + * been read, read() returns 0 indicating that the stream can no longer be
       64 + * used.  On the last close of the subsidiary device, a 0-length message is
       65 + * sent to the manager device.  When the application on the manager side issues
       66 + * a read() or getmsg() and 0 is returned, the user of the manager device
       67 + * decides whether to issue a close() that dismantles the pseudo-terminal
       68 + * subsystem.  If the manager device is not closed, the pseudo-terminal
       69 + * subsystem will be available to another user to open the subsidiary device.
  67   70   *
  68      - * If O_NONBLOCK or O_NDELAY is set, read on the master side returns -1 with
       71 + * If O_NONBLOCK or O_NDELAY is set, read on the manager side returns -1 with
  69   72   * errno set to EAGAIN if no data is available, and write returns -1 with errno
  70   73   * set to EAGAIN if there is internal flow control.
  71   74   *
  72      - * IOCTLS:
  73   75   *
  74      - *  ISPTM: determines whether the file descriptor is that of an open master
  75      - *         device. Return code of zero indicates that the file descriptor
  76      - *         represents master device.
       76 + * IOCTLS
  77   77   *
  78      - *  UNLKPT: unlocks the master and slave devices.  It returns 0 on success. On
  79      - *          failure, the errno is set to EINVAL indicating that the master
  80      - *          device is not open.
       78 + *      ISPTM
       79 + *              Determines whether the file descriptor is that of an open
       80 + *              manager device.  Return code of zero indicates that the file
       81 + *              descriptor represents a manager device.
  81   82   *
  82      - *  ZONEPT: sets the zone membership of the associated pts device.
       83 + *      UNLKPT
       84 + *              Unlocks the manager and subsidiary devices.  It returns 0 on
       85 + *              success. On failure, the errno is set to EINVAL indicating that
       86 + *              the manager device is not open.
  83   87   *
  84      - *  GRPPT:  sets the group owner of the associated pts device.
       88 + *      ZONEPT
       89 + *              Sets the zone membership of the associated subsidiary device.
  85   90   *
  86      - * Synchronization:
       91 + *      GRPPT
       92 + *              Sets the group owner of the associated subsidiary device.
  87   93   *
  88      - *   All global data synchronization between ptm/pts is done via global
  89      - *   ptms_lock mutex which is initialized at system boot time from
  90      - *   ptms_initspace (called from space.c).
  91   94   *
  92      - *   Individual fields of pt_ttys structure (except ptm_rdq, pts_rdq and
  93      - *   pt_nullmsg) are protected by pt_ttys.pt_lock mutex.
       95 + * SYNCHRONIZATION
  94   96   *
  95      - *   PT_ENTER_READ/PT_ENTER_WRITE are reference counter based read-write locks
  96      - *   which allow reader locks to be reacquired by the same thread (usual
  97      - *   reader/writer locks can't be used for that purpose since it is illegal for
  98      - *   a thread to acquire a lock it already holds, even as a reader). The sole
  99      - *   purpose of these macros is to guarantee that the peer queue will not
 100      - *   disappear (due to closing peer) while it is used. It is safe to use
 101      - *   PT_ENTER_READ/PT_EXIT_READ brackets across calls like putq/putnext (since
 102      - *   they are not real locks but reference counts).
       97 + * All global data synchronization between ptm/pts is done via global ptms_lock
       98 + * mutex which is initialized at system boot time from ptms_initspace (called
       99 + * from space.c).
 103  100   *
 104      - *   PT_ENTER_WRITE/PT_EXIT_WRITE brackets are used ONLY in master/slave
 105      - *   open/close paths to modify ptm_rdq and pts_rdq fields. These fields should
 106      - *   be set to appropriate queues *after* qprocson() is called during open (to
 107      - *   prevent peer from accessing the queue with incomplete plumbing) and set to
 108      - *   NULL before qprocsoff() is called during close.
      101 + * Individual fields of pt_ttys structure (except ptm_rdq, pts_rdq and
      102 + * pt_nullmsg) are protected by pt_ttys.pt_lock mutex.
 109  103   *
 110      - *   The pt_nullmsg field is only used in open/close routines and it is also
 111      - *   protected by PT_ENTER_WRITE/PT_EXIT_WRITE brackets to avoid extra mutex
 112      - *   holds.
      104 + * PT_ENTER_READ/PT_ENTER_WRITE are reference counter based read-write locks
      105 + * which allow reader locks to be reacquired by the same thread (usual
      106 + * reader/writer locks can't be used for that purpose since it is illegal for a
      107 + * thread to acquire a lock it already holds, even as a reader). The sole
      108 + * purpose of these macros is to guarantee that the peer queue will not
      109 + * disappear (due to closing peer) while it is used. It is safe to use
      110 + * PT_ENTER_READ/PT_EXIT_READ brackets across calls like putq/putnext (since
      111 + * they are not real locks but reference counts).
 113  112   *
 114      - * Lock Ordering:
      113 + * PT_ENTER_WRITE/PT_EXIT_WRITE brackets are used ONLY in manager/subsidiary
      114 + * open/close paths to modify ptm_rdq and pts_rdq fields. These fields should
      115 + * be set to appropriate queues *after* qprocson() is called during open (to
      116 + * prevent peer from accessing the queue with incomplete plumbing) and set to
      117 + * NULL before qprocsoff() is called during close.
 115  118   *
 116      - *   If both ptms_lock and per-pty lock should be held, ptms_lock should always
 117      - *   be entered first, followed by per-pty lock.
      119 + * The pt_nullmsg field is only used in open/close routines and it is also
      120 + * protected by PT_ENTER_WRITE/PT_EXIT_WRITE brackets to avoid extra mutex
      121 + * holds.
 118  122   *
 119      - * See ptms.h, pts.c and ptms_conf.c for more information.
      123 + *
      124 + * LOCK ORDERING
      125 + *
      126 + * If both ptms_lock and per-pty lock should be held, ptms_lock should always
      127 + * be entered first, followed by per-pty lock.
      128 + *
      129 + * See ptms.h, pts.c, and ptms_conf.c for more information.
 120  130   */
 121  131  
 122  132  #include <sys/types.h>
 123  133  #include <sys/param.h>
 124  134  #include <sys/file.h>
 125  135  #include <sys/sysmacros.h>
 126  136  #include <sys/stream.h>
 127  137  #include <sys/stropts.h>
 128  138  #include <sys/proc.h>
 129  139  #include <sys/errno.h>
↓ open down ↓ 15 lines elided ↑ open up ↑
 145  155  #else
 146  156  #define DBG(a)
 147  157  #endif
 148  158  
 149  159  static int ptmopen(queue_t *, dev_t *, int, int, cred_t *);
 150  160  static int ptmclose(queue_t *, int, cred_t *);
 151  161  static int ptmwput(queue_t *, mblk_t *);
 152  162  static int ptmrsrv(queue_t *);
 153  163  static int ptmwsrv(queue_t *);
 154  164  
 155      -/*
 156      - * Master Stream Pseudo Terminal Module: stream data structure definitions
 157      - */
 158      -
 159  165  static struct module_info ptm_info = {
 160  166          0xdead,
 161  167          "ptm",
 162  168          0,
 163  169          512,
 164  170          512,
 165  171          128
 166  172  };
 167  173  
 168  174  static struct qinit ptmrint = {
↓ open down ↓ 33 lines elided ↑ open up ↑
 202  208   * this will define (struct cb_ops cb_ptm_ops) and (struct dev_ops ptm_ops)
 203  209   */
 204  210  DDI_DEFINE_STREAM_OPS(ptm_ops, nulldev, nulldev, ptm_attach, ptm_detach,
 205  211      nodev, ptm_devinfo, D_MP, &ptminfo, ddi_quiesce_not_supported);
 206  212  
 207  213  /*
 208  214   * Module linkage information for the kernel.
 209  215   */
 210  216  
 211  217  static struct modldrv modldrv = {
 212      -        &mod_driverops, /* Type of module.  This one is a pseudo driver */
 213      -        "Master streams driver 'ptm'",
 214      -        &ptm_ops,       /* driver ops */
      218 +        &mod_driverops,
      219 +        "Pseudo-Terminal Manager Driver",
      220 +        &ptm_ops,
 215  221  };
 216  222  
 217  223  static struct modlinkage modlinkage = {
 218  224          MODREV_1,
 219  225          &modldrv,
 220  226          NULL
 221  227  };
 222  228  
 223  229  int
 224  230  _init(void)
↓ open down ↓ 41 lines elided ↑ open up ↑
 266  272  static int
 267  273  ptm_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
 268  274  {
 269  275          if (cmd != DDI_DETACH)
 270  276                  return (DDI_FAILURE);
 271  277  
 272  278          ddi_remove_minor_node(devi, NULL);
 273  279          return (DDI_SUCCESS);
 274  280  }
 275  281  
 276      -/*ARGSUSED*/
 277  282  static int
 278  283  ptm_devinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
 279  284      void **result)
 280  285  {
 281  286          int error;
 282  287  
 283  288          switch (infocmd) {
 284  289          case DDI_INFO_DEVT2DEVINFO:
 285  290                  if (ptm_dip == NULL) {
 286  291                          error = DDI_FAILURE;
↓ open down ↓ 6 lines elided ↑ open up ↑
 293  298                  *result = (void *)0;
 294  299                  error = DDI_SUCCESS;
 295  300                  break;
 296  301          default:
 297  302                  error = DDI_FAILURE;
 298  303          }
 299  304          return (error);
 300  305  }
 301  306  
 302  307  
 303      -/* ARGSUSED */
 304  308  /*
 305      - * Open a minor of the master device. Store the write queue pointer and set the
 306      - * pt_state field to (PTMOPEN | PTLOCK).
      309 + * Open a minor of the manager device. Store the write queue pointer and set
      310 + * the pt_state field to (PTMOPEN | PTLOCK).
 307  311   * This code will work properly with both clone opens and direct opens of the
 308      - * master device.
      312 + * manager device.
 309  313   */
 310  314  static int
 311  315  ptmopen(
 312  316          queue_t *rqp,           /* pointer to the read side queue */
 313  317          dev_t   *devp,          /* pointer to stream tail's dev */
 314  318          int     oflag,          /* the user open(2) supplied flags */
 315  319          int     sflag,          /* open state flag */
 316  320          cred_t  *credp)         /* credentials */
 317  321  {
 318  322          struct pt_ttys  *ptmp;
↓ open down ↓ 3 lines elided ↑ open up ↑
 322  326  
 323  327          /* Allow reopen */
 324  328          if (rqp->q_ptr != NULL)
 325  329                  return (0);
 326  330  
 327  331          if (sflag & MODOPEN)
 328  332                  return (ENXIO);
 329  333  
 330  334          if (!(sflag & CLONEOPEN) && dminor != 0) {
 331  335                  /*
 332      -                 * This is a direct open to specific master device through an
      336 +                 * This is a direct open to specific manager device through an
 333  337                   * artificially created entry with specific minor in
 334      -                 * /dev/directory. Such behavior is not supported.
      338 +                 * /dev/directory.  Such behavior is not supported.
 335  339                   */
 336  340                  return (ENXIO);
 337  341          }
 338  342  
 339  343          /*
 340      -         * The master open requires that the slave be attached
 341      -         * before it returns so that attempts to open the slave will
 342      -         * succeeed
      344 +         * The manager open requires that the subsidiary be attached before it
      345 +         * returns so that attempts to open the subsidiary will succeeed
 343  346           */
 344      -        if (ptms_attach_slave() != 0) {
      347 +        if (ptms_attach_subsidiary() != 0) {
 345  348                  return (ENXIO);
 346  349          }
 347  350  
 348  351          mop = allocb(sizeof (struct stroptions), BPRI_MED);
 349  352          if (mop == NULL) {
 350  353                  DDBG("ptmopen(): mop allocation failed\n", 0);
 351  354                  return (ENOMEM);
 352  355          }
 353  356  
 354  357          if ((ptmp = pt_ttys_alloc()) == NULL) {
↓ open down ↓ 4 lines elided ↑ open up ↑
 359  362  
 360  363          dminor = ptmp->pt_minor;
 361  364  
 362  365          DDBGP("ptmopen(): allocated ptmp %p\n", (uintptr_t)ptmp);
 363  366          DDBG("ptmopen(): allocated minor %d\n", dminor);
 364  367  
 365  368          WR(rqp)->q_ptr = rqp->q_ptr = ptmp;
 366  369  
 367  370          qprocson(rqp);
 368  371  
 369      -        /* Allow slave to send messages to master */
      372 +        /* Allow subsidiary to send messages to manager */
 370  373          PT_ENTER_WRITE(ptmp);
 371  374          ptmp->ptm_rdq = rqp;
 372  375          PT_EXIT_WRITE(ptmp);
 373  376  
 374  377          /*
 375  378           * set up hi/lo water marks on stream head read queue
 376  379           * and add controlling tty if not set
 377  380           */
 378  381          mop->b_datap->db_type = M_SETOPTS;
 379  382          mop->b_wptr += sizeof (struct stroptions);
↓ open down ↓ 10 lines elided ↑ open up ↑
 390  393           * The input, devp, is a major device number, the output is put
 391  394           * into the same parm as a major,minor pair.
 392  395           */
 393  396          *devp = makedevice(getmajor(*devp), dminor);
 394  397  
 395  398          return (0);
 396  399  }
 397  400  
 398  401  
 399  402  /*
 400      - * Find the address to private data identifying the slave's write queue.
 401      - * Send a hang-up message up the slave's read queue to designate the
 402      - * master/slave pair is tearing down. Uattach the master and slave by
 403      - * nulling out the write queue fields in the private data structure.
 404      - * Finally, unlock the master/slave pair and mark the master as closed.
      403 + * Find the address to private data identifying the subsidiary's write queue.
      404 + * Send a hang-up message up the subsidiary's read queue to designate the
      405 + * manager/subsidiary pair is tearing down. Uattach the manager and subsidiary
      406 + * by nulling out the write queue fields in the private data structure.
      407 + * Finally, unlock the manager/subsidiary pair and mark the manager as closed.
 405  408   */
 406      -/*ARGSUSED1*/
 407  409  static int
 408  410  ptmclose(queue_t *rqp, int flag, cred_t *credp)
 409  411  {
 410  412          struct pt_ttys  *ptmp;
 411  413          queue_t *pts_rdq;
 412  414  
 413  415          ASSERT(rqp->q_ptr);
 414  416  
 415  417          ptmp = (struct pt_ttys *)rqp->q_ptr;
 416  418          PT_ENTER_READ(ptmp);
 417  419          if (ptmp->pts_rdq) {
 418  420                  pts_rdq = ptmp->pts_rdq;
 419  421                  if (pts_rdq->q_next) {
 420      -                        DBG(("send hangup message to slave\n"));
      422 +                        DBG(("send hangup message to subsidiary\n"));
 421  423                          (void) putnextctl(pts_rdq, M_HANGUP);
 422  424                  }
 423  425          }
 424  426          PT_EXIT_READ(ptmp);
 425  427          /*
 426  428           * ptm_rdq should be cleared before call to qprocsoff() to prevent pts
 427  429           * write procedure to attempt using ptm_rdq after qprocsoff.
 428  430           */
 429  431          PT_ENTER_WRITE(ptmp);
 430  432          ptmp->ptm_rdq = NULL;
 431  433          freemsg(ptmp->pt_nullmsg);
 432  434          ptmp->pt_nullmsg = NULL;
 433  435          /*
 434      -         * qenable slave side write queue so that it can flush
 435      -         * its messages as master's read queue is going away
      436 +         * qenable subsidiary side write queue so that it can flush
      437 +         * its messages as manager's read queue is going away
 436  438           */
 437  439          if (ptmp->pts_rdq)
 438  440                  qenable(WR(ptmp->pts_rdq));
 439  441          PT_EXIT_WRITE(ptmp);
 440  442  
 441  443          qprocsoff(rqp);
 442  444  
 443  445          /* Finish the close */
 444  446          rqp->q_ptr = NULL;
 445  447          WR(rqp)->q_ptr = NULL;
↓ open down ↓ 13 lines elided ↑ open up ↑
 459  461          struct iocblk   *iocp;
 460  462  
 461  463          DBG(("entering ptmwput\n"));
 462  464          ASSERT(qp->q_ptr);
 463  465  
 464  466          ptmp = (struct pt_ttys *)qp->q_ptr;
 465  467          PT_ENTER_READ(ptmp);
 466  468  
 467  469          switch (mp->b_datap->db_type) {
 468  470          /*
 469      -         * if write queue request, flush master's write
 470      -         * queue and send FLUSHR up slave side. If read
 471      -         * queue request, convert to FLUSHW and putnext().
      471 +         * If this is a write queue request, flush manager's write queue and
      472 +         * send FLUSHR up subsidiary side.  If it is a read queue request,
      473 +         * convert to FLUSHW and putnext().
 472  474           */
 473  475          case M_FLUSH:
 474  476                  {
 475  477                          unsigned char flush_flg = 0;
 476  478  
 477  479                          DBG(("ptm got flush request\n"));
 478  480                          if (*mp->b_rptr & FLUSHW) {
 479  481                                  DBG(("got FLUSHW, flush ptm write Q\n"));
 480      -                                if (*mp->b_rptr & FLUSHBAND)
      482 +                                if (*mp->b_rptr & FLUSHBAND) {
 481  483                                          /*
 482  484                                           * if it is a FLUSHBAND, do flushband.
 483  485                                           */
 484  486                                          flushband(qp, *(mp->b_rptr + 1),
 485  487                                              FLUSHDATA);
 486      -                                else
      488 +                                } else {
 487  489                                          flushq(qp, FLUSHDATA);
      490 +                                }
 488  491                                  flush_flg = (*mp->b_rptr & ~FLUSHW) | FLUSHR;
 489  492                          }
 490  493                          if (*mp->b_rptr & FLUSHR) {
 491  494                                  DBG(("got FLUSHR, set FLUSHW\n"));
 492  495                                  flush_flg |= (*mp->b_rptr & ~FLUSHR) | FLUSHW;
 493  496                          }
 494  497                          if (flush_flg != 0 && ptmp->pts_rdq &&
 495  498                              !(ptmp->pt_state & PTLOCK)) {
 496  499                                  DBG(("putnext to pts\n"));
 497  500                                  *mp->b_rptr = flush_flg;
 498  501                                  putnext(ptmp->pts_rdq, mp);
 499      -                        } else
      502 +                        } else {
 500  503                                  freemsg(mp);
      504 +                        }
 501  505                          break;
 502  506                  }
 503  507  
 504  508          case M_IOCTL:
 505  509                  iocp = (struct iocblk *)mp->b_rptr;
 506  510                  switch (iocp->ioc_cmd) {
 507  511                  default:
 508  512                          if ((ptmp->pt_state & PTLOCK) ||
 509  513                              (ptmp->pts_rdq == NULL)) {
 510      -                                DBG(("got M_IOCTL but no slave\n"));
      514 +                                DBG(("got M_IOCTL but no subsidiary\n"));
 511  515                                  miocnak(qp, mp, 0, EINVAL);
 512  516                                  PT_EXIT_READ(ptmp);
 513  517                                  return (0);
 514  518                          }
 515  519                          (void) putq(qp, mp);
 516  520                          break;
 517  521                  case UNLKPT:
 518  522                          mutex_enter(&ptmp->pt_lock);
 519  523                          ptmp->pt_state &= ~PTLOCK;
 520  524                          mutex_exit(&ptmp->pt_lock);
↓ open down ↓ 59 lines elided ↑ open up ↑
 580  584                          ptmp->pt_ruid = ptop->pto_ruid;
 581  585                          ptmp->pt_rgid = ptop->pto_rgid;
 582  586                          mutex_exit(&ptmp->pt_lock);
 583  587                          miocack(qp, mp, 0, 0);
 584  588                          break;
 585  589                  }
 586  590                  }
 587  591                  break;
 588  592  
 589  593          case M_READ:
 590      -                /* Caused by ldterm - can not pass to slave */
      594 +                /* Caused by ldterm - can not pass to subsidiary */
 591  595                  freemsg(mp);
 592  596                  break;
 593  597  
 594  598          /*
 595      -         * send other messages to slave
      599 +         * Send other messages to the subsidiary:
 596  600           */
 597  601          default:
 598      -                if ((ptmp->pt_state  & PTLOCK) || (ptmp->pts_rdq == NULL)) {
 599      -                        DBG(("got msg. but no slave\n"));
      602 +                if ((ptmp->pt_state & PTLOCK) || (ptmp->pts_rdq == NULL)) {
      603 +                        DBG(("got msg. but no subsidiary\n"));
 600  604                          mp = mexchange(NULL, mp, 2, M_ERROR, -1);
 601  605                          if (mp != NULL) {
 602  606                                  mp->b_rptr[0] = NOERROR;
 603  607                                  mp->b_rptr[1] = EINVAL;
 604  608                                  qreply(qp, mp);
 605  609                          }
 606  610                          PT_EXIT_READ(ptmp);
 607  611                          return (0);
 608  612                  }
 609      -                DBG(("put msg on master's write queue\n"));
      613 +                DBG(("put msg on manager's write queue\n"));
 610  614                  (void) putq(qp, mp);
 611  615                  break;
 612  616          }
 613  617          DBG(("return from ptmwput()\n"));
 614  618          PT_EXIT_READ(ptmp);
 615  619          return (0);
 616  620  }
 617  621  
 618  622  
 619  623  /*
 620      - * enable the write side of the slave. This triggers the
 621      - * slave to send any messages queued on its write side to
 622      - * the read side of this master.
      624 + * Enable the write side of the subsidiary.  This triggers the subsidiary to
      625 + * send any messages queued on its write side to the read side of this manager.
 623  626   */
 624  627  static int
 625  628  ptmrsrv(queue_t *qp)
 626  629  {
 627  630          struct pt_ttys  *ptmp;
 628  631  
 629  632          DBG(("entering ptmrsrv\n"));
 630  633          ASSERT(qp->q_ptr);
 631  634  
 632  635          ptmp = (struct pt_ttys *)qp->q_ptr;
↓ open down ↓ 1 lines elided ↑ open up ↑
 634  637          if (ptmp->pts_rdq) {
 635  638                  qenable(WR(ptmp->pts_rdq));
 636  639          }
 637  640          PT_EXIT_READ(ptmp);
 638  641          DBG(("leaving ptmrsrv\n"));
 639  642          return (0);
 640  643  }
 641  644  
 642  645  
 643  646  /*
 644      - * If there are messages on this queue that can be sent to
 645      - * slave, send them via putnext(). Else, if queued messages
 646      - * cannot be sent, leave them on this queue. If priority
 647      - * messages on this queue, send them to slave no matter what.
      647 + * If there are messages on this queue that can be sent to subsidiary, send
      648 + * them via putnext().  Otherwise, if queued messages cannot be sent, leave
      649 + * them on this queue.  If priority messages on this queue, send them to the
      650 + * subsidiary no matter what.
 648  651   */
 649  652  static int
 650  653  ptmwsrv(queue_t *qp)
 651  654  {
 652  655          struct pt_ttys  *ptmp;
 653  656          mblk_t          *mp;
 654  657  
 655  658          DBG(("entering ptmwsrv\n"));
 656  659          ASSERT(qp->q_ptr);
 657  660  
 658  661          ptmp = (struct pt_ttys *)qp->q_ptr;
 659  662  
 660  663          if ((mp = getq(qp)) == NULL) {
 661  664                  /* If there are no messages there's nothing to do. */
 662  665                  DBG(("leaving ptmwsrv (no messages)\n"));
 663  666                  return (0);
 664  667          }
 665  668  
 666  669          PT_ENTER_READ(ptmp);
 667  670          if ((ptmp->pt_state  & PTLOCK) || (ptmp->pts_rdq == NULL)) {
 668      -                DBG(("in master write srv proc but no slave\n"));
      671 +                DBG(("in manager write srv proc but no subsidiary\n"));
 669  672                  /*
 670  673                   * Free messages on the write queue and send
 671  674                   * NAK for any M_IOCTL type messages to wakeup
 672  675                   * the user process waiting for ACK/NAK from
 673  676                   * the ioctl invocation
 674  677                   */
 675  678                  do {
 676  679                          if (mp->b_datap->db_type == M_IOCTL)
 677  680                                  miocnak(qp, mp, 0, EINVAL);
 678  681                          else
↓ open down ↓ 4 lines elided ↑ open up ↑
 683  686                  mp = mexchange(NULL, NULL, 2, M_ERROR, -1);
 684  687                  if (mp != NULL) {
 685  688                          mp->b_rptr[0] = NOERROR;
 686  689                          mp->b_rptr[1] = EINVAL;
 687  690                          qreply(qp, mp);
 688  691                  }
 689  692                  PT_EXIT_READ(ptmp);
 690  693                  return (0);
 691  694          }
 692  695          /*
 693      -         * while there are messages on this write queue...
      696 +         * While there are messages on this write queue...
 694  697           */
 695  698          do {
 696  699                  /*
 697      -                 * if don't have control message and cannot put
 698      -                 * msg. on slave's read queue, put it back on
 699      -                 * this queue.
      700 +                 * If this is not a control message, and we cannot put messages
      701 +                 * on the subsidiary's read queue, put it back on this queue.
 700  702                   */
 701  703                  if (mp->b_datap->db_type <= QPCTL &&
 702  704                      !bcanputnext(ptmp->pts_rdq, mp->b_band)) {
 703  705                          DBG(("put msg. back on queue\n"));
 704  706                          (void) putbq(qp, mp);
 705  707                          break;
 706  708                  }
 707  709                  /*
 708      -                 * else send the message up slave's stream
      710 +                 * Otherwise send the message up subsidiary's stream
 709  711                   */
 710      -                DBG(("send message to slave\n"));
      712 +                DBG(("send message to subsidiary\n"));
 711  713                  putnext(ptmp->pts_rdq, mp);
 712  714          } while ((mp = getq(qp)) != NULL);
 713  715          DBG(("leaving ptmwsrv\n"));
 714  716          PT_EXIT_READ(ptmp);
 715  717          return (0);
 716  718  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX