From a9adcd158b03b8a1b5316a9d1fdb8ccb8b8e9e73 Mon Sep 17 00:00:00 2001
From: Christopher Dykes <cdykes@fb.com>
Date: Thu, 10 Nov 2016 12:32:51 -0800
Subject: [PATCH] Don't try to call _free_osfhnd when not compiling agains the
 static CRT

Summary:
Because, unfortunately, it isn't exported from the dynamic CRT dlls :(
There's not really a nice way to handle this when using the dynamic CRT without doing very fragile hocus-pocus that relies on the exact layout and implementation details of the file descriptor table in the CRT, so the best we can really do is close the socket and just let the file descriptor itself leak.

Reviewed By: yfeldblum

Differential Revision: D4156558

fbshipit-source-id: 32cb4bf357f6746cf6597b66649ff9f018fb1bed
---
 folly/portability/Unistd.cpp | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/folly/portability/Unistd.cpp b/folly/portability/Unistd.cpp
index bf598d23..b55aa4aa 100755
--- a/folly/portability/Unistd.cpp
+++ b/folly/portability/Unistd.cpp
@@ -54,8 +54,10 @@ int access(char const* fn, int am) { return _access(fn, am); }
 
 int chdir(const char* path) { return _chdir(path); }
 
+#if defined(_MT) && !defined(_DLL)
 // We aren't hooking into the internals of the CRT, nope, not at all.
 extern "C" int __cdecl _free_osfhnd(int const fh);
+#endif
 int close(int fh) {
   if (folly::portability::sockets::is_fh_socket(fh)) {
     SOCKET h = (SOCKET)_get_osfhandle(fh);
@@ -69,8 +71,17 @@ int close(int fh) {
     // Luckily though, there is a function in the internals of the
     // CRT that is used to free only the file descriptor, so we
     // can call that to avoid leaking the file descriptor itself.
+    //
+    // Unfortunately, we can only access the function when we're
+    // compiling against the static CRT, as it isn't an exported
+    // symbol. Leaking the file descriptor is less of a leak than
+    // leaking the socket's resources, so we close the socket and
+    // leave the descriptor itself alone.
     auto c = closesocket(h);
+#if defined(_MT) && !defined(_DLL)
+    // We're building for the static CRT. We can do things!
     _free_osfhnd(fh);
+#endif
     return c;
   }
   return _close(fh);
-- 
2.34.1