From 65f4a09ad54ed580c433377572b15a3e4dc2082f Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Sun, 17 Apr 2022 14:20:27 +0200 Subject: [PATCH] Try to fix ZStd stuff for servers. --- Robust.Shared/Native/Libc.cs | 19 +++++++++++ Robust.Shared/Utility/ZStd.cs | 59 ++++++++++++++++++++++++++++++++++- 2 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 Robust.Shared/Native/Libc.cs diff --git a/Robust.Shared/Native/Libc.cs b/Robust.Shared/Native/Libc.cs new file mode 100644 index 000000000..06be04d55 --- /dev/null +++ b/Robust.Shared/Native/Libc.cs @@ -0,0 +1,19 @@ +using System; +using System.Runtime.InteropServices; + +namespace Robust.Shared.Native; + +internal static class Libc +{ + public const int RTLD_LAZY = 0x00001; + public const int RTLD_NOW = 0x00002; + public const int RTLD_BINDING_MASK = 0x3; + public const int RTLD_NOLOAD = 0x00004; + public const int RTLD_DEEPBIND = 0x00008; + public const int RTLD_GLOBAL = 0x00100; + public const int RTLD_LOCAL = 0; + public const int RTLD_NODELETE = 0x01000; + + [DllImport("libdl.so.2")] + public static extern IntPtr dlopen([MarshalAs(UnmanagedType.LPUTF8Str)] string name, int flags); +} diff --git a/Robust.Shared/Utility/ZStd.cs b/Robust.Shared/Utility/ZStd.cs index 75f437911..88300b5d5 100644 --- a/Robust.Shared/Utility/ZStd.cs +++ b/Robust.Shared/Utility/ZStd.cs @@ -1,11 +1,13 @@ using System; using System.Buffers; using System.IO; +using System.Reflection; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; using SharpZstd.Interop; +using static Robust.Shared.Native.Libc; using static SharpZstd.Interop.Zstd; namespace Robust.Shared.Utility; @@ -30,6 +32,61 @@ public static class ZStd return (int) result; } } + +#pragma warning disable CA2255 + [ModuleInitializer] +#pragma warning restore CA2255 + internal static void InitZStd() + { + try + { + NativeLibrary.SetDllImportResolver( + typeof(Zstd).Assembly, + ResolveZstd + ); + } + catch (InvalidOperationException) + { + // Launcher loader probably already set this, ignore. + } + } + + private static IntPtr ResolveZstd(string name, Assembly assembly, DllImportSearchPath? path) + { + if (name == "zstd" && OperatingSystem.IsLinux()) + { + try + { + var paths = (string)AppContext.GetData("NATIVE_DLL_SEARCH_DIRECTORIES")!; + foreach (var p in paths.Split(':', StringSplitOptions.RemoveEmptyEntries)) + { + var tryPath = Path.Join(p, "zstd.so"); + // Console.WriteLine($"TRYING: {tryPath}"); + var result = dlopen(tryPath, RTLD_LOCAL | RTLD_DEEPBIND | RTLD_LAZY); + // Console.WriteLine(result); + if (result != IntPtr.Zero) + { + // Console.WriteLine($"FOUND: {tryPath}"); + return result; + } + } + } + catch (Exception ex) + { + // Catch and at least provide some way of retrieving this. + System.Console.Error.WriteLine($"Exception during ZStd libdl search: {ex}"); + } + + // Try some extra paths too worst case. + if (NativeLibrary.TryLoad("libzstd.so.1", out var handle)) + return handle; + + if (NativeLibrary.TryLoad("libzstd.so", out handle)) + return handle; + } + + return IntPtr.Zero; + } } [Serializable]