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

@@ -107,10 +107,14 @@
         int fd;
         int error;
         int type;
 
         type = type_w_flags & SOCK_TYPE_MASK;
+        type_w_flags &= ~SOCK_TYPE_MASK;
+        if (type_w_flags & ~(SOCK_CLOEXEC|SOCK_NDELAY|SOCK_NONBLOCK))
+                return (set_errno(EINVAL));
+
         if (devpath != NULL) {
                 char *buf;
                 size_t kdevpathlen = 0;
 
                 buf = kmem_alloc(MAXPATHLEN, KM_SLEEP);

@@ -138,10 +142,18 @@
         }
 
         /*
          * Now fill in the entries that falloc reserved
          */
+        if (type_w_flags & SOCK_NDELAY) {
+                so->so_state |= SS_NDELAY;
+                fp->f_flag |= FNDELAY;
+        }
+        if (type_w_flags & SOCK_NONBLOCK) {
+                so->so_state |= SS_NONBLOCK;
+                fp->f_flag |= FNONBLOCK;
+        }
         mutex_exit(&fp->f_tlock);
         setf(fd, fp);
         if ((type_w_flags & SOCK_CLOEXEC) != 0) {
                 f_setfd(fd, FD_CLOEXEC);
         }

@@ -486,23 +498,35 @@
                         socket_destroy(nso);
                         eprintsoline(nso, error);
                         goto done;
                 }
                 /*
+                 * copy over FNONBLOCK and FNDELAY flags should they exist
+                 */
+                if (so1->so_state & SS_NONBLOCK)
+                        nfp->f_flag |= FNONBLOCK;
+                if (so1->so_state & SS_NDELAY)
+                        nfp->f_flag |= FNDELAY;
+
+                /*
                  * fill in the entries that falloc reserved
                  */
                 mutex_exit(&nfp->f_tlock);
                 setf(nfd, nfp);
 
+                /*
+                 * get the original flags before we release
+                 */
+                VERIFY(f_getfd_error(svs[0], &orig_flags) == 0);
+
                 releasef(svs[0]);
                 releasef(svs[1]);
 
                 /*
                  * If FD_CLOEXEC was set on the filedescriptor we're
                  * swapping out, we should set it on the new one too.
                  */
-                VERIFY(f_getfd_error(svs[0], &orig_flags) == 0);
                 if (orig_flags & FD_CLOEXEC) {
                         f_setfd(nfd, FD_CLOEXEC);
                 }
 
                 /*