Print this page
    
3910 t_look(3NSL) should never return T_ERROR
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/lib/libnsl/nsl/t_look.c
          +++ new/usr/src/lib/libnsl/nsl/t_look.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License, Version 1.0 only
   6    6   * (the "License").  You may not use this file except in compliance
   7    7   * with the License.
   8    8   *
   9    9   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10   10   * or http://www.opensolaris.org/os/licensing.
  11   11   * See the License for the specific language governing permissions
  12   12   * and limitations under the License.
  13   13   *
  14   14   * When distributing Covered Code, include this CDDL HEADER in each
  15   15   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16   16   * If applicable, add the following below this CDDL HEADER, with the
  17   17   * fields enclosed by brackets "[]" replaced with your own identifying
  18   18   * information: Portions Copyright [yyyy] [name of copyright owner]
  
    | 
      ↓ open down ↓ | 
    18 lines elided | 
    
      ↑ open up ↑ | 
  
  19   19   *
  20   20   * CDDL HEADER END
  21   21   */
  22   22  
  23   23  /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
  24   24  /*        All Rights Reserved   */
  25   25  
  26   26  /*
  27   27   * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  28   28   * Use is subject to license terms.
       29 + * Copyright 2014 Gary Mills
  29   30   */
  30   31  
  31      -#pragma ident   "%Z%%M% %I%     %E% SMI"
  32      -
  33   32  #include "mt.h"
  34   33  #include <errno.h>
  35   34  #include <unistd.h>
  36   35  #include <sys/stream.h>
  37   36  #include <stropts.h>
  38   37  #define _SUN_TPI_VERSION 2
  39   38  #include <sys/tihdr.h>
  40   39  #include <sys/timod.h>
  41   40  #include <xti.h>
  42   41  #include <assert.h>
  43   42  #include "tx.h"
  44   43  
  45   44  int
  46   45  _tx_look(int fd, int api_semantics)
  47   46  {
  48   47          int state;
  49   48          int sv_errno;
  50   49          int do_expinline_peek;   /* unusual XTI specific processing */
  51   50          struct _ti_user *tiptr;
  52   51  
  53   52          if ((tiptr = _t_checkfd(fd, 0, api_semantics)) == NULL)
  54   53                  return (-1);
  55   54          sig_mutex_lock(&tiptr->ti_lock);
  56   55  
  57   56          if (_T_IS_XTI(api_semantics))
  58   57                  do_expinline_peek = 1;
  59   58          else
  60   59                  do_expinline_peek = 0;
  61   60          state = _t_look_locked(fd, tiptr, do_expinline_peek, api_semantics);
  62   61  
  63   62          sv_errno = errno;
  64   63  
  65   64          sig_mutex_unlock(&tiptr->ti_lock);
  66   65          errno = sv_errno;
  67   66          return (state);
  68   67  }
  69   68  
  70   69  /*
  71   70   * _t_look_locked() assumes tiptr->ti_lock lock is already held and signals
  72   71   * already blocked in MT case.
  73   72   * Intended for use by other TLI routines only.
  74   73   */
  75   74  int
  76   75  _t_look_locked(
  77   76          int fd,
  78   77          struct _ti_user *tiptr,
  79   78          int do_expinline_peek,
  80   79          int api_semantics
  81   80  )
  82   81  {
  83   82          struct strpeek strpeek;
  84   83          int retval;
  85   84          union T_primitives *pptr;
  86   85          t_scalar_t type;
  87   86          t_scalar_t ctltype;
  88   87  
  89   88          assert(MUTEX_HELD(&tiptr->ti_lock));
  90   89  
  91   90  #ifdef notyet
  92   91          if (_T_IS_XTI(api_semantics)) {
  93   92                  /*
  94   93                   * XTI requires the strange T_GODATA and T_GOEXDATA
  95   94                   * events which are almost brain-damaged but thankfully
  96   95                   * not tested. Anyone feeling the need for those should
  97   96                   * consider the need for using non-blocking endpoint.
  98   97                   * Probably introduced at the behest of some weird-os
  99   98                   * vendor which did not understand the non-blocking endpoint
 100   99                   * option.
 101  100                   * We choose not to implment these mis-features.
 102  101                   * Here is the plan-of-action (POA)if we are ever forced
 103  102                   * to implement these.
 104  103                   * - When returning TFLOW set state to indicate if it was
 105  104                   *   a normal or expedited data send attempt.
 106  105                   * - In routines that set TFLOW, clear the above set state
 107  106                   *   on each entry/reentry
 108  107                   * - In this routine, if that state flag is set,
 109  108                   * do a I_CANPUT on appropriate band to to see if it
 110  109                   * is writeable. If that indicates that the band is
 111  110                   * writeable, return T_GODATA or T_GOEXDATA event.
 112  111                   *
 113  112                   * Actions are also influenced by whether T_EXDATA_REQ stays
 114  113                   * band 1 or goes to band 0 if EXPINLINE is set
 115  114                   *
 116  115                   * We will also need to sort out if "write side" events
 117  116                   * (such as T_GODATA/T_GOEXDATA) take precedence over
 118  117                   * all other events (all read side) or not.
 119  118                   */
 120  119          }
 121  120  #endif /* notyet */
 122  121  
 123  122          strpeek.ctlbuf.maxlen = (int)sizeof (ctltype);
 124  123          strpeek.ctlbuf.len = 0;
 125  124          strpeek.ctlbuf.buf = (char *)&ctltype;
  
    | 
      ↓ open down ↓ | 
    83 lines elided | 
    
      ↑ open up ↑ | 
  
 126  125          strpeek.databuf.maxlen = 0;
 127  126          strpeek.databuf.len = 0;
 128  127          strpeek.databuf.buf = NULL;
 129  128          strpeek.flags = 0;
 130  129  
 131  130          do {
 132  131                  retval = ioctl(fd, I_PEEK, &strpeek);
 133  132          } while (retval < 0 && errno == EINTR);
 134  133  
 135  134          if (retval < 0) {
 136      -                if (_T_IS_TLI(api_semantics)) {
 137      -                        /*
 138      -                         * This return of T_ERROR event is ancient
 139      -                         * SVR3 TLI semantics and not documented for
 140      -                         * current SVR4 TLI interface.
 141      -                         * Fixing this will impact some apps
 142      -                         * (e.g. nfsd,lockd) in ON consolidation
 143      -                         * so they need to be fixed first before TLI
 144      -                         * can be fixed.
 145      -                         * XXX Should we never fix this because it might
 146      -                         * break apps in field ?
 147      -                         */
 148      -                        return (T_ERROR);
 149      -                }
 150  135                  /*
 151      -                 * XTI semantics (also identical to documented,
 152      -                 * but not implemented TLI semantics).
      136 +                 * XTI semantics (also identical to documented
      137 +                 * TLI semantics).
 153  138                   */
 154  139                  t_errno = TSYSERR;
 155  140                  return (-1);
 156  141          }
 157  142  
 158  143          /*
 159  144           * if something there and cntl part also there
 160  145           */
 161  146          if ((tiptr->ti_lookcnt > 0) ||
 162      -        ((retval > 0) && (strpeek.ctlbuf.len >= (int)sizeof (t_scalar_t)))) {
      147 +            ((retval > 0) && (strpeek.ctlbuf.len >=
      148 +            (int)sizeof (t_scalar_t)))) {
 163  149                  /* LINTED pointer cast */
 164  150                  pptr = (union T_primitives *)strpeek.ctlbuf.buf;
 165  151                  if (tiptr->ti_lookcnt > 0) {
 166  152                          /* LINTED pointer cast */
 167  153                          type = *((t_scalar_t *)tiptr->ti_lookbufs.tl_lookcbuf);
 168  154                          /*
 169  155                           * If message on stream head is a T_DISCON_IND, that
 170  156                           * has priority over a T_ORDREL_IND in the look
 171  157                           * buffer.
 172  158                           * (This assumes that T_ORDREL_IND can only be in the
 173  159                           * first look buffer in the list)
 174  160                           */
 175  161                          if ((type == T_ORDREL_IND) && retval &&
 176  162                              (pptr->type == T_DISCON_IND)) {
 177  163                                  type = pptr->type;
 178  164                                  /*
 179  165                                   * Blow away T_ORDREL_IND
 180  166                                   */
 181  167                                  _t_free_looklist_head(tiptr);
 182  168                          }
 183  169                  } else
 184  170                          type = pptr->type;
 185  171  
 186  172                  switch (type) {
 187  173  
 188  174                  case T_CONN_IND:
 189  175                          return (T_LISTEN);
 190  176  
 191  177                  case T_CONN_CON:
 192  178                          return (T_CONNECT);
 193  179  
 194  180                  case T_DISCON_IND:
 195  181                          return (T_DISCONNECT);
 196  182  
 197  183                  case T_DATA_IND: {
 198  184                          int event = T_DATA;
 199  185                          int retval, exp_on_q;
 200  186  
 201  187                          if (do_expinline_peek &&
 202  188                              (tiptr->ti_prov_flag & EXPINLINE)) {
 203  189                                  assert(_T_IS_XTI(api_semantics));
 204  190                                  retval = _t_expinline_queued(fd, &exp_on_q);
 205  191                                  if (retval < 0) {
 206  192                                          t_errno = TSYSERR;
 207  193                                          return (-1);
 208  194                                  }
 209  195                                  if (exp_on_q)
 210  196                                          event = T_EXDATA;
 211  197                          }
 212  198                          return (event);
 213  199                  }
 214  200  
 215  201                  case T_UNITDATA_IND:
 216  202                          return (T_DATA);
 217  203  
 218  204                  case T_EXDATA_IND:
 219  205                          return (T_EXDATA);
 220  206  
 221  207                  case T_UDERROR_IND:
 222  208                          return (T_UDERR);
 223  209  
 224  210                  case T_ORDREL_IND:
 225  211                          return (T_ORDREL);
 226  212  
 227  213                  default:
 228  214                          t_errno = TSYSERR;
 229  215                          errno = EPROTO;
 230  216                          return (-1);
 231  217                  }
 232  218          }
 233  219  
 234  220          /*
 235  221           * if something there put no control part
 236  222           * it must be data on the stream head.
 237  223           */
 238  224          if ((retval > 0) && (strpeek.ctlbuf.len <= 0)) {
 239  225                  int event = T_DATA;
 240  226                  int retval, exp_on_q;
 241  227  
 242  228                  if (do_expinline_peek &&
 243  229                      (tiptr->ti_prov_flag & EXPINLINE)) {
 244  230                          assert(_T_IS_XTI(api_semantics));
 245  231                          retval = _t_expinline_queued(fd, &exp_on_q);
 246  232                          if (retval < 0)
 247  233                                  return (-1);
 248  234                          if (exp_on_q)
 249  235                                  event = T_EXDATA;
 250  236                  }
 251  237                  return (event);
 252  238          }
 253  239  
 254  240          /*
 255  241           * if msg there and control
 256  242           * part not large enough to determine type?
 257  243           * it must be illegal TLI message
 258  244           */
 259  245          if ((retval > 0) && (strpeek.ctlbuf.len > 0)) {
 260  246                  t_errno = TSYSERR;
 261  247                  errno = EPROTO;
 262  248                  return (-1);
 263  249          }
 264  250          return (0);
 265  251  }
  
    | 
      ↓ open down ↓ | 
    93 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX