Print this page
3769 Implement SOCK_NONBLOCK flag to socket()
Reviewed-by: Robert Mustacchi <rm@joyent.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/sockfs/socksyscalls.c
          +++ new/usr/src/uts/common/fs/sockfs/socksyscalls.c
↓ open down ↓ 101 lines elided ↑ open up ↑
 102  102      int version)
 103  103  {
 104  104          struct sonode *so;
 105  105          vnode_t *vp;
 106  106          struct file *fp;
 107  107          int fd;
 108  108          int error;
 109  109          int type;
 110  110  
 111  111          type = type_w_flags & SOCK_TYPE_MASK;
      112 +        type_w_flags &= ~SOCK_TYPE_MASK;
      113 +        if (type_w_flags & ~(SOCK_CLOEXEC|SOCK_NDELAY|SOCK_NONBLOCK))
      114 +                return (set_errno(EINVAL));
      115 +
 112  116          if (devpath != NULL) {
 113  117                  char *buf;
 114  118                  size_t kdevpathlen = 0;
 115  119  
 116  120                  buf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
 117  121                  if ((error = copyinstr(devpath, buf,
 118  122                      MAXPATHLEN, &kdevpathlen)) != 0) {
 119  123                          kmem_free(buf, MAXPATHLEN);
 120  124                          return (set_errno(error));
 121  125                  }
↓ open down ↓ 11 lines elided ↑ open up ↑
 133  137          vp = SOTOV(so);
 134  138          if (error = falloc(vp, FWRITE|FREAD, &fp, &fd)) {
 135  139                  (void) socket_close(so, 0, CRED());
 136  140                  socket_destroy(so);
 137  141                  return (set_errno(error));
 138  142          }
 139  143  
 140  144          /*
 141  145           * Now fill in the entries that falloc reserved
 142  146           */
      147 +        if (type_w_flags & SOCK_NDELAY) {
      148 +                so->so_state |= SS_NDELAY;
      149 +                fp->f_flag |= FNDELAY;
      150 +        }
      151 +        if (type_w_flags & SOCK_NONBLOCK) {
      152 +                so->so_state |= SS_NONBLOCK;
      153 +                fp->f_flag |= FNONBLOCK;
      154 +        }
 143  155          mutex_exit(&fp->f_tlock);
 144  156          setf(fd, fp);
 145  157          if ((type_w_flags & SOCK_CLOEXEC) != 0) {
 146  158                  f_setfd(fd, FD_CLOEXEC);
 147  159          }
 148  160  
 149  161          return (fd);
 150  162  }
 151  163  
 152  164  /*
↓ open down ↓ 328 lines elided ↑ open up ↑
 481  493                  }
 482  494  
 483  495                  nvp = SOTOV(nso);
 484  496                  if (error = falloc(nvp, FWRITE|FREAD, &nfp, &nfd)) {
 485  497                          (void) socket_close(nso, 0, CRED());
 486  498                          socket_destroy(nso);
 487  499                          eprintsoline(nso, error);
 488  500                          goto done;
 489  501                  }
 490  502                  /*
      503 +                 * copy over FNONBLOCK and FNDELAY flags should they exist
      504 +                 */
      505 +                if (so1->so_state & SS_NONBLOCK)
      506 +                        nfp->f_flag |= FNONBLOCK;
      507 +                if (so1->so_state & SS_NDELAY)
      508 +                        nfp->f_flag |= FNDELAY;
      509 +
      510 +                /*
 491  511                   * fill in the entries that falloc reserved
 492  512                   */
 493  513                  mutex_exit(&nfp->f_tlock);
 494  514                  setf(nfd, nfp);
 495  515  
      516 +                /*
      517 +                 * get the original flags before we release
      518 +                 */
      519 +                VERIFY(f_getfd_error(svs[0], &orig_flags) == 0);
      520 +
 496  521                  releasef(svs[0]);
 497  522                  releasef(svs[1]);
 498  523  
 499  524                  /*
 500  525                   * If FD_CLOEXEC was set on the filedescriptor we're
 501  526                   * swapping out, we should set it on the new one too.
 502  527                   */
 503      -                VERIFY(f_getfd_error(svs[0], &orig_flags) == 0);
 504  528                  if (orig_flags & FD_CLOEXEC) {
 505  529                          f_setfd(nfd, FD_CLOEXEC);
 506  530                  }
 507  531  
 508  532                  /*
 509  533                   * The socketpair library routine will close the original
 510  534                   * svs[0] when this code passes out a different file
 511  535                   * descriptor.
 512  536                   */
 513  537                  svs[0] = nfd;
↓ open down ↓ 2551 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX