Support using fcntl to mark pipes as non-blocking
authorChristopher Dykes <cdykes@fb.com>
Tue, 9 Aug 2016 21:57:19 +0000 (14:57 -0700)
committerFacebook Github Bot <facebook-github-bot-bot@fb.com>
Tue, 9 Aug 2016 22:08:29 +0000 (15:08 -0700)
Summary: Because the comment was a lie; sockets are blocking by default, not non-blocking.

Reviewed By: yfeldblum

Differential Revision: D3691145

fbshipit-source-id: 5d3c62b3573205fe416d77fe4b5b9fbd593ffd93

folly/portability/Fcntl.cpp

index e02a767c12f76336232dfe5ed44c7386c5d4d07f..015f4a6d54ec7637700290bc57676ec0630adbba 100755 (executable)
@@ -60,8 +60,7 @@ int fcntl(int fd, int cmd, ...) {
     case F_SETFL: {
       int flags = va_arg(args, int);
       if (flags & O_NONBLOCK) {
-        // If it's not a socket, it's probably a pipe, and
-        // those are non-blocking by default with Windows.
+        // If it's not a socket, it's probably a pipe.
         if (folly::portability::sockets::is_fh_socket(fd)) {
           SOCKET s = (SOCKET)_get_osfhandle(fd);
           if (s != INVALID_SOCKET) {
@@ -69,7 +68,13 @@ int fcntl(int fd, int cmd, ...) {
             res = ioctlsocket(s, FIONBIO, &nonBlockingEnabled);
           }
         } else {
-          res = 0;
+          HANDLE p = (HANDLE)_get_osfhandle(fd);
+          if (GetFileType(p) == FILE_TYPE_PIPE) {
+            DWORD newMode = PIPE_READMODE_BYTE | PIPE_NOWAIT;
+            if (SetNamedPipeHandleState(p, &newMode, nullptr, nullptr)) {
+              res = 0;
+            }
+          }
         }
       }
       break;