From dd133c17ea8fe4cac4b5dac8955f173681569492 Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Sun, 31 Jan 2016 17:07:58 -0800
Subject: [PATCH] Prevent the need to install libc6-dev on Linux

---
 src/csharp/Grpc.Core/Internal/PlatformApis.cs |  7 ++++++
 .../Grpc.Core/Internal/UnmanagedLibrary.cs    | 24 +++++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/src/csharp/Grpc.Core/Internal/PlatformApis.cs b/src/csharp/Grpc.Core/Internal/PlatformApis.cs
index d71e7eccdd..f0c5b0f63f 100644
--- a/src/csharp/Grpc.Core/Internal/PlatformApis.cs
+++ b/src/csharp/Grpc.Core/Internal/PlatformApis.cs
@@ -49,6 +49,7 @@ namespace Grpc.Core.Internal
         static readonly bool isLinux;
         static readonly bool isMacOSX;
         static readonly bool isWindows;
+        static readonly bool isMono;
 
         static PlatformApis()
         {
@@ -58,6 +59,7 @@ namespace Grpc.Core.Internal
             isMacOSX = (platform == PlatformID.Unix && GetUname() == "Darwin");
             isLinux = (platform == PlatformID.Unix && !isMacOSX);
             isWindows = (platform == PlatformID.Win32NT || platform == PlatformID.Win32S || platform == PlatformID.Win32Windows);
+            isMono = Type.GetType("Mono.Runtime") != null;
         }
 
         public static bool IsLinux
@@ -75,6 +77,11 @@ namespace Grpc.Core.Internal
             get { return isWindows; }
         }
 
+        public static bool IsMono
+        {
+            get { return isMono; }
+        }
+
         public static bool Is64Bit
         {
             get { return IntPtr.Size == 8; }
diff --git a/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs b/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs
index e614cab6ab..95a8797e3e 100644
--- a/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs
+++ b/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs
@@ -91,6 +91,10 @@ namespace Grpc.Core.Internal
         {
             if (PlatformApis.IsLinux)
             {
+                if (PlatformApis.IsMono)
+                {
+                    return Mono.dlsym(this.handle, symbolName);
+                }
                 return Linux.dlsym(this.handle, symbolName);
             }
             if (PlatformApis.IsMacOSX)
@@ -122,6 +126,10 @@ namespace Grpc.Core.Internal
             }
             if (PlatformApis.IsLinux)
             {
+                if (PlatformApis.IsMono)
+                {
+                    return Mono.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY);
+                }
                 return Linux.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY);
             }
             if (PlatformApis.IsMacOSX)
@@ -154,5 +162,21 @@ namespace Grpc.Core.Internal
             [DllImport("libSystem.dylib")]
             internal static extern IntPtr dlsym(IntPtr handle, string symbol);
         }
+
+        /// <summary>
+        /// On Linux systems, using using dlopen and dlsym results in
+        /// DllNotFoundException("libdl.so not found") if libc6-dev
+        /// is not installed. As a workaround, we load symbols for
+        /// dlopen and dlsym from the current process as on Linux
+        /// Mono sure is linked against these symbols.
+        /// </summary>
+        private static class Mono
+        {
+            [DllImport("__Internal")]
+            internal static extern IntPtr dlopen(string filename, int flags);
+
+            [DllImport("__Internal")]
+            internal static extern IntPtr dlsym(IntPtr handle, string symbol);
+        }
     }
 }
-- 
GitLab