Don't try to call _free_osfhnd when not compiling agains the static CRT
authorChristopher Dykes <cdykes@fb.com>
Thu, 10 Nov 2016 20:32:51 +0000 (12:32 -0800)
committerFacebook Github Bot <facebook-github-bot-bot@fb.com>
Thu, 10 Nov 2016 20:38:28 +0000 (12:38 -0800)
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

index bf598d237285df0a1177d2efe47b36ef918d6dfd..b55aa4aa618c81666361c31faf08531e2f7debe9 100755 (executable)
@@ -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);