From bbd925fcff419a5be90d60d14bbf8e0cc8d2162b Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Wed, 30 Nov 2022 19:09:21 +0100 Subject: [PATCH 01/39] wip --- Directory.Build.props | 3 + eng/pipelines/common/platform-matrix.yml | 21 + .../common/templates/wasi-build-only.yml | 49 ++ .../common/templates/wasm-library-tests.yml | 15 - eng/pipelines/runtime-linker-tests.yml | 24 + eng/pipelines/runtime.yml | 8 + eng/targetingpacks.targets | 2 +- eng/testing/wasi-provisioning.targets | 3 + eng/versioning.targets | 6 + .../System.Console/src/System.Console.csproj | 36 +- .../src/System/ConsolePal.Unix.cs | 91 ++- .../System.Console/src/System/IO/KeyParser.cs | 4 +- .../src/System/IO/StdInReader.cs | 20 + .../src/CompatibilitySuppressions.xml | 6 + .../src/System.IO.Compression.csproj | 4 +- .../src/System.Net.Http.csproj | 7 +- .../src/CompatibilitySuppressions.xml | 12 + .../src/System.Net.Primitives.csproj | 6 +- .../System.Private.CoreLib.Shared.projitems | 20 +- .../src/System/AppContext.AnyOS.cs | 2 +- .../System/Diagnostics/Tracing/EventSource.cs | 4 +- .../src/System/IO/FileStatus.Unix.cs | 8 +- .../src/System/Reflection/Assembly.cs | 4 +- .../RuntimeInformation.Browser.cs | 6 + .../Threading/EventWaitHandle.Windows.cs | 2 +- .../src/System/Threading/Mutex.Windows.cs | 4 +- .../src/System/Threading/Overlapped.cs | 2 +- .../src/System/Threading/Semaphore.Windows.cs | 2 +- .../src/System/Threading/Thread.cs | 2 +- .../src/System/Threading/Thread.Mono.cs | 10 +- src/mono/sample/wasi/CommonAssemblyInfo.cs | 4 + src/mono/sample/wasi/Directory.Build.props | 37 ++ src/mono/sample/wasi/Directory.Build.targets | 72 ++ src/mono/sample/wasi/console/Program.cs | 16 + .../wasi/console/Wasi.Console.Sample.csproj | 12 + src/mono/wasi/.gitignore | 2 + src/mono/wasi/Makefile | 51 -- src/mono/wasi/Makefile.variable | 16 - src/mono/wasi/README.md | 52 +- src/mono/wasi/build/WasiApp.InTree.props | 2 + src/mono/wasi/build/WasiApp.InTree.targets | 2 + src/mono/wasi/include/netdb.h | 1 + .../driver.h | 1 - src/mono/wasi/mono-include/pinvoke.h | 52 ++ .../wasi/{include => mono-include}/pthread.h | 0 .../wasi/{include => mono-include}/setjmp.h | 0 src/mono/wasi/mono-include/wasm-config.h.in | 15 + src/mono/wasi/provision.ps1 | 14 + src/mono/wasi/runtime/CMakeLists.txt | 39 ++ .../{mono-wasi-driver => runtime}/driver.c | 619 ++++++++---------- src/mono/wasi/runtime/pinvoke.c | 64 ++ .../{mono-wasi-driver => runtime}/stubs.c | 0 .../synthetic-pthread.c | 0 src/mono/wasi/sample/.gitignore | 1 - src/mono/wasi/sample/Directory.Build.props | 8 - src/mono/wasi/sample/SampleMakefile.variable | 20 - src/mono/wasi/sample/console/Makefile | 28 - .../sample/console/WasiConsoleApp/Program.cs | 16 - .../WasiConsoleApp/WasiConsoleApp.csproj | 10 - src/mono/wasi/sample/console/main.c | 21 - src/mono/wasi/wasi-sdk-version.txt | 1 + src/mono/wasi/wasmtime-version.txt | 1 + src/native/libs/System.Native/pal_console.c | 32 + .../libs/System.Native/pal_dynamicload.c | 24 + .../System.Native/pal_interfaceaddresses.c | 9 + src/native/libs/System.Native/pal_io.c | 87 ++- .../libs/System.Native/pal_maphardwaretype.c | 4 + src/native/libs/System.Native/pal_mount.c | 32 +- .../libs/System.Native/pal_networkchange.c | 2 + .../libs/System.Native/pal_networking.c | 257 +++++++- .../System.Native/pal_networkstatistics.c | 2 + src/native/libs/System.Native/pal_process.c | 56 +- src/native/libs/System.Native/pal_signal.c | 48 +- src/native/libs/System.Native/pal_threading.c | 27 + src/native/libs/System.Native/pal_time.c | 5 + src/native/libs/System.Native/pal_uid.c | 46 +- 76 files changed, 1524 insertions(+), 667 deletions(-) create mode 100644 eng/pipelines/common/templates/wasi-build-only.yml create mode 100644 eng/testing/wasi-provisioning.targets create mode 100644 src/mono/sample/wasi/CommonAssemblyInfo.cs create mode 100644 src/mono/sample/wasi/Directory.Build.props create mode 100644 src/mono/sample/wasi/Directory.Build.targets create mode 100644 src/mono/sample/wasi/console/Program.cs create mode 100644 src/mono/sample/wasi/console/Wasi.Console.Sample.csproj create mode 100644 src/mono/wasi/.gitignore delete mode 100644 src/mono/wasi/Makefile delete mode 100644 src/mono/wasi/Makefile.variable create mode 100644 src/mono/wasi/build/WasiApp.InTree.props create mode 100644 src/mono/wasi/build/WasiApp.InTree.targets create mode 100644 src/mono/wasi/include/netdb.h rename src/mono/wasi/{mono-wasi-driver => mono-include}/driver.h (95%) create mode 100644 src/mono/wasi/mono-include/pinvoke.h rename src/mono/wasi/{include => mono-include}/pthread.h (100%) rename src/mono/wasi/{include => mono-include}/setjmp.h (100%) create mode 100644 src/mono/wasi/mono-include/wasm-config.h.in create mode 100644 src/mono/wasi/provision.ps1 create mode 100644 src/mono/wasi/runtime/CMakeLists.txt rename src/mono/wasi/{mono-wasi-driver => runtime}/driver.c (50%) create mode 100644 src/mono/wasi/runtime/pinvoke.c rename src/mono/wasi/{mono-wasi-driver => runtime}/stubs.c (100%) rename src/mono/wasi/{mono-wasi-driver => runtime}/synthetic-pthread.c (100%) delete mode 100644 src/mono/wasi/sample/.gitignore delete mode 100644 src/mono/wasi/sample/Directory.Build.props delete mode 100644 src/mono/wasi/sample/SampleMakefile.variable delete mode 100644 src/mono/wasi/sample/console/Makefile delete mode 100644 src/mono/wasi/sample/console/WasiConsoleApp/Program.cs delete mode 100644 src/mono/wasi/sample/console/WasiConsoleApp/WasiConsoleApp.csproj delete mode 100644 src/mono/wasi/sample/console/main.c create mode 100644 src/mono/wasi/wasi-sdk-version.txt create mode 100644 src/mono/wasi/wasmtime-version.txt diff --git a/Directory.Build.props b/Directory.Build.props index 3b052e4db1be79..ff902e73dcd261 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -36,6 +36,7 @@ s390x ppc64le wasm + wasm x64 x64 $(TargetArchitecture) @@ -118,6 +119,8 @@ $([MSBuild]::NormalizePath('$(TestExclusionListTasksDir)', 'TestExclusionListTasks.dll')) $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'coreclr', '$(TargetOS).$(TargetArchitecture).$(Configuration)')) $(CoreCLRToolPath) + + $([MSBuild]::NormalizeDirectory($(ArtifactsBinDir), 'wasmtime')) diff --git a/eng/pipelines/common/platform-matrix.yml b/eng/pipelines/common/platform-matrix.yml index bafab38c125d62..5bd0c98d18c35f 100644 --- a/eng/pipelines/common/platform-matrix.yml +++ b/eng/pipelines/common/platform-matrix.yml @@ -374,6 +374,27 @@ jobs: crossBuild: true ${{ insert }}: ${{ parameters.jobParameters }} +# WASI WebAssembly + +- ${{ if containsValue(parameters.platforms, 'wasi_wasm') }}: + - template: xplat-setup.yml + parameters: + jobTemplate: ${{ parameters.jobTemplate }} + helixQueuesTemplate: ${{ parameters.helixQueuesTemplate }} + variables: ${{ parameters.variables }} + osGroup: wasi + archType: wasm + targetRid: wasi-wasm + platform: wasi_wasm + shouldContinueOnError: ${{ parameters.shouldContinueOnError }} + container: Browser_wasm + jobParameters: + hostedOs: Linux + runtimeFlavor: ${{ parameters.runtimeFlavor }} + stagedBuild: ${{ parameters.stagedBuild }} + buildConfig: ${{ parameters.buildConfig }} + ${{ insert }}: ${{ parameters.jobParameters }} + # Browser WebAssembly - ${{ if containsValue(parameters.platforms, 'Browser_wasm') }}: diff --git a/eng/pipelines/common/templates/wasi-build-only.yml b/eng/pipelines/common/templates/wasi-build-only.yml new file mode 100644 index 00000000000000..e161b02b1270c3 --- /dev/null +++ b/eng/pipelines/common/templates/wasi-build-only.yml @@ -0,0 +1,49 @@ +parameters: + alwaysRun: false + extraBuildArgs: '' + isExtraPlatformsBuild: false + nameSuffix: '' + platforms: [] + +jobs: + +# +# Build for WASI/wasm and test it +# +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml + buildConfig: Release + runtimeFlavor: mono + platforms: ${{ parameters.platforms }} + variables: + # map dependencies variables to local variables + - name: alwaysRunVar + value: ${{ parameters.alwaysRun }} + - name: shouldRunOnDefaultPipelines + value: $[ + or( + eq(variables['wasmDarcDependenciesChanged'], true), + eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), + and( + eq(dependencies.evaluate_paths.outputs['SetPathVars_wasm.containsChange'], true), + eq(dependencies.evaluate_paths.outputs['SetPathVars_non_runtimetests.containsChange'], true)), + eq(dependencies.evaluate_paths.outputs['SetPathVars_wasm_libraries.containsChange'], true), + eq(dependencies.evaluate_paths.outputs['SetPathVars_mono_excluding_wasm.containsChange'], true)) + ] + jobParameters: + isExtraPlatforms: ${{ parameters.isExtraPlatformsBuild }} + testGroup: innerloop + nameSuffix: ${{ parameters.nameSuffix }}_BuildOnly + buildArgs: -s mono+libs+host -c $(_BuildConfig) /p:ArchiveTests=true ${{ parameters.extraBuildArgs }} + timeoutInMinutes: 240 + # if !alwaysRun, then: + # if this is runtime-wasm (isWasmOnlyBuild): + # - then run only if it would not have run on default pipelines (based + # on path changes) + # - else run based on path changes + condition: >- + or( + eq(variables['alwaysRunVar'], true), + eq(variables['isDefaultPipeline'], variables['shouldRunOnDefaultPipelines'])) diff --git a/eng/pipelines/common/templates/wasm-library-tests.yml b/eng/pipelines/common/templates/wasm-library-tests.yml index caf4a09b31eb19..a05ca0bf166813 100644 --- a/eng/pipelines/common/templates/wasm-library-tests.yml +++ b/eng/pipelines/common/templates/wasm-library-tests.yml @@ -70,18 +70,3 @@ jobs: or( eq(variables['alwaysRunVar'], true), eq(variables['isDefaultPipeline'], variables['shouldRunOnDefaultPipelines'])) - # extra steps, run tests - extraStepsTemplate: /eng/pipelines/common/templates/additional-steps-then-helix.yml - extraStepsParameters: - additionalSteps: - - ${{ if eq(parameters.buildAndRunWasi, true) }}: - - script: >- - make -C src/mono/wasi provision-deps all && - make -C src/mono/wasi/sample/console run - name: build_wasi - displayName: Build WASI, and run a sample - - creator: dotnet-bot - testRunNamePrefixSuffix: Mono_$(_BuildConfig) - extraHelixArguments: /p:BrowserHost=$(_hostedOs) $(_wasmRunSmokeTestsOnlyArg) ${{ parameters.extraHelixArgs }} - scenarios: ${{ parameters.scenarios }} diff --git a/eng/pipelines/runtime-linker-tests.yml b/eng/pipelines/runtime-linker-tests.yml index 4a75a0be9f90b2..bfe756fb690a7b 100644 --- a/eng/pipelines/runtime-linker-tests.yml +++ b/eng/pipelines/runtime-linker-tests.yml @@ -127,3 +127,27 @@ extends: extraStepsTemplate: /eng/pipelines/libraries/execute-trimming-tests-steps.yml extraStepsParameters: extraTestArgs: '/p:WasmBuildNative=false' + + # + # Build Release config vertical for WASI-wasm + # + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + buildConfig: release + platforms: + - wasi_wasm + jobParameters: + testGroup: innerloop + timeoutInMinutes: 120 + nameSuffix: Runtime_Release + buildArgs: -s mono+libs -c $(_BuildConfig) -p:WasmBuildNative=false + condition: + or( + eq(variables['isRollingBuild'], true), + eq(dependencies.evaluate_paths.outputs['SetPathVars_wasm_libraries.containsChange'], true), + eq(dependencies.evaluate_paths.outputs['SetPathVars_wasm.containsChange'], true), + eq(dependencies.evaluate_paths.outputs['DarcDependenciesChanged.Microsoft_NET_ILLink_Tasks'], true)) + extraStepsTemplate: /eng/pipelines/libraries/execute-trimming-tests-steps.yml + extraStepsParameters: + extraTestArgs: '/p:WasmBuildNative=false' diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index cc877ba25fa46f..8e244f6f52051c 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -456,6 +456,14 @@ extends: extraBuildArgs: /p:WasmEnablePerfTracing=true alwaysRun: ${{ variables.isRollingBuild }} + # BUILD ONLY - WASI/Wasm + - template: /eng/pipelines/common/templates/wasi-build-only.yml + parameters: + platforms: + - wasi_wasm + extraBuildArgs: /p:WasmEnableThreads=true + alwaysRun: ${{ variables.isRollingBuild }} + # # iOS/tvOS devices - Full AOT + AggressiveTrimming to reduce size # Build the whole product using Mono and run libraries tests diff --git a/eng/targetingpacks.targets b/eng/targetingpacks.targets index 744a0cd20b469a..e7386ccb5e8d40 100644 --- a/eng/targetingpacks.targets +++ b/eng/targetingpacks.targets @@ -41,7 +41,7 @@ RuntimeFrameworkName="$(LocalFrameworkOverrideName)" LatestRuntimeFrameworkVersion="$(ProductVersion)" RuntimePackNamePatterns="$(LocalFrameworkOverrideName).Runtime.Mono.**RID**" - RuntimePackRuntimeIdentifiers="linux-arm;linux-armv6;linux-arm64;linux-musl-arm64;linux-bionic-arm64;linux-loongarch64;linux-musl-x64;linux-bionic-x64;linux-x64;osx-x64;rhel.6-x64;win-arm;win-arm64;win-x64;win-x86;linux-musl-arm;osx-arm64;maccatalyst-x64;maccatalyst-arm64;browser-wasm;ios-arm64;ios-arm;iossimulator-arm64;iossimulator-x64;iossimulator-x86;tvos-arm64;tvossimulator-arm64;tvossimulator-x64;android-arm64;android-arm;android-x64;android-x86" + RuntimePackRuntimeIdentifiers="linux-arm;linux-armv6;linux-arm64;linux-musl-arm64;linux-bionic-arm64;linux-loongarch64;linux-musl-x64;linux-bionic-x64;linux-x64;osx-x64;rhel.6-x64;win-arm;win-arm64;win-x64;win-x86;linux-musl-arm;osx-arm64;maccatalyst-x64;maccatalyst-arm64;browser-wasm;wasi-wasm;ios-arm64;ios-arm;iossimulator-arm64;iossimulator-x64;iossimulator-x86;tvos-arm64;tvossimulator-arm64;tvossimulator-x64;android-arm64;android-arm;android-x64;android-x86" RuntimePackLabels="Mono" Condition="'@(KnownRuntimePack)' == '' or !@(KnownRuntimePack->AnyHaveMetadataValue('TargetFramework', '$(NetCoreAppCurrent)'))"/> + + diff --git a/eng/versioning.targets b/eng/versioning.targets index d5191990135999..b4f6471c93f95d 100644 --- a/eng/versioning.targets +++ b/eng/versioning.targets @@ -65,6 +65,9 @@ true + + true + @@ -78,6 +81,9 @@ + + + diff --git a/src/libraries/System.Console/src/System.Console.csproj b/src/libraries/System.Console/src/System.Console.csproj index 2097f08efe7162..5d26b793996077 100644 --- a/src/libraries/System.Console/src/System.Console.csproj +++ b/src/libraries/System.Console/src/System.Console.csproj @@ -1,12 +1,14 @@ true - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Android;$(NetCoreAppCurrent)-iOS;$(NetCoreAppCurrent)-tvOS;$(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent) + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Android;$(NetCoreAppCurrent)-iOS;$(NetCoreAppCurrent)-tvOS;$(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent)-wasi;$(NetCoreAppCurrent) $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) SR.PlatformNotSupported_SystemConsole + $(DefineConstants);TARGET_BROWSER + $(DefineConstants);TARGET_WASI @@ -47,7 +49,7 @@ Common\Interop\Android\Interop.Libraries.cs - + + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Console/src/System/ConsolePal.Unix.cs b/src/libraries/System.Console/src/System/ConsolePal.Unix.cs index 5d22a24ae678ed..d22e7936c6428c 100644 --- a/src/libraries/System.Console/src/System/ConsolePal.Unix.cs +++ b/src/libraries/System.Console/src/System/ConsolePal.Unix.cs @@ -25,6 +25,7 @@ internal static partial class ConsolePal // and we can use a smaller buffer to minimize working set. private const int InteractiveBufferSize = 255; +#if !TARGET_WASI // For performance we cache Cursor{Left,Top} and Window{Width,Height}. // These values must be read/written under lock (Console.Out). // We also need to invalidate these values when certain signals occur. @@ -38,7 +39,6 @@ internal static partial class ConsolePal private static int s_windowWidth; // Cached WindowWidth, -1 when invalid. private static int s_windowHeight; // Cached WindowHeight, invalid when s_windowWidth == -1. private static int s_invalidateCachedSettings = 1; // Tracks whether we should invalidate the cached settings. - /// Gets the lazily-initialized terminal information for the terminal. public static TerminalFormatStrings TerminalFormatStringsInstance { get { return s_terminalFormatStringsInstance.Value; } } private static readonly Lazy s_terminalFormatStringsInstance = new(() => new TerminalFormatStrings(TermInfo.DatabaseFactory.ReadActiveDatabase())); @@ -59,6 +59,25 @@ public static Stream OpenStandardError() return new UnixConsoleStream(Interop.CheckIo(Interop.Sys.Dup(Interop.Sys.FileDescriptors.STDERR_FILENO)), FileAccess.Write); } +#else + // there is no dup on WASI + public static Stream OpenStandardInput() + { + return new UnixConsoleStream(Interop.CheckIo(Interop.Sys.FileDescriptors.STDIN_FILENO), FileAccess.Read, + useReadLine: !Console.IsInputRedirected); + } + + public static Stream OpenStandardOutput() + { + return new UnixConsoleStream(Interop.CheckIo(Interop.Sys.FileDescriptors.STDOUT_FILENO), FileAccess.Write); + } + + public static Stream OpenStandardError() + { + return new UnixConsoleStream(Interop.CheckIo(Interop.Sys.FileDescriptors.STDERR_FILENO), FileAccess.Write); + } + +#endif public static Encoding InputEncoding { get { return GetConsoleEncoding(); } @@ -138,6 +157,26 @@ public static ConsoleKeyInfo ReadKey(bool intercept) return keyInfo; } +#if TARGET_WASI + public static bool TreatControlCAsInput + { + get => throw new PlatformNotSupportedException(); + set => throw new PlatformNotSupportedException(); + } + + public static ConsoleColor ForegroundColor + { + get => throw new PlatformNotSupportedException(); + set => throw new PlatformNotSupportedException(); + } + public static ConsoleColor BackgroundColor + { + get => throw new PlatformNotSupportedException(); + set => throw new PlatformNotSupportedException(); + } + public static void ResetColor() => throw new PlatformNotSupportedException(); + +#else public static bool TreatControlCAsInput { get @@ -183,6 +222,7 @@ public static void ResetColor() WriteResetColorString(); } } +#endif public static bool NumberLock { get { throw new PlatformNotSupportedException(); } } @@ -194,9 +234,13 @@ public static int CursorSize set { throw new PlatformNotSupportedException(); } } + public static string Title { get { throw new PlatformNotSupportedException(); } +#if TARGET_WASI + set => throw new PlatformNotSupportedException(); +#else set { if (Console.IsOutputRedirected) @@ -209,8 +253,12 @@ public static string Title WriteStdoutAnsiString(ansiStr, mayChangeCursorPosition: false); } } +#endif } +#if TARGET_WASI + public static void Beep() => throw new PlatformNotSupportedException(); +#else public static void Beep() { if (!Console.IsOutputRedirected) @@ -218,7 +266,15 @@ public static void Beep() WriteStdoutAnsiString(TerminalFormatStringsInstance.Bell, mayChangeCursorPosition: false); } } - +#endif + +#if TARGET_WASI + public static void Clear() => throw new PlatformNotSupportedException(); + public static void SetCursorPosition(int left, int top) => throw new PlatformNotSupportedException(); + public static bool IsInputRedirectedCore() => throw new PlatformNotSupportedException(); + public static bool IsOutputRedirectedCore() => throw new PlatformNotSupportedException(); + public static bool IsErrorRedirectedCore() => throw new PlatformNotSupportedException(); +#else public static void Clear() { if (!Console.IsOutputRedirected) @@ -295,6 +351,7 @@ private static bool TryGetCachedCursorPosition(out int left, out int top) return hasCachedCursorPosition; } +#endif public static int BufferWidth { get { return WindowWidth; } @@ -351,6 +408,9 @@ public static int WindowHeight private static void GetWindowSize(out int width, out int height) { +#if TARGET_WASI + throw new PlatformNotSupportedException(); +#else lock (Console.Out) { // Invalidate before reading cached values. @@ -373,10 +433,14 @@ private static void GetWindowSize(out int width, out int height) width = s_windowWidth; height = s_windowHeight; } +#endif } public static void SetWindowSize(int width, int height) { +#if TARGET_WASI + throw new PlatformNotSupportedException(); +#else lock (Console.Out) { Interop.Sys.WinSize winsize = default; @@ -395,6 +459,7 @@ public static void SetWindowSize(int width, int height) Interop.GetIOException(errorInfo); } } +#endif } public static bool CursorVisible @@ -402,16 +467,25 @@ public static bool CursorVisible get { throw new PlatformNotSupportedException(); } set { +#if TARGET_WASI + throw new PlatformNotSupportedException(); +#else if (!Console.IsOutputRedirected) { WriteStdoutAnsiString(value ? TerminalFormatStringsInstance.CursorVisible : TerminalFormatStringsInstance.CursorInvisible); } +#endif } } public static (int Left, int Top) GetCursorPosition() +#if TARGET_WASI + { + throw new PlatformNotSupportedException(); + } +#else { TryGetCursorPosition(out int left, out int top); return (left, top); @@ -702,6 +776,7 @@ public static bool IsErrorRedirectedCore() return IsHandleRedirected(Interop.Sys.FileDescriptors.STDERR_FILENO); } +#endif /// Creates an encoding from the current environment. /// The encoding. private static Encoding GetConsoleEncoding() @@ -752,6 +827,11 @@ public static void SetWindowPosition(int left, int top) #pragma warning restore IDE0060 +#if TARGET_WASI + internal static void EnsureConsoleInitialized() + { + } +#else /// /// Refreshes the foreground and background colors in use by the terminal by resetting /// the colors and then reissuing commands for both foreground and background, if necessary. @@ -937,6 +1017,7 @@ private static unsafe void EnsureInitializedCore() } } } +#endif /// Reads data from the file descriptor into the buffer. /// The file descriptor. @@ -969,7 +1050,9 @@ internal static unsafe void Write(SafeFileHandle fd, ReadOnlySpan buffer, int count = buffer.Length; while (count > 0) { +#if !TARGET_WASI int cursorVersion = mayChangeCursorPosition ? Volatile.Read(ref s_cursorVersion) : -1; +#endif int bytesWritten = Interop.Sys.Write(fd, bufPtr, count); if (bytesWritten < 0) @@ -998,6 +1081,7 @@ internal static unsafe void Write(SafeFileHandle fd, ReadOnlySpan buffer, throw Interop.GetExceptionForIoErrno(errorInfo); } } +#if !TARGET_WASI else { if (mayChangeCursorPosition) @@ -1005,6 +1089,7 @@ internal static unsafe void Write(SafeFileHandle fd, ReadOnlySpan buffer, UpdatedCachedCursorPosition(bufPtr, bytesWritten, cursorVersion); } } +#endif count -= bytesWritten; bufPtr += bytesWritten; @@ -1012,6 +1097,7 @@ internal static unsafe void Write(SafeFileHandle fd, ReadOnlySpan buffer, } } +#if !TARGET_WASI private static unsafe void UpdatedCachedCursorPosition(byte* bufPtr, int count, int cursorVersion) { lock (Console.Out) @@ -1099,6 +1185,7 @@ private static void InvalidateTerminalSettings() { Volatile.Write(ref s_invalidateCachedSettings, 1); } +#endif /// Writes a terminfo-based ANSI escape string to stdout. /// The string to write. diff --git a/src/libraries/System.Console/src/System/IO/KeyParser.cs b/src/libraries/System.Console/src/System/IO/KeyParser.cs index 1167d00ec81c76..0b048f030fba78 100644 --- a/src/libraries/System.Console/src/System/IO/KeyParser.cs +++ b/src/libraries/System.Console/src/System/IO/KeyParser.cs @@ -15,6 +15,7 @@ internal static class KeyParser private const int MinimalSequenceLength = 3; private const int SequencePrefixLength = 2; // ^[[ ("^[" stands for Escape) +#if !TARGET_WASI internal static ConsoleKeyInfo Parse(char[] buffer, TerminalFormatStrings terminalFormatStrings, byte posixDisableValue, byte veraseCharacter, ref int startIndex, int endIndex) { int length = endIndex - startIndex; @@ -308,8 +309,9 @@ static ConsoleModifiers MapRxvtModifiers(char modifier) static ConsoleKeyInfo Create(char keyChar, ConsoleKey key, ConsoleModifiers modifiers) => new(keyChar, key, (modifiers & ConsoleModifiers.Shift) != 0, (modifiers & ConsoleModifiers.Alt) != 0, (modifiers & ConsoleModifiers.Control) != 0); } +#endif - private static ConsoleKeyInfo ParseFromSingleChar(char single, bool isAlt) + internal static ConsoleKeyInfo ParseFromSingleChar(char single, bool isAlt) { bool isShift = false, isCtrl = false; char keyChar = single; diff --git a/src/libraries/System.Console/src/System/IO/StdInReader.cs b/src/libraries/System.Console/src/System/IO/StdInReader.cs index 801c0c78e53dda..56c2977245161d 100644 --- a/src/libraries/System.Console/src/System/IO/StdInReader.cs +++ b/src/libraries/System.Console/src/System/IO/StdInReader.cs @@ -15,8 +15,10 @@ namespace System.IO */ internal sealed class StdInReader : TextReader { +#if !TARGET_WASI private static string? s_moveLeftString; // string written to move the cursor to the left private static string? s_clearToEol; // string written to clear from cursor to end of line +#endif private readonly StringBuilder _readLineSB; // SB that holds readLine output. This is a field simply to enable reuse; it's only used in ReadLine. private readonly Stack _tmpKeys = new Stack(); // temporary working stack; should be empty outside of ReadLine @@ -198,6 +200,7 @@ private bool ReadLineCore(bool consumeKeys) removed = _tmpKeys.TryPop(out _); } +#if !TARGET_WASI if (removed && freshKeys) { // The ReadLine input may wrap across terminal rows and we need to handle that. @@ -223,6 +226,7 @@ private bool ReadLineCore(bool consumeKeys) Console.Write(s_moveLeftString); } } +#endif } else if (keyInfo.Key == ConsoleKey.Tab) { @@ -294,12 +298,19 @@ private int ReadOrPeek(bool peek) return -1; } +#if TARGET_WASI + private static bool IsEol(char c) + { + return false; // TODOWASI + } +#else private static bool IsEol(char c) { return c != ConsolePal.s_posixDisableValue && (c == ConsolePal.s_veolCharacter || c == ConsolePal.s_veol2Character || c == ConsolePal.s_veofCharacter); } +#endif /// /// Try to intercept the key pressed. @@ -345,15 +356,24 @@ private unsafe ConsoleKeyInfo ReadKey() // Could be empty if EOL entered on its own. Pick one of the EOL characters we have, // or just use 0 if none are available. return new ConsoleKeyInfo((char) +#if TARGET_WASI + 0,// TODOWASI +#else (ConsolePal.s_veolCharacter != ConsolePal.s_posixDisableValue ? ConsolePal.s_veolCharacter : ConsolePal.s_veol2Character != ConsolePal.s_posixDisableValue ? ConsolePal.s_veol2Character : ConsolePal.s_veofCharacter != ConsolePal.s_posixDisableValue ? ConsolePal.s_veofCharacter : 0), +#endif default(ConsoleKey), false, false, false); } } +#if TARGET_WASI + // TODOWASI + return KeyParser.ParseFromSingleChar(_unprocessedBufferToBeRead[_startIndex++], false); +#else return KeyParser.Parse(_unprocessedBufferToBeRead, ConsolePal.TerminalFormatStringsInstance, ConsolePal.s_posixDisableValue, ConsolePal.s_veraseCharacter, ref _startIndex, _endIndex); +#endif } finally { diff --git a/src/libraries/System.IO.Compression/src/CompatibilitySuppressions.xml b/src/libraries/System.IO.Compression/src/CompatibilitySuppressions.xml index 5914451471cbb7..8d4094d4b8c18f 100644 --- a/src/libraries/System.IO.Compression/src/CompatibilitySuppressions.xml +++ b/src/libraries/System.IO.Compression/src/CompatibilitySuppressions.xml @@ -7,6 +7,12 @@ ref/net7.0/System.IO.Compression.dll runtimes/browser/lib/net7.0/System.IO.Compression.dll + + CP0001 + T:System.IO.Compression.ZLibException + ref/net7.0/System.IO.Compression.dll + runtimes/wasi/lib/net7.0/System.IO.Compression.dll + CP0001 T:System.IO.Compression.ZLibException diff --git a/src/libraries/System.IO.Compression/src/System.IO.Compression.csproj b/src/libraries/System.IO.Compression/src/System.IO.Compression.csproj index 150b3efdb70eae..5179e9a2370ed1 100644 --- a/src/libraries/System.IO.Compression/src/System.IO.Compression.csproj +++ b/src/libraries/System.IO.Compression/src/System.IO.Compression.csproj @@ -1,7 +1,7 @@ true - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent) + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent)-wasi;$(NetCoreAppCurrent) @@ -50,7 +50,7 @@ Link="Common\Interop\Windows\Interop.Libraries.cs" /> - + win true $(DefineConstants);HTTP_DLL - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Linux;$(NetCoreAppCurrent)-OSX;$(NetCoreAppCurrent)-FreeBSD;$(NetCoreAppCurrent)-MacCatalyst;$(NetCoreAppCurrent)-iOS;$(NetCoreAppCurrent)-tvOS;$(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent)-illumos;$(NetCoreAppCurrent)-Solaris;$(NetCoreAppCurrent)-Android;$(NetCoreAppCurrent) + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Linux;$(NetCoreAppCurrent)-OSX;$(NetCoreAppCurrent)-FreeBSD;$(NetCoreAppCurrent)-MacCatalyst;$(NetCoreAppCurrent)-iOS;$(NetCoreAppCurrent)-tvOS;$(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent)-wasi;$(NetCoreAppCurrent)-illumos;$(NetCoreAppCurrent)-Solaris;$(NetCoreAppCurrent)-Android;$(NetCoreAppCurrent) true @@ -17,14 +17,15 @@ $(DefineConstants);TARGET_MACCATALYST $(DefineConstants);TARGET_TVOS $(DefineConstants);TARGET_BROWSER + $(DefineConstants);TARGET_WASI $(MSBuildThisFileDirectory)ILLink\ - - + + diff --git a/src/libraries/System.Net.Primitives/src/CompatibilitySuppressions.xml b/src/libraries/System.Net.Primitives/src/CompatibilitySuppressions.xml index b359c8b66a64f8..04c65897d928ec 100644 --- a/src/libraries/System.Net.Primitives/src/CompatibilitySuppressions.xml +++ b/src/libraries/System.Net.Primitives/src/CompatibilitySuppressions.xml @@ -7,12 +7,24 @@ ref/net7.0/System.Net.Primitives.dll runtimes/browser/lib/net7.0/System.Net.Primitives.dll + + CP0001 + T:System.Net.CookieVariant + ref/net7.0/System.Net.Primitives.dll + runtimes/wasi/lib/net7.0/System.Net.Primitives.dll + CP0001 T:System.Net.PathList ref/net7.0/System.Net.Primitives.dll runtimes/browser/lib/net7.0/System.Net.Primitives.dll + + CP0001 + T:System.Net.PathList + ref/net7.0/System.Net.Primitives.dll + runtimes/wasi/lib/net7.0/System.Net.Primitives.dll + CP0001 T:System.Net.CookieVariant diff --git a/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj b/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj index b77d6366c7a966..c62b006b2eabbd 100644 --- a/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj +++ b/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj @@ -2,7 +2,7 @@ true false - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent) + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent)-wasi;$(NetCoreAppCurrent) $(DefineConstants);SYSTEM_NET_PRIMITIVES_DLL @@ -113,7 +113,7 @@ - + @@ -144,7 +144,7 @@ - + enable true true - true + true true true true @@ -20,7 +20,7 @@ $(MSBuildThisFileDirectory)ILLink\ true true - true + true $(DefineConstants);BIGENDIAN @@ -2039,7 +2039,7 @@ - + Common\Interop\Unix\Interop.Errors.cs @@ -2289,7 +2289,7 @@ - + @@ -2298,7 +2298,7 @@ - + @@ -2332,7 +2332,7 @@ - + @@ -2436,7 +2436,7 @@ - + @@ -2449,11 +2449,11 @@ - + - + @@ -2471,7 +2471,7 @@ - + diff --git a/src/libraries/System.Private.CoreLib/src/System/AppContext.AnyOS.cs b/src/libraries/System.Private.CoreLib/src/System/AppContext.AnyOS.cs index 2dc7015dda0a3f..b2c83e67dd4538 100644 --- a/src/libraries/System.Private.CoreLib/src/System/AppContext.AnyOS.cs +++ b/src/libraries/System.Private.CoreLib/src/System/AppContext.AnyOS.cs @@ -12,7 +12,7 @@ namespace System { public static partial class AppContext { -#if !TARGET_BROWSER +#if !TARGET_BROWSER && !TARGET_WASI [UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file", Justification = "Single File apps should always set APP_CONTEXT_BASE_DIRECTORY therefore code handles Assembly.Location equals null")] private static string GetBaseDirectoryCore() diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs index 14186011ecef7a..c8fcd9e9b3079f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs @@ -1327,12 +1327,12 @@ protected unsafe void WriteEventWithRelatedActivityIdCore(int eventId, Guid* rel if (m_Dispatchers != null && metadata.EnabledForAnyListener) { -#if MONO && !TARGET_BROWSER +#if MONO && !TARGET_BROWSER && !TARGET_WASI // On Mono, managed events from NativeRuntimeEventSource are written using WriteEventCore which can be // written doubly because EventPipe tries to pump it back up to EventListener via NativeRuntimeEventSource.ProcessEvents. // So we need to prevent this from getting written directly to the Listeners. if (this.GetType() != typeof(NativeRuntimeEventSource)) -#endif // MONO && !TARGET_BROWSER +#endif // MONO && !TARGET_BROWSER && !TARGET_WASI { var eventCallbackArgs = new EventWrittenEventArgs(this, eventId, pActivityId, relatedActivityId); WriteToAllListeners(eventCallbackArgs, eventDataCount, data); diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/FileStatus.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/IO/FileStatus.Unix.cs index fe14a0aa99a19f..283404991036ab 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/FileStatus.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/FileStatus.Unix.cs @@ -57,7 +57,7 @@ private bool HasReadOnlyFlag return false; } -#if TARGET_BROWSER +#if TARGET_BROWSER || TARGET_WASI var mode = ((UnixFileMode)_fileCache.Mode & FileSystem.ValidUnixFileModes); bool isUserReadOnly = (mode & UnixFileMode.UserRead) != 0 && // has read permission (mode & UnixFileMode.UserWrite) == 0; // but not write permission @@ -81,7 +81,7 @@ private bool HasReadOnlyFlag } } -#if !TARGET_BROWSER +#if !TARGET_BROWSER && !TARGET_WASI // HasReadOnlyFlag cache. // Must only be used after calling EnsureCachesInitialized. private int _isReadOnlyCache; @@ -394,7 +394,7 @@ private unsafe void SetAccessOrWriteTimeCore(SafeFileHandle? handle, string? pat long seconds = time.ToUnixTimeSeconds(); long nanoseconds = UnixTimeSecondsToNanoseconds(time, seconds); -#if TARGET_BROWSER +#if TARGET_BROWSER || TARGET_WASI buf[0].TvSec = seconds; buf[0].TvNsec = nanoseconds; buf[1].TvSec = seconds; @@ -499,7 +499,7 @@ internal void RefreshCaches(SafeFileHandle? handle, ReadOnlySpan path) { Debug.Assert(handle is not null || path.Length > 0); -#if !TARGET_BROWSER +#if !TARGET_BROWSER && !TARGET_WASI _isReadOnlyCache = -1; #endif int rv = handle is not null ? diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs index f6445df9671b8f..00095ffb7f48bd 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs @@ -265,10 +265,10 @@ public static Assembly LoadFile(string path) return result; // we cannot check for file presence on BROWSER. The files could be embedded and not physically present. -#if !TARGET_BROWSER +#if !TARGET_BROWSER && !TARGET_WASI if (!File.Exists(normalizedPath)) throw new FileNotFoundException(SR.Format(SR.FileNotFound_LoadFile, normalizedPath), normalizedPath); -#endif // !TARGET_BROWSER +#endif // !TARGET_BROWSER && !TARGET_WASI AssemblyLoadContext alc = new IndividualAssemblyLoadContext($"Assembly.LoadFile({normalizedPath})"); result = alc.LoadFromAssemblyPath(normalizedPath); diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/RuntimeInformation.Browser.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/RuntimeInformation.Browser.cs index 3fcfb1465a9dd3..7f9aff89b0aba8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/RuntimeInformation.Browser.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/RuntimeInformation.Browser.cs @@ -5,7 +5,13 @@ namespace System.Runtime.InteropServices { public static partial class RuntimeInformation { +#if TARGET_WASI public static string OSDescription => "Browser"; +#elif TARGET_BROWSER + public static string OSDescription => "WASI"; +#else + #error +#endif public static Architecture OSArchitecture => Architecture.Wasm; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/EventWaitHandle.Windows.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/EventWaitHandle.Windows.cs index 95750074698b0a..bc41f1bde322e5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/EventWaitHandle.Windows.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/EventWaitHandle.Windows.cs @@ -18,7 +18,7 @@ private EventWaitHandle(SafeWaitHandle handle) private void CreateEventCore(bool initialState, EventResetMode mode, string? name, out bool createdNew) { -#if TARGET_UNIX || TARGET_BROWSER +#if TARGET_UNIX || TARGET_BROWSER || TARGET_WASI if (name != null) throw new PlatformNotSupportedException(SR.PlatformNotSupported_NamedSynchronizationPrimitives); #endif diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Mutex.Windows.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Mutex.Windows.cs index ab5663297cdc52..10a91926c3e02b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Mutex.Windows.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Mutex.Windows.cs @@ -24,7 +24,7 @@ private void CreateMutexCore(bool initiallyOwned, string? name, out bool created if (mutexHandle.IsInvalid) { mutexHandle.SetHandleAsInvalid(); -#if TARGET_UNIX || TARGET_BROWSER +#if TARGET_UNIX || TARGET_BROWSER || TARGET_WASI if (errorCode == Interop.Errors.ERROR_FILENAME_EXCED_RANGE) // On Unix, length validation is done by CoreCLR's PAL after converting to utf-8 throw new ArgumentException(SR.Argument_WaitHandleNameTooLong, nameof(name)); @@ -56,7 +56,7 @@ private static OpenExistingResult OpenExistingWorker(string name, out Mutex? res myHandle.Dispose(); -#if TARGET_UNIX || TARGET_BROWSER +#if TARGET_UNIX || TARGET_BROWSER || TARGET_WASI if (errorCode == Interop.Errors.ERROR_FILENAME_EXCED_RANGE) { // On Unix, length validation is done by CoreCLR's PAL after converting to utf-8 diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Overlapped.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Overlapped.cs index 0f130cdc53aa82..f7f0cff5894cd6 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Overlapped.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Overlapped.cs @@ -184,7 +184,7 @@ public static void Free(NativeOverlapped* nativeOverlappedPtr) _pNativeOverlapped = pNativeOverlapped; #if FEATURE_PERFTRACING -#if !(TARGET_BROWSER && !FEATURE_WASM_THREADS) +#if !((TARGET_BROWSER || TARGET_WASI) && !FEATURE_WASM_THREADS) if (NativeRuntimeEventSource.Log.IsEnabled()) NativeRuntimeEventSource.Log.ThreadPoolIOPack(pNativeOverlapped); #endif diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Semaphore.Windows.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Semaphore.Windows.cs index a4cb8323ef5b21..027e9fe93f4683 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Semaphore.Windows.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Semaphore.Windows.cs @@ -23,7 +23,7 @@ private void CreateSemaphoreCore(int initialCount, int maximumCount, string? nam Debug.Assert(maximumCount >= 1); Debug.Assert(initialCount <= maximumCount); -#if TARGET_UNIX || TARGET_BROWSER +#if TARGET_UNIX || TARGET_BROWSER || TARGET_WASI if (name != null) throw new PlatformNotSupportedException(SR.PlatformNotSupported_NamedSynchronizationPrimitives); #endif diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs index a27ced32def893..4fb9e43e533477 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs @@ -153,7 +153,7 @@ public Thread(ParameterizedThreadStart start, int maxStackSize) Initialize(); } -#if !TARGET_BROWSER || FEATURE_WASM_THREADS +#if (!TARGET_BROWSER && !TARGET_WASI) || FEATURE_WASM_THREADS [UnsupportedOSPlatformGuard("browser")] internal static bool IsThreadStartSupported => true; internal static bool IsInternalThreadStartSupported => true; diff --git a/src/mono/System.Private.CoreLib/src/System/Threading/Thread.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Threading/Thread.Mono.cs index 13adc4d13f3414..e40507053c6817 100644 --- a/src/mono/System.Private.CoreLib/src/System/Threading/Thread.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Threading/Thread.Mono.cs @@ -65,7 +65,7 @@ public partial class Thread private StartHelper? _startHelper; internal ExecutionContext? _executionContext; internal SynchronizationContext? _synchronizationContext; -#if TARGET_UNIX || TARGET_BROWSER +#if TARGET_UNIX || TARGET_BROWSER || TARGET_WASI internal WaitSubsystem.ThreadWaitInfo? _waitInfo; #endif @@ -138,7 +138,7 @@ internal static int OptimalMaxSpinWaitsPerSpinIteration return 7; } } -#if TARGET_UNIX || TARGET_BROWSER +#if TARGET_UNIX || TARGET_BROWSER || TARGET_WASI internal WaitSubsystem.ThreadWaitInfo WaitInfo { get @@ -196,7 +196,7 @@ public static int GetCurrentProcessorId() public void Interrupt() { -#if TARGET_UNIX || TARGET_BROWSER // TODO: https://github.com/dotnet/runtime/issues/49521 +#if TARGET_UNIX || TARGET_BROWSER || TARGET_WASI // TODO: https://github.com/dotnet/runtime/issues/49521 WaitSubsystem.Interrupt(this); #endif InterruptInternal(this); @@ -209,7 +209,7 @@ public bool Join(int millisecondsTimeout) return JoinInternal(this, millisecondsTimeout); } -#if TARGET_UNIX || TARGET_BROWSER +#if TARGET_UNIX || TARGET_BROWSER || TARGET_WASI [DynamicDependency(nameof(OnThreadExiting))] #endif private void Initialize() @@ -301,7 +301,7 @@ internal void ClearWaitSleepJoinState() private static void OnThreadExiting(Thread thread) { -#if TARGET_UNIX || TARGET_BROWSER +#if TARGET_UNIX || TARGET_BROWSER || TARGET_WASI thread.WaitInfo.OnThreadExiting(); #endif } diff --git a/src/mono/sample/wasi/CommonAssemblyInfo.cs b/src/mono/sample/wasi/CommonAssemblyInfo.cs new file mode 100644 index 00000000000000..1e407edc804221 --- /dev/null +++ b/src/mono/sample/wasi/CommonAssemblyInfo.cs @@ -0,0 +1,4 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +[assembly:System.Runtime.Versioning.SupportedOSPlatform("wasi")] diff --git a/src/mono/sample/wasi/Directory.Build.props b/src/mono/sample/wasi/Directory.Build.props new file mode 100644 index 00000000000000..f2ecb0d30b5db4 --- /dev/null +++ b/src/mono/sample/wasi/Directory.Build.props @@ -0,0 +1,37 @@ + + + + Exe + wasi + + + + + + + bin + + + false + + + + + false + true + false + false + false + true + + + + + + + + + diff --git a/src/mono/sample/wasi/Directory.Build.targets b/src/mono/sample/wasi/Directory.Build.targets new file mode 100644 index 00000000000000..df21a15d0a5453 --- /dev/null +++ b/src/mono/sample/wasi/Directory.Build.targets @@ -0,0 +1,72 @@ + + + + + + true + + + + + + <_ScriptExt Condition="'$(OS)' == 'Windows_NT'">.cmd + <_ScriptExt Condition="'$(OS)' != 'Windows_NT'">.sh + <_Dotnet>$(RepoRoot)dotnet$(_ScriptExt) + <_AOTFlag Condition="'$(RunAOTCompilation)' != ''">/p:RunAOTCompilation=$(RunAOTCompilation) + <_WasmMainJSFileName>$([System.IO.Path]::GetFileName('$(WasmMainJSPath)')) + + + + + + + + + + + + + + + + + + %(_VersionLines.Identity) + https://github.com/bytecodealliance/wasmtime/releases/download/v$(WasmtimeVersion)/wasmtime-v$(WasmtimeVersion)-x86_64-linux.tar.xz + https://github.com/bytecodealliance/wasmtime/releases/download/v$(WasmtimeVersion)/wasmtime-v$(WasmtimeVersion)-x86_64-macos.tar.xz + https://github.com/bytecodealliance/wasmtime/releases/download/v$(WasmtimeVersion)/wasmtime-v$(WasmtimeVersion)-x86_64-windows.zip + + + + + + + + + + + + + + + + + + diff --git a/src/mono/sample/wasi/console/Program.cs b/src/mono/sample/wasi/console/Program.cs new file mode 100644 index 00000000000000..c65033a418ebb4 --- /dev/null +++ b/src/mono/sample/wasi/console/Program.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Threading.Tasks; + +public class Test +{ + public static int Main() + { + Console.WriteLine(""); + Console.WriteLine("Hello World!"); + Console.WriteLine(""); + return 0; + } +} diff --git a/src/mono/sample/wasi/console/Wasi.Console.Sample.csproj b/src/mono/sample/wasi/console/Wasi.Console.Sample.csproj new file mode 100644 index 00000000000000..2cbc92e85f134b --- /dev/null +++ b/src/mono/sample/wasi/console/Wasi.Console.Sample.csproj @@ -0,0 +1,12 @@ + + + $(NetCoreAppCurrent) + + + + <_SampleProject>Wasi.Console.Sample.csproj + <_SampleAssembly>Wasi.Console.Sample.dll + + + + diff --git a/src/mono/wasi/.gitignore b/src/mono/wasi/.gitignore new file mode 100644 index 00000000000000..c2313f66ee085a --- /dev/null +++ b/src/mono/wasi/.gitignore @@ -0,0 +1,2 @@ +wasi-sdk/** +wasmtime/** diff --git a/src/mono/wasi/Makefile b/src/mono/wasi/Makefile deleted file mode 100644 index 53ae87f4f76eaf..00000000000000 --- a/src/mono/wasi/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -include Makefile.variable - -all: build-all - -build-all: $(WASI_SDK_CLANG) - mkdir -p $(WASI_OBJ_DIR) - cd $(WASI_OBJ_DIR) && \ - PATH=$(NINJA_DIR):${PATH} cmake -G Ninja \ - -DWASI_SDK_PREFIX=$(WASI_SDK_ROOT) \ - -DCMAKE_SYSROOT=$(WASI_SDK_ROOT)/share/wasi-sysroot \ - -DCMAKE_TOOLCHAIN_FILE=$(WASI_SDK_ROOT)/share/cmake/wasi-sdk.cmake \ - -DCMAKE_C_FLAGS="--sysroot=$(WASI_SDK_ROOT)/share/wasi-sysroot \ - -I$(CURDIR)/include -I$(TOP)/src/mono -I$(TOP)/src/native/public -I$(TOP)/src/mono/mono/eglib -I$(WASI_OBJ_DIR)/mono/eglib -I$(WASI_OBJ_DIR) -I$(TOP)/artifacts/obj/wasm -I$(TOP)/src/mono/wasm/runtime" \ - -DCMAKE_CXX_FLAGS="--sysroot=$(WASI_SDK_ROOT)/share/wasi-sysroot" \ - -DENABLE_MINIMAL=jit,sgen_major_marksweep_conc,sgen_split_nursery,sgen_gc_bridge,sgen_toggleref,sgen_debug_helpers,sgen_binary_protocol,logging,interpreter,threads,qcalls,debugger_agent,sockets,eventpipe \ - -DDISABLE_SHARED_LIBS=1 \ - -Wl,--allow-undefined \ - $(TOP)/src/mono - cd $(WASI_OBJ_DIR) && PATH=$(NINJA_DIR):${PATH} ninja - - mkdir -p $(WASI_BIN_DIR) - cp $(WASI_OBJ_DIR)/mono/mini/*.a $(WASI_OBJ_DIR)/libmono-wasi-driver.a $(WASI_BIN_DIR) - rm -rf $(WASI_BIN_DIR)/libmono-component-hot_reload-static.a - rm -rf $(WASI_BIN_DIR)/libmono-component-diagnostics_tracing-static.a - mkdir -p $(WASI_BIN_DIR)/include/mono-wasi - cp mono-wasi-driver/*.h $(WASI_BIN_DIR)/include/mono-wasi - -$(WASI_SDK_CLANG): - mkdir -p $(WASI_OBJ_DIR) - cd $(WASI_OBJ_DIR) && \ - wget -q https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-$(WASI_SDK_VERSION)/wasi-sdk-$(WASI_SDK_VERSION).0-linux.tar.gz && \ - tar xf wasi-sdk-*.tar.gz - -.stamp-wasmtime-$(WASMTIME_VERSION): - @echo "** Provisioning wasmtime $(WASMTIME_VERSION) **" - rm -Rf $(WASMTIME_DIR) && \ - wget -q https://github.com/bytecodealliance/wasmtime/releases/download/$(WASMTIME_VERSION)/$(WASMTIME_DIR_NAME).tar.xz -O - | tar -C `dirname $(WASMTIME_DIR)` -Jxf - && \ - touch $@ - -.stamp-ninja-$(NINJA_VERSION): - @echo "** Provisioning ninja $(NINJA_VERSION) **" - rm -Rf $(NINJA_DIR); \ - mkdir $(NINJA_DIR) && \ - wget -q https://github.com/ninja-build/ninja/releases/download/v1.11.0/ninja-linux.zip -O $(NINJA_DIR)/ninja.zip && \ - (cd $(NINJA_DIR) && unzip -q ninja.zip && rm ninja.zip) && \ - touch $@ - -provision-deps: .stamp-wasmtime-$(WASMTIME_VERSION) .stamp-ninja-$(NINJA_VERSION) - @echo "-------------------------------------------" - @echo "** Installed wasmtime in $(WASMTIME_DIR)" - @echo "** Installed ninja in $(NINJA_DIR)" diff --git a/src/mono/wasi/Makefile.variable b/src/mono/wasi/Makefile.variable deleted file mode 100644 index ef8b91b245c246..00000000000000 --- a/src/mono/wasi/Makefile.variable +++ /dev/null @@ -1,16 +0,0 @@ -TOP=$(realpath $(CURDIR)/../../..) -CONFIG?=Release -RUNTIME_CONFIG?=Release -WASI_SDK_VERSION=12 - -WASI_OBJ_DIR=$(TOP)/artifacts/obj/mono/Wasi.$(RUNTIME_CONFIG) -WASI_BIN_DIR=$(TOP)/artifacts/bin/mono/Wasi.$(RUNTIME_CONFIG) -WASI_SDK_ROOT=$(WASI_OBJ_DIR)/wasi-sdk-$(WASI_SDK_VERSION).0 -WASI_SDK_CLANG=$(WASI_SDK_ROOT)/bin/clang - -WASMTIME_VERSION=v0.39.1 -WASMTIME_DIR_NAME=wasmtime-$(WASMTIME_VERSION)-x86_64-linux -WASMTIME_DIR=$(TOP)/artifacts/bin/$(WASMTIME_DIR_NAME) - -NINJA_VERSION=v1.11.0 -NINJA_DIR=$(TOP)/artifacts/bin/ninja diff --git a/src/mono/wasi/README.md b/src/mono/wasi/README.md index a44f8d5db93230..66e59384297bb3 100644 --- a/src/mono/wasi/README.md +++ b/src/mono/wasi/README.md @@ -8,59 +8,21 @@ The mechanism for executing .NET code in a WASI runtime environment is equivalen ## How to build the runtime -### 1. Build the WASM runtime - -To build the wasi runtime we need the file `wasm_m2n_invoke.g.h` which is generated when compiling wasm runtime - -``` -make -C src/mono/wasm provision-wasm -export EMSDK_PATH=[path_printed_by_provision_wasm] -./build.sh mono+libs -os browser -``` - -### 2. Build the WASI runtime - -Currently this can only be built in Linux or WSL (tested on Windows 11). Simply run `make` in this directory. It will automatically download and use [WASI SDK](https://github.com/WebAssembly/wasi-sdk). - -The resulting libraries are placed in `(repo_root)/artifacts/bin/mono/Wasi.Release`. - -## How to build and run the sample - -### 1. Obtain a WASI runtime - -To run an application in a WASI environment, you need to have a WASI runtime available. For example, download [wasmtime](https://github.com/bytecodealliance/wasmtime/releases) and make sure it's available on `PATH`: - +on Linux: +```.sh +./build.sh -bl -os wasi -subset mono+libs -c Debug ``` -export PATH=~/wasmtime-v0.31.0-x86_64-linux -wasmtime --version +or for just native rebuild +```.sh +./build.sh -bl -os wasi -subset mono.runtime+libs.native+mono.wasiruntime -c Debug ``` -Other WASI runtimes also work. Tested: [wamr](https://github.com/bytecodealliance/wasm-micro-runtime), [wasmer](https://wasmer.io/). - -### 2. Obtain a suitable .NET build toolchain - -You also need to have a working installation of .NET 7 including the `browser-wasm` runtime pack. For example, obtain the [.NET SDK daily build](https://github.com/dotnet/installer/blob/main/README.md#installers-and-binaries) (`main` branch), and ensure the `browser-wasm` pack is installed: - -``` -dotnet workload install wasm-tools -s https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet7/nuget/v3/index.json -``` - -To make this available to the build scripts, supply environment variables. Example: - -``` -export DOTNET_ROOT=~/dotnet7 -export BROWSER_WASM_RUNTIME_PATH=$(DOTNET_ROOT)/packs/Microsoft.NETCore.App.Runtime.Mono.browser-wasm/7.0.0-alpha.1.22061.11/runtimes/browser-wasm -``` - -You'll need to update these paths to match the location where you extracted the .NET daily SDK build and the exact version of the `browser-wasm` pack you received. - ### 3. Run it Finally, you can build and run the sample: ``` -cd sample/console -make run +./dotnet.sh build /p:TargetOS=wasi /p:Configuration=Debug /t:RunSample src/mono/sample/wasi/console ``` ### 4. Debug it diff --git a/src/mono/wasi/build/WasiApp.InTree.props b/src/mono/wasi/build/WasiApp.InTree.props new file mode 100644 index 00000000000000..8c119d5413b585 --- /dev/null +++ b/src/mono/wasi/build/WasiApp.InTree.props @@ -0,0 +1,2 @@ + + diff --git a/src/mono/wasi/build/WasiApp.InTree.targets b/src/mono/wasi/build/WasiApp.InTree.targets new file mode 100644 index 00000000000000..8c119d5413b585 --- /dev/null +++ b/src/mono/wasi/build/WasiApp.InTree.targets @@ -0,0 +1,2 @@ + + diff --git a/src/mono/wasi/include/netdb.h b/src/mono/wasi/include/netdb.h new file mode 100644 index 00000000000000..f905f3bb8cd197 --- /dev/null +++ b/src/mono/wasi/include/netdb.h @@ -0,0 +1 @@ +const char *gai_strerror(int); diff --git a/src/mono/wasi/mono-wasi-driver/driver.h b/src/mono/wasi/mono-include/driver.h similarity index 95% rename from src/mono/wasi/mono-wasi-driver/driver.h rename to src/mono/wasi/mono-include/driver.h index a27f2b8480614d..664680e137c234 100644 --- a/src/mono/wasi/mono-wasi-driver/driver.h +++ b/src/mono/wasi/mono-include/driver.h @@ -13,7 +13,6 @@ MonoClass* mono_wasm_assembly_find_class (MonoAssembly *assembly, const char *na MonoMethod* mono_wasm_assembly_find_method (MonoClass *klass, const char *name, int arguments); MonoObject* mono_wasm_invoke_method (MonoMethod *method, MonoObject *this_arg, void *params[], MonoObject **out_exc); int mono_unbox_int (MonoObject *obj); -void mono_wasm_setenv (const char *name, const char *value); void add_assembly(const char* base_dir, const char *name); MonoArray* mono_wasm_obj_array_new (int size); diff --git a/src/mono/wasi/mono-include/pinvoke.h b/src/mono/wasi/mono-include/pinvoke.h new file mode 100644 index 00000000000000..78c30f22693c8d --- /dev/null +++ b/src/mono/wasi/mono-include/pinvoke.h @@ -0,0 +1,52 @@ +// TODOWASI deduplicate src/mono/wasm/runtime/pinvoke.h + +#ifndef __PINVOKE_H__ +#define __PINVOKE_H__ + +#include + +typedef struct { + const char *name; + void *func; +} PinvokeImport; + +typedef struct { + void *func; + void *arg; +} InterpFtnDesc; + +void* +wasm_dl_lookup_pinvoke_table (const char *name); + +int +wasm_dl_is_pinvoke_table (void *handle); + +void* +wasm_dl_get_native_to_interp (const char *key, void *extra_arg); + +void +mono_wasm_pinvoke_vararg_stub (void); + +typedef void* (*MonoWasmNativeToInterpCallback) (char * cookie); + +void +mono_wasm_install_interp_to_native_callback (MonoWasmNativeToInterpCallback cb); + +typedef struct _MonoInterpMethodArguments MonoInterpMethodArguments; + +int +mono_wasm_interp_method_args_get_iarg (MonoInterpMethodArguments *margs, int i); + +int64_t +mono_wasm_interp_method_args_get_larg (MonoInterpMethodArguments *margs, int i); + +float +mono_wasm_interp_method_args_get_farg (MonoInterpMethodArguments *margs, int i); + +double +mono_wasm_interp_method_args_get_darg (MonoInterpMethodArguments *margs, int i); + +void* +mono_wasm_interp_method_args_get_retval (MonoInterpMethodArguments *margs); + +#endif diff --git a/src/mono/wasi/include/pthread.h b/src/mono/wasi/mono-include/pthread.h similarity index 100% rename from src/mono/wasi/include/pthread.h rename to src/mono/wasi/mono-include/pthread.h diff --git a/src/mono/wasi/include/setjmp.h b/src/mono/wasi/mono-include/setjmp.h similarity index 100% rename from src/mono/wasi/include/setjmp.h rename to src/mono/wasi/mono-include/setjmp.h diff --git a/src/mono/wasi/mono-include/wasm-config.h.in b/src/mono/wasi/mono-include/wasm-config.h.in new file mode 100644 index 00000000000000..4c33fd663663c0 --- /dev/null +++ b/src/mono/wasi/mono-include/wasm-config.h.in @@ -0,0 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +#ifndef __MONO_WASM_CONFIG_H__ +#define __MONO_WASM_CONFIG_H__ + +/* Support for threads is disabled */ +#cmakedefine DISABLE_THREADS + +/* Support for starting user threads is disabled */ +#cmakedefine DISABLE_WASM_USER_THREADS + +#endif/*__MONO_WASM_CONFIG_H__*/ + +// TODOWASI deduplicate with src/mono/wasm/runtime/wasm-config.h.in \ No newline at end of file diff --git a/src/mono/wasi/provision.ps1 b/src/mono/wasi/provision.ps1 new file mode 100644 index 00000000000000..f20fcbdb888dd8 --- /dev/null +++ b/src/mono/wasi/provision.ps1 @@ -0,0 +1,14 @@ +param( + [Parameter()] + [string]$WasiSdkUrl, + [Parameter()] + [string]$WasiSdkVersion +) + +Remove-Item ./wasi-sdk/ -r -fo -ErrorAction SilentlyContinue +Remove-Item ./wasi-sdk-$WasiSdkVersion.0-mingw.tar.gz -fo +Invoke-WebRequest -Uri $WasiSdkUrl -OutFile ./wasi-sdk-$WasiSdkVersion.0-mingw.tar.gz +tar -xvzf ./wasi-sdk-$WasiSdkVersion.0-mingw.tar.gz +Remove-Item ./wasi-sdk-$WasiSdkVersion.0-mingw.tar.gz -fo +Move-Item ./wasi-sdk-$WasiSdkVersion.*/ ./wasi-sdk/ +Copy-Item ./wasi-sdk-version.txt ./wasi-sdk/wasi-sdk-version.txt diff --git a/src/mono/wasi/runtime/CMakeLists.txt b/src/mono/wasi/runtime/CMakeLists.txt new file mode 100644 index 00000000000000..8e4114f0c31e45 --- /dev/null +++ b/src/mono/wasi/runtime/CMakeLists.txt @@ -0,0 +1,39 @@ +cmake_minimum_required(VERSION 3.14.5) + +project(mono-wasi-runtime C) + +option(DISABLE_THREADS "defined if the build does NOT support multithreading" ON) +option(DISABLE_WASM_USER_THREADS "defined if the build does not allow user threads to be created in a multithreaded build" OFF) + +set(CMAKE_EXECUTABLE_SUFFIX ".wasm") +add_executable(dotnet driver.c pinvoke.c stubs.c synthetic-pthread.c) + +target_include_directories(dotnet PUBLIC ${MONO_INCLUDES} ${MONO_OBJ_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR}/include/wasm) +target_compile_options(dotnet PUBLIC @${NATIVE_BIN_DIR}/src/wasi-default.rsp @${NATIVE_BIN_DIR}/src/wasi-compile.rsp -DCORE_BINDINGS -DGEN_PINVOKE=1) + +set_target_properties(dotnet PROPERTIES COMPILE_FLAGS ${CONFIGURATION_WASICC_FLAGS}) + +target_link_libraries(dotnet + #TODOWASI ${ICU_LIB_DIR}/libicuuc.a + #TODOWASI ${ICU_LIB_DIR}/libicui18n.a + ${MONO_ARTIFACTS_DIR}/libmono-component-hot_reload-static.a + ${MONO_ARTIFACTS_DIR}/libmono-component-debugger-static.a + ${MONO_ARTIFACTS_DIR}/libmono-component-diagnostics_tracing-stub-static.a + ${MONO_ARTIFACTS_DIR}/libmono-component-marshal-ilgen-static.a + ${MONO_ARTIFACTS_DIR}/libmono-ee-interp.a + ${MONO_ARTIFACTS_DIR}/libmonosgen-2.0.a + ${MONO_ARTIFACTS_DIR}/libmono-icall-table.a + ${NATIVE_BIN_DIR}/libSystem.Native.a + ${NATIVE_BIN_DIR}/libSystem.IO.Compression.Native.a +) + +set_target_properties(dotnet PROPERTIES + LINK_DEPENDS "${NATIVE_BIN_DIR}/src/wasi-default.rsp;" + LINK_FLAGS "@${NATIVE_BIN_DIR}/src/wasi-default.rsp @${NATIVE_BIN_DIR}/src/wasi-link.rsp ${CONFIGURATION_LINK_FLAGS} " + RUNTIME_OUTPUT_DIRECTORY "${NATIVE_BIN_DIR}") + +set(ignoreMeWasmOptFlags "${CONFIGURATION_WASM_OPT_FLAGS}${CMAKE_CXX_FLAGS}") + +#TODOWASI wasm-opt + +configure_file(../mono-include/wasm-config.h.in include/wasm/wasm-config.h) diff --git a/src/mono/wasi/mono-wasi-driver/driver.c b/src/mono/wasi/runtime/driver.c similarity index 50% rename from src/mono/wasi/mono-wasi-driver/driver.c rename to src/mono/wasi/runtime/driver.c index df4ef9911429ba..27bfc92a1c55c1 100644 --- a/src/mono/wasi/mono-wasi-driver/driver.c +++ b/src/mono/wasi/runtime/driver.c @@ -8,22 +8,19 @@ #include #include #include -#include -#include -#include #define INVARIANT_GLOBALIZATION 1 +#include #include +#include #include #include #include -#include #include +#include #include -#include -#include -#include +#include #include #include @@ -33,11 +30,21 @@ #include #include -#include "wasm/runtime/pinvoke.h" +#include "pinvoke.h" #ifdef GEN_PINVOKE #include "wasm_m2n_invoke.g.h" #endif +#include "../../wasm/runtime/gc-common.h" + + +#if !defined(ENABLE_AOT) || defined(EE_MODE_LLVMONLY_INTERP) +#define NEED_INTERP 1 +#ifndef LINK_ICALLS +// FIXME: llvm+interp mode needs this to call icalls +#define NEED_NORMAL_ICALL_TABLES 1 +#endif +#endif void mono_wasm_enable_debugging (int); @@ -72,11 +79,15 @@ static MonoDomain *root_domain; #define RUNTIMECONFIG_BIN_FILE "runtimeconfig.bin" static void -wasm_trace_logger (const char *log_domain, const char *log_level, const char *message, mono_bool fatal, void *user_data) +wasi_trace_logger (const char *log_domain, const char *log_level, const char *message, mono_bool fatal, void *user_data) { - printf("[wasm_trace_logger] %s\n", message); - if (fatal) - exit (1); + printf("[wasi_trace_logger] %s\n", message); + if (fatal) { + // make it trap so we could see the stack trace + // (*(int*)(void*)-1)++; + exit(1); + } + } typedef uint32_t target_mword; @@ -124,43 +135,10 @@ struct WasmSatelliteAssembly_ { static WasmSatelliteAssembly *satellite_assemblies; static int satellite_assembly_count; -int32_t time(int32_t x) { - // In the current prototype, libSystem.Native.a is built using Emscripten, whereas the WASI-enabled runtime is being built - // using WASI SDK. Emscripten says that time() returns int32, whereas WASI SDK says it returns int64. - // TODO: Build libSystem.Native.a using WASI SDK. - // In the meantime, as a workaround we can define an int32-returning implementation for time() here. - struct timeval time; - return (gettimeofday(&time, NULL) == 0) ? time.tv_sec : 0; -} - -typedef struct -{ - int32_t Flags; // flags for testing if some members are present (see FileStatusFlags) - int32_t Mode; // file mode (see S_I* constants above for bit values) - uint32_t Uid; // user ID of owner - uint32_t Gid; // group ID of owner - int64_t Size; // total size, in bytes - int64_t ATime; // time of last access - int64_t ATimeNsec; // nanosecond part - int64_t MTime; // time of last modification - int64_t MTimeNsec; // nanosecond part - int64_t CTime; // time of last status change - int64_t CTimeNsec; // nanosecond part - int64_t BirthTime; // time the file was created - int64_t BirthTimeNsec; // nanosecond part - int64_t Dev; // ID of the device containing the file - int64_t Ino; // inode number of the file - uint32_t UserFlags; // user defined flags -} FileStatus; - char* gai_strerror(int code) { - char result[256]; - sprintf(result, "Error code %i", code); - return result; -} - -int32_t dotnet_browser_entropy(uint8_t* buffer, int32_t bufferLength) { - return getentropy (buffer, bufferLength); + char* result = malloc(256); + sprintf(result, "Error code %i", code); + return result; } void @@ -173,183 +151,122 @@ mono_wasm_add_satellite_assembly (const char *name, const char *culture, const u ++satellite_assembly_count; } -void -mono_wasm_setenv (const char *name, const char *value) +static void *sysglobal_native_handle; + +static void* +wasm_dl_load (const char *name, int flags, char **err, void *user_data) { - monoeg_g_setenv (strdup (name), strdup (value), 1); -} + void* handle = wasm_dl_lookup_pinvoke_table (name); + if (handle) + return handle; -static void *sysglobal_native_handle; -int32_t SystemNative_LChflagsCanSetHiddenFlag(void); -char* SystemNative_GetEnv(char* name); -char* SystemNative_GetEnviron(char* name); -void SystemNative_FreeEnviron(char* name); -intptr_t SystemNative_Dup(intptr_t oldfd); -int32_t SystemNative_Write(intptr_t fd, const void* buffer, int32_t bufferSize); -int64_t SystemNative_GetSystemTimeAsTicks(); -int32_t SystemNative_Stat(const char* path, void* output); -int32_t SystemNative_LStat(const char* path, void* output); -int32_t SystemNative_ConvertErrorPlatformToPal(int32_t platformErrno); -void* SystemNative_LowLevelMonitor_Create(); -void SystemNative_LowLevelMonitor_Acquire(void* monitor); -void SystemNative_LowLevelMonitor_Release(void* monitor); -int32_t SystemNative_LowLevelMonitor_TimedWait(void *monitor, int32_t timeoutMilliseconds); -void SystemNative_LowLevelMonitor_Wait(void* monitor); -int SystemNative_GetErrNo(); -void SystemNative_SetErrNo(int value); -char* SystemNative_GetCwd(); -void SystemNative_GetNonCryptographicallySecureRandomBytes(); -void SystemNative_GetCryptographicallySecureRandomBytes(); -int32_t SystemNative_Open(const char* path, int x, int y); -void SystemNative_ConvertErrorPalToPlatform(); -void SystemNative_StrErrorR(); -void SystemNative_Close(); -void SystemNative_FStat(); -void SystemNative_LSeek(); -void SystemNative_PRead(); -void SystemNative_CanGetHiddenFlag(); -int32_t SystemNative_Access(const char* path, int32_t mode); -void SystemNative_Malloc(); -void SystemNative_Free(); -void SystemNative_SysLog(); - -#define PAL_O_RDONLY 0x0000 -#define PAL_O_WRONLY 0x0001 -#define PAL_O_RDWR 0x0002 -#define PAL_O_ACCESS_MODE_MASK 0x000F - -int32_t SystemNative_Open2(const char* path, int flags, int mode) { - //printf ("In SystemNative_Open2 for %s\n", path); - // The implementation in libSystemNative tries to use PAL_O_CLOEXEC, which isn't supported here, so override it - if ((flags & PAL_O_ACCESS_MODE_MASK) == PAL_O_RDONLY) { - flags = O_RDONLY; - } else if ((flags & PAL_O_ACCESS_MODE_MASK) == PAL_O_RDWR) { - flags = O_RDWR; - } else if ((flags & PAL_O_ACCESS_MODE_MASK) == PAL_O_WRONLY) { - flags = O_WRONLY; - } + if (!strcmp (name, "System.Globalization.Native")) + return sysglobal_native_handle; - int result; - while ((result = open(path, flags, (mode_t)mode)) < 0 && errno == EINTR); - return result; +#if WASM_SUPPORTS_DLOPEN + return dlopen(name, flags); +#endif + + return NULL; } -int32_t SystemNative_Stat2(const char* path, FileStatus* output) +static void* +wasm_dl_symbol (void *handle, const char *name, char **err, void *user_data) { - // For some reason the libSystemNative SystemNative_Stat doesn't seem to work. Maybe I did something wrong elsewhere, - // or maybe it's hardcoded to something specific to browser wasm - struct stat stat_result; - int ret; - while ((ret = stat(path, &stat_result)) < 0 && errno == EINTR); - - output->Size = stat_result.st_size; - output->ATime = stat_result.st_atime; - output->MTime = stat_result.st_mtime; - output->CTime = stat_result.st_ctime; - output->Mode = S_ISDIR (stat_result.st_mode) - ? 0x4000 // Dir - : 0x8000; // File - - // Never fail when looking for the root directory. Even if the WASI host isn't giving us filesystem access - // (which is the default), we need the root directory to appear to exist, otherwise things like ASP.NET Core - // will fail by default, whether or not it needs to read anything from the filesystem. - if (ret != 0 && path[0] == '/' && path[1] == 0) { - output->Mode = 0x4000; // Dir - return 0; - } + if (handle == sysglobal_native_handle) + assert (0); - //printf("SystemNative_Stat2 for %s has ISDIR=%i and will return mode %i; ret=%i\n", path, S_ISDIR (stat_result.st_mode), output->Mode, ret); +#if WASM_SUPPORTS_DLOPEN + if (!wasm_dl_is_pinvoke_tables (handle)) { + return dlsym (handle, name); + } +#endif - return ret; + PinvokeImport *table = (PinvokeImport*)handle; + for (int i = 0; table [i].name; ++i) { + if (!strcmp (table [i].name, name)) + return table [i].func; + } + return NULL; } -int32_t SystemNative_Write2(intptr_t fd, const void* buffer, int32_t bufferSize) { - // Not sure why, but am getting fd=-1 when trying to write to stdout (which fails), so here's a workaround - return SystemNative_Write((int)fd == -1 ? 1: fd, buffer, bufferSize); -} +#if !defined(ENABLE_AOT) || defined(EE_MODE_LLVMONLY_INTERP) +#define NEED_INTERP 1 +#ifndef LINK_ICALLS +// FIXME: llvm+interp mode needs this to call icalls +#define NEED_NORMAL_ICALL_TABLES 1 +#endif +#endif -int64_t SystemNative_GetTimestamp2() { - // libSystemNative's implementation of SystemNative_GetTimestamp causes the process to exit. It probably - // relies on calling into JS. - struct timeval time; - return (gettimeofday(&time, NULL) == 0) - ? (int64_t)(time.tv_sec) * 1000000000 + (time.tv_usec * 1000) - : 0; -} +#ifdef LINK_ICALLS -static PinvokeImport SystemNativeImports [] = { - {"SystemNative_GetEnv", SystemNative_GetEnv }, - {"SystemNative_GetEnviron", SystemNative_GetEnviron }, - {"SystemNative_FreeEnviron", SystemNative_FreeEnviron }, - {"SystemNative_LChflagsCanSetHiddenFlag", SystemNative_LChflagsCanSetHiddenFlag }, - {"SystemNative_Dup", SystemNative_Dup}, - {"SystemNative_Write", SystemNative_Write2}, - {"SystemNative_GetSystemTimeAsTicks", SystemNative_GetSystemTimeAsTicks}, - {"SystemNative_LStat", SystemNative_Stat2}, - {"SystemNative_FStat", SystemNative_FStat}, - {"SystemNative_LSeek", SystemNative_LSeek}, - {"SystemNative_ConvertErrorPlatformToPal", SystemNative_ConvertErrorPlatformToPal}, - {"SystemNative_LowLevelMonitor_Create", SystemNative_LowLevelMonitor_Create}, - {"SystemNative_LowLevelMonitor_Acquire", SystemNative_LowLevelMonitor_Acquire}, - {"SystemNative_LowLevelMonitor_Release", SystemNative_LowLevelMonitor_Release}, - {"SystemNative_LowLevelMonitor_TimedWait", SystemNative_LowLevelMonitor_TimedWait}, - {"SystemNative_LowLevelMonitor_Wait", SystemNative_LowLevelMonitor_Wait}, - {"SystemNative_GetErrNo", SystemNative_GetErrNo}, - {"SystemNative_SetErrNo", SystemNative_SetErrNo}, - {"SystemNative_GetCwd", SystemNative_GetCwd}, - {"SystemNative_GetNonCryptographicallySecureRandomBytes", SystemNative_GetNonCryptographicallySecureRandomBytes}, - {"SystemNative_GetCryptographicallySecureRandomBytes", SystemNative_GetCryptographicallySecureRandomBytes}, - {"SystemNative_Stat", SystemNative_Stat2}, - {"SystemNative_Open", SystemNative_Open2}, - {"SystemNative_Close", SystemNative_Close}, - {"SystemNative_ConvertErrorPalToPlatform", SystemNative_ConvertErrorPalToPlatform}, - {"SystemNative_StrErrorR", SystemNative_StrErrorR}, - {"SystemNative_PRead", SystemNative_PRead}, - {"SystemNative_CanGetHiddenFlag", SystemNative_CanGetHiddenFlag}, - {"SystemNative_GetTimestamp", SystemNative_GetTimestamp2}, - {"SystemNative_Access", SystemNative_Access}, - {"SystemNative_Malloc", SystemNative_Malloc}, - {"SystemNative_Free", SystemNative_Free}, - {"SystemNative_SysLog", SystemNative_SysLog}, - {NULL, NULL} -}; +#include "icall-table.h" -void GlobalizationNative_LoadICU() { - assert(0); +static int +compare_int (const void *k1, const void *k2) +{ + return *(int*)k1 - *(int*)k2; } -static PinvokeImport SystemGlobalizationNativeImports [] = { - {"GlobalizationNative_LoadICU", GlobalizationNative_LoadICU }, - {NULL, NULL} -}; - static void* -wasm_dl_load (const char *name, int flags, char **err, void *user_data) +icall_table_lookup (MonoMethod *method, char *classname, char *methodname, char *sigstart, int32_t *out_flags) { - if (!strcmp (name, "libSystem.Native")) - return SystemNativeImports; - if (!strcmp (name, "libSystem.Globalization.Native")) - return SystemGlobalizationNativeImports; + uint32_t token = mono_method_get_token (method); + assert (token); + assert ((token & MONO_TOKEN_METHOD_DEF) == MONO_TOKEN_METHOD_DEF); + uint32_t token_idx = token - MONO_TOKEN_METHOD_DEF; + + int *indexes = NULL; + int indexes_size = 0; + uint8_t *flags = NULL; + void **funcs = NULL; + + *out_flags = 0; + + const char *image_name = mono_image_get_name (mono_class_get_image (mono_method_get_class (method))); + +#if defined(ICALL_TABLE_corlib) + if (!strcmp (image_name, "System.Private.CoreLib")) { + indexes = corlib_icall_indexes; + indexes_size = sizeof (corlib_icall_indexes) / 4; + flags = corlib_icall_flags; + funcs = corlib_icall_funcs; + assert (sizeof (corlib_icall_indexes [0]) == 4); + } +#endif +#ifdef ICALL_TABLE_System + if (!strcmp (image_name, "System")) { + indexes = System_icall_indexes; + indexes_size = sizeof (System_icall_indexes) / 4; + flags = System_icall_flags; + funcs = System_icall_funcs; + } +#endif + assert (indexes); - //printf("In wasm_dl_load for name %s but treating as NOT FOUND\n", name); - return 0; + void *p = bsearch (&token_idx, indexes, indexes_size, 4, compare_int); + if (!p) { + return NULL; + printf ("wasm: Unable to lookup icall: %s\n", mono_method_get_name (method)); + exit (1); + } + + uint32_t idx = (int*)p - indexes; + *out_flags = flags [idx]; + + //printf ("ICALL: %s %x %d %d\n", methodname, token, idx, (int)(funcs [idx])); + + return funcs [idx]; } -static void* -wasm_dl_symbol (void *handle, const char *name, char **err, void *user_data) +static const char* +icall_table_lookup_symbol (void *func) { - if (handle == sysglobal_native_handle) - assert (0); - - PinvokeImport *table = (PinvokeImport*)handle; - for (int i = 0; table [i].name; ++i) { - if (!strcmp (table [i].name, name)) - return table [i].func; - } + assert (0); return NULL; } -#define NEED_INTERP 1 +#endif /* * get_native_to_interp: @@ -361,6 +278,9 @@ wasm_dl_symbol (void *handle, const char *name, char **err, void *user_data) void* get_native_to_interp (MonoMethod *method, void *extra_arg) { + void *addr; + + MONO_ENTER_GC_UNSAFE; MonoClass *klass = mono_method_get_class (method); MonoImage *image = mono_class_get_image (klass); MonoAssembly *assembly = mono_image_get_assembly (image); @@ -379,9 +299,9 @@ get_native_to_interp (MonoMethod *method, void *extra_arg) key [i] = '_'; } - assert(0); return 0; - //void *addr = wasm_dl_get_native_to_interp (key, extra_arg); - //return addr; + addr = wasm_dl_get_native_to_interp (key, extra_arg); + MONO_EXIT_GC_UNSAFE; + return addr; } void @@ -401,6 +321,8 @@ mono_wasm_register_bundled_satellite_assemblies (void) } } +void mono_wasm_link_icu_shim (void); + void cleanup_runtime_config (MonovmRuntimeConfigArguments *args, void *user_data) { @@ -409,7 +331,7 @@ cleanup_runtime_config (MonovmRuntimeConfigArguments *args, void *user_data) } void -mono_wasm_load_runtime (const char *argv, int debug_level) +mono_wasm_load_runtime (const char *unused, int debug_level) { const char *interp_opts = ""; @@ -421,12 +343,13 @@ mono_wasm_load_runtime (const char *argv, int debug_level) #ifdef DEBUG monoeg_g_setenv ("MONO_LOG_LEVEL", "debug", 0); - monoeg_g_setenv ("MONO_LOG_MASK", "gc", 0); - // Setting this env var allows Diagnostic.Debug to write to stderr. In a browser environment this - // output will be sent to the console. Right now this is the only way to emit debug logging from - // corlib assemblies. - monoeg_g_setenv ("COMPlus_DebugWriteToStdErr", "1", 0); + monoeg_g_setenv ("MONO_LOG_MASK", "all", 0); + // Setting this env var allows Diagnostic.Debug to write to stderr. In a browser environment this + // output will be sent to the console. Right now this is the only way to emit debug logging from + // corlib assemblies. + // monoeg_g_setenv ("COMPlus_DebugWriteToStdErr", "1", 0); #endif + char* debugger_fd = monoeg_g_getenv ("DEBUGGER_FD"); if (debugger_fd != 0) { @@ -447,7 +370,7 @@ mono_wasm_load_runtime (const char *argv, int debug_level) const char *appctx_values[2]; appctx_values [0] = "/"; - appctx_values [1] = "browser-wasm"; + appctx_values [1] = "wasi-wasm"; const char *file_name = RUNTIMECONFIG_BIN_FILE; int str_len = strlen (file_name) + 1; // +1 is for the "/" @@ -472,13 +395,53 @@ mono_wasm_load_runtime (const char *argv, int debug_level) mono_dl_fallback_register (wasm_dl_load, wasm_dl_symbol, NULL, NULL); mono_wasm_install_get_native_to_interp_tramp (get_native_to_interp); - + #ifdef GEN_PINVOKE mono_wasm_install_interp_to_native_callback (mono_wasm_interp_to_native_callback); #endif +#ifdef ENABLE_AOT + monoeg_g_setenv ("MONO_AOT_MODE", "aot", 1); + + // Defined in driver-gen.c + register_aot_modules (); +#ifdef EE_MODE_LLVMONLY_INTERP + mono_jit_set_aot_mode (MONO_AOT_MODE_LLVMONLY_INTERP); +#else + mono_jit_set_aot_mode (MONO_AOT_MODE_LLVMONLY); +#endif +#else mono_jit_set_aot_mode (MONO_AOT_MODE_INTERP_ONLY); + /* + * debug_level > 0 enables debugging and sets the debug log level to debug_level + * debug_level == 0 disables debugging and enables interpreter optimizations + * debug_level < 0 enabled debugging and disables debug logging. + * + * Note: when debugging is enabled interpreter optimizations are disabled. + */ + if (debug_level) { + // Disable optimizations which interfere with debugging + interp_opts = "-all"; + mono_wasm_enable_debugging (debug_level); + } + +#endif + +#ifdef LINK_ICALLS + /* Link in our own linked icall table */ + static const MonoIcallTableCallbacks mono_icall_table_callbacks = + { + MONO_ICALL_TABLE_CALLBACKS_VERSION, + icall_table_lookup, + icall_table_lookup_symbol + }; + mono_install_icall_table_callbacks (&mono_icall_table_callbacks); +#endif + +#ifdef NEED_NORMAL_ICALL_TABLES + mono_icall_table_init (); +#endif mono_ee_interp_init (interp_opts); mono_marshal_ilgen_init (); mono_method_builder_ilgen_init (); @@ -498,7 +461,7 @@ mono_wasm_load_runtime (const char *argv, int debug_level) mono_wasm_register_bundled_satellite_assemblies (); mono_trace_init (); - mono_trace_set_log_handler (wasm_trace_logger, NULL); + mono_trace_set_log_handler (wasi_trace_logger, NULL); root_domain = mono_jit_init_version ("mono", NULL); mono_thread_set_main (mono_thread_current ()); @@ -507,10 +470,9 @@ mono_wasm_load_runtime (const char *argv, int debug_level) MonoAssembly* mono_wasm_assembly_load (const char *name) { + assert (name); MonoImageOpenStatus status; MonoAssemblyName* aname = mono_assembly_name_new (name); - if (!name) - return NULL; MonoAssembly *res = mono_assembly_load (aname, NULL, &status); mono_assembly_name_free (aname); @@ -518,86 +480,65 @@ mono_wasm_assembly_load (const char *name) return res; } -MonoClass* -mono_wasm_find_corlib_class (const char *namespace, const char *name) +MonoAssembly* +mono_wasm_get_corlib (const char *namespace, const char *name) { - return mono_class_from_name (mono_get_corlib (), namespace, name); + MonoAssembly* result; + MONO_ENTER_GC_UNSAFE; + result = mono_image_get_assembly (mono_get_corlib()); + MONO_EXIT_GC_UNSAFE; + return result; } MonoClass* mono_wasm_assembly_find_class (MonoAssembly *assembly, const char *namespace, const char *name) { - return mono_class_from_name (mono_assembly_get_image (assembly), namespace, name); + assert (assembly); + MonoClass *result; + MONO_ENTER_GC_UNSAFE; + result = mono_class_from_name (mono_assembly_get_image (assembly), namespace, name); + MONO_EXIT_GC_UNSAFE; + return result; } MonoMethod* mono_wasm_assembly_find_method (MonoClass *klass, const char *name, int arguments) { - return mono_class_get_method_from_name (klass, name, arguments); -} - -MonoMethod* -mono_wasm_get_delegate_invoke (MonoObject *delegate) -{ - return mono_get_delegate_invoke(mono_object_get_class (delegate)); + assert (klass); + MonoMethod* result; + MONO_ENTER_GC_UNSAFE; + result = mono_class_get_method_from_name (klass, name, arguments); + MONO_EXIT_GC_UNSAFE; + return result; } -MonoObject* -mono_wasm_box_primitive (MonoClass *klass, void *value, int value_size) -{ - if (!klass) - return NULL; - - MonoType *type = mono_class_get_type (klass); - int alignment; - if (mono_type_size (type, &alignment) > value_size) - return NULL; - - // TODO: use mono_value_box_checked and propagate error out - return mono_value_box (root_domain, klass, value); -} void -mono_wasm_invoke_method_ref (MonoMethod *method, MonoObject **this_arg_in, void *params[], MonoObject **out_exc, MonoObject **out_result) +mono_wasm_invoke_method_ref (MonoMethod *method, MonoObject **this_arg_in, void *params[], MonoObject **_out_exc, MonoObject **out_result) { - MonoObject* temp_exc = NULL; + PPVOLATILE(MonoObject) out_exc = _out_exc; + PVOLATILE(MonoObject) temp_exc = NULL; if (out_exc) *out_exc = NULL; else out_exc = &temp_exc; + MONO_ENTER_GC_UNSAFE; if (out_result) { *out_result = NULL; - *out_result = mono_runtime_invoke (method, this_arg_in ? *this_arg_in : NULL, params, out_exc); + PVOLATILE(MonoObject) invoke_result = mono_runtime_invoke (method, this_arg_in ? *this_arg_in : NULL, params, (MonoObject **)out_exc); + store_volatile(out_result, invoke_result); } else { - mono_runtime_invoke (method, this_arg_in ? *this_arg_in : NULL, params, out_exc); + mono_runtime_invoke (method, this_arg_in ? *this_arg_in : NULL, params, (MonoObject **)out_exc); } if (*out_exc && out_result) { - MonoObject *exc2 = NULL; - *out_result = (MonoObject*)mono_object_to_string (*out_exc, &exc2); + PVOLATILE(MonoObject) exc2 = NULL; + store_volatile(out_result, (MonoObject*)mono_object_to_string (*out_exc, (MonoObject **)&exc2)); if (exc2) - *out_result = (MonoObject*) mono_string_new (root_domain, "Exception Double Fault"); - return; + store_volatile(out_result, (MonoObject*)mono_string_new (root_domain, "Exception Double Fault")); } -} - -// deprecated -MonoObject* -mono_wasm_invoke_method (MonoMethod *method, MonoObject *this_arg, void *params[], MonoObject **out_exc) -{ - MonoObject* result = NULL; - mono_wasm_invoke_method_ref (method, &this_arg, params, out_exc, &result); - - MonoMethodSignature *sig = mono_method_signature (method); - MonoType *type = mono_signature_get_return_type (sig); - // If the method return type is void return null - // This gets around a memory access crash when the result return a value when - // a void method is invoked. - if (mono_type_get_type (type) == MONO_TYPE_VOID) - return NULL; - - return result; + MONO_EXIT_GC_UNSAFE; } MonoMethod* @@ -606,10 +547,11 @@ mono_wasm_assembly_get_entry_point (MonoAssembly *assembly) MonoImage *image; MonoMethod *method; + MONO_ENTER_GC_UNSAFE; image = mono_assembly_get_image (assembly); uint32_t entry = mono_image_get_entry_point (image); if (!entry) - return NULL; + goto end; mono_domain_ensure_entry_assembly (root_domain, assembly); method = mono_get_method (image, entry, NULL); @@ -626,9 +568,10 @@ mono_wasm_assembly_get_entry_point (MonoAssembly *assembly) int name_length = strlen (name); if ((*name != '<') || (name [name_length - 1] != '>')) - return method; + goto end; MonoClass *klass = mono_method_get_class (method); + assert(klass); char *async_name = malloc (name_length + 2); snprintf (async_name, name_length + 2, "%s$", name); @@ -637,7 +580,8 @@ mono_wasm_assembly_get_entry_point (MonoAssembly *assembly) MonoMethod *async_method = mono_class_get_method_from_name (klass, async_name, mono_signature_get_param_count (sig)); if (async_method != NULL) { free (async_name); - return async_method; + method = async_method; + goto end; } // look for "Name" by trimming the first and last character of "" @@ -646,24 +590,12 @@ mono_wasm_assembly_get_entry_point (MonoAssembly *assembly) free (async_name); if (async_method != NULL) - return async_method; + method = async_method; } - return method; -} - -char * -mono_wasm_string_get_utf8 (MonoString *str) -{ - return mono_string_to_utf8 (str); //XXX JS is responsible for freeing this -} -MonoString * -mono_wasm_string_from_js (const char *str) -{ - if (str) - return mono_string_new (root_domain, str); - else - return NULL; + end: + MONO_EXIT_GC_UNSAFE; + return method; } int @@ -691,49 +623,18 @@ mono_unbox_int (MonoObject *obj) return *(unsigned int*)ptr; case MONO_TYPE_CHAR: return *(short*)ptr; - // WASM doesn't support returning longs to JS - // case MONO_TYPE_I8: - // case MONO_TYPE_U8: default: printf ("Invalid type %d to mono_unbox_int\n", mono_type_get_type (type)); return 0; } } -int -mono_wasm_array_length (MonoArray *array) -{ - return mono_array_length (array); -} - -MonoObject* -mono_wasm_array_get (MonoArray *array, int idx) -{ - return mono_array_get (array, MonoObject*, idx); -} - -MonoArray* -mono_wasm_obj_array_new (int size) -{ - return mono_array_new (root_domain, mono_get_object_class (), size); -} - -void -mono_wasm_obj_array_set (MonoArray *array, int idx, MonoObject *obj) -{ - mono_array_setref (array, idx, obj); -} - -MonoArray* -mono_wasm_string_array_new (int size) -{ - return mono_array_new (root_domain, mono_get_string_class (), size); -} void mono_wasm_string_get_data_ref ( MonoString **string, mono_unichar2 **outChars, int *outLengthBytes, int *outIsInterned ) { + MONO_ENTER_GC_UNSAFE; if (!string || !(*string)) { if (outChars) *outChars = 0; @@ -741,16 +642,15 @@ mono_wasm_string_get_data_ref ( *outLengthBytes = 0; if (outIsInterned) *outIsInterned = 1; - return; - } - + } else { if (outChars) *outChars = mono_string_chars (*string); if (outLengthBytes) *outLengthBytes = mono_string_length (*string) * 2; if (outIsInterned) *outIsInterned = mono_string_instance_is_interned (*string); - return; + } + MONO_EXIT_GC_UNSAFE; } void @@ -761,36 +661,63 @@ mono_wasm_string_get_data ( } void add_assembly(const char* base_dir, const char *name) { - FILE *fileptr; - unsigned char *buffer; - long filelen; - char filename[256]; - sprintf(filename, "%s/%s", base_dir, name); - // printf("Loading %s...\n", filename); - - fileptr = fopen(filename, "rb"); - if (fileptr == 0) { - printf("Failed to load %s\n", filename); - fflush(stdout); - } - - fseek(fileptr, 0, SEEK_END); - filelen = ftell(fileptr); - rewind(fileptr); - - buffer = (unsigned char *)malloc(filelen * sizeof(char)); - fread(buffer, filelen, 1, fileptr); - fclose(fileptr); - - assert(mono_wasm_add_assembly(name, buffer, filelen)); + FILE *fileptr; + unsigned char *buffer; + long filelen; + char filename[256]; + sprintf(filename, "%s/%s", base_dir, name); + // printf("Loading %s...\n", filename); + + fileptr = fopen(filename, "rb"); + if (fileptr == 0) { + printf("Failed to load %s\n", filename); + fflush(stdout); + } + + fseek(fileptr, 0, SEEK_END); + filelen = ftell(fileptr); + rewind(fileptr); + + buffer = (unsigned char *)malloc(filelen * sizeof(char)); + if(!fread(buffer, filelen, 1, fileptr)) { + printf("Failed to load %s\n", filename); + fflush(stdout); + } + fclose(fileptr); + + assert(mono_wasm_add_assembly(name, buffer, filelen)); } MonoMethod* lookup_dotnet_method(const char* assembly_name, const char* namespace, const char* type_name, const char* method_name, int num_params) { - MonoAssembly* assembly = mono_wasm_assembly_load (assembly_name); + MonoAssembly* assembly = mono_wasm_assembly_load (assembly_name); assert (assembly); - MonoClass* class = mono_wasm_assembly_find_class (assembly, namespace, type_name); + MonoClass* class = mono_wasm_assembly_find_class (assembly, namespace, type_name); assert (class); - MonoMethod* method = mono_wasm_assembly_find_method (class, method_name, num_params); + MonoMethod* method = mono_wasm_assembly_find_method (class, method_name, num_params); assert (method); return method; } + +int main() { + // Assume the runtime pack has been copied into the output directory as 'runtime' + // Otherwise we have to mount an unrelated part of the filesystem within the WASM environment + mono_set_assemblies_path(".:./runtime/native:./runtime/lib/net7.0"); + mono_wasm_load_runtime("", 0); + + MonoAssembly* assembly = mono_wasm_assembly_load ("Wasi.Console.Sample"); + MonoMethod* entry_method = mono_wasm_assembly_get_entry_point (assembly); + MonoObject* out_exc; + MonoObject* out_res; + mono_wasm_invoke_method_ref (entry_method, NULL, NULL, &out_exc, &out_res); + if (out_exc) + { + mono_print_unhandled_exception(out_exc); + exit(1); + } + if(out_res) + { + int r= mono_unbox_int (out_res); + return r; + } + return 0; +} \ No newline at end of file diff --git a/src/mono/wasi/runtime/pinvoke.c b/src/mono/wasi/runtime/pinvoke.c new file mode 100644 index 00000000000000..0655b256f034dc --- /dev/null +++ b/src/mono/wasi/runtime/pinvoke.c @@ -0,0 +1,64 @@ +// TODOWASI deduplicate src/mono/wasm/runtime/pinvoke.c +#include "wasm-config.h" +#include "pinvoke.h" + +#include +#include + +/* + * The table header contain autogenerated function declarations, so avoid including standard headers + * to avoid incompatible declarations. + */ +#define NULL ((void*)0) +int strcmp (const char *s1, const char *s2); +void mono_wasm_printerr (const char *s); + +#ifdef GEN_PINVOKE +#include "pinvoke-table.h" +#else +#include "pinvoke-tables-default.h" +#endif + +void +mono_wasm_pinvoke_vararg_stub (void) +{ + /* This is just a stub used to mark vararg pinvokes */ +} + +void* +wasm_dl_lookup_pinvoke_table (const char *name) +{ + for (int i = 0; i < sizeof (pinvoke_tables) / sizeof (void*); ++i) { + if (!strcmp (name, pinvoke_names [i])) + return pinvoke_tables [i]; + } + return NULL; +} + +int +wasm_dl_is_pinvoke_table (void *handle) +{ + for (int i = 0; i < sizeof (pinvoke_tables) / sizeof (void*); ++i) { + if (pinvoke_tables [i] == handle) { + return 1; + } + } + return 0; +} + +void* +wasm_dl_get_native_to_interp (const char *key, void *extra_arg) +{ +#ifdef GEN_PINVOKE + for (int i = 0; i < sizeof (wasm_native_to_interp_map) / sizeof (void*); ++i) { + if (!strcmp (wasm_native_to_interp_map [i], key)) { + void *addr = wasm_native_to_interp_funcs [i]; + wasm_native_to_interp_ftndescs [i] = *(InterpFtnDesc*)extra_arg; + return addr; + } + } + return NULL; +#else + return NULL; +#endif +} diff --git a/src/mono/wasi/mono-wasi-driver/stubs.c b/src/mono/wasi/runtime/stubs.c similarity index 100% rename from src/mono/wasi/mono-wasi-driver/stubs.c rename to src/mono/wasi/runtime/stubs.c diff --git a/src/mono/wasi/mono-wasi-driver/synthetic-pthread.c b/src/mono/wasi/runtime/synthetic-pthread.c similarity index 100% rename from src/mono/wasi/mono-wasi-driver/synthetic-pthread.c rename to src/mono/wasi/runtime/synthetic-pthread.c diff --git a/src/mono/wasi/sample/.gitignore b/src/mono/wasi/sample/.gitignore deleted file mode 100644 index 19e1bced9ad8a5..00000000000000 --- a/src/mono/wasi/sample/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.wasm diff --git a/src/mono/wasi/sample/Directory.Build.props b/src/mono/wasi/sample/Directory.Build.props deleted file mode 100644 index 69b70ee868b5a6..00000000000000 --- a/src/mono/wasi/sample/Directory.Build.props +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - bin/$(Configuration)/net7.0 - - diff --git a/src/mono/wasi/sample/SampleMakefile.variable b/src/mono/wasi/sample/SampleMakefile.variable deleted file mode 100644 index 99f7e6916e9cdc..00000000000000 --- a/src/mono/wasi/sample/SampleMakefile.variable +++ /dev/null @@ -1,20 +0,0 @@ -TOP=$(realpath $(CURDIR)/../../../../..) - -COMPILE_FLAGS=\ - $(WASI_BIN_DIR)/*.a \ - $(BROWSER_WASM_RUNTIME_PATH)/native/libSystem.Native.a \ - --sysroot=$(WASI_SDK_ROOT)/share/wasi-sysroot \ - -I$(TOP)/src/mono -I$(TOP)/src/native/public - -LINK_FLAGS=\ - -Wl,--export=malloc,--export=free,--export=__heap_base,--export=__data_end \ - -Wl,-z,stack-size=1048576,--initial-memory=5242880,--max-memory=52428800,-lwasi-emulated-mman - -ifndef DOTNET_ROOT -DOTNET_ROOT=$(TOP)/.dotnet -echo "DOTNET_ROOT is undefined. Example: export DOTNET_ROOT=~/dotnet7. Defaulting to $(DOTNET_ROOT) -endif -ifndef BROWSER_WASM_RUNTIME_PATH -BROWSER_WASM_RUNTIME_PATH=$(TOP)/artifacts/bin/microsoft.netcore.app.runtime.browser-wasm/$(CONFIG)/runtimes/browser-wasm -echo "BROWSER_WASM_RUNTIME_PATH is undefined. Example: export BROWSER_WASM_RUNTIME_PATH=$(DOTNET_ROOT)/packs/Microsoft.NETCore.App.Runtime.Mono.browser-wasm/7.0.0-alpha.1.22061.11/runtimes/browser-wasm). Defaulting to $(BROWSER_WASM_RUNTIME_PATH)" -endif diff --git a/src/mono/wasi/sample/console/Makefile b/src/mono/wasi/sample/console/Makefile deleted file mode 100644 index b4d731f9d3f37b..00000000000000 --- a/src/mono/wasi/sample/console/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -include ../../Makefile.variable -include ../SampleMakefile.variable - -BIN_DIR=WasiConsoleApp/bin/Debug/net7.0 - -all: console.wasm $(BIN_DIR)/WasiConsoleApp.dll - -run: all - @(which wasmtime || PATH=$(WASMTIME_DIR):${PATH} which wasmtime); \ - test "$$?" -ne 0 \ - && echo "wasmtime not found. Either install that yourself, or use 'make provision-deps' to install one." \ - || PATH=$(WASMTIME_DIR):${PATH} wasmtime --dir=. console.wasm - -run-wasmer: all - wasmer --dir=. console.wasm - -console.wasm: main.c - $(WASI_SDK_CLANG) main.c -o console.wasm $(COMPILE_FLAGS) $(LINK_FLAGS) - -$(BIN_DIR)/WasiConsoleApp.dll: WasiConsoleApp/*.csproj WasiConsoleApp/*.cs - find $(BROWSER_WASM_RUNTIME_PATH) -type f - cd WasiConsoleApp && $(DOTNET_ROOT)/dotnet build -c Debug - touch $(BIN_DIR)/*.dll - cp -R $(BROWSER_WASM_RUNTIME_PATH) $(BIN_DIR)/runtime - -debug: all -#wasmtime has a bug when passing --tcplisten and --dir, to make it work we should use this PR https://github.com/bytecodealliance/wasmtime/pull/3995 and then the fd of the socket will be 4. - PATH=$(WASMTIME_DIR):${PATH} wasmtime --tcplisten localhost:64000 --dir=. console.wasm --env DEBUGGER_FD=4 diff --git a/src/mono/wasi/sample/console/WasiConsoleApp/Program.cs b/src/mono/wasi/sample/console/WasiConsoleApp/Program.cs deleted file mode 100644 index 83a7facbcf64d4..00000000000000 --- a/src/mono/wasi/sample/console/WasiConsoleApp/Program.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace WasiConsoleApp -{ - public class Program - { - public static int Main() - { - Console.WriteLine($"Hello from .NET at {DateTime.Now.ToLongTimeString()}"); - return 0; - } - } -} diff --git a/src/mono/wasi/sample/console/WasiConsoleApp/WasiConsoleApp.csproj b/src/mono/wasi/sample/console/WasiConsoleApp/WasiConsoleApp.csproj deleted file mode 100644 index 2e577472d68606..00000000000000 --- a/src/mono/wasi/sample/console/WasiConsoleApp/WasiConsoleApp.csproj +++ /dev/null @@ -1,10 +0,0 @@ - - - - Exe - net7.0 - true - embedded - - - diff --git a/src/mono/wasi/sample/console/main.c b/src/mono/wasi/sample/console/main.c deleted file mode 100644 index 8647c4878f2aba..00000000000000 --- a/src/mono/wasi/sample/console/main.c +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include "../../mono-wasi-driver/driver.h" - -int main() { - // Assume the runtime pack has been copied into the output directory as 'runtime' - // Otherwise we have to mount an unrelated part of the filesystem within the WASM environment - const char* app_base_dir = "./WasiConsoleApp/bin/Debug/net7.0"; - char* assemblies_path; - asprintf(&assemblies_path, "%s:%s/runtime/native:%s/runtime/lib/net7.0", app_base_dir, app_base_dir, app_base_dir); - - add_assembly(app_base_dir, "WasiConsoleApp.dll"); - mono_set_assemblies_path(assemblies_path); - - mono_wasm_load_runtime("", 0); - - MonoAssembly* assembly = mono_wasm_assembly_load ("WasiConsoleApp.dll"); - MonoMethod* entry_method = mono_wasm_assembly_get_entry_point (assembly); - MonoObject* out_exc; - MonoObject *exit_code = mono_wasm_invoke_method (entry_method, NULL, NULL, &out_exc); - return mono_unbox_int (exit_code); -} diff --git a/src/mono/wasi/wasi-sdk-version.txt b/src/mono/wasi/wasi-sdk-version.txt new file mode 100644 index 00000000000000..19c7bdba7b1e9b --- /dev/null +++ b/src/mono/wasi/wasi-sdk-version.txt @@ -0,0 +1 @@ +16 \ No newline at end of file diff --git a/src/mono/wasi/wasmtime-version.txt b/src/mono/wasi/wasmtime-version.txt new file mode 100644 index 00000000000000..56fea8a08d2faa --- /dev/null +++ b/src/mono/wasi/wasmtime-version.txt @@ -0,0 +1 @@ +3.0.0 \ No newline at end of file diff --git a/src/native/libs/System.Native/pal_console.c b/src/native/libs/System.Native/pal_console.c index d217075e5a276b..e7ce2a7e13a7c6 100644 --- a/src/native/libs/System.Native/pal_console.c +++ b/src/native/libs/System.Native/pal_console.c @@ -13,10 +13,14 @@ #include #include #include +#if HAVE_TERMIOS_H #include +#endif #include #include +#if HAVE_PTHREAD_H #include +#endif #include int32_t SystemNative_GetWindowSize(WinSize* windowSize) @@ -87,6 +91,7 @@ void SystemNative_SetKeypadXmit(const char* terminfoString) WriteKeypadXmit(); } +#if !defined(TARGET_WASI) static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER; // prevents races when initializing and changing the terminal. static bool g_signalForBreak = true; // tracks whether the terminal should send signals for breaks, such that attributes have been changed @@ -225,9 +230,11 @@ void UninitializeTerminal(void) pthread_mutex_unlock(&g_lock); } } +#endif /* TARGET_WASI */ void SystemNative_InitializeConsoleBeforeRead(uint8_t minChars, uint8_t decisecondsTimeout) { +#if !defined(TARGET_WASI) if (pthread_mutex_lock(&g_lock) == 0) { g_reading = true; @@ -236,20 +243,24 @@ void SystemNative_InitializeConsoleBeforeRead(uint8_t minChars, uint8_t deciseco pthread_mutex_unlock(&g_lock); } +#endif /* TARGET_WASI */ } void SystemNative_UninitializeConsoleAfterRead(void) { +#if !defined(TARGET_WASI) if (pthread_mutex_lock(&g_lock) == 0) { g_reading = false; pthread_mutex_unlock(&g_lock); } +#endif /* TARGET_WASI */ } void SystemNative_ConfigureTerminalForChildProcess(int32_t childUsesTerminal) { +#if !defined(TARGET_WASI) assert(childUsesTerminal == 0 || childUsesTerminal == 1); if (pthread_mutex_lock(&g_lock) == 0) @@ -281,8 +292,10 @@ void SystemNative_ConfigureTerminalForChildProcess(int32_t childUsesTerminal) pthread_mutex_unlock(&g_lock); } +#endif /* TARGET_WASI */ } +#if !defined(TARGET_WASI) static int TranslatePalControlCharacterName(int name) { switch (name) @@ -341,6 +354,7 @@ static int TranslatePalControlCharacterName(int name) default: return -1; } } +#endif /* TARGET_WASI */ void SystemNative_GetControlCharacters( int32_t* controlCharacterNames, uint8_t* controlCharacterValues, int32_t controlCharacterLength, @@ -359,6 +373,7 @@ void SystemNative_GetControlCharacters( memset(controlCharacterValues, *posixDisableValue, sizeof(uint8_t) * Int32ToSizeT(controlCharacterLength)); +#if HAVE_TERMIOS_H if (controlCharacterLength > 0) { struct termios newTermios; @@ -376,6 +391,7 @@ void SystemNative_GetControlCharacters( } } } +#endif } int32_t SystemNative_StdinReady(void) @@ -405,13 +421,18 @@ int32_t SystemNative_ReadStdin(void* buffer, int32_t bufferSize) int32_t SystemNative_GetSignalForBreak(void) { +#if !defined(TARGET_WASI) return g_signalForBreak; +#else /* TARGET_WASI */ + return false; +#endif /* TARGET_WASI */ } int32_t SystemNative_SetSignalForBreak(int32_t signalForBreak) { assert(signalForBreak == 0 || signalForBreak == 1); +#if !defined(TARGET_WASI) int rv = 0; if (pthread_mutex_lock(&g_lock) == 0) @@ -426,6 +447,9 @@ int32_t SystemNative_SetSignalForBreak(int32_t signalForBreak) } return rv; +#else /* TARGET_WASI */ + return 0; +#endif /* TARGET_WASI */ } void ReinitializeTerminal(void) @@ -433,6 +457,7 @@ void ReinitializeTerminal(void) // Restores the state of the terminal after being suspended. // pal_signal.cpp calls this on SIGCONT from the signal handling thread. +#if !defined(TARGET_WASI) if (pthread_mutex_lock(&g_lock) == 0) { if (!g_childUsesTerminal) @@ -447,8 +472,10 @@ void ReinitializeTerminal(void) pthread_mutex_unlock(&g_lock); } +#endif /* TARGET_WASI */ } +#if !defined(TARGET_WASI) static void InitializeTerminalCore(void) { bool haveInitTermios = tcgetattr(STDIN_FILENO, &g_initTermios) >= 0; @@ -467,9 +494,11 @@ static void InitializeTerminalCore(void) g_signalForBreak = true; } } +#endif /* TARGET_WASI */ int32_t SystemNative_InitializeTerminalAndSignalHandling(void) { +#if !defined(TARGET_WASI) static int32_t initialized = 0; // The Process, Console and PosixSignalRegistration classes call this method for initialization. @@ -484,4 +513,7 @@ int32_t SystemNative_InitializeTerminalAndSignalHandling(void) } return initialized; +#else /* TARGET_WASI */ + return true; +#endif /* TARGET_WASI */ } diff --git a/src/native/libs/System.Native/pal_dynamicload.c b/src/native/libs/System.Native/pal_dynamicload.c index 76f9c56678af5c..9025b10f43f16f 100644 --- a/src/native/libs/System.Native/pal_dynamicload.c +++ b/src/native/libs/System.Native/pal_dynamicload.c @@ -4,8 +4,11 @@ #include "pal_config.h" #include "pal_dynamicload.h" +#if HAVE_DLFCN_H #include +#endif #include +#include #if HAVE_GNU_LIBNAMES_H #include @@ -13,6 +16,7 @@ void* SystemNative_LoadLibrary(const char* filename) { +#if !defined(TARGET_WASI) // Check whether we have been requested to load 'libc'. If that's the case, then: // * For Linux, use the full name of the library that is defined in by the // LIBC_SO constant. The problem is that calling dlopen("libc.so") will fail for libc even @@ -36,26 +40,45 @@ void* SystemNative_LoadLibrary(const char* filename) } return dlopen(filename, RTLD_LAZY); +#else /* TARGET_WASI */ + return NULL; +#endif /* TARGET_WASI */ } void* SystemNative_GetLoadLibraryError(void) { +#if !defined(TARGET_WASI) return dlerror(); +#else /* TARGET_WASI */ + return NULL; +#endif /* TARGET_WASI */ } void* SystemNative_GetProcAddress(void* handle, const char* symbol) { +#if !defined(TARGET_WASI) // We're not trying to disambiguate between "symbol was not found" and "symbol found, but // the value is null". .NET does not define a behavior for DllImports of null entrypoints, // so we might as well take the "not found" path on the managed side. return dlsym(handle, symbol); +#else /* TARGET_WASI */ + return NULL; +#endif /* TARGET_WASI */ } void SystemNative_FreeLibrary(void* handle) { +#if !defined(TARGET_WASI) dlclose(handle); +#endif /* TARGET_WASI */ } +#if defined TARGET_WASI +void* SystemNative_GetDefaultSearchOrderPseudoHandle(void) +{ + return NULL; +} +#else static void* volatile g_defaultSearchOrderPseudoHandle = NULL; void* SystemNative_GetDefaultSearchOrderPseudoHandle(void) { @@ -76,3 +99,4 @@ void* SystemNative_GetDefaultSearchOrderPseudoHandle(void) } return defaultSearchOrderPseudoHandle; } +#endif diff --git a/src/native/libs/System.Native/pal_interfaceaddresses.c b/src/native/libs/System.Native/pal_interfaceaddresses.c index 4af5d59ae96db9..8fee3e0e3e9649 100644 --- a/src/native/libs/System.Native/pal_interfaceaddresses.c +++ b/src/native/libs/System.Native/pal_interfaceaddresses.c @@ -15,11 +15,17 @@ #include #endif #ifdef ANDROID_GETIFADDRS_WORKAROUND +#if HAVE_DLFCN_H #include +#endif +#if HAVE_PTHREAD_H #include +#endif #include "pal_ifaddrs.h" // fallback for Android API 21-23 #endif +#if HAVE_NET_IF_H #include +#endif #include #include #include @@ -50,6 +56,7 @@ #elif defined(AF_LINK) #include #include +#elif defined(TARGET_WASI) #else #error System must have AF_PACKET or AF_LINK. #endif @@ -66,6 +73,7 @@ // mask parameter is pointer to buffer where address starts and length is // buffer length e.g. 4 for IPv4 and 16 for IPv6. // Code bellow counts consecutive number of 1 bits. +#if !defined(TARGET_WASI) static inline uint8_t mask2prefix(uint8_t* mask, int length) { uint8_t len = 0; @@ -101,6 +109,7 @@ static inline uint8_t mask2prefix(uint8_t* mask, int length) return len; } +#endif /* TARGET_WASI */ #ifdef ANDROID_GETIFADDRS_WORKAROUND // This workaround is necessary as long as we support Android API 21-23 and it can be removed once diff --git a/src/native/libs/System.Native/pal_io.c b/src/native/libs/System.Native/pal_io.c index 0929a0b49ecf42..f696e3cba0ab61 100644 --- a/src/native/libs/System.Native/pal_io.c +++ b/src/native/libs/System.Native/pal_io.c @@ -26,8 +26,12 @@ #include #endif #include +#if HAVE_SYSLOG_H #include +#endif +#if HAVE_TERMIOS_H #include +#endif #include #include #if HAVE_FCOPYFILE @@ -42,7 +46,7 @@ #include #elif HAVE_STATFS_MOUNT // BSD #include -#elif !HAVE_NON_LEGACY_STATFS // SunOS +#elif HAVE_SYS_STATVFS_H && !HAVE_NON_LEGACY_STATFS // SunOS #include #include #include @@ -70,7 +74,7 @@ extern int getpeereid(int, uid_t *__restrict__, gid_t *__restrict__); // Ensure FICLONE is defined for all Linux builds. #ifndef FICLONE #define FICLONE _IOW(0x94, 9, int) -#endif +#endif /* __linux__ */ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wreserved-id-macro" @@ -97,12 +101,13 @@ extern int getpeereid(int, uid_t *__restrict__, gid_t *__restrict__); #define stat_ stat64 #define fstat_ fstat64 #define lstat_ lstat64 -#else +#else /* HAVE_STAT64 */ #define stat_ stat #define fstat_ fstat #define lstat_ lstat -#endif +#endif /* HAVE_STAT64 */ +#if !defined(TARGET_WASI) // These numeric values are specified by POSIX. // Validate that our definitions match. c_static_assert(PAL_S_IRWXU == S_IRWXU); @@ -132,6 +137,7 @@ c_static_assert(PAL_S_IFDIR == S_IFDIR); c_static_assert(PAL_S_IFREG == S_IFREG); c_static_assert(PAL_S_IFLNK == S_IFLNK); c_static_assert(PAL_S_IFSOCK == S_IFSOCK); +#endif /* TARGET_WASI */ // Validate that our enum for inode types is the same as what is // declared by the dirent.h header on the local system. @@ -139,7 +145,7 @@ c_static_assert(PAL_S_IFSOCK == S_IFSOCK); // WebAssembly (BROWSER) has dirent d_type but is not correct // by returning UNKNOWN the managed code properly stats the file // to detect if entry is directory or not. -#if defined(DT_UNKNOWN) || defined(TARGET_WASM) +#if (defined(DT_UNKNOWN) || defined(TARGET_WASM)) && !defined(TARGET_WASI) c_static_assert((int)PAL_DT_UNKNOWN == (int)DT_UNKNOWN); c_static_assert((int)PAL_DT_FIFO == (int)DT_FIFO); c_static_assert((int)PAL_DT_CHR == (int)DT_CHR); @@ -341,10 +347,13 @@ intptr_t SystemNative_Dup(intptr_t oldfd) int result; #if HAVE_F_DUPFD_CLOEXEC while ((result = fcntl(ToFileDescriptor(oldfd), F_DUPFD_CLOEXEC, 0)) < 0 && errno == EINTR); -#else +#elif HAVE_F_DUPFD while ((result = fcntl(ToFileDescriptor(oldfd), F_DUPFD, 0)) < 0 && errno == EINTR); // do CLOEXEC here too fcntl(result, F_SETFD, FD_CLOEXEC); +#else + // https://github.com/bytecodealliance/wasmtime/blob/main/docs/WASI-rationale.md#why-no-dup + result = oldfd; #endif return result; } @@ -570,7 +579,7 @@ int32_t SystemNative_Pipe(int32_t pipeFds[2], int32_t flags) #if HAVE_PIPE2 // If pipe2 is available, use it. This will handle O_CLOEXEC if it was set. while ((result = pipe2(pipeFds, flags)) < 0 && errno == EINTR); -#else +#elif HAVE_PIPE // Otherwise, use pipe. while ((result = pipe(pipeFds)) < 0 && errno == EINTR); @@ -595,7 +604,9 @@ int32_t SystemNative_Pipe(int32_t pipeFds[2], int32_t flags) errno = tmpErrno; } } -#endif +#else /* HAVE_PIPE */ + result = -1; +#endif /* HAVE_PIPE */ return result; } @@ -695,16 +706,24 @@ int32_t SystemNative_MkDir(const char* path, int32_t mode) int32_t SystemNative_ChMod(const char* path, int32_t mode) { +#if HAVE_CHMOD int32_t result; while ((result = chmod(path, (mode_t)mode)) < 0 && errno == EINTR); return result; +#else /* HAVE_CHMOD */ + return EINTR; +#endif /* HAVE_CHMOD */ } int32_t SystemNative_FChMod(intptr_t fd, int32_t mode) { +#if HAVE_FCHMOD int32_t result; while ((result = fchmod(ToFileDescriptor(fd), (mode_t)mode)) < 0 && errno == EINTR); return result; +#else /* HAVE_FCHMOD */ + return EINTR; +#endif /* HAVE_FCHMOD */ } int32_t SystemNative_FSync(intptr_t fd) @@ -725,7 +744,11 @@ int32_t SystemNative_FSync(intptr_t fd) int32_t SystemNative_FLock(intptr_t fd, int32_t operation) { int32_t result; +#if !defined(TARGET_WASI) while ((result = flock(ToFileDescriptor(fd), operation)) < 0 && errno == EINTR); +#else /* TARGET_WASI */ + result = EINTR; +#endif /* TARGET_WASI */ return result; } @@ -748,12 +771,15 @@ int64_t SystemNative_LSeek(intptr_t fd, int64_t offset, int32_t whence) result = #if HAVE_LSEEK64 lseek64( + ToFileDescriptor(fd), + (off_t)offset, + whence)) < 0 && errno == EINTR); #else lseek( -#endif ToFileDescriptor(fd), (off_t)offset, whence)) < 0 && errno == EINTR); +#endif return result; } @@ -773,32 +799,50 @@ int32_t SystemNative_SymLink(const char* target, const char* linkPath) void SystemNative_GetDeviceIdentifiers(uint64_t dev, uint32_t* majorNumber, uint32_t* minorNumber) { +#if !defined(TARGET_WASI) dev_t castedDev = (dev_t)dev; *majorNumber = (uint32_t)major(castedDev); *minorNumber = (uint32_t)minor(castedDev); +#else /* TARGET_WASI */ + dev_t castedDev = (dev_t)dev; + *majorNumber = 0; + *minorNumber = 0; +#endif /* TARGET_WASI */ } int32_t SystemNative_MkNod(const char* pathName, uint32_t mode, uint32_t major, uint32_t minor) { +#if !defined(TARGET_WASI) dev_t dev = (dev_t)makedev(major, minor); int32_t result; while ((result = mknod(pathName, (mode_t)mode, dev)) < 0 && errno == EINTR); return result; +#else /* TARGET_WASI */ + return EINTR; +#endif /* TARGET_WASI */ } int32_t SystemNative_MkFifo(const char* pathName, uint32_t mode) { +#if !defined(TARGET_WASI) int32_t result; while ((result = mkfifo(pathName, (mode_t)mode)) < 0 && errno == EINTR); return result; +#else /* TARGET_WASI */ + return EINTR; +#endif /* TARGET_WASI */ } char* SystemNative_MkdTemp(char* pathTemplate) { +#if !defined(TARGET_WASI) char* result = NULL; while ((result = mkdtemp(pathTemplate)) == NULL && errno == EINTR); return result; +#else /* TARGET_WASI */ + return NULL; +#endif /* TARGET_WASI */ } intptr_t SystemNative_MksTemps(char* pathTemplate, int32_t suffixLength) @@ -840,6 +884,8 @@ intptr_t SystemNative_MksTemps(char* pathTemplate, int32_t suffixLength) { pathTemplate[firstSuffixIndex] = firstSuffixChar; } +#elif TARGET_WASI + result = -1; #else #error "Cannot find mkstemps nor mkstemp on this platform" #endif @@ -976,7 +1022,7 @@ int32_t SystemNative_MAdvise(void* address, uint64_t length, int32_t advice) switch (advice) { case PAL_MADV_DONTFORK: -#ifdef MADV_DONTFORK +#if defined(MADV_DONTFORK) && !defined(TARGET_WASI) return madvise(address, (size_t)length, MADV_DONTFORK); #else (void)address, (void)length, (void)advice; @@ -1005,7 +1051,11 @@ int32_t SystemNative_MSync(void* address, uint64_t length, int32_t flags) return -1; } +#if !defined(TARGET_WASI) return msync(address, (size_t)length, flags); +#else + return -1; +#endif } int64_t SystemNative_SysConf(int32_t name) @@ -1145,7 +1195,9 @@ int32_t SystemNative_RmDir(const char* path) void SystemNative_Sync(void) { +#if !defined(TARGET_WASI) sync(); +#endif /* TARGET_WASI */ } int32_t SystemNative_Write(intptr_t fd, const void* buffer, int32_t bufferSize) @@ -1369,6 +1421,7 @@ int32_t SystemNative_CopyFile(intptr_t sourceFd, intptr_t destinationFd, int64_t return -1; } +#if HAVE_FCHMOD // Copy permissions. // Even though managed code created the file with permissions matching those of the source file, // we need to copy permissions because the open permissions may be filtered by 'umask'. @@ -1377,6 +1430,7 @@ int32_t SystemNative_CopyFile(intptr_t sourceFd, intptr_t destinationFd, int64_t { return -1; } +#endif /* HAVE_FCHMOD */ return 0; #endif // HAVE_FCOPYFILE @@ -1458,9 +1512,14 @@ int32_t SystemNative_GetPeerID(intptr_t socket, uid_t* euid) char* SystemNative_RealPath(const char* path) { assert(path != NULL); +#if !defined(TARGET_WASI) return realpath(path, NULL); +#else /* TARGET_WASI */ + return NULL; +#endif /* TARGET_WASI */ } +#if !defined(TARGET_WASI) static int16_t ConvertLockType(int16_t managedLockType) { // the managed enum Interop.Sys.LockType has no 1:1 mapping with corresponding Unix values @@ -1614,6 +1673,7 @@ static uint32_t MapFileSystemNameToEnum(const char* fileSystemName) return result; } #endif +#endif /* TARGET_WASI */ uint32_t SystemNative_GetFileSystemType(intptr_t fd) { @@ -1634,6 +1694,8 @@ uint32_t SystemNative_GetFileSystemType(intptr_t fd) uint32_t result = (uint32_t)statfsArgs.f_type; return result; #endif +#elif defined(TARGET_WASI) + return EINTR; #elif !HAVE_NON_LEGACY_STATFS int statfsRes; struct statvfs statfsArgs; @@ -1648,6 +1710,7 @@ uint32_t SystemNative_GetFileSystemType(intptr_t fd) int32_t SystemNative_LockFileRegion(intptr_t fd, int64_t offset, int64_t length, int16_t lockType) { +#if !defined(TARGET_WASI) int16_t unixLockType = ConvertLockType(lockType); if (offset < 0 || length < 0) { @@ -1677,6 +1740,9 @@ int32_t SystemNative_LockFileRegion(intptr_t fd, int64_t offset, int64_t length, int32_t ret; while ((ret = fcntl (ToFileDescriptor(fd), command, &lockArgs)) < 0 && errno == EINTR); return ret; +#else /* TARGET_WASI */ + return EINTR; +#endif /* TARGET_WASI */ } int32_t SystemNative_LChflags(const char* path, uint32_t flags) @@ -1856,3 +1922,4 @@ int64_t SystemNative_PWriteV(intptr_t fd, IOVector* vectors, int32_t vectorCount assert(count >= -1); return count; } + diff --git a/src/native/libs/System.Native/pal_maphardwaretype.c b/src/native/libs/System.Native/pal_maphardwaretype.c index 064d802e6d6a83..2a37864b1eaaf9 100644 --- a/src/native/libs/System.Native/pal_maphardwaretype.c +++ b/src/native/libs/System.Native/pal_maphardwaretype.c @@ -21,6 +21,7 @@ #elif defined(AF_LINK) #include #include +#elif defined(TARGET_WASI) #else #error System must have AF_PACKET or AF_LINK. #endif @@ -112,5 +113,8 @@ uint16_t MapHardwareType(uint16_t nativeType) default: return NetworkInterfaceType_Unknown; } +#elif defined(TARGET_WASI) + // TODOWASI + return NetworkInterfaceType_Unknown; #endif } diff --git a/src/native/libs/System.Native/pal_mount.c b/src/native/libs/System.Native/pal_mount.c index 2453bdfe9ede3f..269a1c1cae026d 100644 --- a/src/native/libs/System.Native/pal_mount.c +++ b/src/native/libs/System.Native/pal_mount.c @@ -12,22 +12,27 @@ // Check if we should use getmntinfo or /proc/mounts #if HAVE_MNTINFO #include -#else +#else /* HAVE_MNTINFO */ +#if HAVE_STATFS #include +#endif /* HAVE_STATFS */ #if HAVE_SYS_MNTENT_H #include #include +#if HAVE_SYS_STATVFS_H #include -#else +#endif /* HAVE_SYS_STATVFS_H */ +#else /* HAVE_SYS_MNTENT_H */ +#if HAVE_MNTENT_H #include -#endif #define STRING_BUFFER_SIZE 8192 - // Android does not define MNTOPT_RO #ifndef MNTOPT_RO #define MNTOPT_RO "r" -#endif -#endif +#endif /* MNTOPT_RO */ +#endif /* HAVE_MNTENT_H */ +#endif /* HAVE_SYS_MNTENT_H */ +#endif /* HAVE_MNTINFO */ int32_t SystemNative_GetAllMountPoints(MountPointFound onFound, void* context) { @@ -68,7 +73,7 @@ int32_t SystemNative_GetAllMountPoints(MountPointFound onFound, void* context) return result; } -#else +#elif HAVE_MNTENT_H int result = -1; FILE* fp = setmntent("/proc/mounts", MNTOPT_RO); if (fp != NULL) @@ -90,6 +95,9 @@ int32_t SystemNative_GetAllMountPoints(MountPointFound onFound, void* context) return result; } +#else + return -1; +} #endif @@ -103,12 +111,15 @@ int32_t SystemNative_GetSpaceInfoForMountPoint(const char* name, MountPointInfor memset(&stats, 0, sizeof(struct statfs)); int result = statfs(name, &stats); -#else +#elif HAVE_MNTENT_H struct statvfs stats; memset(&stats, 0, sizeof(struct statvfs)); int result = statvfs(name, &stats); +#else + return -1; #endif +#if HAVE_NON_LEGACY_STATFS || HAVE_MNTENT_H if (result == 0) { // Note that these have signed integer types on some platforms but mustn't be negative. @@ -129,6 +140,7 @@ int32_t SystemNative_GetSpaceInfoForMountPoint(const char* name, MountPointInfor } return result; +#endif /* HAVE_NON_LEGACY_STATFS || HAVE_MNTENT_H */ } int32_t @@ -140,9 +152,11 @@ SystemNative_GetFormatInfoForMountPoint(const char* name, char* formatNameBuffer #if HAVE_NON_LEGACY_STATFS struct statfs stats; int result = statfs(name, &stats); -#else +#elif HAVE_MNTENT_H struct statvfs stats; int result = statvfs(name, &stats); +#else + int result = -1; #endif if (result == 0) { diff --git a/src/native/libs/System.Native/pal_networkchange.c b/src/native/libs/System.Native/pal_networkchange.c index b4386a762f3f08..56391820123dd0 100644 --- a/src/native/libs/System.Native/pal_networkchange.c +++ b/src/native/libs/System.Native/pal_networkchange.c @@ -9,7 +9,9 @@ #include "pal_utilities.h" #include +#if HAVE_NET_IF_H #include +#endif #include #include #include diff --git a/src/native/libs/System.Native/pal_networking.c b/src/native/libs/System.Native/pal_networking.c index e6413d276e4b50..79b6dd9ca96f37 100644 --- a/src/native/libs/System.Native/pal_networking.c +++ b/src/native/libs/System.Native/pal_networking.c @@ -10,7 +10,9 @@ #include #include +#if HAVE_PTHREAD_H #include +#endif #include #include #include @@ -30,7 +32,9 @@ #include #include #include +#if HAVE_NET_IF_H #include +#endif #include #include #include @@ -47,7 +51,9 @@ #include #endif #include +#if HAVE_PWD_H #include +#endif #if HAVE_SENDFILE_4 #include #elif HAVE_SENDFILE_6 @@ -112,7 +118,7 @@ static uint16_t GetKeventFlags(uint32_t flags) #endif #endif -#if !HAVE_IN_PKTINFO +#if !HAVE_IN_PKTINFO && !IP_PKTINFO // On platforms, such as FreeBSD, where in_pktinfo // is not available, fallback to custom definition // with required members. @@ -131,6 +137,7 @@ struct in_pktinfo #define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP #endif +#if !defined(TARGET_WASI) enum { #if defined(__APPLE__) && __APPLE__ @@ -139,18 +146,21 @@ enum LINGER_OPTION_NAME = SO_LINGER, #endif }; +#endif /* TARGET_WASI */ enum { INET6_ADDRSTRLEN_MANAGED = 65 // Managed code has a longer max IPv6 string length }; +#if !defined(TARGET_WASI) c_static_assert(GetHostErrorCodes_HOST_NOT_FOUND == HOST_NOT_FOUND); c_static_assert(GetHostErrorCodes_TRY_AGAIN == TRY_AGAIN); c_static_assert(GetHostErrorCodes_NO_RECOVERY == NO_RECOVERY); c_static_assert(GetHostErrorCodes_NO_DATA == NO_DATA); c_static_assert(GetHostErrorCodes_NO_ADDRESS == NO_ADDRESS); c_static_assert(sizeof(uint8_t) == sizeof(char)); // We make casts from uint8_t to char so make sure it's legal +#endif /* TARGET_WASI */ // sizeof_member(struct foo, bar) is not valid C++. // The fix is to remove struct. That is not valid C. @@ -262,6 +272,7 @@ static void ConvertByteArrayToSockAddrIn6(struct sockaddr_in6* addr, const uint8 // Mark that this is INET6 addr->sin6_family = AF_INET6; } +#if !defined(TARGET_WASI) static void ConvertByteArrayToInAddr(struct in_addr* addr, const uint8_t* buffer, int32_t bufferLength) { @@ -288,19 +299,29 @@ static int32_t ConvertGetAddrInfoAndGetNameInfoErrorsToPal(int32_t error) { case 0: return 0; +#ifdef EAI_AGAIN case EAI_AGAIN: return GetAddrInfoErrorFlags_EAI_AGAIN; +#endif +#ifdef EAI_BADFLAGS case EAI_BADFLAGS: return GetAddrInfoErrorFlags_EAI_BADFLAGS; +#endif #ifdef EAI_FAIL case EAI_FAIL: return GetAddrInfoErrorFlags_EAI_FAIL; #endif +#ifdef EAI_FAMILY case EAI_FAMILY: return GetAddrInfoErrorFlags_EAI_FAMILY; +#endif +#ifdef EAI_MEMORY case EAI_MEMORY: return GetAddrInfoErrorFlags_EAI_MEMORY; +#endif +#ifdef EAI_NONAME case EAI_NONAME: +#endif #ifdef EAI_NODATA case EAI_NODATA: #endif @@ -333,6 +354,7 @@ static int32_t CopySockAddrToIPAddress(sockaddr* addr, sa_family_t family, IPAdd return -1; } +#endif /* TARGET_WASI */ int32_t SystemNative_GetHostEntryForName(const uint8_t* address, int32_t addressFamily, HostEntry* entry) { @@ -340,6 +362,7 @@ int32_t SystemNative_GetHostEntryForName(const uint8_t* address, int32_t address { return GetAddrInfoErrorFlags_EAI_BADARG; } +#if !defined(TARGET_WASI) int32_t ret = GetAddrInfoErrorFlags_EAI_SUCCESS; @@ -516,6 +539,9 @@ int32_t SystemNative_GetHostEntryForName(const uint8_t* address, int32_t address } return ret; +#else /* TARGET_WASI */ + return -1; +#endif /* TARGET_WASI */ } void SystemNative_FreeHostEntry(HostEntry* entry) @@ -538,6 +564,7 @@ typedef int32_t NativeFlagsType; typedef uint32_t NativeFlagsType; #endif +#if !defined(TARGET_WASI) static inline NativeFlagsType ConvertGetNameInfoFlagsToNative(int32_t flags) { NativeFlagsType outFlags = 0; @@ -552,6 +579,7 @@ static inline NativeFlagsType ConvertGetNameInfoFlagsToNative(int32_t flags) return outFlags; } +#endif int32_t SystemNative_GetNameInfo(const uint8_t* address, int32_t addressLength, @@ -567,6 +595,7 @@ int32_t SystemNative_GetNameInfo(const uint8_t* address, assert((host != NULL) || (service != NULL)); assert((hostLength > 0) || (serviceLength > 0)); +#if !defined(TARGET_WASI) NativeFlagsType nativeFlags = ConvertGetNameInfoFlagsToNative(flags); int32_t result; @@ -598,6 +627,9 @@ int32_t SystemNative_GetNameInfo(const uint8_t* address, } return ConvertGetAddrInfoAndGetNameInfoErrorsToPal(result); +#else /* TARGET_WASI */ + return Error_EINVAL; +#endif /* TARGET_WASI */ } int32_t SystemNative_GetDomainName(uint8_t* name, int32_t nameLength) @@ -897,6 +929,7 @@ SystemNative_SetIPv6Address(uint8_t* socketAddress, int32_t socketAddressLen, ui return Error_SUCCESS; } +#if !defined(TARGET_WASI) static int8_t IsStreamSocket(int socket) { int type; @@ -923,15 +956,21 @@ static void ConvertMessageHeaderToMsghdr(struct msghdr* header, const MessageHea header->msg_controllen = (uint32_t)messageHeader->ControlBufferLen; header->msg_flags = 0; } +#endif /* TARGET_WASI */ int32_t SystemNative_GetControlMessageBufferSize(int32_t isIPv4, int32_t isIPv6) { +#if defined(CMSG_SPACE) // Note: it is possible that the address family of the socket is neither // AF_INET nor AF_INET6. In this case both inputs will be 0 and // the control message buffer size should be zero. return (isIPv4 != 0 ? CMSG_SPACE(sizeof(struct in_pktinfo)) : 0) + (isIPv6 != 0 ? CMSG_SPACE(sizeof(struct in6_pktinfo)) : 0); +#else /* CMSG_SPACE */ + return Error_EINVAL; +#endif /* CMSG_SPACE */ } +#if !defined(TARGET_WASI) static int32_t GetIPv4PacketInformation(struct cmsghdr* controlMessage, IPPacketInformation* packetInfo) { assert(controlMessage != NULL); @@ -1010,6 +1049,7 @@ static struct cmsghdr* GET_CMSG_NXTHDR(struct msghdr* mhdr, struct cmsghdr* cmsg #pragma clang diagnostic pop #endif } +#endif /* TARGET_WASI */ int32_t SystemNative_TryGetIPPacketInformation(MessageHeader* messageHeader, int32_t isIPv4, IPPacketInformation* packetInfo) @@ -1019,6 +1059,7 @@ SystemNative_TryGetIPPacketInformation(MessageHeader* messageHeader, int32_t isI return 0; } +#if !defined(TARGET_WASI) struct msghdr header; ConvertMessageHeaderToMsghdr(&header, messageHeader, -1); @@ -1047,6 +1088,9 @@ SystemNative_TryGetIPPacketInformation(MessageHeader* messageHeader, int32_t isI } return 0; +#else /* TARGET_WASI */ + return Error_EINVAL; +#endif /* TARGET_WASI */ } static int8_t GetMulticastOptionName(int32_t multicastOption, int8_t isIPv6, int* optionName) @@ -1116,6 +1160,7 @@ int32_t SystemNative_SetIPv4MulticastOption(intptr_t socket, int32_t multicastOp return Error_EFAULT; } +#if !defined(TARGET_WASI) int fd = ToFileDescriptor(socket); int optionName; @@ -1142,6 +1187,9 @@ int32_t SystemNative_SetIPv4MulticastOption(intptr_t socket, int32_t multicastOp #endif int err = setsockopt(fd, IPPROTO_IP, optionName, &opt, sizeof(opt)); return err == 0 ? Error_SUCCESS : SystemNative_ConvertErrorPlatformToPal(errno); +#else /* TARGET_WASI */ + return Error_EINVAL; +#endif /* TARGET_WASI */ } int32_t SystemNative_GetIPv6MulticastOption(intptr_t socket, int32_t multicastOption, IPv6MulticastOption* option) @@ -1178,6 +1226,7 @@ int32_t SystemNative_SetIPv6MulticastOption(intptr_t socket, int32_t multicastOp { return Error_EFAULT; } +#if !defined(TARGET_WASI) int fd = ToFileDescriptor(socket); @@ -1201,8 +1250,12 @@ int32_t SystemNative_SetIPv6MulticastOption(intptr_t socket, int32_t multicastOp int err = setsockopt(fd, IPPROTO_IPV6, optionName, &opt, sizeof(opt)); return err == 0 ? Error_SUCCESS : SystemNative_ConvertErrorPlatformToPal(errno); +#else /* TARGET_WASI */ + return Error_EINVAL; +#endif /* TARGET_WASI */ } +#if !defined(TARGET_WASI) #if defined(__APPLE__) && __APPLE__ static int32_t GetMaxLingerTime(void) { @@ -1239,6 +1292,7 @@ static int32_t GetMaxLingerTime(void) return Min(65535U, (1U << (sizeof_member(linger, l_linger) * 8 - 1)) - 1); } #endif +#endif /* TARGET_WASI */ int32_t SystemNative_GetLingerOption(intptr_t socket, LingerOption* option) { @@ -1247,6 +1301,7 @@ int32_t SystemNative_GetLingerOption(intptr_t socket, LingerOption* option) return Error_EFAULT; } +#if !defined(TARGET_WASI) int fd = ToFileDescriptor(socket); struct linger opt; @@ -1261,6 +1316,10 @@ int32_t SystemNative_GetLingerOption(intptr_t socket, LingerOption* option) option->OnOff = opt.l_onoff; option->Seconds = opt.l_linger; return Error_SUCCESS; +#else /* TARGET_WASI */ + memset(option, 0, sizeof(LingerOption)); + return Error_EINVAL; +#endif /* TARGET_WASI */ } int32_t SystemNative_SetLingerOption(intptr_t socket, LingerOption* option) @@ -1270,6 +1329,7 @@ int32_t SystemNative_SetLingerOption(intptr_t socket, LingerOption* option) return Error_EFAULT; } +#if !defined(TARGET_WASI) if (option->OnOff != 0 && (option->Seconds < 0 || option->Seconds > GetMaxLingerTime())) { return Error_EINVAL; @@ -1294,8 +1354,12 @@ int32_t SystemNative_SetLingerOption(intptr_t socket, LingerOption* option) #endif return err == 0 ? Error_SUCCESS : SystemNative_ConvertErrorPlatformToPal(errno); +#else /* TARGET_WASI */ + return Error_EINVAL; +#endif /* TARGET_WASI */ } +#if !defined(TARGET_WASI) static int32_t SetTimeoutOption(int32_t socket, int32_t millisecondsTimeout, int optionName) { if (millisecondsTimeout < 0) @@ -1310,15 +1374,24 @@ static int32_t SetTimeoutOption(int32_t socket, int32_t millisecondsTimeout, int int err = setsockopt(socket, SOL_SOCKET, optionName, &timeout, sizeof(timeout)); return err == 0 ? Error_SUCCESS : SystemNative_ConvertErrorPlatformToPal(errno); } +#endif /* TARGET_WASI */ int32_t SystemNative_SetReceiveTimeout(intptr_t socket, int32_t millisecondsTimeout) { +#if !defined(TARGET_WASI) return SetTimeoutOption(ToFileDescriptor(socket), millisecondsTimeout, SO_RCVTIMEO); +#else /* TARGET_WASI */ + return Error_EINVAL; +#endif /* TARGET_WASI */ } int32_t SystemNative_SetSendTimeout(intptr_t socket, int32_t millisecondsTimeout) { +#if !defined(TARGET_WASI) return SetTimeoutOption(ToFileDescriptor(socket), millisecondsTimeout, SO_SNDTIMEO); +#else /* TARGET_WASI */ + return Error_EINVAL; +#endif /* TARGET_WASI */ } static int8_t ConvertSocketFlagsPalToPlatform(int32_t palFlags, int* platformFlags) @@ -1330,26 +1403,44 @@ static int8_t ConvertSocketFlagsPalToPlatform(int32_t palFlags, int* platformFla return false; } - *platformFlags = ((palFlags & SocketFlags_MSG_OOB) == 0 ? 0 : MSG_OOB) | + *platformFlags = +#ifdef MSG_OOB + ((palFlags & SocketFlags_MSG_OOB) == 0 ? 0 : MSG_OOB) | +#endif /* MSG_OOB */ ((palFlags & SocketFlags_MSG_PEEK) == 0 ? 0 : MSG_PEEK) | +#ifdef MSG_DONTROUTE ((palFlags & SocketFlags_MSG_DONTROUTE) == 0 ? 0 : MSG_DONTROUTE) | +#endif /* MSG_DONTROUTE */ +#if defined(MSG_TRUNC) && !defined(TARGET_WASI) // https://github.com/WebAssembly/wasi-libc/issues/305 ((palFlags & SocketFlags_MSG_TRUNC) == 0 ? 0 : MSG_TRUNC) | - ((palFlags & SocketFlags_MSG_CTRUNC) == 0 ? 0 : MSG_CTRUNC); +#endif /* MSG_TRUNC */ +#ifdef MSG_CTRUNC + ((palFlags & SocketFlags_MSG_CTRUNC) == 0 ? 0 : MSG_CTRUNC) | +#endif /* MSG_CTRUNC */ + (0); return true; } +#if !defined(TARGET_WASI) static int32_t ConvertSocketFlagsPlatformToPal(int platformFlags) { - const int SupportedFlagsMask = MSG_OOB | MSG_DONTROUTE | MSG_TRUNC | MSG_CTRUNC; - - platformFlags &= SupportedFlagsMask; - - return ((platformFlags & MSG_OOB) == 0 ? 0 : SocketFlags_MSG_OOB) | + return +#ifdef MSG_OOB + ((platformFlags & MSG_OOB) == 0 ? 0 : SocketFlags_MSG_OOB) | +#endif /* MSG_OOB */ +#ifdef MSG_DONTROUTE ((platformFlags & MSG_DONTROUTE) == 0 ? 0 : SocketFlags_MSG_DONTROUTE) | +#endif /* MSG_DONTROUTE */ +#if defined(MSG_TRUNC) && !defined(TARGET_WASI) // https://github.com/WebAssembly/wasi-libc/issues/305 ((platformFlags & MSG_TRUNC) == 0 ? 0 : SocketFlags_MSG_TRUNC) | - ((platformFlags & MSG_CTRUNC) == 0 ? 0 : SocketFlags_MSG_CTRUNC); +#endif /* MSG_TRUNC */ +#ifdef MSG_CTRUNC + ((platformFlags & MSG_CTRUNC) == 0 ? 0 : SocketFlags_MSG_CTRUNC) | +#endif /* MSG_CTRUNC */ + (0); } +#endif /* TARGET_WASI */ int32_t SystemNative_Receive(intptr_t socket, void* buffer, int32_t bufferLen, int32_t flags, int32_t* received) { @@ -1387,6 +1478,7 @@ int32_t SystemNative_ReceiveMessage(intptr_t socket, MessageHeader* messageHeade return Error_EFAULT; } +#if !defined(TARGET_WASI) int fd = ToFileDescriptor(socket); int socketFlags; @@ -1420,6 +1512,9 @@ int32_t SystemNative_ReceiveMessage(intptr_t socket, MessageHeader* messageHeade *received = 0; return SystemNative_ConvertErrorPlatformToPal(errno); +#else /* TARGET_WASI */ + return Error_EINVAL; +#endif /* TARGET_WASI */ } int32_t SystemNative_Send(intptr_t socket, void* buffer, int32_t bufferLen, int32_t flags, int32_t* sent) @@ -1429,6 +1524,7 @@ int32_t SystemNative_Send(intptr_t socket, void* buffer, int32_t bufferLen, int3 return Error_EFAULT; } +#if !defined(TARGET_WASI) int fd = ToFileDescriptor(socket); int socketFlags; @@ -1455,6 +1551,9 @@ int32_t SystemNative_Send(intptr_t socket, void* buffer, int32_t bufferLen, int3 *sent = 0; return SystemNative_ConvertErrorPlatformToPal(errno); +#else /* TARGET_WASI */ + return Error_EINVAL; +#endif /* TARGET_WASI */ } int32_t SystemNative_SendMessage(intptr_t socket, MessageHeader* messageHeader, int32_t flags, int64_t* sent) @@ -1465,6 +1564,7 @@ int32_t SystemNative_SendMessage(intptr_t socket, MessageHeader* messageHeader, return Error_EFAULT; } +#if !defined(TARGET_WASI) int fd = ToFileDescriptor(socket); int socketFlags; @@ -1494,6 +1594,9 @@ int32_t SystemNative_SendMessage(intptr_t socket, MessageHeader* messageHeader, *sent = 0; return SystemNative_ConvertErrorPlatformToPal(errno); +#else /* TARGET_WASI */ + return Error_EINVAL; +#endif /* TARGET_WASI */ } int32_t SystemNative_Accept(intptr_t socket, uint8_t* socketAddress, int32_t* socketAddressLen, intptr_t* acceptedSocket) @@ -1554,6 +1657,7 @@ int32_t SystemNative_Bind(intptr_t socket, int32_t protocolType, uint8_t* socket return Error_EFAULT; } +#if !defined(TARGET_WASI) int fd = ToFileDescriptor(socket); // On Windows, Bind during TCP_WAIT is allowed. @@ -1570,6 +1674,9 @@ int32_t SystemNative_Bind(intptr_t socket, int32_t protocolType, uint8_t* socket (socklen_t)socketAddressLen); return err == 0 ? Error_SUCCESS : SystemNative_ConvertErrorPlatformToPal(errno); +#else /* TARGET_WASI */ + return Error_EINVAL; +#endif /* TARGET_WASI */ } int32_t SystemNative_Connect(intptr_t socket, uint8_t* socketAddress, int32_t socketAddressLen) @@ -1579,11 +1686,15 @@ int32_t SystemNative_Connect(intptr_t socket, uint8_t* socketAddress, int32_t so return Error_EFAULT; } +#if !defined(TARGET_WASI) int fd = ToFileDescriptor(socket); int err; while ((err = connect(fd, (struct sockaddr*)socketAddress, (socklen_t)socketAddressLen)) < 0 && errno == EINTR); return err == 0 ? Error_SUCCESS : SystemNative_ConvertErrorPlatformToPal(errno); +#else /* TARGET_WASI */ + return Error_EINVAL; +#endif /* TARGET_WASI */ } int32_t SystemNative_GetPeerName(intptr_t socket, uint8_t* socketAddress, int32_t* socketAddressLen) @@ -1593,6 +1704,7 @@ int32_t SystemNative_GetPeerName(intptr_t socket, uint8_t* socketAddress, int32_ return Error_EFAULT; } +#if !defined(TARGET_WASI) int fd = ToFileDescriptor(socket); socklen_t addrLen = (socklen_t)*socketAddressLen; @@ -1604,6 +1716,9 @@ int32_t SystemNative_GetPeerName(intptr_t socket, uint8_t* socketAddress, int32_ *socketAddressLen = (int32_t)addrLen; return Error_SUCCESS; +#else /* TARGET_WASI */ + return Error_EINVAL; +#endif /* TARGET_WASI */ } int32_t SystemNative_GetSockName(intptr_t socket, uint8_t* socketAddress, int32_t* socketAddressLen) @@ -1613,6 +1728,7 @@ int32_t SystemNative_GetSockName(intptr_t socket, uint8_t* socketAddress, int32_ return Error_EFAULT; } +#if !defined(TARGET_WASI) int fd = ToFileDescriptor(socket); socklen_t addrLen = (socklen_t)*socketAddressLen; @@ -1625,13 +1741,20 @@ int32_t SystemNative_GetSockName(intptr_t socket, uint8_t* socketAddress, int32_ assert(addrLen <= (socklen_t)*socketAddressLen); *socketAddressLen = (int32_t)addrLen; return Error_SUCCESS; +#else /* TARGET_WASI */ + return Error_EINVAL; +#endif /* TARGET_WASI */ } int32_t SystemNative_Listen(intptr_t socket, int32_t backlog) { +#if !defined(TARGET_WASI) int fd = ToFileDescriptor(socket); int err = listen(fd, backlog); return err == 0 ? Error_SUCCESS : SystemNative_ConvertErrorPlatformToPal(errno); +#else /* TARGET_WASI */ + return Error_EINVAL; +#endif /* TARGET_WASI */ } int32_t SystemNative_Shutdown(intptr_t socket, int32_t socketShutdown) @@ -1646,6 +1769,7 @@ int32_t SystemNative_GetSocketErrorOption(intptr_t socket, int32_t* error) return Error_EFAULT; } +#if !defined(TARGET_WASI) int fd = ToFileDescriptor(socket); int socketErrno; @@ -1659,6 +1783,9 @@ int32_t SystemNative_GetSocketErrorOption(intptr_t socket, int32_t* error) assert(optLen == sizeof(socketErrno)); *error = SystemNative_ConvertErrorPlatformToPal(socketErrno); return Error_SUCCESS; +#else /* TARGET_WASI */ + return Error_EINVAL; +#endif /* TARGET_WASI */ } static bool TryGetPlatformSocketOption(int32_t socketOptionLevel, int32_t socketOptionName, int* optLevel, int* optName) @@ -1670,75 +1797,107 @@ static bool TryGetPlatformSocketOption(int32_t socketOptionLevel, int32_t socket switch (socketOptionName) { +#ifdef SO_DEBUG case SocketOptionName_SO_DEBUG: *optName = SO_DEBUG; return true; +#endif +#ifdef SO_ACCEPTCONN case SocketOptionName_SO_ACCEPTCONN: *optName = SO_ACCEPTCONN; return true; +#endif +#ifdef SO_REUSEADDR case SocketOptionName_SO_REUSEADDR: *optName = SO_REUSEADDR; return true; +#endif +#ifdef SO_KEEPALIVE case SocketOptionName_SO_KEEPALIVE: *optName = SO_KEEPALIVE; return true; +#endif +#ifdef SO_DONTROUTE case SocketOptionName_SO_DONTROUTE: *optName = SO_DONTROUTE; return true; +#endif +#ifdef SO_BROADCAST case SocketOptionName_SO_BROADCAST: *optName = SO_BROADCAST; return true; +#endif // case SocketOptionName_SO_USELOOPBACK: +#ifdef SO_LINGER case SocketOptionName_SO_LINGER: *optName = SO_LINGER; return true; +#endif +#ifdef SO_OOBINLINE case SocketOptionName_SO_OOBINLINE: *optName = SO_OOBINLINE; return true; +#endif // case SocketOptionName_SO_DONTLINGER: // case SocketOptionName_SO_EXCLUSIVEADDRUSE: +#ifdef SO_SNDBUF case SocketOptionName_SO_SNDBUF: *optName = SO_SNDBUF; return true; +#endif +#ifdef SO_RCVBUF case SocketOptionName_SO_RCVBUF: *optName = SO_RCVBUF; return true; +#endif +#ifdef SO_SNDLOWAT case SocketOptionName_SO_SNDLOWAT: *optName = SO_SNDLOWAT; return true; +#endif +#ifdef SO_RCVLOWAT case SocketOptionName_SO_RCVLOWAT: *optName = SO_RCVLOWAT; return true; +#endif +#ifdef SO_SNDTIMEO case SocketOptionName_SO_SNDTIMEO: *optName = SO_SNDTIMEO; return true; +#endif +#ifdef SO_RCVTIMEO case SocketOptionName_SO_RCVTIMEO: *optName = SO_RCVTIMEO; return true; +#endif +#ifdef SO_ERROR case SocketOptionName_SO_ERROR: *optName = SO_ERROR; return true; +#endif +#ifdef SO_TYPE case SocketOptionName_SO_TYPE: *optName = SO_TYPE; return true; +#endif // case SocketOptionName_SO_MAXCONN: @@ -1930,10 +2089,11 @@ static bool TryConvertSocketTypePlatformToPal(int platformSocketType, int32_t* p case SOCK_DGRAM: *palSocketType = SocketType_SOCK_DGRAM; return true; - +#ifdef SOCK_RAW case SOCK_RAW: *palSocketType = SocketType_SOCK_RAW; return true; +#endif #ifdef SOCK_RDM case SOCK_RDM: @@ -1941,9 +2101,11 @@ static bool TryConvertSocketTypePlatformToPal(int platformSocketType, int32_t* p return true; #endif +#ifdef SOCK_SEQPACKET case SOCK_SEQPACKET: *palSocketType = SocketType_SOCK_SEQPACKET; return true; +#endif default: *palSocketType = (int32_t)platformSocketType; @@ -2099,6 +2261,7 @@ SystemNative_SetSockOpt(intptr_t socket, int32_t socketOptionLevel, int32_t sock return Error_EFAULT; } +#if !defined(TARGET_WASI) int fd = ToFileDescriptor(socket); // @@ -2175,6 +2338,9 @@ SystemNative_SetSockOpt(intptr_t socket, int32_t socketOptionLevel, int32_t sock int err = setsockopt(fd, optLevel, optName, optionValue, (socklen_t)optionLen); return err == 0 ? Error_SUCCESS : SystemNative_ConvertErrorPlatformToPal(errno); +#else /* TARGET_WASI */ + return Error_EINVAL; +#endif /* TARGET_WASI */ } int32_t SystemNative_SetRawSockOpt( @@ -2185,10 +2351,15 @@ int32_t SystemNative_SetRawSockOpt( return Error_EFAULT; } +#if !defined(TARGET_WASI) int err = setsockopt(ToFileDescriptor(socket), socketOptionLevel, socketOptionName, optionValue, (socklen_t)optionLen); return err == 0 ? Error_SUCCESS : SystemNative_ConvertErrorPlatformToPal(errno); +#else /* TARGET_WASI */ + return Error_EINVAL; +#endif /* TARGET_WASI */ } +#if !defined(TARGET_WASI) static bool TryConvertSocketTypePalToPlatform(int32_t palSocketType, int* platformSocketType) { assert(platformSocketType != NULL); @@ -2203,9 +2374,11 @@ static bool TryConvertSocketTypePalToPlatform(int32_t palSocketType, int* platfo *platformSocketType = SOCK_DGRAM; return true; +#ifdef SOCK_RAW case SocketType_SOCK_RAW: *platformSocketType = SOCK_RAW; return true; +#endif #ifdef SOCK_RDM case SocketType_SOCK_RDM: @@ -2213,9 +2386,11 @@ static bool TryConvertSocketTypePalToPlatform(int32_t palSocketType, int* platfo return true; #endif +#ifdef SOCK_SEQPACKET case SocketType_SOCK_SEQPACKET: *platformSocketType = SOCK_SEQPACKET; return true; +#endif default: *platformSocketType = (int)palSocketType; @@ -2270,10 +2445,11 @@ static bool TryConvertProtocolTypePalToPlatform(int32_t palAddressFamily, int32_ case ProtocolType_PT_UDP: *platformProtocolType = IPPROTO_UDP; return true; - +#ifdef IPPROTO_IGMP case ProtocolType_PT_IGMP: *platformProtocolType = IPPROTO_IGMP; return true; +#endif case ProtocolType_PT_RAW: *platformProtocolType = IPPROTO_RAW; @@ -2291,10 +2467,12 @@ static bool TryConvertProtocolTypePalToPlatform(int32_t palAddressFamily, int32_ *platformProtocolType = 0; return true; +#ifdef IPPROTO_ICMPV6 case ProtocolType_PT_ICMPV6: case ProtocolType_PT_ICMP: *platformProtocolType = IPPROTO_ICMPV6; return true; +#endif case ProtocolType_PT_TCP: *platformProtocolType = IPPROTO_TCP; @@ -2304,29 +2482,39 @@ static bool TryConvertProtocolTypePalToPlatform(int32_t palAddressFamily, int32_ *platformProtocolType = IPPROTO_UDP; return true; +#ifdef IPPROTO_IGMP case ProtocolType_PT_IGMP: *platformProtocolType = IPPROTO_IGMP; return true; +#endif case ProtocolType_PT_RAW: *platformProtocolType = IPPROTO_RAW; return true; +#ifdef IPPROTO_DSTOPTS case ProtocolType_PT_DSTOPTS: *platformProtocolType = IPPROTO_DSTOPTS; return true; +#endif +#ifdef IPPROTO_NONE case ProtocolType_PT_NONE: *platformProtocolType = IPPROTO_NONE; return true; +#endif +#ifdef IPPROTO_ROUTING case ProtocolType_PT_ROUTING: *platformProtocolType = IPPROTO_ROUTING; return true; +#endif +#ifdef IPPROTO_FRAGMENT case ProtocolType_PT_FRAGMENT: *platformProtocolType = IPPROTO_FRAGMENT; return true; +#endif default: *platformProtocolType = (int)palProtocolType; @@ -2394,9 +2582,11 @@ static bool TryConvertProtocolTypePlatformToPal(int32_t palAddressFamily, int pl *palProtocolType = ProtocolType_PT_UDP; return true; +#ifdef IPPROTO_IGMP case IPPROTO_IGMP: *palProtocolType = ProtocolType_PT_IGMP; return true; +#endif case IPPROTO_RAW: *palProtocolType = ProtocolType_PT_RAW; @@ -2414,9 +2604,11 @@ static bool TryConvertProtocolTypePlatformToPal(int32_t palAddressFamily, int pl *palProtocolType = ProtocolType_PT_UNSPECIFIED; return true; +#ifdef IPPROTO_ICMPV6 case IPPROTO_ICMPV6: *palProtocolType = ProtocolType_PT_ICMPV6; return true; +#endif case IPPROTO_TCP: *palProtocolType = ProtocolType_PT_TCP; @@ -2426,29 +2618,39 @@ static bool TryConvertProtocolTypePlatformToPal(int32_t palAddressFamily, int pl *palProtocolType = ProtocolType_PT_UDP; return true; +#ifdef IPPROTO_IGMP case IPPROTO_IGMP: *palProtocolType = ProtocolType_PT_IGMP; return true; +#endif case IPPROTO_RAW: *palProtocolType = ProtocolType_PT_RAW; return true; +#ifdef IPPROTO_DSTOPTS case IPPROTO_DSTOPTS: *palProtocolType = ProtocolType_PT_DSTOPTS; return true; +#endif +#ifdef IPPROTO_NONE case IPPROTO_NONE: *palProtocolType = ProtocolType_PT_NONE; return true; +#endif +#ifdef IPPROTO_ROUTING case IPPROTO_ROUTING: *palProtocolType = ProtocolType_PT_ROUTING; return true; +#endif +#ifdef IPPROTO_FRAGMENT case IPPROTO_FRAGMENT: *palProtocolType = ProtocolType_PT_FRAGMENT; return true; +#endif default: *palProtocolType = (int)platformProtocolType; @@ -2467,6 +2669,7 @@ static bool TryConvertProtocolTypePlatformToPal(int32_t palAddressFamily, int pl } } } +#endif /* TARGET_WASI */ int32_t SystemNative_Socket(int32_t addressFamily, int32_t socketType, int32_t protocolType, intptr_t* createdSocket) { @@ -2475,6 +2678,7 @@ int32_t SystemNative_Socket(int32_t addressFamily, int32_t socketType, int32_t p return Error_EFAULT; } +#if !defined(TARGET_WASI) sa_family_t platformAddressFamily; int platformSocketType, platformProtocolType; @@ -2509,6 +2713,9 @@ int32_t SystemNative_Socket(int32_t addressFamily, int32_t socketType, int32_t p fcntl(ToFileDescriptor(*createdSocket), F_SETFD, FD_CLOEXEC); // ignore any failures; this is best effort #endif return Error_SUCCESS; +#else /* TARGET_WASI */ + return Error_EINVAL; +#endif /* TARGET_WASI */ } int32_t SystemNative_GetSocketType(intptr_t socket, int32_t* addressFamily, int32_t* socketType, int32_t* protocolType, int32_t* isListening) @@ -2576,6 +2783,7 @@ int32_t SystemNative_GetSocketType(intptr_t socket, int32_t* addressFamily, int3 int listeningValue; socklen_t listeningLength = sizeof(int); +#ifdef SO_ACCEPTCONN if (getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &listeningValue, &listeningLength) == 0) { *isListening = (listeningValue != 0); @@ -2584,6 +2792,9 @@ int32_t SystemNative_GetSocketType(intptr_t socket, int32_t* addressFamily, int3 { *isListening = 0; } +#else + *isListening = 0; +#endif #endif return Error_SUCCESS; } @@ -2595,6 +2806,7 @@ int32_t SystemNative_GetAtOutOfBandMark(intptr_t socket, int32_t* atMark) return Error_EFAULT; } +#if !defined(TARGET_WASI) int fd = ToFileDescriptor(socket); int result; @@ -2608,6 +2820,9 @@ int32_t SystemNative_GetAtOutOfBandMark(intptr_t socket, int32_t* atMark) *atMark = (int32_t)result; return Error_SUCCESS; +#else /* TARGET_WASI */ + return Error_EINVAL; +#endif /* TARGET_WASI */ } int32_t SystemNative_GetBytesAvailable(intptr_t socket, int32_t* available) @@ -2927,10 +3142,13 @@ static int32_t WaitForSocketEventsInner(int32_t port, SocketEvent* buffer, int32 #else static const size_t SocketEventBufferElementSize = 0; +#if !defined(TARGET_WASI) static SocketEvents GetSocketEvents(int16_t filter, uint16_t flags) { return SocketEvents_SA_NONE; } +#endif /* TARGET_WASI */ + static int32_t CloseSocketEventPortInner(int32_t port) { return Error_ENOSYS; @@ -3036,6 +3254,7 @@ int32_t SystemNative_PlatformSupportsDualModeIPv4PacketInfo(void) #endif } +#if !defined(TARGET_WASI) static char* GetNameFromUid(uid_t uid) { size_t bufferLength = 512; @@ -3072,17 +3291,23 @@ static char* GetNameFromUid(uid_t uid) bufferLength = tmpBufferLength; } } +#endif /* TARGET_WASI */ char* SystemNative_GetPeerUserName(intptr_t socket) { +#if !defined(TARGET_WASI) uid_t euid; return SystemNative_GetPeerID(socket, &euid) == 0 ? GetNameFromUid(euid) : NULL; +#else /* TARGET_WASI */ + return NULL; +#endif /* TARGET_WASI */ } void SystemNative_GetDomainSocketSizes(int32_t* pathOffset, int32_t* pathSize, int32_t* addressSize) { +#if !defined(TARGET_WASI) assert(pathOffset != NULL); assert(pathSize != NULL); assert(addressSize != NULL); @@ -3092,6 +3317,11 @@ void SystemNative_GetDomainSocketSizes(int32_t* pathOffset, int32_t* pathSize, i *pathOffset = offsetof(struct sockaddr_un, sun_path); *pathSize = sizeof(domainSocket.sun_path); *addressSize = sizeof(domainSocket); +#else /* TARGET_WASI */ + *pathOffset = -1; + *pathSize = -1; + *addressSize = -1; +#endif /* TARGET_WASI */ } int32_t SystemNative_GetMaximumAddressSize(void) @@ -3266,7 +3496,12 @@ int32_t SystemNative_SendFile(intptr_t out_fd, intptr_t in_fd, int64_t offset, i uint32_t SystemNative_InterfaceNameToIndex(char* interfaceName) { assert(interfaceName != NULL); +#if !defined(TARGET_WASI) if (interfaceName[0] == '%') interfaceName++; return if_nametoindex(interfaceName); +#else /* TARGET_WASI */ + return Error_EINVAL; +#endif /* TARGET_WASI */ } + diff --git a/src/native/libs/System.Native/pal_networkstatistics.c b/src/native/libs/System.Native/pal_networkstatistics.c index 987a0a80d81596..eeeb8ac802942f 100644 --- a/src/native/libs/System.Native/pal_networkstatistics.c +++ b/src/native/libs/System.Native/pal_networkstatistics.c @@ -32,7 +32,9 @@ #else #include #endif +#if HAVE_NET_IF_H #include +#endif #include #include diff --git a/src/native/libs/System.Native/pal_process.c b/src/native/libs/System.Native/pal_process.c index 509049b2fdcd7a..0ac81db47cc753 100644 --- a/src/native/libs/System.Native/pal_process.c +++ b/src/native/libs/System.Native/pal_process.c @@ -8,14 +8,20 @@ #include #include +#if HAVE_GRP_H #include +#endif #include #include #include #include #include +#if HAVE_SYS_WAIT_H #include +#endif +#if HAVE_SYSLOG_H #include +#endif #include #if HAVE_CRT_EXTERNS_H #include @@ -23,7 +29,9 @@ #if HAVE_PIPE2 #include #endif +#if HAVE_PTHREAD_H #include +#endif #if HAVE_SCHED_SETAFFINITY || HAVE_SCHED_GETAFFINITY #include @@ -41,6 +49,7 @@ #include +#if !defined(TARGET_WASI) // Validate that our SysLogPriority values are correct for the platform c_static_assert(PAL_LOG_EMERG == LOG_EMERG); c_static_assert(PAL_LOG_ALERT == LOG_ALERT); @@ -208,6 +217,7 @@ handler_from_sigaction (struct sigaction *sa) return sa->sa_handler; } } +#endif /* TARGET_WASI */ int32_t SystemNative_ForkAndExecProcess(const char* filename, char* const argv[], @@ -511,6 +521,7 @@ done:; #endif } +#if !defined(TARGET_WASI) // Each platform type has it's own RLIMIT values but the same name, so we need // to convert our standard types into the platform specific ones. static int32_t ConvertRLimitResourcesPalToPlatform(RLimitResources value) @@ -519,10 +530,14 @@ static int32_t ConvertRLimitResourcesPalToPlatform(RLimitResources value) { case PAL_RLIMIT_CPU: return RLIMIT_CPU; +#ifdef RLIMIT_FSIZE case PAL_RLIMIT_FSIZE: return RLIMIT_FSIZE; +#endif +#ifdef RLIMIT_DATA case PAL_RLIMIT_DATA: return RLIMIT_DATA; +#endif case PAL_RLIMIT_STACK: return RLIMIT_STACK; case PAL_RLIMIT_CORE: @@ -605,11 +620,12 @@ typedef __priority_which_t priorityWhich; typedef int rlimitResource; typedef int priorityWhich; #endif +#endif /* TARGET_WASI */ int32_t SystemNative_GetRLimit(RLimitResources resourceType, RLimit* limits) { assert(limits != NULL); - +#if HAVE_SYS_RESOURCE_H int32_t platformLimit = ConvertRLimitResourcesPalToPlatform(resourceType); struct rlimit internalLimit; int result = getrlimit((rlimitResource)platformLimit, &internalLimit); @@ -621,6 +637,10 @@ int32_t SystemNative_GetRLimit(RLimitResources resourceType, RLimit* limits) { memset(limits, 0, sizeof(RLimit)); } +#else /* HAVE_SYS_RESOURCE_H */ + int result = -1; + memset(limits, 0, sizeof(RLimit)); +#endif return result; } @@ -629,14 +649,19 @@ int32_t SystemNative_SetRLimit(RLimitResources resourceType, const RLimit* limit { assert(limits != NULL); +#if HAVE_SYS_RESOURCE_H int32_t platformLimit = ConvertRLimitResourcesPalToPlatform(resourceType); struct rlimit internalLimit; ConvertFromRLimitManagedToPal(limits, &internalLimit); return setrlimit((rlimitResource)platformLimit, &internalLimit); +#else /* HAVE_SYS_RESOURCE_H */ + return -1; +#endif } int32_t SystemNative_Kill(int32_t pid, int32_t signal) { +#if HAVE_SIGNAL_KILL switch (signal) { case PAL_NONE: @@ -658,25 +683,39 @@ int32_t SystemNative_Kill(int32_t pid, int32_t signal) } return kill(pid, signal); +#else /* HAVE_SIGNAL_KILL */ + return -1; +#endif /* HAVE_SIGNAL_KILL */ } int32_t SystemNative_GetPid(void) { +#if !defined(TARGET_WASI) return getpid(); +#else /* TARGET_WASI */ + return -1; +#endif /* TARGET_WASI */ } int32_t SystemNative_GetSid(int32_t pid) { +#if !defined(TARGET_WASI) return getsid(pid); +#else /* TARGET_WASI */ + return -1; +#endif /* TARGET_WASI */ } void SystemNative_SysLog(SysLogPriority priority, const char* message, const char* arg1) { +#if !defined(TARGET_WASI) syslog((int)(LOG_USER | priority), message, arg1); +#endif /* TARGET_WASI */ } int32_t SystemNative_WaitIdAnyExitedNoHangNoWait(void) { +#if !defined(TARGET_WASI) siginfo_t siginfo; memset(&siginfo, 0, sizeof(siginfo)); int32_t result; @@ -696,10 +735,14 @@ int32_t SystemNative_WaitIdAnyExitedNoHangNoWait(void) result = 0; } return result; +#else /* TARGET_WASI */ + return -1; +#endif /* TARGET_WASI */ } int32_t SystemNative_WaitPidExitedNoHang(int32_t pid, int32_t* exitCode) { +#if !defined(TARGET_WASI) assert(exitCode != NULL); int32_t result; @@ -723,6 +766,9 @@ int32_t SystemNative_WaitPidExitedNoHang(int32_t pid, int32_t* exitCode) } } return result; +#else /* TARGET_WASI */ + return -1; +#endif /* TARGET_WASI */ } int64_t SystemNative_PathConf(const char* path, PathConfName name) @@ -771,6 +817,7 @@ int64_t SystemNative_PathConf(const char* path, PathConfName name) int32_t SystemNative_GetPriority(PriorityWhich which, int32_t who) { +#if !defined(TARGET_WASI) // GetPriority uses errno 0 to show success to make sure we don't have a stale value errno = 0; #if PRIORITY_REQUIRES_INT_WHO @@ -778,15 +825,22 @@ int32_t SystemNative_GetPriority(PriorityWhich which, int32_t who) #else return getpriority((priorityWhich)which, (id_t)who); #endif +#else /* TARGET_WASI */ + return -1; +#endif /* TARGET_WASI */ } int32_t SystemNative_SetPriority(PriorityWhich which, int32_t who, int32_t nice) { +#if !defined(TARGET_WASI) #if PRIORITY_REQUIRES_INT_WHO return setpriority((priorityWhich)which, who, nice); #else return setpriority((priorityWhich)which, (id_t)who, nice); #endif +#else /* TARGET_WASI */ + return -1; +#endif /* TARGET_WASI */ } char* SystemNative_GetCwd(char* buffer, int32_t bufferSize) diff --git a/src/native/libs/System.Native/pal_signal.c b/src/native/libs/System.Native/pal_signal.c index 257969dc67a945..f09b45ff33f0b4 100644 --- a/src/native/libs/System.Native/pal_signal.c +++ b/src/native/libs/System.Native/pal_signal.c @@ -9,13 +9,19 @@ #include #include +#if HAVE_PTHREAD_H #include +#endif #include #include #include +#if HAVE_SYS_WAIT_H #include +#endif #include +#if !defined(TARGET_WASI) + static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; // Saved signal handlers @@ -180,14 +186,6 @@ int32_t SystemNative_GetPlatformSignalNumber(PosixSignal signal) return 0; } -void SystemNative_SetPosixSignalHandler(PosixSignalHandler signalHandler) -{ - assert(signalHandler); - assert(g_posixSignalHandler == NULL || g_posixSignalHandler == signalHandler); - - g_posixSignalHandler = signalHandler; -} - static struct sigaction* OrigActionFor(int sig) { return &g_origSigHandler[sig - 1]; @@ -244,8 +242,21 @@ static void SignalHandler(int sig, siginfo_t* siginfo, void* context) } } +#endif /* TARGET_WASI */ + +void SystemNative_SetPosixSignalHandler(PosixSignalHandler signalHandler) +{ + assert(signalHandler); +#if !defined(TARGET_WASI) + assert(g_posixSignalHandler == NULL || g_posixSignalHandler == signalHandler); + + g_posixSignalHandler = signalHandler; +#endif /* TARGET_WASI */ +} + void SystemNative_HandleNonCanceledPosixSignal(int32_t signalCode) { +#if !defined(TARGET_WASI) switch (signalCode) { case SIGCONT: @@ -299,8 +310,10 @@ void SystemNative_HandleNonCanceledPosixSignal(int32_t signalCode) kill(g_pid, signalCode); break; } +#endif /* TARGET_WASI */ } +#if !defined(TARGET_WASI) // Entrypoint for the thread that handles signals where our handling // isn't signal-safe. Those signal handlers write the signal to a pipe, // which this loop reads and processes. @@ -471,10 +484,12 @@ static bool InstallSignalHandler(int sig, int flags) *isInstalled = true; return true; } +#endif /* TARGET_WASI */ void SystemNative_SetTerminalInvalidationHandler(TerminalInvalidationCallback callback) { assert(callback != NULL); +#if !defined(TARGET_WASI) assert(g_terminalInvalidationCallback == NULL); bool installed = false; (void)installed; // only used for assert @@ -491,11 +506,13 @@ void SystemNative_SetTerminalInvalidationHandler(TerminalInvalidationCallback ca assert(installed); } pthread_mutex_unlock(&lock); +#endif /* TARGET_WASI */ } void SystemNative_RegisterForSigChld(SigChldCallback callback) { assert(callback != NULL); +#if !defined(TARGET_WASI) assert(g_sigChldCallback == NULL); bool installed = false; (void)installed; // only used for assert @@ -508,15 +525,19 @@ void SystemNative_RegisterForSigChld(SigChldCallback callback) assert(installed); } pthread_mutex_unlock(&lock); +#endif /* TARGET_WASI */ } void SystemNative_SetDelayedSigChildConsoleConfigurationHandler(void (*callback)(void)) { +#if !defined(TARGET_WASI) assert(g_sigChldConsoleConfigurationCallback == NULL); g_sigChldConsoleConfigurationCallback = callback; +#endif /* TARGET_WASI */ } +#if !defined(TARGET_WASI) static bool CreateSignalHandlerThread(int* readFdPtr) { pthread_attr_t attr; @@ -614,9 +635,11 @@ int32_t InitializeSignalHandlingCore(void) return 1; } +#endif /* TARGET_WASI */ int32_t SystemNative_EnablePosixSignalHandling(int signalCode) { +#if !defined(TARGET_WASI) assert(g_posixSignalHandler != NULL); assert(signalCode > 0 && signalCode <= GetSignalMax()); @@ -630,10 +653,14 @@ int32_t SystemNative_EnablePosixSignalHandling(int signalCode) pthread_mutex_unlock(&lock); return installed ? 1 : 0; +#else /* TARGET_WASI */ + return false; +#endif /* TARGET_WASI */ } void SystemNative_DisablePosixSignalHandling(int signalCode) { +#if !defined(TARGET_WASI) assert(signalCode > 0 && signalCode <= GetSignalMax()); pthread_mutex_lock(&lock); @@ -655,8 +682,10 @@ void SystemNative_DisablePosixSignalHandling(int signalCode) } } pthread_mutex_unlock(&lock); +#endif /* TARGET_WASI */ } +#if !defined(TARGET_WASI) void InstallTTOUHandlerForConsole(ConsoleSigTtouHandler handler) { bool installed; @@ -717,4 +746,5 @@ int32_t SystemNative_InitializeTerminalAndSignalHandling(void) return initialized; } -#endif +#endif /* !HAS_CONSOLE_SIGNALS */ +#endif /* !TARGET_WASI */ diff --git a/src/native/libs/System.Native/pal_threading.c b/src/native/libs/System.Native/pal_threading.c index b524327ef820b4..09d49be20fb07d 100644 --- a/src/native/libs/System.Native/pal_threading.c +++ b/src/native/libs/System.Native/pal_threading.c @@ -4,6 +4,7 @@ #include "pal_config.h" #include "pal_threading.h" +#include #include #include #include @@ -20,7 +21,9 @@ // So we can use the declaration of pthread_cond_timedwait_relative_np #undef _XOPEN_SOURCE #endif +#if HAVE_PTHREAD_H #include +#endif #if defined(TARGET_OSX) #define _XOPEN_SOURCE #endif @@ -30,8 +33,12 @@ struct LowLevelMonitor { +#if !defined(TARGET_WASI) pthread_mutex_t Mutex; pthread_cond_t Condition; +#else /* !TARGET_WASI */ + bool Dummy; +#endif /* !TARGET_WASI */ #ifdef DEBUG bool IsLocked; #endif @@ -55,6 +62,7 @@ LowLevelMonitor* SystemNative_LowLevelMonitor_Create(void) { return NULL; } +#if !defined(TARGET_WASI) int error; @@ -105,12 +113,16 @@ LowLevelMonitor* SystemNative_LowLevelMonitor_Create(void) assert(error == 0); free(monitor); return NULL; +#else /* !TARGET_WASI */ + return monitor; +#endif /* !TARGET_WASI */ } void SystemNative_LowLevelMonitor_Destroy(LowLevelMonitor* monitor) { assert(monitor != NULL); +#if !defined(TARGET_WASI) int error; error = pthread_cond_destroy(&monitor->Condition); @@ -121,6 +133,7 @@ void SystemNative_LowLevelMonitor_Destroy(LowLevelMonitor* monitor) (void)error; // unused in release build +#endif /* !TARGET_WASI */ free(monitor); } @@ -128,9 +141,11 @@ void SystemNative_LowLevelMonitor_Acquire(LowLevelMonitor* monitor) { assert(monitor != NULL); +#if !defined(TARGET_WASI) int error = pthread_mutex_lock(&monitor->Mutex); assert(error == 0); (void)error; // unused in release build +#endif /* !TARGET_WASI */ SetIsLocked(monitor, true); } @@ -141,9 +156,11 @@ void SystemNative_LowLevelMonitor_Release(LowLevelMonitor* monitor) SetIsLocked(monitor, false); +#if !defined(TARGET_WASI) int error = pthread_mutex_unlock(&monitor->Mutex); assert(error == 0); (void)error; // unused in release build +#endif /* !TARGET_WASI */ } void SystemNative_LowLevelMonitor_Wait(LowLevelMonitor* monitor) @@ -152,9 +169,11 @@ void SystemNative_LowLevelMonitor_Wait(LowLevelMonitor* monitor) SetIsLocked(monitor, false); +#if !defined(TARGET_WASI) int error = pthread_cond_wait(&monitor->Condition, &monitor->Mutex); assert(error == 0); (void)error; // unused in release build +#endif /* !TARGET_WASI */ SetIsLocked(monitor, true); } @@ -165,6 +184,7 @@ int32_t SystemNative_LowLevelMonitor_TimedWait(LowLevelMonitor *monitor, int32_t SetIsLocked(monitor, false); +#if !defined(TARGET_WASI) int error; // Calculate the time at which a timeout should occur, and wait. Older versions of OSX don't support clock_gettime with @@ -199,12 +219,16 @@ int32_t SystemNative_LowLevelMonitor_TimedWait(LowLevelMonitor *monitor, int32_t SetIsLocked(monitor, true); return error == 0; +#else /* !TARGET_WASI */ + return true; +#endif /* !TARGET_WASI */ } void SystemNative_LowLevelMonitor_Signal_Release(LowLevelMonitor* monitor) { assert(monitor != NULL); +#if !defined(TARGET_WASI) int error; error = pthread_cond_signal(&monitor->Condition); @@ -216,11 +240,13 @@ void SystemNative_LowLevelMonitor_Signal_Release(LowLevelMonitor* monitor) assert(error == 0); (void)error; // unused in release build +#endif /* !TARGET_WASI */ } int32_t SystemNative_CreateThread(uintptr_t stackSize, void *(*startAddress)(void*), void *parameter) { bool result = false; +#if !defined(TARGET_WASI) pthread_attr_t attrs; int error = pthread_attr_init(&attrs); @@ -261,6 +287,7 @@ int32_t SystemNative_CreateThread(uintptr_t stackSize, void *(*startAddress)(voi CreateThreadExit: error = pthread_attr_destroy(&attrs); assert(error == 0); +#endif /* !TARGET_WASI */ return result; } diff --git a/src/native/libs/System.Native/pal_time.c b/src/native/libs/System.Native/pal_time.c index 04ffd55865d301..76786b9ca8ee85 100644 --- a/src/native/libs/System.Native/pal_time.c +++ b/src/native/libs/System.Native/pal_time.c @@ -121,6 +121,7 @@ int64_t SystemNative_GetBootTimeTicks(void) double SystemNative_GetCpuUtilization(ProcessCpuInformation* previousCpuInfo) { +#ifdef HAVE_GETRUSAGE uint64_t kernelTime = 0; uint64_t userTime = 0; @@ -169,4 +170,8 @@ double SystemNative_GetCpuUtilization(ProcessCpuInformation* previousCpuInfo) previousCpuInfo->lastRecordedKernelTime = kernelTime; return cpuUtilization; +#else + assert(false); + return 0; +#endif } diff --git a/src/native/libs/System.Native/pal_uid.c b/src/native/libs/System.Native/pal_uid.c index 0f94484cafec4d..e2cf3a24fb3213 100644 --- a/src/native/libs/System.Native/pal_uid.c +++ b/src/native/libs/System.Native/pal_uid.c @@ -11,20 +11,27 @@ #include #include #include +#if HAVE_GRP_H #include +#endif +#if HAVE_PWD_H #include +#endif // Linux c-libraries (glibc, musl) provide a thread-safe getgrouplist. // OSX man page mentions explicitly the implementation is not thread safe, // due to using getgrent. -#ifndef __linux__ +#if !defined(__linux__) && !defined(TARGET_WASI) #define USE_GROUPLIST_LOCK #endif #if defined(USE_GROUPLIST_LOCK) || !HAVE_GETGRGID_R +#if HAVE_PTHREAD_H #include #endif +#endif +#if !defined(TARGET_WASI) static int32_t ConvertNativePasswdToPalPasswd(int error, struct passwd* nativePwd, struct passwd* result, Passwd* pwd) { // positive error number returned -> failure other than entry-not-found @@ -53,6 +60,7 @@ static int32_t ConvertNativePasswdToPalPasswd(int error, struct passwd* nativePw pwd->Shell = nativePwd->pw_shell; return 0; } +#endif /* !TARGET_WASI */ int32_t SystemNative_GetPwUidR(uint32_t uid, Passwd* pwd, char* buf, int32_t buflen) { @@ -63,12 +71,16 @@ int32_t SystemNative_GetPwUidR(uint32_t uid, Passwd* pwd, char* buf, int32_t buf if (buflen < 0) return EINVAL; +#if !defined(TARGET_WASI) struct passwd nativePwd; struct passwd* result; int error; while ((error = getpwuid_r(uid, &nativePwd, buf, Int32ToSizeT(buflen), &result)) == EINTR); return ConvertNativePasswdToPalPasswd(error, &nativePwd, result, pwd); +#else /* !TARGET_WASI */ + return EINVAL; +#endif /* !TARGET_WASI */ } int32_t SystemNative_GetPwNamR(const char* name, Passwd* pwd, char* buf, int32_t buflen) @@ -80,34 +92,50 @@ int32_t SystemNative_GetPwNamR(const char* name, Passwd* pwd, char* buf, int32_t if (buflen < 0) return EINVAL; +#if !defined(TARGET_WASI) struct passwd nativePwd; struct passwd* result; int error; while ((error = getpwnam_r(name, &nativePwd, buf, Int32ToSizeT(buflen), &result)) == EINTR); return ConvertNativePasswdToPalPasswd(error, &nativePwd, result, pwd); +#else /* !TARGET_WASI */ + return EINVAL; +#endif /* !TARGET_WASI */ } uint32_t SystemNative_GetEUid(void) { +#if !defined(TARGET_WASI) return geteuid(); +#else /* !TARGET_WASI */ + return EINVAL; +#endif /* !TARGET_WASI */ } uint32_t SystemNative_GetEGid(void) { +#if !defined(TARGET_WASI) return getegid(); +#else /* !TARGET_WASI */ + return EINVAL; +#endif /* !TARGET_WASI */ } int32_t SystemNative_SetEUid(uint32_t euid) { +#if !defined(TARGET_WASI) return seteuid(euid); +#else /* !TARGET_WASI */ + return EINVAL; +#endif /* !TARGET_WASI */ } #ifdef USE_GROUPLIST_LOCK static pthread_mutex_t s_groupLock = PTHREAD_MUTEX_INITIALIZER; #endif -#if !HAVE_GETGROUPLIST +#if !HAVE_GETGROUPLIST && !defined(TARGET_WASI) int getgrouplist(const char *uname, gid_t agroup, gid_t *groups, int *groupCount) { int ngroups = 1; @@ -204,8 +232,10 @@ int32_t SystemNative_GetGroupList(const char* name, uint32_t group, uint32_t* gr #ifdef __APPLE__ // On OSX groups are passed as a signed int. rv = getgrouplist(name, (int)group, (int*)groups, &groupsAvailable); -#else +#elif HAVE_GETGROUPLIST rv = getgrouplist(name, group, groups, &groupsAvailable); +#else + rv = 0; #endif #ifdef USE_GROUPLIST_LOCK @@ -236,10 +266,14 @@ int32_t SystemNative_GetGroups(int32_t ngroups, uint32_t* groups) assert(ngroups >= 0); assert(groups != NULL); +#if !defined(TARGET_WASI) return getgroups(ngroups, groups); +#else /* TARGET_WASI */ + return -1; +#endif /* TARGET_WASI */ } -#if !HAVE_GETGRGID_R +#if !HAVE_GETGRGID_R && !defined(TARGET_WASI) // Need to call getgrgid which is not thread-safe, and protect it with a mutex static pthread_mutex_t s_getgrgid_lock = PTHREAD_MUTEX_INITIALIZER; #endif @@ -282,7 +316,7 @@ char* SystemNative_GetGroupName(uint32_t gid) } bufferLength = tmpBufferLength; } -#else +#elif !defined(TARGET_WASI) // Platforms like Android API level < 24 do not have getgrgid_r available int rv = pthread_mutex_lock(&s_getgrgid_lock); if (rv != 0) @@ -300,5 +334,7 @@ char* SystemNative_GetGroupName(uint32_t gid) char* name = strdup(result->gr_name); pthread_mutex_unlock(&s_getgrgid_lock); return name; +#else + return NULL; #endif } From fa5081a561a2799dac14c2f208efa11660882850 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Wed, 30 Nov 2022 19:30:39 +0100 Subject: [PATCH 02/39] wip --- eng/build.ps1 | 4 + eng/native/configurecompiler.cmake | 6 +- eng/native/configureplatform.cmake | 12 +- eng/native/configuretools.cmake | 2 +- eng/native/gen-buildsys.cmd | 17 +- src/coreclr/pal/src/config.h.in | 3 + src/coreclr/pal/src/configure.cmake | 3 + src/mono/CMakeLists.txt | 29 ++- .../System.Private.CoreLib.csproj | 21 +- src/mono/cmake/config.h.in | 3 + src/mono/cmake/configure.cmake | 13 +- src/mono/mono.proj | 78 +++++- src/mono/mono/mini/CMakeLists.txt | 2 +- src/mono/mono/utils/CMakeLists.txt | 2 +- src/mono/mono/utils/mono-rand.c | 33 +-- src/mono/wasi/wasi.proj | 242 ++++++++++++++++++ src/mono/wasm/runtime/gc-common.h | 4 + src/native/libs/Common/pal_config.h.in | 16 ++ src/native/libs/Common/pal_error_common.h | 14 + src/native/libs/Common/pal_io_common.h | 4 + src/native/libs/Common/pal_utilities.h | 2 + .../CMakeLists.txt | 12 +- .../extra_libs.cmake | 2 +- src/native/libs/System.Native/CMakeLists.txt | 8 +- .../System.Net.Security.Native/CMakeLists.txt | 4 +- src/native/libs/build-native.sh | 15 +- src/native/libs/configure.cmake | 76 +++++- 27 files changed, 534 insertions(+), 93 deletions(-) diff --git a/eng/build.ps1 b/eng/build.ps1 index 9382d460248aff..e3e009d12da47d 100644 --- a/eng/build.ps1 +++ b/eng/build.ps1 @@ -241,6 +241,10 @@ if ($PSBoundParameters.ContainsKey('os') -and $PSBoundParameters['os'] -eq "Brow # make sure it is capitalized $PSBoundParameters['os'] = "Browser" } +if ($PSBoundParameters.ContainsKey('os') -and $PSBoundParameters['os'] -eq "wasi") { + # make sure it is not capitalized + $PSBoundParameters['os'] = "wasi" +} foreach ($argument in $PSBoundParameters.Keys) { diff --git a/eng/native/configurecompiler.cmake b/eng/native/configurecompiler.cmake index 2357455f9db677..507ff9e0ded205 100644 --- a/eng/native/configurecompiler.cmake +++ b/eng/native/configurecompiler.cmake @@ -169,7 +169,7 @@ elseif (CLR_CMAKE_HOST_UNIX) endif () endif(UPPERCASE_CMAKE_BUILD_TYPE STREQUAL DEBUG OR UPPERCASE_CMAKE_BUILD_TYPE STREQUAL CHECKED) - if(CLR_CMAKE_HOST_BROWSER) + if(CLR_CMAKE_HOST_BROWSER OR CLR_CMAKE_HOST_WASI) # The emscripten build has additional warnings so -Werror breaks add_compile_options(-Wno-unused-parameter) add_compile_options(-Wno-alloca) @@ -391,7 +391,7 @@ if (CLR_CMAKE_HOST_UNIX) add_definitions(-DLSE_INSTRUCTIONS_ENABLED_BY_DEFAULT) add_compile_options(-mcpu=apple-m1) endif(CLR_CMAKE_HOST_UNIX_ARM64) - elseif(NOT CLR_CMAKE_HOST_BROWSER) + elseif(NOT CLR_CMAKE_HOST_BROWSER AND NOT CLR_CMAKE_HOST_WASI) check_c_compiler_flag(-fstack-protector-strong COMPILER_SUPPORTS_F_STACK_PROTECTOR_STRONG) if (COMPILER_SUPPORTS_F_STACK_PROTECTOR_STRONG) add_compile_options(-fstack-protector-strong) @@ -793,7 +793,7 @@ if (CLR_CMAKE_HOST_WIN32) message(FATAL_ERROR "MC not found") endif() -elseif (NOT CLR_CMAKE_HOST_BROWSER) +elseif (NOT CLR_CMAKE_HOST_BROWSER AND NOT CLR_CMAKE_HOST_WASI) # This is a workaround for upstream issue: https://gitlab.kitware.com/cmake/cmake/-/issues/22995. # # In Clang.cmake, the decision to use single or double hyphen for target and gcc-toolchain diff --git a/eng/native/configureplatform.cmake b/eng/native/configureplatform.cmake index c849c592174af3..b064079402eb45 100644 --- a/eng/native/configureplatform.cmake +++ b/eng/native/configureplatform.cmake @@ -214,9 +214,9 @@ if(CLR_CMAKE_HOST_OS STREQUAL Emscripten) set(CLR_CMAKE_HOST_BROWSER 1) endif(CLR_CMAKE_HOST_OS STREQUAL Emscripten) -if(CLR_CMAKE_TARGET_OS STREQUAL Wasi) +if(CLR_CMAKE_TARGET_OS STREQUAL WASI) set(CLR_CMAKE_HOST_WASI 1) -endif(CLR_CMAKE_TARGET_OS STREQUAL Wasi) +endif(CLR_CMAKE_TARGET_OS STREQUAL WASI) #-------------------------------------------- # This repo builds two set of binaries @@ -417,9 +417,9 @@ if(CLR_CMAKE_TARGET_OS STREQUAL Emscripten) set(CLR_CMAKE_TARGET_BROWSER 1) endif(CLR_CMAKE_TARGET_OS STREQUAL Emscripten) -if(CLR_CMAKE_TARGET_OS STREQUAL Wasi) +if(CLR_CMAKE_TARGET_OS STREQUAL WASI) set(CLR_CMAKE_TARGET_WASI 1) -endif(CLR_CMAKE_TARGET_OS STREQUAL Wasi) +endif(CLR_CMAKE_TARGET_OS STREQUAL WASI) if(CLR_CMAKE_TARGET_UNIX) if(CLR_CMAKE_TARGET_ARCH STREQUAL x64) @@ -454,7 +454,7 @@ else() endif(CLR_CMAKE_TARGET_UNIX) # check if host & target os/arch combination are valid -if (NOT (CLR_CMAKE_TARGET_OS STREQUAL CLR_CMAKE_HOST_OS)) +if (NOT (CLR_CMAKE_TARGET_OS STREQUAL CLR_CMAKE_HOST_OS) AND NOT CLR_CMAKE_TARGET_WASI) if(NOT (CLR_CMAKE_HOST_OS STREQUAL windows)) message(FATAL_ERROR "Invalid host and target os/arch combination. Host OS: ${CLR_CMAKE_HOST_OS}") endif() @@ -466,7 +466,7 @@ if (NOT (CLR_CMAKE_TARGET_OS STREQUAL CLR_CMAKE_HOST_OS)) endif() endif() -if(NOT CLR_CMAKE_TARGET_BROWSER) +if(NOT CLR_CMAKE_TARGET_BROWSER AND NOT CLR_CMAKE_TARGET_WASI) # The default linker on Solaris also does not support PIE. if(NOT CLR_CMAKE_TARGET_ANDROID AND NOT CLR_CMAKE_TARGET_SUNOS AND NOT CLR_CMAKE_TARGET_OSX AND NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT CLR_CMAKE_HOST_TVOS AND NOT CLR_CMAKE_HOST_IOS AND NOT MSVC) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie") diff --git a/eng/native/configuretools.cmake b/eng/native/configuretools.cmake index 07a3bbfafe4dd9..1f800b0f897895 100644 --- a/eng/native/configuretools.cmake +++ b/eng/native/configuretools.cmake @@ -6,7 +6,7 @@ if (CMAKE_C_COMPILER MATCHES "-?[0-9]+(\.[0-9]+)?$") set(CLR_CMAKE_COMPILER_FILE_NAME_VERSION "${CMAKE_MATCH_0}") endif() -if(NOT WIN32 AND NOT CLR_CMAKE_TARGET_BROWSER) +if(NOT WIN32 AND NOT CLR_CMAKE_TARGET_BROWSER AND NOT CLR_CMAKE_TARGET_WASI) if(CMAKE_C_COMPILER_ID MATCHES "Clang") if(APPLE) set(TOOLSET_PREFIX "") diff --git a/eng/native/gen-buildsys.cmd b/eng/native/gen-buildsys.cmd index b97b8125e0f8c0..ed87ef0ad52eec 100644 --- a/eng/native/gen-buildsys.cmd +++ b/eng/native/gen-buildsys.cmd @@ -48,12 +48,12 @@ if /i "%__Arch%" == "wasm" ( ) if /i "%__Os%" == "Browser" ( if "%EMSDK_PATH%" == "" ( - if not exist "%__repoRoot%src\mono\wasm\emsdk" ( + if not exist "%__repoRoot%\src\mono\wasm\emsdk" ( echo Error: Should set EMSDK_PATH environment variable pointing to emsdk root. exit /B 1 ) - set EMSDK_PATH=%__repoRoot%src\mono\wasm\emsdk + set EMSDK_PATH=%__repoRoot%\src\mono\wasm\emsdk set EMSDK_PATH=!EMSDK_PATH:\=/! ) @@ -61,8 +61,17 @@ if /i "%__Arch%" == "wasm" ( set __UseEmcmake=1 ) if /i "%__Os%" == "wasi" ( - echo Error: WASI build not implemented on Windows yet - exit /B 1 + if "%WASI_SDK_PATH%" == "" ( + if not exist "%__repoRoot%\src\mono\wasi\wasi-sdk" ( + echo Error: Should set WASI_SDK_PATH environment variable pointing to emsdk root. + exit /B 1 + ) + + set WASI_SDK_PATH=%__repoRoot%src\mono\wasi\wasi-sdk + set WASI_SDK_PATH=!WASI_SDK_PATH:\=/! + ) + set __CmakeGenerator=Ninja + set __ExtraCmakeParams=%__ExtraCmakeParams% -DCLR_CMAKE_TARGET_OS=WASI -DCLR_CMAKE_TARGET_ARCH=wasm "-DWASI_SDK_PREFIX=!WASI_SDK_PATH!" "-DCMAKE_TOOLCHAIN_FILE=!WASI_SDK_PATH!/share/cmake/wasi-sdk.cmake" "-DCMAKE_SYSROOT=!WASI_SDK_PATH!/share/wasi-sysroot" ) ) else ( set __ExtraCmakeParams=%__ExtraCmakeParams% "-DCMAKE_SYSTEM_VERSION=10.0" diff --git a/src/coreclr/pal/src/config.h.in b/src/coreclr/pal/src/config.h.in index 75507804d23a00..5a48d405330de9 100644 --- a/src/coreclr/pal/src/config.h.in +++ b/src/coreclr/pal/src/config.h.in @@ -63,6 +63,9 @@ #cmakedefine01 HAS_SYSV_SEMAPHORES #cmakedefine01 HAS_PTHREAD_MUTEXES #cmakedefine HAVE_TTRACE +#cmakedefine01 HAVE_CHMOD +#cmakedefine01 HAVE_FCHMOD +#cmakedefine01 HAVE_PIPE #cmakedefine01 HAVE_PIPE2 #cmakedefine01 HAVE_SCHED_GETAFFINITY #cmakedefine01 HAVE_SCHED_SETAFFINITY diff --git a/src/coreclr/pal/src/configure.cmake b/src/coreclr/pal/src/configure.cmake index 4f900a5555ef63..399174a8764129 100644 --- a/src/coreclr/pal/src/configure.cmake +++ b/src/coreclr/pal/src/configure.cmake @@ -135,6 +135,9 @@ check_function_exists(semget HAS_SYSV_SEMAPHORES) check_function_exists(pthread_mutex_init HAS_PTHREAD_MUTEXES) check_function_exists(ttrace HAVE_TTRACE) check_function_exists(pipe2 HAVE_PIPE2) +check_function_exists(pipe HAVE_PIPE) +check_function_exists(chmod HAVE_CHMOD) +check_function_exists(fchmod HAVE_FCHMOD) check_cxx_source_compiles(" #include diff --git a/src/mono/CMakeLists.txt b/src/mono/CMakeLists.txt index cdff32677c0f5c..362c402dabd5cf 100644 --- a/src/mono/CMakeLists.txt +++ b/src/mono/CMakeLists.txt @@ -248,20 +248,15 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "WASI") add_definitions(-D_WASI_EMULATED_SIGNAL -D_WASI_EMULATED_MMAN -DHOST_WASI) add_definitions(-DNO_GLOBALIZATION_SHIM) add_definitions(-D_THREAD_SAFE) - add_definitions(-DGEN_PINVOKE) + add_definitions(-DDISABLE_SOCKET_TRANSPORT) + add_definitions(-DDISABLE_EGD_SOCKET) + add_definitions(-DDISABLE_EVENTPIPE) + set(ENABLE_PERFTRACING 0) + add_compile_options(-Wl,--allow-undefined) set(DISABLE_SHARED_LIBS 1) set(INTERNAL_ZLIB 1) set(DISABLE_EXECUTABLES 1) set(STATIC_COMPONENTS 1) - - set(WASI_DRIVER_SOURCES - wasi/mono-wasi-driver/driver.c - wasi/mono-wasi-driver/stubs.c - wasi/mono-wasi-driver/synthetic-pthread.c - ) - add_library(mono-wasi-driver STATIC ${WASI_DRIVER_SOURCES}) - target_compile_options(mono-wasi-driver PRIVATE -Wno-missing-prototypes -Wno-strict-prototypes) - install(TARGETS mono-wasi-driver LIBRARY) elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows") set(HOST_WIN32 1) set(EXE_SUFFIX ".exe") @@ -333,6 +328,10 @@ elseif(TARGET_SYSTEM_NAME STREQUAL "Emscripten") endif() elseif(TARGET_SYSTEM_NAME STREQUAL "WASI") set(TARGET_WASI 1) + set(DISABLE_THREADS 1) + if (CMAKE_BUILD_TYPE STREQUAL "Release") + add_compile_options(-Os) + endif() elseif(TARGET_SYSTEM_NAME STREQUAL "Windows") set(TARGET_WIN32 1) elseif(TARGET_SYSTEM_NAME STREQUAL "SunOS") @@ -679,7 +678,11 @@ elseif(HOST_OSX AND NOT HOST_MACCAT) set(OSX_ICU_LIBRARY_PATH /usr/lib/libicucore.dylib) set(ICU_FLAGS "-DTARGET_UNIX -DU_DISABLE_RENAMING -Wno-reserved-id-macro -Wno-documentation -Wno-documentation-unknown-command -Wno-switch-enum -Wno-covered-switch-default -Wno-extra-semi-stmt -Wno-unknown-warning-option -Wno-deprecated-declarations") set(HAVE_SYS_ICU 1) -elseif(HOST_WASM) +elseif(HOST_WASI) + set(HAVE_SYS_ICU 0) + set(STATIC_ICU 1) + set(ICU_LIBS "icucore") +elseif(HOST_BROWSER) set(ICU_FLAGS "-DPALEXPORT=\"\" -DU_DISABLE_RENAMING -DHAVE_UDAT_STANDALONE_SHORTER_WEEKDAYS -DHAVE_SET_MAX_VARIABLE -DTARGET_UNIX -Wno-reserved-id-macro -Wno-documentation -Wno-documentation-unknown-command -Wno-switch-enum -Wno-covered-switch-default -Wno-extra-semi-stmt -Wno-unknown-warning-option") set(HAVE_SYS_ICU 1) set(STATIC_ICU 1) @@ -736,6 +739,8 @@ elseif(GC_SUSPEND STREQUAL "default") # use preemptive elseif(TARGET_SYSTEM_NAME STREQUAL "Emscripten") # use preemptive + elseif(TARGET_SYSTEM_NAME STREQUAL "WASI") + # use preemptive else() set(ENABLE_HYBRID_SUSPEND 1) endif() @@ -903,7 +908,7 @@ endif() add_subdirectory("${CLR_SRC_NATIVE_DIR}/public" public_apis) add_subdirectory(mono) -if (ENABLE_MSCORDBI AND NOT TARGET_ARCH STREQUAL "arm64" AND NOT CMAKE_CROSSCOMPILING AND NOT TARGET_IOS AND NOT TARGET_ANDROID AND NOT TARGET_BROWSER AND NOT HOST_MACCAT) +if (ENABLE_MSCORDBI AND NOT TARGET_ARCH STREQUAL "arm64" AND NOT CMAKE_CROSSCOMPILING AND NOT TARGET_IOS AND NOT TARGET_ANDROID AND NOT TARGET_BROWSER AND NOT TARGET_WASI AND NOT HOST_MACCAT) add_subdirectory(dlls/mscordbi) add_subdirectory(dlls/dbgshim) endif() diff --git a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj index b23dce200a1ab0..284975754fbe6c 100644 --- a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -121,13 +121,13 @@ $(DefineConstants);MONO_FEATURE_SRE true - true - true + true + true true true - true - true - true + true + true + true true @@ -274,16 +274,16 @@ - + - + - + - + @@ -301,6 +301,9 @@ + + + diff --git a/src/mono/cmake/config.h.in b/src/mono/cmake/config.h.in index f53d12433aae82..13704912bea374 100644 --- a/src/mono/cmake/config.h.in +++ b/src/mono/cmake/config.h.in @@ -171,6 +171,9 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_PWD_H 1 +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_GRP_H 1 + /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_SELECT_H 1 diff --git a/src/mono/cmake/configure.cmake b/src/mono/cmake/configure.cmake index ae55fd112b321e..56b092e0add08b 100644 --- a/src/mono/cmake/configure.cmake +++ b/src/mono/cmake/configure.cmake @@ -23,7 +23,7 @@ if(HOST_SOLARIS) endif() if(HOST_WASI) - set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_WASI_EMULATED_SIGNAL -D_WASI_EMULATED_MMAN") + set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_WASI_EMULATED_PROCESS_CLOCKS -D_WASI_EMULATED_SIGNAL -D_WASI_EMULATED_MMAN") endif() function(ac_check_headers) @@ -85,13 +85,18 @@ ac_check_funcs ( gethrtime read_real_time gethostbyname gethostbyname2 getnameinfo getifaddrs access inet_ntop Qp2getifaddrs getpid mktemp) -if (HOST_LINUX OR HOST_BROWSER) +if (HOST_LINUX OR HOST_BROWSER OR HOST_WASI) # sysctl is deprecated on Linux and doesn't work on Browser set(HAVE_SYS_SYSCTL_H 0) else () check_include_files("sys/types.h;sys/sysctl.h" HAVE_SYS_SYSCTL_H) endif() +if (HOST_WASI) + # sysctl is deprecated on Linux and doesn't work on Browser + set(HAVE_GETRUSAGE 0) +endif() + check_include_files("sys/types.h;sys/user.h" HAVE_SYS_USER_H) if(NOT HOST_DARWIN) @@ -99,7 +104,9 @@ if(NOT HOST_DARWIN) ac_check_funcs (getentropy) endif() -find_package(Threads) +if(NOT HOST_WASI) + find_package(Threads) +endif() # Needed to find pthread_ symbols set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}") diff --git a/src/mono/mono.proj b/src/mono/mono.proj index 59fea4a2f72e1d..7ac2b47b923d12 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -28,7 +28,7 @@ $(CoreClrLibName) $(LibPrefix)$(MonoSharedLibName)$(LibSuffix) $(LibPrefix)$(MonoLibName)$(StaticLibSuffix) - $(MonoStaticLibFileName) + $(MonoStaticLibFileName) $(MonoSharedLibFileName) mono-aot-cross$(ExeSuffix) mono-aot-cross.pdb @@ -62,7 +62,7 @@ coop - preemptive + preemptive hybrid @@ -70,6 +70,7 @@ true + true true true false @@ -80,12 +81,12 @@ true - + - + <_MonoCMakeArgs Include="-DENABLE_WERROR=1"/> @@ -98,6 +99,7 @@ + @@ -139,15 +141,15 @@ - .sh + .ps1 $(ProvisionEmscriptenDir) $([MSBuild]::NormalizeDirectory('$(MSBuildThisFileDirectory)', 'wasm')) emsdk %(_VersionLines.Identity) - ./emsdk$(EmsdkExt) install $(EmscriptenVersion) - ./emsdk$(EmsdkExt) activate $(EmscriptenVersion) + $(EMSDK_PATH)/emsdk$(EmsdkExt) install $(EmscriptenVersion) + $(EMSDK_PATH)/emsdk$(EmsdkExt) activate $(EmscriptenVersion) powershell -NonInteractive -command "& $(InstallCmd); Exit $LastExitCode " powershell -NonInteractive -command "& $(ActivateCmd); Exit $LastExitCode " @@ -161,6 +163,50 @@ IgnoreStandardErrorWarningFormat="true" /> + + + + + + + + $(ProvisionWasiSdkDir) + $([MSBuild]::NormalizeDirectory('$(MSBuildThisFileDirectory)', 'wasi')) + %(_VersionLines.Identity) + https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-$(WasiSdkVersion)/wasi-sdk-$(WasiSdkVersion).0-linux.tar.gz + https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-$(WasiSdkVersion)/wasi-sdk-$(WasiSdkVersion).0-macos.tar.gz + https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-$(WasiSdkVersion)/wasi-sdk-$(WasiSdkVersion).0-mingw.tar.gz + + + + + + + + + + + + + + + + + + %(_ActualVersionLines.Identity) + %(_ExpectedVersionLines.Identity) + + + + @@ -487,7 +533,7 @@ <_MonoCMakeArgs Include="-DFEATURE_PERFTRACING_DISABLE_DEFAULT_LISTEN_PORT=1"/> - + <_MonoCMakeArgs Include="-DFEATURE_PERFTRACING_DISABLE_PERFTRACING_LISTEN_PORTS=1"/> <_MonoCMakeArgs Include="-DFEATURE_PERFTRACING_DISABLE_DEFAULT_LISTEN_PORT=1"/> <_MonoCMakeArgs Include="-DFEATURE_PERFTRACING_DISABLE_CONNECT_PORTS=1" /> @@ -512,18 +558,21 @@ $([MSBuild]::EnsureTrailingSlash('$(EMSDK_PATH)')) + $([MSBuild]::EnsureTrailingSlash('$(WASI_SDK_PATH)')) <_MonoCMakeConfigureCommand>cmake @(_MonoCMakeArgs, ' ') $(MonoCMakeExtraArgs) "$(MonoProjectRoot.TrimEnd('\/'))" - <_MonoCMakeConfigureCommand Condition="'$(TargetsBrowser)' != 'true' and '$(_MonoRunInitCompiler)' != 'false' and '$(HostOS)' != 'windows'">bash -c 'source $(RepositoryEngineeringCommonDir)native/init-compiler.sh "$(RepositoryEngineeringCommonDir)native" "$(_CompilerTargetArch)" "$(MonoCCompiler)" && @(_MonoBuildEnv, ' ') $(_MonoCMakeConfigureCommand)' - <_MonoCMakeConfigureCommand Condition="'$(TargetsBrowser)' != 'true' and '$(_MonoRunInitCompiler)' != 'false' and '$(HostOS)' == 'windows'">call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" $(_CompilerTargetArch) && cd /D "$(MonoObjDir)" && @(_MonoBuildEnv, ' ') $(_MonoCMakeConfigureCommand) - <_MonoCMakeConfigureCommand Condition="'$(TargetsBrowser)' != 'true' and '$(_MonoRunInitCompiler)' == 'false'">$(_MonoCCOption) $(_MonoCXXOption) @(_MonoBuildEnv, ' ') $(_MonoCMakeConfigureCommand) + <_MonoCMakeConfigureCommand Condition="'$(TargetsBrowser)' != 'true' and '$(TargetsWasi)' != 'true' and '$(_MonoRunInitCompiler)' != 'false' and '$(HostOS)' != 'windows'">bash -c 'source $(RepositoryEngineeringCommonDir)native/init-compiler.sh "$(RepositoryEngineeringCommonDir)native" "$(_CompilerTargetArch)" "$(MonoCCompiler)" && @(_MonoBuildEnv, ' ') $(_MonoCMakeConfigureCommand)' + <_MonoCMakeConfigureCommand Condition="'$(TargetsBrowser)' != 'true' and '$(TargetsWasi)' != 'true' and '$(_MonoRunInitCompiler)' != 'false' and '$(HostOS)' == 'windows'">call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" $(_CompilerTargetArch) && cd /D "$(MonoObjDir)" && @(_MonoBuildEnv, ' ') $(_MonoCMakeConfigureCommand) + <_MonoCMakeConfigureCommand Condition="'$(TargetsBrowser)' != 'true' and '$(TargetsWasi)' != 'true' and '$(_MonoRunInitCompiler)' == 'false'">$(_MonoCCOption) $(_MonoCXXOption) @(_MonoBuildEnv, ' ') $(_MonoCMakeConfigureCommand) <_MonoCMakeConfigureCommand Condition="'$(TargetsBrowser)' == 'true' and '$(HostOS)' != 'windows'">bash -c 'source $(EMSDK_PATH)/emsdk_env.sh 2>&1 && emcmake $(_MonoCMakeConfigureCommand)' <_MonoCMakeConfigureCommand Condition="'$(TargetsBrowser)' == 'true' and '$(HostOS)' == 'windows'">call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" && call "$([MSBuild]::NormalizePath('$(EMSDK_PATH)', 'emsdk_env.bat'))" && emcmake $(_MonoCMakeConfigureCommand) + <_MonoCMakeConfigureCommand Condition="'$(TargetsWasi)' == 'true'">$(_MonoCMakeConfigureCommand) -DWASI_SDK_PREFIX=$(WASI_SDK_PATH) -DCMAKE_SYSROOT=$(WASI_SDK_PATH)share/wasi-sysroot -DCMAKE_TOOLCHAIN_FILE=$(WASI_SDK_PATH)share/cmake/wasi-sdk.cmake -DCMAKE_CXX_FLAGS="--sysroot=$(WASI_SDK_PATH)share/wasi-sysroot" + <_MonoCMakeBuildCommand>cmake --build . --target install --config $(Configuration) <_MonoCMakeBuildCommand Condition="'$(MonoVerboseBuild)' == 'true'">$(_MonoCMakeBuildCommand) --verbose <_MonoCMakeBuildCommand Condition="'$(_MonoUseNinja)' != 'true'">$(_MonoCMakeBuildCommand) --parallel $([System.Environment]::ProcessorCount) - <_MonoCMakeBuildCommand Condition="'$(TargetsBrowser)' != 'true' and '$(HostOS)' != 'windows'">@(_MonoBuildEnv, ' ') $(_MonoCMakeBuildCommand) - <_MonoCMakeBuildCommand Condition="'$(TargetsBrowser)' != 'true' and '$(HostOS)' == 'windows'">call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" $(_CompilerTargetArch) && cd /D "$(MonoObjDir)" && @(_MonoBuildEnv, ' ') $(_MonoCMakeBuildCommand) + <_MonoCMakeBuildCommand Condition="'$(TargetsBrowser)' != 'true' and '$(TargetsWasi)' != 'true' and '$(HostOS)' != 'windows'">@(_MonoBuildEnv, ' ') $(_MonoCMakeBuildCommand) + <_MonoCMakeBuildCommand Condition="'$(TargetsBrowser)' != 'true' and '$(TargetsWasi)' != 'true' and '$(HostOS)' == 'windows'">call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" $(_CompilerTargetArch) && cd /D "$(MonoObjDir)" && @(_MonoBuildEnv, ' ') $(_MonoCMakeBuildCommand) <_MonoCMakeBuildCommand Condition="'$(TargetsBrowser)' == 'true' and '$(HostOS)' == 'windows'">call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" && $(_MonoCMakeBuildCommand) @@ -797,6 +846,7 @@ CheckEnv;GetXcodeDir;GenerateRuntimeVersionFile;BuildMonoRuntime;BuildMonoCross GenerateRuntimeVersionFile;ProvisionEmscripten;$(MonoDependsOnTargets) + GenerateRuntimeVersionFile;ProvisionWasiSdk;ValidateWasiSdk;$(MonoDependsOnTargets) @@ -805,7 +855,7 @@ <_MonoRuntimeFilePath Condition="'$(TargetsWindows)' == 'true'">$(MonoObjDir)out\bin\$(MonoFileName) <_MonoRuntimeFilePath Condition="'$(_MonoRuntimeFilePath)' == ''">$(MonoObjDir)out\lib\$(MonoFileName) <_MonoRuntimeStaticFilePath Condition="'$(TargetsMacCatalyst)' == 'true' or '$(TargetsiOS)' == 'true' or '$(TargetstvOS)' == 'true' or '$(TargetsAndroid)' == 'true' or '$(TargetsLinuxBionic)' == 'true'">$(MonoObjDir)out\lib\$(MonoStaticLibFileName) - <_MonoIncludeInterpStaticFiles Condition="'$(TargetsBrowser)' == 'true'">true + <_MonoIncludeInterpStaticFiles Condition="'$(TargetsBrowser)' == 'true' or '$(TargetsWasi)' == 'true'">true <_MonoIncludeIcuFiles Condition="'$(TargetsiOS)' == 'true' or '$(TargetstvOS)' == 'true' or '$(TargetsMacCatalyst)' == 'true'">true diff --git a/src/mono/mono/mini/CMakeLists.txt b/src/mono/mono/mini/CMakeLists.txt index 30df4bac1f7797..0848baf8593e44 100644 --- a/src/mono/mono/mini/CMakeLists.txt +++ b/src/mono/mono/mini/CMakeLists.txt @@ -340,7 +340,7 @@ endif() if(HOST_WIN32) set(mini_sources "${mini_sources};${VERSION_FILE_RC_PATH}") # this is generated by GenerateNativeVersionFile in Arcade -elseif(NOT HOST_BROWSER) +elseif(NOT HOST_BROWSER AND NOT HOST_WASI) set(mini_sources "${mini_sources};${VERSION_FILE_PATH}") # this is generated by GenerateNativeVersionFile in Arcade endif() diff --git a/src/mono/mono/utils/CMakeLists.txt b/src/mono/mono/utils/CMakeLists.txt index 4d552b6e033dd9..f4011f0e6f9586 100644 --- a/src/mono/mono/utils/CMakeLists.txt +++ b/src/mono/mono/utils/CMakeLists.txt @@ -217,7 +217,7 @@ elseif(TARGET_RISCV64) set(utils_arch_sources "${utils_arch_sources};mono-hwcap-riscv.c") elseif(TARGET_S390X) set(utils_arch_sources "${utils_arch_sources};mono-hwcap-s390x.c") -elseif(TARGET_WASM) +elseif(TARGET_BROWSER OR TARGET_WASI) set(utils_arch_sources "${utils_arch_sources};mono-hwcap-wasm.c;mono-mmap-wasm.c") elseif(TARGET_POWERPC OR TARGET_POWERPC64) set(utils_arch_sources "${utils_arch_sources};mono-hwcap-ppc.c") diff --git a/src/mono/mono/utils/mono-rand.c b/src/mono/mono/utils/mono-rand.c index cb78275d75677d..0f64d3b9eacdbd 100644 --- a/src/mono/mono/utils/mono-rand.c +++ b/src/mono/mono/utils/mono-rand.c @@ -121,6 +121,7 @@ mono_getentropy (guchar *buffer, gssize buffer_size, MonoError *error) } #endif /* HAVE_GETENTROPY */ +#if !defined(DISABLE_EGD_SOCKET) static void get_entropy_from_egd (const char *path, guchar *buffer, gssize buffer_size, MonoError *error) { @@ -222,6 +223,7 @@ mono_rand_open (void) return TRUE; } +#endif /* !DISABLE_EGD_SOCKET */ gpointer mono_rand_init (const guchar *seed, gssize seed_size) @@ -250,9 +252,9 @@ mono_rand_try_get_bytes (gpointer *handle, guchar *buffer, gssize buffer_size, M if (res == 1) return TRUE; +#elif !defined(DISABLE_EGD_SOCKET) /* getrandom() or getentropy() function is not available: failed with ENOSYS or EPERM. Fall back on reading from /dev/urandom. */ -#endif if (use_egd) { char *socket_path = g_getenv ("MONO_EGD_SOCKET"); @@ -263,21 +265,22 @@ mono_rand_try_get_bytes (gpointer *handle, guchar *buffer, gssize buffer_size, M } get_entropy_from_egd (socket_path, buffer, buffer_size, error); g_free (socket_path); - } else { - /* Read until the buffer is filled. This may block if using NAME_DEV_RANDOM. */ - while (buffer_size > 0) { - gssize const err = read (file, buffer, buffer_size); - if (err < 0) { - if (errno == EINTR) - continue; - g_warning("Entropy error! Error in read (%s).", strerror (errno)); - /* exception will be thrown in managed code */ - mono_error_set_execution_engine (error, "Entropy error! Error in read (%s).", strerror (errno)); - return FALSE; - } - buffer += err; - buffer_size -= err; + return TRUE; + } +#endif + /* Read until the buffer is filled. This may block if using NAME_DEV_RANDOM. */ + while (buffer_size > 0) { + gssize const err = read (file, buffer, buffer_size); + if (err < 0) { + if (errno == EINTR) + continue; + g_warning("Entropy error! Error in read (%s).", strerror (errno)); + /* exception will be thrown in managed code */ + mono_error_set_execution_engine (error, "Entropy error! Error in read (%s).", strerror (errno)); + return FALSE; } + buffer += err; + buffer_size -= err; } return TRUE; } diff --git a/src/mono/wasi/wasi.proj b/src/mono/wasi/wasi.proj index 7053b6b952e0e6..5ec5c4cc121fe0 100644 --- a/src/mono/wasi/wasi.proj +++ b/src/mono/wasi/wasi.proj @@ -1,2 +1,244 @@ + + + wasi-wasm + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'native', '$(NetCoreAppCurrent)-$(TargetOS)-$(Configuration)-$(TargetArchitecture)')) + + + + + $([MSBuild]::NormalizeDirectory('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'browser-wasm', 'native', 'lib')) + $([MSBuild]::NormalizeDirectory('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'browser-wasm-threads', 'native', 'lib')) + false + false + $(ArtifactsObjDir)wasm + <_WasiDefaultsRspPath>$(NativeBinDir)src\wasi-default.rsp + <_WasiCompileRspPath>$(NativeBinDir)src\wasi-compile.rsp + <_WasiLinkRspPath>$(NativeBinDir)src\wasi-link.rsp + false + + + + + + + + + + + + + + + + + $(NativeBinDir)dotnet.timezones.blat + + + + + + + + + $(WasmObjDir)\pinvoke-table.h + $(WasmObjDir)\wasm_m2n_invoke.g.h + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_WasiFlags Include="@(_WasiCommonFlags)" /> + + <_WasiCompileFlags Condition="'$(MonoWasmThreads)' == 'true'" Include="-I$([MSBuild]::NormalizePath('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'browser-wasm-threads', 'native', 'include').Replace('\','/'))"/> + <_WasiCompileFlags Condition="'$(MonoWasmThreads)' != 'true'" Include="-I$([MSBuild]::NormalizePath('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'browser-wasm', 'native', 'include').Replace('\','/'))"/> + <_WasiCompileFlags Include="-I$([MSBuild]::NormalizePath('$(MonoProjectRoot)', 'wasi', 'include').Replace('\','/'))"/> + <_WasiCompileFlags Include="-I$([MSBuild]::NormalizePath('$(MonoProjectRoot)', 'wasi', 'mono-include').Replace('\','/'))"/> + <_WasiCompileFlags Include="-I$([MSBuild]::NormalizePath('$(RepoRoot)', 'src', 'native', 'public').Replace('\','/'))"/> + <_WasiCompileFlags Include="-I$([MSBuild]::NormalizePath('$(MonoProjectRoot)', 'mono', 'eglib').Replace('\','/'))"/> + <_WasiCompileFlags Include="-D_WASI_EMULATED_PROCESS_CLOCKS"/> + <_WasiCompileFlags Include="-D_WASI_EMULATED_SIGNAL"/> + <_WasiCompileFlags Include="-D_WASI_EMULATED_MMAN"/> + <_WasiLinkFlags Include="-Wl,-z,stack-size=1048576,--initial-memory=5242880,--max-memory=52428800,-lwasi-emulated-process-clocks,-lwasi-emulated-signal,-lwasi-emulated-mman"/> + + + + <_WasmOptConfigurationFlags>@(WasmOptConfigurationFlags, '%3B ') + <_WasiPropsJson> + + + + + + + + + + + + + + + + + + + + + $(ArtifactsObjDir)wasm/pinvoke-table.h + $(ArtifactsObjDir)wasm/wasm_m2n_invoke.g.h + + -g -Os -DDEBUG=1 -DENABLE_AOT_PROFILER=1 + -Oz + + $(CMakeConfigurationWasiFlags) + -O2 + + cmake $(MSBuildThisFileDirectory)runtime + cmake -G Ninja $(MSBuildThisFileDirectory)runtime + + $(CMakeBuildRuntimeConfigureCmd) -DWASI_SDK_PREFIX=$(WASI_SDK_PATH) + $(CMakeBuildRuntimeConfigureCmd) -DCMAKE_SYSROOT=$(WASI_SDK_PATH)share/wasi-sysroot + $(CMakeBuildRuntimeConfigureCmd) -DCMAKE_TOOLCHAIN_FILE=$(WASI_SDK_PATH)share/cmake/wasi-sdk.cmake + $(CMakeBuildRuntimeConfigureCmd) -DCMAKE_CXX_FLAGS="--sysroot=$(WASI_SDK_PATH)share/wasi-sysroot" + + $(CMakeBuildRuntimeConfigureCmd) -DCONFIGURATION_WASICC_FLAGS="$(CMakeConfigurationWasiFlags)" + $(CMakeBuildRuntimeConfigureCmd) -DCONFIGURATION_LINK_FLAGS="$(CMakeConfigurationLinkFlags)" + $(CMakeBuildRuntimeConfigureCmd) -DCONFIGURATION_WASM_OPT_FLAGS="@(WasmOptConfigurationFlags, ';')" + $(CMakeBuildRuntimeConfigureCmd) -DMONO_INCLUDES="$(MonoArtifactsPath)include/mono-2.0" + $(CMakeBuildRuntimeConfigureCmd) -DMONO_OBJ_INCLUDES="$(MonoObjDir.TrimEnd('\/'))" + + $(CMakeBuildRuntimeConfigureCmd) -DMONO_ARTIFACTS_DIR="$(MonoArtifactsPath.TrimEnd('\/'))" + $(CMakeBuildRuntimeConfigureCmd) -DNATIVE_BIN_DIR="$(NativeBinDir.TrimEnd('\/'))" + $(CMakeBuildRuntimeConfigureCmd) -DWASM_OPT_ADDITIONAL_FLAGS="--enable-simd" + $(CMakeBuildRuntimeConfigureCmd) -DDISABLE_THREADS=0 + $(CMakeBuildRuntimeConfigureCmd) -DDISABLE_WASM_USER_THREADS=1 + call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" wasm && $(CMakeBuildRuntimeConfigureCmd) + + -v + cmake --build . --config $(Configuration) $(CmakeOptions) + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mono/wasm/runtime/gc-common.h b/src/mono/wasm/runtime/gc-common.h index 92789e641a361e..4432633db76459 100644 --- a/src/mono/wasm/runtime/gc-common.h +++ b/src/mono/wasm/runtime/gc-common.h @@ -1,6 +1,10 @@ #define PVOLATILE(T) T* volatile #define PPVOLATILE(T) T* volatile * +#if !defined(TARGET_BROWSER) && !defined(EMSCRIPTEN_KEEPALIVE) +#define EMSCRIPTEN_KEEPALIVE +#endif + #define gpointer void* MONO_API MONO_RT_EXTERNAL_ONLY gpointer diff --git a/src/native/libs/Common/pal_config.h.in b/src/native/libs/Common/pal_config.h.in index acacfb33e34a3c..464ae1d3266070 100644 --- a/src/native/libs/Common/pal_config.h.in +++ b/src/native/libs/Common/pal_config.h.in @@ -8,6 +8,7 @@ #cmakedefine01 HAVE_STATFS_MOUNT #cmakedefine01 HAVE_FLOCK64 #cmakedefine01 HAVE_F_DUPFD_CLOEXEC +#cmakedefine01 HAVE_F_DUPFD #cmakedefine01 HAVE_F_FULLFSYNC #cmakedefine01 HAVE_O_CLOEXEC #cmakedefine01 HAVE_GETIFADDRS @@ -15,6 +16,9 @@ #cmakedefine01 HAVE_STAT64 #cmakedefine01 HAVE_FORK #cmakedefine01 HAVE_VFORK +#cmakedefine01 HAVE_CHMOD +#cmakedefine01 HAVE_FCHMOD +#cmakedefine01 HAVE_PIPE #cmakedefine01 HAVE_PIPE2 #cmakedefine01 HAVE_STAT_BIRTHTIME #cmakedefine01 HAVE_STAT_TIMESPEC @@ -51,6 +55,9 @@ #cmakedefine01 HAVE_FDS_BITS #cmakedefine01 HAVE_PRIVATE_FDS_BITS #cmakedefine01 HAVE_STATFS +#cmakedefine01 HAVE_MNTENT_H +#cmakedefine01 HAVE_SIGNAL_KILL +#cmakedefine01 HAVE_SYS_RESOURCE_H #cmakedefine01 HAVE_SYS_SOCKIO_H #cmakedefine01 HAVE_ETHTOOL_H #cmakedefine01 HAVE_SYS_POLL_H @@ -126,6 +133,15 @@ #cmakedefine01 HAVE_CFSETSPEED #cmakedefine01 HAVE_CFMAKERAW #cmakedefine01 HAVE_GETGROUPLIST +#cmakedefine01 HAVE_SYSLOG_H +#cmakedefine01 HAVE_PWD_H +#cmakedefine01 HAVE_GRP_H +#cmakedefine01 HAVE_TERMIOS_H +#cmakedefine01 HAVE_DLFCN_H +#cmakedefine01 HAVE_PTHREAD_H +#cmakedefine01 HAVE_SYS_WAIT_H +#cmakedefine01 HAVE_SYS_STATVFS_H +#cmakedefine01 HAVE_NET_IF_H #cmakedefine01 HAVE_SYS_PROCINFO_H #cmakedefine01 HAVE_IOSS_H #cmakedefine01 HAVE_ALIGNED_ALLOC diff --git a/src/native/libs/Common/pal_error_common.h b/src/native/libs/Common/pal_error_common.h index cf1bb7bcf4b5a1..e9de2b793e4086 100644 --- a/src/native/libs/Common/pal_error_common.h +++ b/src/native/libs/Common/pal_error_common.h @@ -309,12 +309,18 @@ inline static int32_t ConvertErrorPlatformToPal(int32_t platformErrno) case ESOCKTNOSUPPORT: return Error_ESOCKTNOSUPPORT; #endif +#ifdef EPFNOSUPPORT // not available in WASI case EPFNOSUPPORT: return Error_EPFNOSUPPORT; +#endif +#ifdef ESHUTDOWN // not available in WASI case ESHUTDOWN: return Error_ESHUTDOWN; +#endif +#ifdef EHOSTDOWN // not available in WASI case EHOSTDOWN: return Error_EHOSTDOWN; +#endif #ifdef ENODATA // not available in FreeBSD case ENODATA: return Error_ENODATA; @@ -495,16 +501,22 @@ inline static int32_t ConvertErrorPalToPlatform(int32_t error) return ETXTBSY; case Error_EXDEV: return EXDEV; +#ifdef EPFNOSUPPORT // not available in WASI case Error_EPFNOSUPPORT: return EPFNOSUPPORT; +#endif #ifdef ESOCKTNOSUPPORT case Error_ESOCKTNOSUPPORT: return ESOCKTNOSUPPORT; #endif +#ifdef ESHUTDOWN // not available in WASI case Error_ESHUTDOWN: return ESHUTDOWN; +#endif +#ifdef EHOSTDOWN // not available in WASI case Error_EHOSTDOWN: return EHOSTDOWN; +#endif #ifdef ENODATA // not available in FreeBSD case Error_ENODATA: return ENODATA; @@ -537,9 +549,11 @@ static bool TryConvertErrorToGai(int32_t error, int32_t* gaiError) switch (error) { +#ifdef EAI_NONAME // not available in WASI case EHOSTNOTFOUND: *gaiError = EAI_NONAME; return true; +#endif default: *gaiError = error; return false; diff --git a/src/native/libs/Common/pal_io_common.h b/src/native/libs/Common/pal_io_common.h index 82a82897444739..75c73b6ef68139 100644 --- a/src/native/libs/Common/pal_io_common.h +++ b/src/native/libs/Common/pal_io_common.h @@ -109,9 +109,11 @@ inline static int32_t Common_Poll(PollEvent* pollEvents, uint32_t eventCount, in case PAL_POLLIN: pollfds[i].events = POLLIN; break; +#ifdef POLLPRI // not available in WASI case PAL_POLLPRI: pollfds[i].events = POLLPRI; break; +#endif case PAL_POLLOUT: pollfds[i].events = POLLOUT; break; @@ -157,9 +159,11 @@ inline static int32_t Common_Poll(PollEvent* pollEvents, uint32_t eventCount, in case POLLIN: pollEvents[i].TriggeredEvents = PAL_POLLIN; break; +#ifdef POLLPRI // not available in WASI case POLLPRI: pollEvents[i].TriggeredEvents = PAL_POLLPRI; break; +#endif case POLLOUT: pollEvents[i].TriggeredEvents = PAL_POLLOUT; break; diff --git a/src/native/libs/Common/pal_utilities.h b/src/native/libs/Common/pal_utilities.h index d517974c9fcf3d..babb42bc4ceccd 100644 --- a/src/native/libs/Common/pal_utilities.h +++ b/src/native/libs/Common/pal_utilities.h @@ -83,7 +83,9 @@ inline static int ToFileDescriptorUnchecked(intptr_t fd) */ inline static int ToFileDescriptor(intptr_t fd) { +#ifndef TARGET_WASI assert(0 <= fd && fd < sysconf(_SC_OPEN_MAX)); +#endif return ToFileDescriptorUnchecked(fd); } diff --git a/src/native/libs/System.IO.Compression.Native/CMakeLists.txt b/src/native/libs/System.IO.Compression.Native/CMakeLists.txt index a44f847dfca43f..a2fe7605b47eae 100644 --- a/src/native/libs/System.IO.Compression.Native/CMakeLists.txt +++ b/src/native/libs/System.IO.Compression.Native/CMakeLists.txt @@ -6,7 +6,7 @@ set(NATIVECOMPRESSION_SOURCES pal_zlib.c ) -if (NOT CLR_CMAKE_TARGET_BROWSER) +if (NOT CLR_CMAKE_TARGET_BROWSER AND NOT CLR_CMAKE_TARGET_WASI) if (CLR_CMAKE_USE_SYSTEM_BROTLI) add_definitions(-DFEATURE_USE_SYSTEM_BROTLI) @@ -25,11 +25,11 @@ if (NOT CLR_CMAKE_TARGET_BROWSER) ) endif () -if (CLR_CMAKE_TARGET_UNIX OR CLR_CMAKE_TARGET_BROWSER) +if (CLR_CMAKE_TARGET_UNIX OR CLR_CMAKE_TARGET_BROWSER OR CLR_CMAKE_TARGET_WASI) set(NATIVE_LIBS_EXTRA) append_extra_compression_libs(NATIVE_LIBS_EXTRA) - if (CLR_CMAKE_TARGET_BROWSER) + if (CLR_CMAKE_TARGET_BROWSER OR CLR_CMAKE_TARGET_WASI) include(${CLR_SRC_NATIVE_DIR}/external/zlib.cmake) add_definitions(-DINTERNAL_ZLIB) set(NATIVECOMPRESSION_SOURCES ${ZLIB_SOURCES} ${NATIVECOMPRESSION_SOURCES}) @@ -44,7 +44,9 @@ if (CLR_CMAKE_TARGET_UNIX OR CLR_CMAKE_TARGET_BROWSER) # Delete this suppression once brotli is upgraded to vNext (current latest v1.0.9 # does not contain upstream fix: https://github.com/google/brotli/commit/0a3944c) - set(FLAGS "${FLAGS} -Wno-vla-parameter") + if (NOT CLR_CMAKE_TARGET_WASI) + set(FLAGS "${FLAGS} -Wno-vla-parameter") + endif () set_source_files_properties(${NATIVECOMPRESSION_SOURCES} PROPERTIES COMPILE_FLAGS ${FLAGS}) @@ -118,7 +120,7 @@ else () ) endif () - if (NOT GEN_SHARED_LIB AND NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_ANDROID AND NOT CLR_CMAKE_TARGET_BROWSER) + if (NOT GEN_SHARED_LIB AND NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_ANDROID AND NOT CLR_CMAKE_TARGET_BROWSER AND NOT CLR_CMAKE_TARGET_WASI) set(NATIVECOMPRESSION_SOURCES ${NATIVECOMPRESSION_SOURCES} entrypoints.c) endif () diff --git a/src/native/libs/System.IO.Compression.Native/extra_libs.cmake b/src/native/libs/System.IO.Compression.Native/extra_libs.cmake index b10776372f6cf5..78530ae98e8ff7 100644 --- a/src/native/libs/System.IO.Compression.Native/extra_libs.cmake +++ b/src/native/libs/System.IO.Compression.Native/extra_libs.cmake @@ -1,7 +1,7 @@ macro(append_extra_compression_libs NativeLibsExtra) # TODO: remove the mono-style HOST_ variable checks once Mono is using eng/native/configureplatform.cmake to define the CLR_CMAKE_TARGET_ defines - if (CLR_CMAKE_TARGET_BROWSER OR HOST_BROWSER) + if (CLR_CMAKE_TARGET_BROWSER OR HOST_BROWSER OR CLR_CMAKE_TARGET_WASI OR HOST_WASI) # nothing special to link elseif (CLR_CMAKE_TARGET_ANDROID OR HOST_ANDROID) # need special case here since we want to link against libz.so but find_package() would resolve libz.a diff --git a/src/native/libs/System.Native/CMakeLists.txt b/src/native/libs/System.Native/CMakeLists.txt index 61cd36da93b79b..d5037d5557d555 100644 --- a/src/native/libs/System.Native/CMakeLists.txt +++ b/src/native/libs/System.Native/CMakeLists.txt @@ -1,6 +1,6 @@ project(System.Native C) -if (NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS) +if (NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_WASI) add_definitions(-DHAS_CONSOLE_SIGNALS) endif () @@ -79,7 +79,7 @@ else () pal_iossupportversion.c) endif () -if (NOT CLR_CMAKE_TARGET_BROWSER) +if (NOT CLR_CMAKE_TARGET_BROWSER AND NOT CLR_CMAKE_TARGET_WASI) list (APPEND NATIVE_SOURCES pal_networkchange.c) endif () @@ -107,7 +107,7 @@ if (GEN_SHARED_LIB) ${NATIVE_LIBS_EXTRA} ) - if (NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_ANDROID AND NOT CLR_CMAKE_TARGET_BROWSER) + if (NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_ANDROID AND NOT CLR_CMAKE_TARGET_BROWSER AND NOT CLR_CMAKE_TARGET_WASI) add_custom_command(TARGET System.Native POST_BUILD COMMENT "Verifying System.Native entry points against entrypoints.c " COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/../verify-entrypoints.sh @@ -121,7 +121,7 @@ if (GEN_SHARED_LIB) install_with_stripped_symbols (System.Native PROGRAMS .) endif () -if (NOT GEN_SHARED_LIB AND NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_ANDROID AND NOT CLR_CMAKE_TARGET_BROWSER) +if (NOT GEN_SHARED_LIB AND NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_ANDROID AND NOT CLR_CMAKE_TARGET_BROWSER AND NOT CLR_CMAKE_TARGET_WASI) set(NATIVE_SOURCES ${NATIVE_SOURCES} entrypoints.c) endif() diff --git a/src/native/libs/System.Net.Security.Native/CMakeLists.txt b/src/native/libs/System.Net.Security.Native/CMakeLists.txt index 6fbe18f76872ef..50c9228fe3dd34 100644 --- a/src/native/libs/System.Net.Security.Native/CMakeLists.txt +++ b/src/native/libs/System.Net.Security.Native/CMakeLists.txt @@ -19,7 +19,7 @@ if (GEN_SHARED_LIB) ) endif() -if (NOT GEN_SHARED_LIB AND NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_ANDROID AND NOT CLR_CMAKE_TARGET_BROWSER) +if (NOT GEN_SHARED_LIB AND NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_ANDROID AND NOT CLR_CMAKE_TARGET_BROWSER AND NOT CLR_CMAKE_TARGET_WASI) set(NATIVEGSS_SOURCES ${NATIVEGSS_SOURCES} entrypoints.c) endif() @@ -35,7 +35,7 @@ if (GEN_SHARED_LIB) ${NATIVE_LIBS_EXTRA} ) - if (NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_ANDROID AND NOT CLR_CMAKE_TARGET_BROWSER) + if (NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_ANDROID AND NOT CLR_CMAKE_TARGET_BROWSER AND NOT CLR_CMAKE_TARGET_WASI) add_custom_command(TARGET System.Net.Security.Native POST_BUILD COMMENT "Verifying System.Net.Security.Native entry points against entrypoints.c " COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/../verify-entrypoints.sh diff --git a/src/native/libs/build-native.sh b/src/native/libs/build-native.sh index d93bffefbdd9f2..dc42d0d265a65a 100755 --- a/src/native/libs/build-native.sh +++ b/src/native/libs/build-native.sh @@ -52,11 +52,20 @@ if [[ "$__TargetOS" == Browser ]]; then fi fi source "$EMSDK_PATH"/emsdk_env.sh - export CLR_CC=$(which emcc) elif [[ "$__TargetOS" == wasi ]]; then - # nothing to do here - true + if [[ -z "$WASI_SDK_PATH" ]]; then + if [[ -d "$__RepoRootDir"/src/mono/wasi/wasi-sdk/ ]]; then + export WASI_SDK_PATH="$__RepoRootDir"/src/mono/wasi/wasi-sdk/ + else + echo "Error: You need to set the WASI_SDK_PATH environment variable pointing to the WASI SDK root." + exit 1 + fi + fi + + export CLR_CC="$WASI_SDK_PATH"bin/clang + export TARGET_BUILD_ARCH=wasm + __CMakeArgs="-DCLR_CMAKE_TARGET_OS=WASI -DCLR_CMAKE_TARGET_ARCH=wasm -DWASI_SDK_PREFIX=$WASI_SDK_PATH -DCMAKE_TOOLCHAIN_FILE=$WASI_SDK_PATH/share/cmake/wasi-sdk.cmake" elif [[ "$__TargetOS" == iOS || "$__TargetOS" == iOSSimulator ]]; then # nothing to do here true diff --git a/src/native/libs/configure.cmake b/src/native/libs/configure.cmake index 7c5b88e96d5d0f..3a023d53b8654b 100644 --- a/src/native/libs/configure.cmake +++ b/src/native/libs/configure.cmake @@ -131,6 +131,11 @@ check_symbol_exists( fcntl.h HAVE_F_DUPFD_CLOEXEC) +check_symbol_exists( + F_DUPFD + fcntl.h + HAVE_F_DUPFD) + check_symbol_exists( F_FULLFSYNC fcntl.h @@ -367,6 +372,19 @@ check_symbol_exists( ${STATFS_INCLUDES} HAVE_STATFS) +check_symbol_exists( + "kill" + "signal.h" + HAVE_SIGNAL_KILL) + +check_include_files( + "mntent.h" + HAVE_MNTENT_H) + +check_include_files( + "sys/resource.h" + HAVE_SYS_RESOURCE_H) + check_type_size( "struct statfs" STATFS_SIZE @@ -577,7 +595,7 @@ elseif(CLR_CMAKE_TARGET_ANDROID) unset(HAVE_ALIGNED_ALLOC) # only exists on newer Android set(HAVE_CLOCK_MONOTONIC 1) set(HAVE_CLOCK_REALTIME 1) -elseif(CLR_CMAKE_TARGET_BROWSER) +elseif(CLR_CMAKE_TARGET_BROWSER OR CLR_CMAKE_TARGET_WASI) set(HAVE_FORK 0) else() if(CLR_CMAKE_TARGET_OSX) @@ -661,7 +679,9 @@ elseif (HAVE_PTHREAD_IN_LIBC) set(PTHREAD_LIBRARY c) endif() -check_library_exists(${PTHREAD_LIBRARY} pthread_condattr_setclock "" HAVE_PTHREAD_CONDATTR_SETCLOCK) +if (NOT CLR_CMAKE_TARGET_WASI) + check_library_exists(${PTHREAD_LIBRARY} pthread_condattr_setclock "" HAVE_PTHREAD_CONDATTR_SETCLOCK) +endif() check_symbol_exists( futimes @@ -784,7 +804,7 @@ check_c_source_compiles( " HAVE_MKSTEMP) -if (NOT HAVE_MKSTEMPS AND NOT HAVE_MKSTEMP) +if (NOT HAVE_MKSTEMPS AND NOT HAVE_MKSTEMP AND NOT CLR_CMAKE_TARGET_WASI) message(FATAL_ERROR "Cannot find mkstemps nor mkstemp on this platform.") endif() @@ -872,6 +892,42 @@ check_symbol_exists( "unistd.h;grp.h" HAVE_GETGROUPLIST) +check_include_files( + "grp.h" + HAVE_GRP_H) + +check_include_files( + "syslog.h" + HAVE_SYSLOG_H) + +check_include_files( + "pwd.h" + HAVE_PWD_H) + +check_include_files( + "termios.h" + HAVE_TERMIOS_H) + +check_include_files( + "dlfcn.h" + HAVE_DLFCN_H) + +check_include_files( + "sys/wait.h" + HAVE_SYS_WAIT_H) + +check_include_files( + "sys/statvfs.h" + HAVE_SYS_STATVFS_H) + +check_include_files( + "net/if.h" + HAVE_NET_IF_H) + +check_include_files( + "pthread.h" + HAVE_PTHREAD_H) + if(CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS) set(HAVE_IOS_NET_ROUTE_H 1) set(HAVE_IOS_NET_IFMEDIA_H 1) @@ -1007,7 +1063,7 @@ set (CMAKE_REQUIRED_LIBRARIES ${PREVIOUS_CMAKE_REQUIRED_LIBRARIES}) set (HAVE_INOTIFY 0) if (HAVE_INOTIFY_INIT AND HAVE_INOTIFY_ADD_WATCH AND HAVE_INOTIFY_RM_WATCH) set (HAVE_INOTIFY 1) -elseif (CLR_CMAKE_TARGET_LINUX AND NOT CLR_CMAKE_TARGET_BROWSER) +elseif (CLR_CMAKE_TARGET_LINUX AND NOT CLR_CMAKE_TARGET_BROWSER AND NOT CLR_CMAKE_TARGET_WASI) message(FATAL_ERROR "Cannot find inotify functions on a Linux platform.") endif() @@ -1092,14 +1148,16 @@ check_symbol_exists( sys/sysmacros.h HAVE_MAKEDEV_SYSMACROSH) -if (NOT HAVE_MAKEDEV_FILEH AND NOT HAVE_MAKEDEV_SYSMACROSH) +if (NOT HAVE_MAKEDEV_FILEH AND NOT HAVE_MAKEDEV_SYSMACROSH AND NOT CLR_CMAKE_TARGET_WASI) message(FATAL_ERROR "Cannot find the makedev function on this platform.") endif() -check_symbol_exists( - getgrgid_r - grp.h - HAVE_GETGRGID_R) +if (NOT CLR_CMAKE_TARGET_WASI) + check_symbol_exists( + getgrgid_r + grp.h + HAVE_GETGRGID_R) +endif() configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/Common/pal_config.h.in From 31964c3467174eb219d4077044730a1f6770ff6d Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Wed, 30 Nov 2022 19:36:34 +0100 Subject: [PATCH 03/39] wip --- src/mono/Directory.Build.props | 9 +++++- src/mono/mono.proj | 30 +++++++++++++++---- src/native/libs/CMakeLists.txt | 22 ++++++++++---- .../CMakeLists.txt | 4 +-- 4 files changed, 52 insertions(+), 13 deletions(-) diff --git a/src/mono/Directory.Build.props b/src/mono/Directory.Build.props index b64f87e11d95c0..14ecb194fb8435 100644 --- a/src/mono/Directory.Build.props +++ b/src/mono/Directory.Build.props @@ -40,10 +40,17 @@ $([MSBuild]::NormalizeDirectory('$(MSBuildThisFileDirectory)', 'wasm', 'emsdk')) - true + true $(ProvisionEmscriptenDir.Replace('\', '/')) + + + $([MSBuild]::NormalizeDirectory('$(MSBuildThisFileDirectory)', 'wasi', 'wasi-sdk')) + $(ProvisionWasiSdkDir.Replace('\', '/')) + true + + $(TargetOS).$(Platform).$(Configuration) $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'mono', '$(TargetOS).$(Platform).$(Configuration)')) diff --git a/src/mono/mono.proj b/src/mono/mono.proj index 7ac2b47b923d12..ae6d1f92b59bba 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -252,7 +252,7 @@ <_MonoCMakeArgs Condition="'$(_MonoUseNinja)' == 'true'" Include="-G Ninja"/> - <_MonoCMakeArgs Include="-DCMAKE_INSTALL_PREFIX="$(MonoObjDir)out""/> + <_MonoCMakeArgs Include="-DCMAKE_INSTALL_PREFIX="$(MonoObjDir.Replace('\','/'))out""/> <_MonoCMakeArgs Include="-DCMAKE_INSTALL_LIBDIR=lib"/> <_MonoCMakeArgs Include="-DCMAKE_BUILD_TYPE=$(Configuration)"/> <_MonoCMakeArgs Condition="'$(CMakeArgs)' != ''" Include="$(CMakeArgs)"/> @@ -384,30 +384,50 @@ <_MonoBuildEnv Condition="'$(BuildArchitecture)' == 'arm64'" Include="arch -arch arm64" /> - + <_MonoMinimal Condition="'$(Configuration)' == 'Release'">,debugger_agent,log_dest <_MonoMinimal Condition="'$(Configuration)' == 'Release' and '$(MonoEnableAssertMessages)' != 'true'">$(_MonoMinimal),assert_messages <_MonoMinimal Condition="'$(MonoWasmThreads)' != 'true'">$(_MonoMinimal),threads <_MonoMinimal Condition="'$(MonoWasmThreadsNoUser)' == 'true'">$(_MonoMinimal),wasm_user_threads - + <_MonoCMakeArgs Include="-DENABLE_MINIMAL=jit,sgen_major_marksweep_conc,sgen_split_nursery,sgen_gc_bridge,sgen_toggleref,sgen_debug_helpers,sgen_binary_protocol,logging,interpreter,qcalls$(_MonoMinimal)"/> <_MonoCMakeArgs Include="-DENABLE_INTERP_LIB=1"/> <_MonoCMakeArgs Include="-DDISABLE_ICALL_TABLES=1"/> <_MonoCMakeArgs Include="-DENABLE_ICALL_EXPORT=1"/> <_MonoCMakeArgs Include="-DENABLE_LAZY_GC_THREAD_CREATION=1"/> - <_MonoCMakeArgs Include="-DENABLE_LLVM_RUNTIME=1"/> - <_MonoCMakeArgs Include="-DEMSCRIPTEN_SYSTEM_PROCESSOR=wasm"/> <_MonoCFLAGS Include="-fexceptions"/> <_MonoCFLAGS Condition="'$(MonoWasmThreads)' == 'true'" Include="-pthread"/> <_MonoCFLAGS Condition="'$(MonoWasmThreads)' == 'true'" Include="-D_GNU_SOURCE=1" /> <_MonoCXXFLAGS Include="-fexceptions"/> <_MonoCXXFLAGS Condition="'$(MonoWasmThreads)' == 'true'" Include="-pthread"/> <_MonoCXXFLAGS Condition="'$(MonoWasmThreads)' == 'true'" Include="-D_GNU_SOURCE=1" /> + + + + <_MonoCMakeArgs Include="-DENABLE_LLVM_RUNTIME=1"/> + <_MonoCMakeArgs Include="-DEMSCRIPTEN_SYSTEM_PROCESSOR=wasm"/> <_MonoCFLAGS Condition="'$(MonoWasmThreads)' == 'true'" Include="$(EscapedQuoteW)-I$([MSBuild]::NormalizePath('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'browser-wasm-threads', 'native', 'include'))$(EscapedQuoteW)"/> <_MonoCFLAGS Condition="'$(MonoWasmThreads)' != 'true'" Include="$(EscapedQuoteW)-I$([MSBuild]::NormalizePath('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'browser-wasm', 'native', 'include'))$(EscapedQuoteW)"/> + + + + <_MonoCFLAGS Include="$(EscapedQuoteW)-I$([MSBuild]::NormalizePath('$(MonoProjectRoot)', 'wasi', 'include').Replace('\','/'))$(EscapedQuoteW)"/> + <_MonoCFLAGS Include="$(EscapedQuoteW)-I$([MSBuild]::NormalizePath('$(MonoProjectRoot)', 'wasi', 'mono-include').Replace('\','/'))$(EscapedQuoteW)"/> + <_MonoCFLAGS Include="$(EscapedQuoteW)-I$([MSBuild]::NormalizePath('$(RepoRoot)', 'src', 'native', 'public').Replace('\','/'))$(EscapedQuoteW)"/> + <_MonoCFLAGS Include="$(EscapedQuoteW)-I$([MSBuild]::NormalizePath('$(MonoProjectRoot)', 'mono', 'eglib').Replace('\','/'))$(EscapedQuoteW)"/> + <_MonoCFLAGS Include="-D_WASI_EMULATED_PROCESS_CLOCKS"/> + <_MonoCFLAGS Include="-D_WASI_EMULATED_SIGNAL"/> + <_MonoCFLAGS Include="-D_WASI_EMULATED_MMAN"/> + + <_MonoCFLAGS Condition="'$(MonoWasmThreads)' == 'true'" Include="$(EscapedQuoteW)-I$([MSBuild]::NormalizePath('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'browser-wasm-threads', 'native', 'include').Replace('\','/'))$(EscapedQuoteW)"/> + <_MonoCFLAGS Condition="'$(MonoWasmThreads)' != 'true'" Include="$(EscapedQuoteW)-I$([MSBuild]::NormalizePath('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'browser-wasm', 'native', 'include').Replace('\','/'))$(EscapedQuoteW)"/> + <_MonoCCOption>CC="$(XcodeDir)/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" diff --git a/src/native/libs/CMakeLists.txt b/src/native/libs/CMakeLists.txt index 26ff71928ffb67..13c06f11493d75 100644 --- a/src/native/libs/CMakeLists.txt +++ b/src/native/libs/CMakeLists.txt @@ -35,7 +35,7 @@ else () set(STATIC_LIB_DESTINATION .) endif () -if (CLR_CMAKE_TARGET_UNIX OR CLR_CMAKE_TARGET_BROWSER) +if (CLR_CMAKE_TARGET_UNIX OR CLR_CMAKE_TARGET_BROWSER OR CLR_CMAKE_TARGET_WASI) set(CMAKE_MACOSX_RPATH ON) if (CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS) set(CMAKE_BUILD_WITH_INSTALL_NAME_DIR ON) @@ -48,11 +48,23 @@ if (CLR_CMAKE_TARGET_UNIX OR CLR_CMAKE_TARGET_BROWSER) add_compile_options(-I${CMAKE_CURRENT_SOURCE_DIR}/Common) add_compile_options(-I${CMAKE_CURRENT_BINARY_DIR}/Common) - if (CLR_CMAKE_TARGET_BROWSER) + if (CLR_CMAKE_TARGET_BROWSER OR CLR_CMAKE_TARGET_WASI) set(GEN_SHARED_LIB 0) set(STATIC_LIB_DESTINATION .) endif () + if (CLR_CMAKE_TARGET_WASI) + add_compile_options(-I${CLR_REPO_ROOT_DIR}/src/mono/wasi/include/) + add_compile_options(-I${CLR_REPO_ROOT_DIR}/src/mono/wasi/libs-include/) + add_compile_options(-Wno-unused-variable) + add_compile_options(-Wno-unused-parameter) + add_compile_options(-Wno-gnu-statement-expression) + add_compile_options(-D_WASI_EMULATED_PROCESS_CLOCKS) + add_compile_options(-D_WASI_EMULATED_SIGNAL) + add_compile_options(-D_WASI_EMULATED_MMAN) + add_link_options(-Wl,-z,stack-size=1048576,--initial-memory=5242880,--max-memory=52428800,-lwasi-emulated-process-clocks,-lwasi-emulated-signal,-lwasi-emulated-mman) + endif () + if (CLR_CMAKE_TARGET_TVOS) # with -fembed-bitcode passing -headerpad_max_install_names is not allowed so remove it from the CMake flags string(REPLACE "-Wl,-headerpad_max_install_names" "" CMAKE_C_LINK_FLAGS ${CMAKE_C_LINK_FLAGS}) @@ -133,10 +145,10 @@ endif () add_subdirectory(System.IO.Compression.Native) -if (CLR_CMAKE_TARGET_UNIX OR CLR_CMAKE_TARGET_BROWSER) +if (CLR_CMAKE_TARGET_UNIX OR CLR_CMAKE_TARGET_BROWSER OR CLR_CMAKE_TARGET_WASI) include(configure.cmake) - if (NOT CLR_CMAKE_TARGET_BROWSER AND NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_ANDROID) + if (NOT CLR_CMAKE_TARGET_BROWSER AND NOT CLR_CMAKE_TARGET_WASI AND NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_ANDROID) add_subdirectory(System.IO.Ports.Native) endif () @@ -154,7 +166,7 @@ if (CLR_CMAKE_TARGET_UNIX OR CLR_CMAKE_TARGET_BROWSER) add_subdirectory(System.Native) - if (CLR_CMAKE_TARGET_BROWSER) + if (CLR_CMAKE_TARGET_BROWSER OR CLR_CMAKE_TARGET_WASI) # skip for now elseif (CLR_CMAKE_TARGET_MACCATALYST) add_subdirectory(System.Net.Security.Native) diff --git a/src/native/libs/System.Globalization.Native/CMakeLists.txt b/src/native/libs/System.Globalization.Native/CMakeLists.txt index 5e2fb2948cc436..0ee4e400c5f4ce 100644 --- a/src/native/libs/System.Globalization.Native/CMakeLists.txt +++ b/src/native/libs/System.Globalization.Native/CMakeLists.txt @@ -77,11 +77,11 @@ if (CLR_CMAKE_TARGET_OSX OR CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS endif() # time zone names are filtered out of icu data for the browser and associated functionality is disabled -if (NOT CLR_CMAKE_TARGET_BROWSER) +if (NOT CLR_CMAKE_TARGET_BROWSER AND NOT CLR_CMAKE_TARGET_WASI) set(NATIVEGLOBALIZATION_SOURCES ${NATIVEGLOBALIZATION_SOURCES} pal_timeZoneInfo.c) endif() -if (NOT GEN_SHARED_LIB AND NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_ANDROID AND NOT CLR_CMAKE_TARGET_BROWSER) +if (NOT GEN_SHARED_LIB AND NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_ANDROID AND NOT CLR_CMAKE_TARGET_BROWSER AND NOT CLR_CMAKE_TARGET_WASI) set(NATIVEGLOBALIZATION_SOURCES ${NATIVEGLOBALIZATION_SOURCES} entrypoints.c) endif() From d261d1b393a92f0a5116397d2ee8ce59a70e7b34 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Wed, 30 Nov 2022 20:08:53 +0100 Subject: [PATCH 04/39] wip --- src/libraries/System.Console/src/System/ConsolePal.Unix.cs | 4 +++- src/libraries/System.Console/src/System/IO/KeyParser.cs | 2 +- src/libraries/System.Console/src/System/IO/StdInReader.cs | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Console/src/System/ConsolePal.Unix.cs b/src/libraries/System.Console/src/System/ConsolePal.Unix.cs index d22e7936c6428c..c82d2c30300648 100644 --- a/src/libraries/System.Console/src/System/ConsolePal.Unix.cs +++ b/src/libraries/System.Console/src/System/ConsolePal.Unix.cs @@ -23,9 +23,9 @@ internal static partial class ConsolePal // StdInReader is only used when input isn't redirected and we're working // with an interactive terminal. In that case, performance isn't critical // and we can use a smaller buffer to minimize working set. +#if !TARGET_WASI private const int InteractiveBufferSize = 255; -#if !TARGET_WASI // For performance we cache Cursor{Left,Top} and Window{Width,Height}. // These values must be read/written under lock (Console.Out). // We also need to invalidate these values when certain signals occur. @@ -269,11 +269,13 @@ public static void Beep() #endif #if TARGET_WASI +#pragma warning disable IDE0060 public static void Clear() => throw new PlatformNotSupportedException(); public static void SetCursorPosition(int left, int top) => throw new PlatformNotSupportedException(); public static bool IsInputRedirectedCore() => throw new PlatformNotSupportedException(); public static bool IsOutputRedirectedCore() => throw new PlatformNotSupportedException(); public static bool IsErrorRedirectedCore() => throw new PlatformNotSupportedException(); +#pragma warning restore IDE0060 #else public static void Clear() { diff --git a/src/libraries/System.Console/src/System/IO/KeyParser.cs b/src/libraries/System.Console/src/System/IO/KeyParser.cs index 0b048f030fba78..ce1114c23fe6f2 100644 --- a/src/libraries/System.Console/src/System/IO/KeyParser.cs +++ b/src/libraries/System.Console/src/System/IO/KeyParser.cs @@ -10,12 +10,12 @@ internal static class KeyParser { private const char Escape = '\u001B'; private const char Delete = '\u007F'; +#if !TARGET_WASI private const char VtSequenceEndTag = '~'; private const char ModifierSeparator = ';'; private const int MinimalSequenceLength = 3; private const int SequencePrefixLength = 2; // ^[[ ("^[" stands for Escape) -#if !TARGET_WASI internal static ConsoleKeyInfo Parse(char[] buffer, TerminalFormatStrings terminalFormatStrings, byte posixDisableValue, byte veraseCharacter, ref int startIndex, int endIndex) { int length = endIndex - startIndex; diff --git a/src/libraries/System.Console/src/System/IO/StdInReader.cs b/src/libraries/System.Console/src/System/IO/StdInReader.cs index 56c2977245161d..009a4cb4c35497 100644 --- a/src/libraries/System.Console/src/System/IO/StdInReader.cs +++ b/src/libraries/System.Console/src/System/IO/StdInReader.cs @@ -299,10 +299,12 @@ private int ReadOrPeek(bool peek) } #if TARGET_WASI +#pragma warning disable IDE0060 private static bool IsEol(char c) { return false; // TODOWASI } +#pragma warning restore IDE0060 #else private static bool IsEol(char c) { @@ -357,7 +359,7 @@ private unsafe ConsoleKeyInfo ReadKey() // or just use 0 if none are available. return new ConsoleKeyInfo((char) #if TARGET_WASI - 0,// TODOWASI + 0, // TODOWASI #else (ConsolePal.s_veolCharacter != ConsolePal.s_posixDisableValue ? ConsolePal.s_veolCharacter : ConsolePal.s_veol2Character != ConsolePal.s_posixDisableValue ? ConsolePal.s_veol2Character : From 2782819b8f4223e57356badcf3d2950ede3cfd5d Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Wed, 30 Nov 2022 21:11:44 +0100 Subject: [PATCH 05/39] wip --- src/native/libs/System.Native/pal_io.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/native/libs/System.Native/pal_io.c b/src/native/libs/System.Native/pal_io.c index f696e3cba0ab61..6574282c81be11 100644 --- a/src/native/libs/System.Native/pal_io.c +++ b/src/native/libs/System.Native/pal_io.c @@ -711,6 +711,8 @@ int32_t SystemNative_ChMod(const char* path, int32_t mode) while ((result = chmod(path, (mode_t)mode)) < 0 && errno == EINTR); return result; #else /* HAVE_CHMOD */ + (void)path; // unused + (void)mode; // unused return EINTR; #endif /* HAVE_CHMOD */ } @@ -722,6 +724,8 @@ int32_t SystemNative_FChMod(intptr_t fd, int32_t mode) while ((result = fchmod(ToFileDescriptor(fd), (mode_t)mode)) < 0 && errno == EINTR); return result; #else /* HAVE_FCHMOD */ + (void)path; // unused + (void)mode; // unused return EINTR; #endif /* HAVE_FCHMOD */ } From 867e8d8ed2411719ecd986d8f957a3f4c5d47940 Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Wed, 30 Nov 2022 21:25:55 +0100 Subject: [PATCH 06/39] wip --- src/native/libs/System.Native/pal_io.c | 2 +- src/native/libs/System.Native/pal_time.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/native/libs/System.Native/pal_io.c b/src/native/libs/System.Native/pal_io.c index 6574282c81be11..dd683bc7959098 100644 --- a/src/native/libs/System.Native/pal_io.c +++ b/src/native/libs/System.Native/pal_io.c @@ -724,7 +724,7 @@ int32_t SystemNative_FChMod(intptr_t fd, int32_t mode) while ((result = fchmod(ToFileDescriptor(fd), (mode_t)mode)) < 0 && errno == EINTR); return result; #else /* HAVE_FCHMOD */ - (void)path; // unused + (void)fd; // unused (void)mode; // unused return EINTR; #endif /* HAVE_FCHMOD */ diff --git a/src/native/libs/System.Native/pal_time.c b/src/native/libs/System.Native/pal_time.c index 76786b9ca8ee85..51b463c76a605d 100644 --- a/src/native/libs/System.Native/pal_time.c +++ b/src/native/libs/System.Native/pal_time.c @@ -171,7 +171,8 @@ double SystemNative_GetCpuUtilization(ProcessCpuInformation* previousCpuInfo) return cpuUtilization; #else - assert(false); - return 0; + (void)previousCpuInfo; // unused + assert(false); + return 0; #endif } From 87de23e785b480f04b434ad8197143f1e7012415 Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Wed, 30 Nov 2022 21:55:37 +0100 Subject: [PATCH 07/39] wip --- src/native/libs/System.Native/pal_networking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/native/libs/System.Native/pal_networking.c b/src/native/libs/System.Native/pal_networking.c index 79b6dd9ca96f37..a831bd9a6f99fe 100644 --- a/src/native/libs/System.Native/pal_networking.c +++ b/src/native/libs/System.Native/pal_networking.c @@ -118,7 +118,7 @@ static uint16_t GetKeventFlags(uint32_t flags) #endif #endif -#if !HAVE_IN_PKTINFO && !IP_PKTINFO +#if !HAVE_IN_PKTINFO && !defined(IP_PKTINFO) // On platforms, such as FreeBSD, where in_pktinfo // is not available, fallback to custom definition // with required members. From 2ae03394fb9351053372d39278365bc080d73c4d Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Wed, 30 Nov 2022 23:21:15 +0100 Subject: [PATCH 08/39] fix --- src/native/libs/Common/pal_config.h.in | 3 +++ src/native/libs/System.Native/pal_process.c | 6 ++++-- src/native/libs/configure.cmake | 15 +++++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/native/libs/Common/pal_config.h.in b/src/native/libs/Common/pal_config.h.in index 464ae1d3266070..8ccc221b39a3f6 100644 --- a/src/native/libs/Common/pal_config.h.in +++ b/src/native/libs/Common/pal_config.h.in @@ -58,6 +58,9 @@ #cmakedefine01 HAVE_MNTENT_H #cmakedefine01 HAVE_SIGNAL_KILL #cmakedefine01 HAVE_SYS_RESOURCE_H +#cmakedefine01 HAVE_GETRUSAGE +#cmakedefine01 HAVE_GETRLIMIT +#cmakedefine01 HAVE_SETRLIMIT #cmakedefine01 HAVE_SYS_SOCKIO_H #cmakedefine01 HAVE_ETHTOOL_H #cmakedefine01 HAVE_SYS_POLL_H diff --git a/src/native/libs/System.Native/pal_process.c b/src/native/libs/System.Native/pal_process.c index 0ac81db47cc753..cc0291519737a8 100644 --- a/src/native/libs/System.Native/pal_process.c +++ b/src/native/libs/System.Native/pal_process.c @@ -625,7 +625,7 @@ typedef int priorityWhich; int32_t SystemNative_GetRLimit(RLimitResources resourceType, RLimit* limits) { assert(limits != NULL); -#if HAVE_SYS_RESOURCE_H +#if HAVE_GETRLIMIT int32_t platformLimit = ConvertRLimitResourcesPalToPlatform(resourceType); struct rlimit internalLimit; int result = getrlimit((rlimitResource)platformLimit, &internalLimit); @@ -649,12 +649,14 @@ int32_t SystemNative_SetRLimit(RLimitResources resourceType, const RLimit* limit { assert(limits != NULL); -#if HAVE_SYS_RESOURCE_H +#if HAVE_SETRLIMIT int32_t platformLimit = ConvertRLimitResourcesPalToPlatform(resourceType); struct rlimit internalLimit; ConvertFromRLimitManagedToPal(limits, &internalLimit); return setrlimit((rlimitResource)platformLimit, &internalLimit); #else /* HAVE_SYS_RESOURCE_H */ + (void)resourceType; // unused + (void)limits; // unused return -1; #endif } diff --git a/src/native/libs/configure.cmake b/src/native/libs/configure.cmake index 3a023d53b8654b..cd9c49d6d7e536 100644 --- a/src/native/libs/configure.cmake +++ b/src/native/libs/configure.cmake @@ -385,6 +385,21 @@ check_include_files( "sys/resource.h" HAVE_SYS_RESOURCE_H) +check_symbol_exists( + "getrusage" + "sys/resource.h" + HAVE_GETRUSAGE) + +check_symbol_exists( + "getrlimit" + "sys/resource.h" + HAVE_GETRLIMIT) + +check_symbol_exists( + "setrlimit" + "sys/resource.h" + HAVE_SETRLIMIT) + check_type_size( "struct statfs" STATFS_SIZE From 2efd28f08eb735dbbd2b65808336c091fec25099 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Thu, 1 Dec 2022 13:35:52 +0100 Subject: [PATCH 09/39] provision SDK to WASI_SDK_PATH --- eng/native/gen-buildsys.cmd | 4 ++-- src/mono/Directory.Build.props | 1 + src/mono/mono.proj | 17 ++++++++--------- src/mono/wasi/provision.ps1 | 14 ++++++++------ src/mono/wasi/wasi.proj | 1 + 5 files changed, 20 insertions(+), 17 deletions(-) diff --git a/eng/native/gen-buildsys.cmd b/eng/native/gen-buildsys.cmd index ed87ef0ad52eec..976f1c3247b082 100644 --- a/eng/native/gen-buildsys.cmd +++ b/eng/native/gen-buildsys.cmd @@ -54,8 +54,8 @@ if /i "%__Arch%" == "wasm" ( ) set EMSDK_PATH=%__repoRoot%\src\mono\wasm\emsdk - set EMSDK_PATH=!EMSDK_PATH:\=/! ) + set EMSDK_PATH=!EMSDK_PATH:\=/! set __ExtraCmakeParams=%__ExtraCmakeParams% "-DCMAKE_TOOLCHAIN_FILE=!EMSDK_PATH!/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake" set __UseEmcmake=1 @@ -68,8 +68,8 @@ if /i "%__Arch%" == "wasm" ( ) set WASI_SDK_PATH=%__repoRoot%src\mono\wasi\wasi-sdk - set WASI_SDK_PATH=!WASI_SDK_PATH:\=/! ) + set WASI_SDK_PATH=!WASI_SDK_PATH:\=/! set __CmakeGenerator=Ninja set __ExtraCmakeParams=%__ExtraCmakeParams% -DCLR_CMAKE_TARGET_OS=WASI -DCLR_CMAKE_TARGET_ARCH=wasm "-DWASI_SDK_PREFIX=!WASI_SDK_PATH!" "-DCMAKE_TOOLCHAIN_FILE=!WASI_SDK_PATH!/share/cmake/wasi-sdk.cmake" "-DCMAKE_SYSROOT=!WASI_SDK_PATH!/share/wasi-sysroot" ) diff --git a/src/mono/Directory.Build.props b/src/mono/Directory.Build.props index 14ecb194fb8435..d729540809b291 100644 --- a/src/mono/Directory.Build.props +++ b/src/mono/Directory.Build.props @@ -49,6 +49,7 @@ $([MSBuild]::NormalizeDirectory('$(MSBuildThisFileDirectory)', 'wasi', 'wasi-sdk')) $(ProvisionWasiSdkDir.Replace('\', '/')) true + true diff --git a/src/mono/mono.proj b/src/mono/mono.proj index ae6d1f92b59bba..c0acf3f4d264a5 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -171,7 +171,6 @@ - $(ProvisionWasiSdkDir) $([MSBuild]::NormalizeDirectory('$(MSBuildThisFileDirectory)', 'wasi')) %(_VersionLines.Identity) https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-$(WasiSdkVersion)/wasi-sdk-$(WasiSdkVersion).0-linux.tar.gz @@ -180,20 +179,20 @@ - - - + @@ -203,7 +202,7 @@ %(_ActualVersionLines.Identity) %(_ExpectedVersionLines.Identity) - @@ -577,8 +576,8 @@ - $([MSBuild]::EnsureTrailingSlash('$(EMSDK_PATH)')) - $([MSBuild]::EnsureTrailingSlash('$(WASI_SDK_PATH)')) + $([MSBuild]::EnsureTrailingSlash('$(EMSDK_PATH)').Replace('\', '/')) + $([MSBuild]::EnsureTrailingSlash('$(WASI_SDK_PATH)').Replace('\', '/')) <_MonoCMakeConfigureCommand>cmake @(_MonoCMakeArgs, ' ') $(MonoCMakeExtraArgs) "$(MonoProjectRoot.TrimEnd('\/'))" <_MonoCMakeConfigureCommand Condition="'$(TargetsBrowser)' != 'true' and '$(TargetsWasi)' != 'true' and '$(_MonoRunInitCompiler)' != 'false' and '$(HostOS)' != 'windows'">bash -c 'source $(RepositoryEngineeringCommonDir)native/init-compiler.sh "$(RepositoryEngineeringCommonDir)native" "$(_CompilerTargetArch)" "$(MonoCCompiler)" && @(_MonoBuildEnv, ' ') $(_MonoCMakeConfigureCommand)' <_MonoCMakeConfigureCommand Condition="'$(TargetsBrowser)' != 'true' and '$(TargetsWasi)' != 'true' and '$(_MonoRunInitCompiler)' != 'false' and '$(HostOS)' == 'windows'">call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" $(_CompilerTargetArch) && cd /D "$(MonoObjDir)" && @(_MonoBuildEnv, ' ') $(_MonoCMakeConfigureCommand) diff --git a/src/mono/wasi/provision.ps1 b/src/mono/wasi/provision.ps1 index f20fcbdb888dd8..3d3602f0a901c3 100644 --- a/src/mono/wasi/provision.ps1 +++ b/src/mono/wasi/provision.ps1 @@ -2,13 +2,15 @@ param( [Parameter()] [string]$WasiSdkUrl, [Parameter()] - [string]$WasiSdkVersion + [string]$WasiSdkVersion, + [Parameter()] + [string]$WasiSdkPath, + [Parameter()] + [string]$WasiLocalPath ) -Remove-Item ./wasi-sdk/ -r -fo -ErrorAction SilentlyContinue -Remove-Item ./wasi-sdk-$WasiSdkVersion.0-mingw.tar.gz -fo +New-Item -Path $WasiSdkPath -ItemType "directory" Invoke-WebRequest -Uri $WasiSdkUrl -OutFile ./wasi-sdk-$WasiSdkVersion.0-mingw.tar.gz -tar -xvzf ./wasi-sdk-$WasiSdkVersion.0-mingw.tar.gz +tar --strip-components=1 -xvzf ./wasi-sdk-$WasiSdkVersion.0-mingw.tar.gz -C $WasiSdkPath +Copy-Item $WasiLocalPath/wasi-sdk-version.txt $WasiSdkPath/wasi-sdk-version.txt Remove-Item ./wasi-sdk-$WasiSdkVersion.0-mingw.tar.gz -fo -Move-Item ./wasi-sdk-$WasiSdkVersion.*/ ./wasi-sdk/ -Copy-Item ./wasi-sdk-version.txt ./wasi-sdk/wasi-sdk-version.txt diff --git a/src/mono/wasi/wasi.proj b/src/mono/wasi/wasi.proj index 5ec5c4cc121fe0..f0fe64044f8e58 100644 --- a/src/mono/wasi/wasi.proj +++ b/src/mono/wasi/wasi.proj @@ -154,6 +154,7 @@ $(ArtifactsObjDir)wasm/pinvoke-table.h $(ArtifactsObjDir)wasm/wasm_m2n_invoke.g.h + $([MSBuild]::EnsureTrailingSlash('$(WASI_SDK_PATH)').Replace('\', '/')) -g -Os -DDEBUG=1 -DENABLE_AOT_PROFILER=1 -Oz From 6bffc9d4e2f8b6df222556abaa142f2c8c080a93 Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Thu, 1 Dec 2022 14:02:50 +0100 Subject: [PATCH 10/39] fix --- eng/native/gen-buildsys.cmd | 2 ++ src/mono/mono.proj | 2 +- src/native/libs/build-native.sh | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/eng/native/gen-buildsys.cmd b/eng/native/gen-buildsys.cmd index 976f1c3247b082..f9ac55ce6b26c7 100644 --- a/eng/native/gen-buildsys.cmd +++ b/eng/native/gen-buildsys.cmd @@ -56,6 +56,7 @@ if /i "%__Arch%" == "wasm" ( set EMSDK_PATH=%__repoRoot%\src\mono\wasm\emsdk ) set EMSDK_PATH=!EMSDK_PATH:\=/! + if not "%EMSDK_PATH:~-1%"=="/" set "EMSDK_PATH=%EMSDK_PATH%/" set __ExtraCmakeParams=%__ExtraCmakeParams% "-DCMAKE_TOOLCHAIN_FILE=!EMSDK_PATH!/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake" set __UseEmcmake=1 @@ -70,6 +71,7 @@ if /i "%__Arch%" == "wasm" ( set WASI_SDK_PATH=%__repoRoot%src\mono\wasi\wasi-sdk ) set WASI_SDK_PATH=!WASI_SDK_PATH:\=/! + if not "%WASI_SDK_PATH:~-1%"=="/" set "WASI_SDK_PATH=%WASI_SDK_PATH%/" set __CmakeGenerator=Ninja set __ExtraCmakeParams=%__ExtraCmakeParams% -DCLR_CMAKE_TARGET_OS=WASI -DCLR_CMAKE_TARGET_ARCH=wasm "-DWASI_SDK_PREFIX=!WASI_SDK_PATH!" "-DCMAKE_TOOLCHAIN_FILE=!WASI_SDK_PATH!/share/cmake/wasi-sdk.cmake" "-DCMAKE_SYSROOT=!WASI_SDK_PATH!/share/wasi-sysroot" ) diff --git a/src/mono/mono.proj b/src/mono/mono.proj index c0acf3f4d264a5..9a0f51a387b257 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -179,7 +179,7 @@ - diff --git a/src/native/libs/build-native.sh b/src/native/libs/build-native.sh index dc42d0d265a65a..f56cb52f5b1a42 100755 --- a/src/native/libs/build-native.sh +++ b/src/native/libs/build-native.sh @@ -62,7 +62,7 @@ elif [[ "$__TargetOS" == wasi ]]; then exit 1 fi fi - + export WASI_SDK_PATH="${WASI_SDK_PATH%/}/" export CLR_CC="$WASI_SDK_PATH"bin/clang export TARGET_BUILD_ARCH=wasm __CMakeArgs="-DCLR_CMAKE_TARGET_OS=WASI -DCLR_CMAKE_TARGET_ARCH=wasm -DWASI_SDK_PREFIX=$WASI_SDK_PATH -DCMAKE_TOOLCHAIN_FILE=$WASI_SDK_PATH/share/cmake/wasi-sdk.cmake" From 83a54e33a847a583d9043b22456e78400f9cc96d Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Thu, 1 Dec 2022 14:54:23 +0100 Subject: [PATCH 11/39] wip --- eng/native/gen-buildsys.cmd | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/eng/native/gen-buildsys.cmd b/eng/native/gen-buildsys.cmd index f9ac55ce6b26c7..1259cbde4265f2 100644 --- a/eng/native/gen-buildsys.cmd +++ b/eng/native/gen-buildsys.cmd @@ -55,8 +55,8 @@ if /i "%__Arch%" == "wasm" ( set EMSDK_PATH=%__repoRoot%\src\mono\wasm\emsdk ) - set EMSDK_PATH=!EMSDK_PATH:\=/! - if not "%EMSDK_PATH:~-1%"=="/" set "EMSDK_PATH=%EMSDK_PATH%/" + set "EMSDK_PATH=!EMSDK_PATH:\=/!" + if not "!EMSDK_PATH:~-1!" == "/" set "EMSDK_PATH=!EMSDK_PATH!/" set __ExtraCmakeParams=%__ExtraCmakeParams% "-DCMAKE_TOOLCHAIN_FILE=!EMSDK_PATH!/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake" set __UseEmcmake=1 @@ -70,8 +70,8 @@ if /i "%__Arch%" == "wasm" ( set WASI_SDK_PATH=%__repoRoot%src\mono\wasi\wasi-sdk ) - set WASI_SDK_PATH=!WASI_SDK_PATH:\=/! - if not "%WASI_SDK_PATH:~-1%"=="/" set "WASI_SDK_PATH=%WASI_SDK_PATH%/" + set "WASI_SDK_PATH=!WASI_SDK_PATH:\=/!" + if not "!WASI_SDK_PATH:~-1!" == "/" set "WASI_SDK_PATH=!WASI_SDK_PATH!/" set __CmakeGenerator=Ninja set __ExtraCmakeParams=%__ExtraCmakeParams% -DCLR_CMAKE_TARGET_OS=WASI -DCLR_CMAKE_TARGET_ARCH=wasm "-DWASI_SDK_PREFIX=!WASI_SDK_PATH!" "-DCMAKE_TOOLCHAIN_FILE=!WASI_SDK_PATH!/share/cmake/wasi-sdk.cmake" "-DCMAKE_SYSROOT=!WASI_SDK_PATH!/share/wasi-sysroot" ) From 8de88e1971e7cbe2e24f074d1fa8a162aeaf2212 Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Thu, 1 Dec 2022 15:41:01 +0100 Subject: [PATCH 12/39] wip --- src/mono/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/Directory.Build.props b/src/mono/Directory.Build.props index d729540809b291..e5c49c0ab048f1 100644 --- a/src/mono/Directory.Build.props +++ b/src/mono/Directory.Build.props @@ -47,7 +47,7 @@ $([MSBuild]::NormalizeDirectory('$(MSBuildThisFileDirectory)', 'wasi', 'wasi-sdk')) - $(ProvisionWasiSdkDir.Replace('\', '/')) + $(ProvisionWasiSdkDir.Replace('\', '/')) true true From 9b36c3bc5ca77d8d94f1d9abfccdfe418d91d22b Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Mon, 5 Dec 2022 17:18:21 +0100 Subject: [PATCH 13/39] fix after merge --- src/mono/sample/wasi/Directory.Build.targets | 2 +- .../wasi/console/Wasi.Console.Sample.csproj | 1 + src/mono/wasi/runtime/driver.c | 2 +- src/mono/wasi/sample/Directory.Build.props | 8 ------ src/mono/wasi/sample/Directory.Build.targets | 6 ---- src/mono/wasi/sample/console/Makefile | 28 ------------------- .../WasiConsoleApp/WasiConsoleApp.csproj | 11 -------- src/mono/wasi/sample/console/main.c | 21 -------------- src/mono/wasi/wasi.proj | 1 - 9 files changed, 3 insertions(+), 77 deletions(-) delete mode 100644 src/mono/wasi/sample/Directory.Build.props delete mode 100644 src/mono/wasi/sample/Directory.Build.targets delete mode 100644 src/mono/wasi/sample/console/Makefile delete mode 100644 src/mono/wasi/sample/console/WasiConsoleApp/WasiConsoleApp.csproj delete mode 100644 src/mono/wasi/sample/console/main.c diff --git a/src/mono/sample/wasi/Directory.Build.targets b/src/mono/sample/wasi/Directory.Build.targets index df21a15d0a5453..1e6a5fff8268f8 100644 --- a/src/mono/sample/wasi/Directory.Build.targets +++ b/src/mono/sample/wasi/Directory.Build.targets @@ -14,7 +14,7 @@ " Outputs=" bin/publish/runtime/native/dotnet.wasm; - bin/publish/runtime/lib/net7.0/lib/mscorlib.dll; + bin/publish/runtime/lib/$(NetCoreAppCurrent)/lib/mscorlib.dll; bin/publish/$(_SampleAssembly); " > diff --git a/src/mono/sample/wasi/console/Wasi.Console.Sample.csproj b/src/mono/sample/wasi/console/Wasi.Console.Sample.csproj index 2cbc92e85f134b..da5ab16c38d0f9 100644 --- a/src/mono/sample/wasi/console/Wasi.Console.Sample.csproj +++ b/src/mono/sample/wasi/console/Wasi.Console.Sample.csproj @@ -1,6 +1,7 @@ $(NetCoreAppCurrent) + false diff --git a/src/mono/wasi/runtime/driver.c b/src/mono/wasi/runtime/driver.c index 27bfc92a1c55c1..f460a450c0bd31 100644 --- a/src/mono/wasi/runtime/driver.c +++ b/src/mono/wasi/runtime/driver.c @@ -701,7 +701,7 @@ MonoMethod* lookup_dotnet_method(const char* assembly_name, const char* namespac int main() { // Assume the runtime pack has been copied into the output directory as 'runtime' // Otherwise we have to mount an unrelated part of the filesystem within the WASM environment - mono_set_assemblies_path(".:./runtime/native:./runtime/lib/net7.0"); + mono_set_assemblies_path(".:./runtime/native:./runtime/lib/net8.0"); mono_wasm_load_runtime("", 0); MonoAssembly* assembly = mono_wasm_assembly_load ("Wasi.Console.Sample"); diff --git a/src/mono/wasi/sample/Directory.Build.props b/src/mono/wasi/sample/Directory.Build.props deleted file mode 100644 index cd84104a099ad4..00000000000000 --- a/src/mono/wasi/sample/Directory.Build.props +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - bin/$(Configuration)/$(NetCoreAppCurrent) - - diff --git a/src/mono/wasi/sample/Directory.Build.targets b/src/mono/wasi/sample/Directory.Build.targets deleted file mode 100644 index fd6cac33af7e80..00000000000000 --- a/src/mono/wasi/sample/Directory.Build.targets +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/mono/wasi/sample/console/Makefile b/src/mono/wasi/sample/console/Makefile deleted file mode 100644 index c05eb4b3cb621c..00000000000000 --- a/src/mono/wasi/sample/console/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -include ../../Makefile.variable -include ../SampleMakefile.variable - -BIN_DIR=WasiConsoleApp/bin/Debug/net8.0 - -all: console.wasm $(BIN_DIR)/WasiConsoleApp.dll - -run: all - @(which wasmtime || PATH=$(WASMTIME_DIR):${PATH} which wasmtime); \ - test "$$?" -ne 0 \ - && echo "wasmtime not found. Either install that yourself, or use 'make provision-deps' to install one." \ - || PATH=$(WASMTIME_DIR):${PATH} wasmtime --dir=. console.wasm - -run-wasmer: all - wasmer --dir=. console.wasm - -console.wasm: main.c - $(WASI_SDK_CLANG) main.c -o console.wasm $(COMPILE_FLAGS) $(LINK_FLAGS) - -$(BIN_DIR)/WasiConsoleApp.dll: WasiConsoleApp/*.csproj WasiConsoleApp/*.cs - find $(BROWSER_WASM_RUNTIME_PATH) -type f - cd WasiConsoleApp && $(DOTNET_ROOT)/dotnet build -c Debug - touch $(BIN_DIR)/*.dll - cp -R $(BROWSER_WASM_RUNTIME_PATH) $(BIN_DIR)/runtime - -debug: all -#wasmtime has a bug when passing --tcplisten and --dir, to make it work we should use this PR https://github.com/bytecodealliance/wasmtime/pull/3995 and then the fd of the socket will be 4. - PATH=$(WASMTIME_DIR):${PATH} wasmtime --tcplisten localhost:64000 --dir=. console.wasm --env DEBUGGER_FD=4 diff --git a/src/mono/wasi/sample/console/WasiConsoleApp/WasiConsoleApp.csproj b/src/mono/wasi/sample/console/WasiConsoleApp/WasiConsoleApp.csproj deleted file mode 100644 index cae907a0c3cf80..00000000000000 --- a/src/mono/wasi/sample/console/WasiConsoleApp/WasiConsoleApp.csproj +++ /dev/null @@ -1,11 +0,0 @@ - - - - Exe - net8.0 - true - embedded - false - - - diff --git a/src/mono/wasi/sample/console/main.c b/src/mono/wasi/sample/console/main.c deleted file mode 100644 index 10e8ae96c5fef0..00000000000000 --- a/src/mono/wasi/sample/console/main.c +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include "../../mono-wasi-driver/driver.h" - -int main() { - // Assume the runtime pack has been copied into the output directory as 'runtime' - // Otherwise we have to mount an unrelated part of the filesystem within the WASM environment - const char* app_base_dir = "./WasiConsoleApp/bin/Debug/net8.0"; - char* assemblies_path; - asprintf(&assemblies_path, "%s:%s/runtime/native:%s/runtime/lib/net8.0", app_base_dir, app_base_dir, app_base_dir); - - add_assembly(app_base_dir, "WasiConsoleApp.dll"); - mono_set_assemblies_path(assemblies_path); - - mono_wasm_load_runtime("", 0); - - MonoAssembly* assembly = mono_wasm_assembly_load ("WasiConsoleApp.dll"); - MonoMethod* entry_method = mono_wasm_assembly_get_entry_point (assembly); - MonoObject* out_exc; - MonoObject *exit_code = mono_wasm_invoke_method (entry_method, NULL, NULL, &out_exc); - return mono_unbox_int (exit_code); -} diff --git a/src/mono/wasi/wasi.proj b/src/mono/wasi/wasi.proj index f0fe64044f8e58..709ac57cd50b4a 100644 --- a/src/mono/wasi/wasi.proj +++ b/src/mono/wasi/wasi.proj @@ -167,7 +167,6 @@ $(CMakeBuildRuntimeConfigureCmd) -DWASI_SDK_PREFIX=$(WASI_SDK_PATH) $(CMakeBuildRuntimeConfigureCmd) -DCMAKE_SYSROOT=$(WASI_SDK_PATH)share/wasi-sysroot - $(CMakeBuildRuntimeConfigureCmd) -DCMAKE_TOOLCHAIN_FILE=$(WASI_SDK_PATH)share/cmake/wasi-sdk.cmake $(CMakeBuildRuntimeConfigureCmd) -DCMAKE_CXX_FLAGS="--sysroot=$(WASI_SDK_PATH)share/wasi-sysroot" $(CMakeBuildRuntimeConfigureCmd) -DCONFIGURATION_WASICC_FLAGS="$(CMakeConfigurationWasiFlags)" From 2a3d7ea962f6a8a264a376996e1d10366d26f3d5 Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Mon, 5 Dec 2022 22:53:09 +0100 Subject: [PATCH 14/39] wip --- src/mono/wasi/wasi.proj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mono/wasi/wasi.proj b/src/mono/wasi/wasi.proj index 709ac57cd50b4a..1cdad54d21740f 100644 --- a/src/mono/wasi/wasi.proj +++ b/src/mono/wasi/wasi.proj @@ -168,6 +168,7 @@ $(CMakeBuildRuntimeConfigureCmd) -DWASI_SDK_PREFIX=$(WASI_SDK_PATH) $(CMakeBuildRuntimeConfigureCmd) -DCMAKE_SYSROOT=$(WASI_SDK_PATH)share/wasi-sysroot $(CMakeBuildRuntimeConfigureCmd) -DCMAKE_CXX_FLAGS="--sysroot=$(WASI_SDK_PATH)share/wasi-sysroot" + $(CMakeBuildRuntimeConfigureCmd) -DCMAKE_TOOLCHAIN_FILE=$(WASI_SDK_PATH)share/cmake/wasi-sdk.cmake $(CMakeBuildRuntimeConfigureCmd) -DCONFIGURATION_WASICC_FLAGS="$(CMakeConfigurationWasiFlags)" $(CMakeBuildRuntimeConfigureCmd) -DCONFIGURATION_LINK_FLAGS="$(CMakeConfigurationLinkFlags)" From f213ab61e14add5b3164031dc21dfadc676c41b0 Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Mon, 5 Dec 2022 23:06:08 +0100 Subject: [PATCH 15/39] feedback --- src/mono/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/Directory.Build.props b/src/mono/Directory.Build.props index e5c49c0ab048f1..72f3885bbe4b33 100644 --- a/src/mono/Directory.Build.props +++ b/src/mono/Directory.Build.props @@ -46,7 +46,7 @@ - $([MSBuild]::NormalizeDirectory('$(MSBuildThisFileDirectory)', 'wasi', 'wasi-sdk')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'wasi-sdk')) $(ProvisionWasiSdkDir.Replace('\', '/')) true true From 61f1276eb41bb3c1d2f9456461374a8043580308 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Tue, 6 Dec 2022 11:45:43 +0100 Subject: [PATCH 16/39] add wasi_wasm container --- eng/pipelines/common/platform-matrix.yml | 2 +- eng/pipelines/common/templates/pipeline-with-resources.yml | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/eng/pipelines/common/platform-matrix.yml b/eng/pipelines/common/platform-matrix.yml index f243f260644fb2..a876f91e81b7e7 100644 --- a/eng/pipelines/common/platform-matrix.yml +++ b/eng/pipelines/common/platform-matrix.yml @@ -371,7 +371,7 @@ jobs: targetRid: wasi-wasm platform: wasi_wasm shouldContinueOnError: ${{ parameters.shouldContinueOnError }} - container: Browser_wasm + container: wasi_wasm jobParameters: hostedOs: Linux runtimeFlavor: ${{ parameters.runtimeFlavor }} diff --git a/eng/pipelines/common/templates/pipeline-with-resources.yml b/eng/pipelines/common/templates/pipeline-with-resources.yml index 6371f176d872d0..9de181cce75421 100644 --- a/eng/pipelines/common/templates/pipeline-with-resources.yml +++ b/eng/pipelines/common/templates/pipeline-with-resources.yml @@ -60,6 +60,9 @@ resources: - container: Browser_wasm image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-webassembly + - container: wasi_wasm + image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-20.04-webassembly + - container: FreeBSD_x64 image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-cross-freebsd-12 env: From 288199bfb011f7e6a7cde0798d89a9038b5d9b39 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Tue, 6 Dec 2022 17:10:20 +0100 Subject: [PATCH 17/39] feedback --- src/coreclr/pal/src/config.h.in | 3 - src/coreclr/pal/src/configure.cmake | 3 - .../System.Console/src/System.Console.csproj | 8 +- .../System/ConsolePal.Unix.ConsoleStream.cs | 62 +++ .../src/System/ConsolePal.Unix.cs | 140 +----- .../src/System/ConsolePal.Wasi.cs | 333 +++++++++++++ .../System.Console/src/System/IO/KeyParser.cs | 4 +- .../src/System/IO/StdInReader.cs | 22 - .../src/CompatibilitySuppressions.xml | 23 - .../src/CompatibilitySuppressions.xml | 41 -- src/native/libs/Common/pal_config.h.in | 2 - src/native/libs/System.Native/CMakeLists.txt | 34 +- src/native/libs/System.Native/pal_console.c | 32 -- .../libs/System.Native/pal_console_wasi.c | 127 +++++ .../libs/System.Native/pal_dynamicload.c | 24 - .../libs/System.Native/pal_dynamicload_wasi.c | 39 ++ src/native/libs/System.Native/pal_io.c | 8 +- .../libs/System.Native/pal_maphardwaretype.c | 1 - src/native/libs/System.Native/pal_mount.c | 32 +- .../libs/System.Native/pal_mount_wasi.c | 38 ++ .../libs/System.Native/pal_networkchange.c | 2 - .../libs/System.Native/pal_networking.c | 257 +--------- .../libs/System.Native/pal_networking_wasi.c | 449 ++++++++++++++++++ src/native/libs/System.Native/pal_process.c | 58 +-- .../libs/System.Native/pal_process_wasi.c | 163 +++++++ src/native/libs/System.Native/pal_signal.c | 48 +- .../libs/System.Native/pal_signal_wasi.c | 66 +++ src/native/libs/System.Native/pal_threading.c | 27 -- .../libs/System.Native/pal_threading_wasi.c | 88 ++++ src/native/libs/System.Native/pal_uid.c | 46 +- src/native/libs/System.Native/pal_uid_wasi.c | 83 ++++ 31 files changed, 1521 insertions(+), 742 deletions(-) create mode 100644 src/libraries/System.Console/src/System/ConsolePal.Unix.ConsoleStream.cs create mode 100644 src/libraries/System.Console/src/System/ConsolePal.Wasi.cs create mode 100644 src/native/libs/System.Native/pal_console_wasi.c create mode 100644 src/native/libs/System.Native/pal_dynamicload_wasi.c create mode 100644 src/native/libs/System.Native/pal_mount_wasi.c create mode 100644 src/native/libs/System.Native/pal_networking_wasi.c create mode 100644 src/native/libs/System.Native/pal_process_wasi.c create mode 100644 src/native/libs/System.Native/pal_signal_wasi.c create mode 100644 src/native/libs/System.Native/pal_threading_wasi.c create mode 100644 src/native/libs/System.Native/pal_uid_wasi.c diff --git a/src/coreclr/pal/src/config.h.in b/src/coreclr/pal/src/config.h.in index 5a48d405330de9..75507804d23a00 100644 --- a/src/coreclr/pal/src/config.h.in +++ b/src/coreclr/pal/src/config.h.in @@ -63,9 +63,6 @@ #cmakedefine01 HAS_SYSV_SEMAPHORES #cmakedefine01 HAS_PTHREAD_MUTEXES #cmakedefine HAVE_TTRACE -#cmakedefine01 HAVE_CHMOD -#cmakedefine01 HAVE_FCHMOD -#cmakedefine01 HAVE_PIPE #cmakedefine01 HAVE_PIPE2 #cmakedefine01 HAVE_SCHED_GETAFFINITY #cmakedefine01 HAVE_SCHED_SETAFFINITY diff --git a/src/coreclr/pal/src/configure.cmake b/src/coreclr/pal/src/configure.cmake index 399174a8764129..4f900a5555ef63 100644 --- a/src/coreclr/pal/src/configure.cmake +++ b/src/coreclr/pal/src/configure.cmake @@ -135,9 +135,6 @@ check_function_exists(semget HAS_SYSV_SEMAPHORES) check_function_exists(pthread_mutex_init HAS_PTHREAD_MUTEXES) check_function_exists(ttrace HAVE_TTRACE) check_function_exists(pipe2 HAVE_PIPE2) -check_function_exists(pipe HAVE_PIPE) -check_function_exists(chmod HAVE_CHMOD) -check_function_exists(fchmod HAVE_FCHMOD) check_cxx_source_compiles(" #include diff --git a/src/libraries/System.Console/src/System.Console.csproj b/src/libraries/System.Console/src/System.Console.csproj index 5d26b793996077..01210bf763541d 100644 --- a/src/libraries/System.Console/src/System.Console.csproj +++ b/src/libraries/System.Console/src/System.Console.csproj @@ -67,10 +67,11 @@ - + + + @@ -190,6 +191,7 @@ + diff --git a/src/libraries/System.Console/src/System/ConsolePal.Unix.ConsoleStream.cs b/src/libraries/System.Console/src/System/ConsolePal.Unix.ConsoleStream.cs new file mode 100644 index 00000000000000..96eae08d1b5ea6 --- /dev/null +++ b/src/libraries/System.Console/src/System/ConsolePal.Unix.ConsoleStream.cs @@ -0,0 +1,62 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.Win32.SafeHandles; +using System.Diagnostics; +using System.IO; + +namespace System +{ + internal static partial class ConsolePal + { + /// Provides a stream to use for Unix console input or output. + private sealed class UnixConsoleStream : ConsoleStream + { + /// The file descriptor for the opened file. + private readonly SafeFileHandle _handle; + + private readonly bool _useReadLine; + + /// Initialize the stream. + /// The file handle wrapped by this stream. + /// FileAccess.Read or FileAccess.Write. + /// Use ReadLine API for reading. + internal UnixConsoleStream(SafeFileHandle handle, FileAccess access, bool useReadLine = false) + : base(access) + { + Debug.Assert(handle != null, "Expected non-null console handle"); + Debug.Assert(!handle.IsInvalid, "Expected valid console handle"); + _handle = handle; + _useReadLine = useReadLine; + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + _handle.Dispose(); + } + base.Dispose(disposing); + } + + public override int Read(Span buffer) => +#if !TARGET_WASI + _useReadLine ? + ConsolePal.StdInReader.ReadLine(buffer) : +#endif + ConsolePal.Read(_handle, buffer); + + public override void Write(ReadOnlySpan buffer) => + ConsolePal.Write(_handle, buffer); + + public override void Flush() + { + if (_handle.IsClosed) + { + throw Error.GetFileNotOpen(); + } + base.Flush(); + } + } + } +} diff --git a/src/libraries/System.Console/src/System/ConsolePal.Unix.cs b/src/libraries/System.Console/src/System/ConsolePal.Unix.cs index c82d2c30300648..b383f5274f6eff 100644 --- a/src/libraries/System.Console/src/System/ConsolePal.Unix.cs +++ b/src/libraries/System.Console/src/System/ConsolePal.Unix.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.Win32.SafeHandles; -using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; @@ -23,7 +22,6 @@ internal static partial class ConsolePal // StdInReader is only used when input isn't redirected and we're working // with an interactive terminal. In that case, performance isn't critical // and we can use a smaller buffer to minimize working set. -#if !TARGET_WASI private const int InteractiveBufferSize = 255; // For performance we cache Cursor{Left,Top} and Window{Width,Height}. @@ -39,6 +37,7 @@ internal static partial class ConsolePal private static int s_windowWidth; // Cached WindowWidth, -1 when invalid. private static int s_windowHeight; // Cached WindowHeight, invalid when s_windowWidth == -1. private static int s_invalidateCachedSettings = 1; // Tracks whether we should invalidate the cached settings. + /// Gets the lazily-initialized terminal information for the terminal. public static TerminalFormatStrings TerminalFormatStringsInstance { get { return s_terminalFormatStringsInstance.Value; } } private static readonly Lazy s_terminalFormatStringsInstance = new(() => new TerminalFormatStrings(TermInfo.DatabaseFactory.ReadActiveDatabase())); @@ -59,25 +58,6 @@ public static Stream OpenStandardError() return new UnixConsoleStream(Interop.CheckIo(Interop.Sys.Dup(Interop.Sys.FileDescriptors.STDERR_FILENO)), FileAccess.Write); } -#else - // there is no dup on WASI - public static Stream OpenStandardInput() - { - return new UnixConsoleStream(Interop.CheckIo(Interop.Sys.FileDescriptors.STDIN_FILENO), FileAccess.Read, - useReadLine: !Console.IsInputRedirected); - } - - public static Stream OpenStandardOutput() - { - return new UnixConsoleStream(Interop.CheckIo(Interop.Sys.FileDescriptors.STDOUT_FILENO), FileAccess.Write); - } - - public static Stream OpenStandardError() - { - return new UnixConsoleStream(Interop.CheckIo(Interop.Sys.FileDescriptors.STDERR_FILENO), FileAccess.Write); - } - -#endif public static Encoding InputEncoding { get { return GetConsoleEncoding(); } @@ -157,26 +137,6 @@ public static ConsoleKeyInfo ReadKey(bool intercept) return keyInfo; } -#if TARGET_WASI - public static bool TreatControlCAsInput - { - get => throw new PlatformNotSupportedException(); - set => throw new PlatformNotSupportedException(); - } - - public static ConsoleColor ForegroundColor - { - get => throw new PlatformNotSupportedException(); - set => throw new PlatformNotSupportedException(); - } - public static ConsoleColor BackgroundColor - { - get => throw new PlatformNotSupportedException(); - set => throw new PlatformNotSupportedException(); - } - public static void ResetColor() => throw new PlatformNotSupportedException(); - -#else public static bool TreatControlCAsInput { get @@ -222,7 +182,6 @@ public static void ResetColor() WriteResetColorString(); } } -#endif public static bool NumberLock { get { throw new PlatformNotSupportedException(); } } @@ -234,13 +193,9 @@ public static int CursorSize set { throw new PlatformNotSupportedException(); } } - public static string Title { get { throw new PlatformNotSupportedException(); } -#if TARGET_WASI - set => throw new PlatformNotSupportedException(); -#else set { if (Console.IsOutputRedirected) @@ -253,12 +208,8 @@ public static string Title WriteStdoutAnsiString(ansiStr, mayChangeCursorPosition: false); } } -#endif } -#if TARGET_WASI - public static void Beep() => throw new PlatformNotSupportedException(); -#else public static void Beep() { if (!Console.IsOutputRedirected) @@ -266,17 +217,7 @@ public static void Beep() WriteStdoutAnsiString(TerminalFormatStringsInstance.Bell, mayChangeCursorPosition: false); } } -#endif -#if TARGET_WASI -#pragma warning disable IDE0060 - public static void Clear() => throw new PlatformNotSupportedException(); - public static void SetCursorPosition(int left, int top) => throw new PlatformNotSupportedException(); - public static bool IsInputRedirectedCore() => throw new PlatformNotSupportedException(); - public static bool IsOutputRedirectedCore() => throw new PlatformNotSupportedException(); - public static bool IsErrorRedirectedCore() => throw new PlatformNotSupportedException(); -#pragma warning restore IDE0060 -#else public static void Clear() { if (!Console.IsOutputRedirected) @@ -353,7 +294,6 @@ private static bool TryGetCachedCursorPosition(out int left, out int top) return hasCachedCursorPosition; } -#endif public static int BufferWidth { get { return WindowWidth; } @@ -410,9 +350,6 @@ public static int WindowHeight private static void GetWindowSize(out int width, out int height) { -#if TARGET_WASI - throw new PlatformNotSupportedException(); -#else lock (Console.Out) { // Invalidate before reading cached values. @@ -435,14 +372,10 @@ private static void GetWindowSize(out int width, out int height) width = s_windowWidth; height = s_windowHeight; } -#endif } public static void SetWindowSize(int width, int height) { -#if TARGET_WASI - throw new PlatformNotSupportedException(); -#else lock (Console.Out) { Interop.Sys.WinSize winsize = default; @@ -461,7 +394,6 @@ public static void SetWindowSize(int width, int height) Interop.GetIOException(errorInfo); } } -#endif } public static bool CursorVisible @@ -469,25 +401,16 @@ public static bool CursorVisible get { throw new PlatformNotSupportedException(); } set { -#if TARGET_WASI - throw new PlatformNotSupportedException(); -#else if (!Console.IsOutputRedirected) { WriteStdoutAnsiString(value ? TerminalFormatStringsInstance.CursorVisible : TerminalFormatStringsInstance.CursorInvisible); } -#endif } } public static (int Left, int Top) GetCursorPosition() -#if TARGET_WASI - { - throw new PlatformNotSupportedException(); - } -#else { TryGetCursorPosition(out int left, out int top); return (left, top); @@ -778,7 +701,6 @@ public static bool IsErrorRedirectedCore() return IsHandleRedirected(Interop.Sys.FileDescriptors.STDERR_FILENO); } -#endif /// Creates an encoding from the current environment. /// The encoding. private static Encoding GetConsoleEncoding() @@ -829,11 +751,6 @@ public static void SetWindowPosition(int left, int top) #pragma warning restore IDE0060 -#if TARGET_WASI - internal static void EnsureConsoleInitialized() - { - } -#else /// /// Refreshes the foreground and background colors in use by the terminal by resetting /// the colors and then reissuing commands for both foreground and background, if necessary. @@ -1019,7 +936,6 @@ private static unsafe void EnsureInitializedCore() } } } -#endif /// Reads data from the file descriptor into the buffer. /// The file descriptor. @@ -1052,9 +968,7 @@ internal static unsafe void Write(SafeFileHandle fd, ReadOnlySpan buffer, int count = buffer.Length; while (count > 0) { -#if !TARGET_WASI int cursorVersion = mayChangeCursorPosition ? Volatile.Read(ref s_cursorVersion) : -1; -#endif int bytesWritten = Interop.Sys.Write(fd, bufPtr, count); if (bytesWritten < 0) @@ -1083,7 +997,6 @@ internal static unsafe void Write(SafeFileHandle fd, ReadOnlySpan buffer, throw Interop.GetExceptionForIoErrno(errorInfo); } } -#if !TARGET_WASI else { if (mayChangeCursorPosition) @@ -1091,7 +1004,6 @@ internal static unsafe void Write(SafeFileHandle fd, ReadOnlySpan buffer, UpdatedCachedCursorPosition(bufPtr, bytesWritten, cursorVersion); } } -#endif count -= bytesWritten; bufPtr += bytesWritten; @@ -1099,7 +1011,6 @@ internal static unsafe void Write(SafeFileHandle fd, ReadOnlySpan buffer, } } -#if !TARGET_WASI private static unsafe void UpdatedCachedCursorPosition(byte* bufPtr, int count, int cursorVersion) { lock (Console.Out) @@ -1187,7 +1098,6 @@ private static void InvalidateTerminalSettings() { Volatile.Write(ref s_invalidateCachedSettings, 1); } -#endif /// Writes a terminfo-based ANSI escape string to stdout. /// The string to write. @@ -1214,53 +1124,5 @@ internal static void WriteStdoutAnsiString(string? value, bool mayChangeCursorPo Write(Interop.Sys.FileDescriptors.STDOUT_FILENO, data, mayChangeCursorPosition); } } - - /// Provides a stream to use for Unix console input or output. - private sealed class UnixConsoleStream : ConsoleStream - { - /// The file descriptor for the opened file. - private readonly SafeFileHandle _handle; - - private readonly bool _useReadLine; - - /// Initialize the stream. - /// The file handle wrapped by this stream. - /// FileAccess.Read or FileAccess.Write. - /// Use ReadLine API for reading. - internal UnixConsoleStream(SafeFileHandle handle, FileAccess access, bool useReadLine = false) - : base(access) - { - Debug.Assert(handle != null, "Expected non-null console handle"); - Debug.Assert(!handle.IsInvalid, "Expected valid console handle"); - _handle = handle; - _useReadLine = useReadLine; - } - - protected override void Dispose(bool disposing) - { - if (disposing) - { - _handle.Dispose(); - } - base.Dispose(disposing); - } - - public override int Read(Span buffer) => - _useReadLine ? - ConsolePal.StdInReader.ReadLine(buffer) : - ConsolePal.Read(_handle, buffer); - - public override void Write(ReadOnlySpan buffer) => - ConsolePal.Write(_handle, buffer); - - public override void Flush() - { - if (_handle.IsClosed) - { - throw Error.GetFileNotOpen(); - } - base.Flush(); - } - } } } diff --git a/src/libraries/System.Console/src/System/ConsolePal.Wasi.cs b/src/libraries/System.Console/src/System/ConsolePal.Wasi.cs new file mode 100644 index 00000000000000..22fb160f4c1814 --- /dev/null +++ b/src/libraries/System.Console/src/System/ConsolePal.Wasi.cs @@ -0,0 +1,333 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.Win32.SafeHandles; +using System.Diagnostics; +using System.IO; +using System.Text; +using System.Threading; +#pragma warning disable IDE0060 + +namespace System +{ + // Provides Unix-based support for System.Console. + // + // NOTE: The test class reflects over this class to run the tests due to limitations in + // the test infrastructure that prevent OS-specific builds of test binaries. If you + // change any of the class / struct / function names, parameters, etc then you need + // to also change the test class. + internal static partial class ConsolePal + { + // StdInReader is only used when input isn't redirected and we're working + // with an interactive terminal. In that case, performance isn't critical + // and we can use a smaller buffer to minimize working set. + // there is no dup on WASI + public static Stream OpenStandardInput() + { + return new UnixConsoleStream(Interop.CheckIo(Interop.Sys.FileDescriptors.STDIN_FILENO), FileAccess.Read, + useReadLine: !Console.IsInputRedirected); + } + + public static Stream OpenStandardOutput() + { + return new UnixConsoleStream(Interop.CheckIo(Interop.Sys.FileDescriptors.STDOUT_FILENO), FileAccess.Write); + } + + public static Stream OpenStandardError() + { + return new UnixConsoleStream(Interop.CheckIo(Interop.Sys.FileDescriptors.STDERR_FILENO), FileAccess.Write); + } + + public static Encoding InputEncoding + { + get { return GetConsoleEncoding(); } + } + + public static Encoding OutputEncoding + { + get { return GetConsoleEncoding(); } + } + + internal static TextReader GetOrCreateReader() + { + Stream inputStream = OpenStandardInput(); + return inputStream == Stream.Null ? + StreamReader.Null : + new StreamReader( + stream: inputStream, + encoding: Console.InputEncoding, + detectEncodingFromByteOrderMarks: false, + bufferSize: Console.ReadBufferSize, + leaveOpen: true); + } + + public static bool KeyAvailable => false; + + public static ConsoleKeyInfo ReadKey(bool intercept) => throw new PlatformNotSupportedException(); + + public static bool TreatControlCAsInput + { + get => throw new PlatformNotSupportedException(); + set => throw new PlatformNotSupportedException(); + } + + public static ConsoleColor ForegroundColor + { + get => throw new PlatformNotSupportedException(); + set => throw new PlatformNotSupportedException(); + } + public static ConsoleColor BackgroundColor + { + get => throw new PlatformNotSupportedException(); + set => throw new PlatformNotSupportedException(); + } + public static void ResetColor() => throw new PlatformNotSupportedException(); + + public static bool NumberLock { get { throw new PlatformNotSupportedException(); } } + + public static bool CapsLock { get { throw new PlatformNotSupportedException(); } } + + public static int CursorSize + { + get { return 100; } + set { throw new PlatformNotSupportedException(); } + } + + + public static string Title + { + get { throw new PlatformNotSupportedException(); } + set => throw new PlatformNotSupportedException(); + } + + public static void Beep() => throw new PlatformNotSupportedException(); + + public static void Clear() => throw new PlatformNotSupportedException(); + public static void SetCursorPosition(int left, int top) => throw new PlatformNotSupportedException(); + public static bool IsInputRedirectedCore() => throw new PlatformNotSupportedException(); + public static bool IsOutputRedirectedCore() => throw new PlatformNotSupportedException(); + public static bool IsErrorRedirectedCore() => throw new PlatformNotSupportedException(); + + public static int BufferWidth + { + get { return WindowWidth; } + set { throw new PlatformNotSupportedException(); } + } + + public static int BufferHeight + { + get { return WindowHeight; } + set { throw new PlatformNotSupportedException(); } + } + + public static int LargestWindowWidth + { + get { return WindowWidth; } + } + + public static int LargestWindowHeight + { + get { return WindowHeight; } + } + + public static int WindowLeft + { + get { return 0; } + set { throw new PlatformNotSupportedException(); } + } + + public static int WindowTop + { + get { return 0; } + set { throw new PlatformNotSupportedException(); } + } + + public static int WindowWidth + { + get + { + GetWindowSize(out int width, out _); + return width; + } + set => SetWindowSize(value, WindowHeight); + } + + public static int WindowHeight + { + get + { + GetWindowSize(out _, out int height); + return height; + } + set => SetWindowSize(WindowWidth, value); + } + + private static void GetWindowSize(out int width, out int height) + { + throw new PlatformNotSupportedException(); + } + + public static void SetWindowSize(int width, int height) + { + throw new PlatformNotSupportedException(); + } + + public static bool CursorVisible + { + get { throw new PlatformNotSupportedException(); } + set + { + throw new PlatformNotSupportedException(); + } + } + + public static (int Left, int Top) GetCursorPosition() + { + throw new PlatformNotSupportedException(); + } + + /// Creates an encoding from the current environment. + /// The encoding. + private static Encoding GetConsoleEncoding() + { + Encoding? enc = EncodingHelper.GetEncodingFromCharset(); + return enc != null ? + enc.RemovePreamble() : + Encoding.Default; + } + +#pragma warning disable IDE0060 + public static void Beep(int frequency, int duration) + { + throw new PlatformNotSupportedException(); + } + + public static void MoveBufferArea(int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight, int targetLeft, int targetTop) + { + throw new PlatformNotSupportedException(); + } + + public static void MoveBufferArea(int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight, int targetLeft, int targetTop, char sourceChar, ConsoleColor sourceForeColor, ConsoleColor sourceBackColor) + { + throw new PlatformNotSupportedException(); + } + + public static void SetBufferSize(int width, int height) + { + throw new PlatformNotSupportedException(); + } + + public static void SetConsoleInputEncoding(Encoding enc) + { + // No-op. + // There is no good way to set the terminal console encoding. + } + + public static void SetConsoleOutputEncoding(Encoding enc) + { + // No-op. + // There is no good way to set the terminal console encoding. + } + + public static void SetWindowPosition(int left, int top) + { + throw new PlatformNotSupportedException(); + } + +#pragma warning restore IDE0060 + + internal static void EnsureConsoleInitialized() + { + } + + /// Reads data from the file descriptor into the buffer. + /// The file descriptor. + /// The buffer to read into. + /// The number of bytes read, or an exception if there's an error. + private static unsafe int Read(SafeFileHandle fd, Span buffer) + { + fixed (byte* bufPtr = buffer) + { + int result = Interop.CheckIo(Interop.Sys.Read(fd, bufPtr, buffer.Length)); + Debug.Assert(result <= buffer.Length); + return result; + } + } + + /// Writes data from the buffer into the file descriptor. + /// The file descriptor. + /// The buffer from which to write data. + /// Writing this buffer may change the cursor position. + internal static unsafe void Write(SafeFileHandle fd, ReadOnlySpan buffer, bool mayChangeCursorPosition = true) + { + // Console initialization might emit data to stdout. + // In order to avoid splitting user data we need to + // complete it before any writes are performed. + EnsureConsoleInitialized(); + + fixed (byte* p = buffer) + { + byte* bufPtr = p; + int count = buffer.Length; + while (count > 0) + { + int bytesWritten = Interop.Sys.Write(fd, bufPtr, count); + if (bytesWritten < 0) + { + Interop.ErrorInfo errorInfo = Interop.Sys.GetLastErrorInfo(); + if (errorInfo.Error == Interop.Error.EPIPE) + { + // Broken pipe... likely due to being redirected to a program + // that ended, so simply pretend we were successful. + return; + } + else if (errorInfo.Error == Interop.Error.EAGAIN) // aka EWOULDBLOCK + { + // May happen if the file handle is configured as non-blocking. + // In that case, we need to wait to be able to write and then + // try again. We poll, but don't actually care about the result, + // only the blocking behavior, and thus ignore any poll errors + // and loop around to do another write (which may correctly fail + // if something else has gone wrong). + Interop.Sys.Poll(fd, Interop.PollEvents.POLLOUT, Timeout.Infinite, out Interop.PollEvents triggered); + continue; + } + else + { + // Something else... fail. + throw Interop.GetExceptionForIoErrno(errorInfo); + } + } + count -= bytesWritten; + bufPtr += bytesWritten; + } + } + } + + /// Writes a terminfo-based ANSI escape string to stdout. + /// The string to write. + /// Writing this value may change the cursor position. + internal static void WriteStdoutAnsiString(string? value, bool mayChangeCursorPosition = true) + { + if (string.IsNullOrEmpty(value)) + return; + + scoped Span data; + if (value.Length <= 256) // except for extremely rare cases, ANSI escape strings are very short + { + data = stackalloc byte[Encoding.UTF8.GetMaxByteCount(value.Length)]; + int bytesToWrite = Encoding.UTF8.GetBytes(value, data); + data = data.Slice(0, bytesToWrite); + } + else + { + data = Encoding.UTF8.GetBytes(value); + } + + lock (Console.Out) // synchronize with other writers + { + Write(Interop.Sys.FileDescriptors.STDOUT_FILENO, data, mayChangeCursorPosition); + } + } + } +} diff --git a/src/libraries/System.Console/src/System/IO/KeyParser.cs b/src/libraries/System.Console/src/System/IO/KeyParser.cs index ce1114c23fe6f2..1167d00ec81c76 100644 --- a/src/libraries/System.Console/src/System/IO/KeyParser.cs +++ b/src/libraries/System.Console/src/System/IO/KeyParser.cs @@ -10,7 +10,6 @@ internal static class KeyParser { private const char Escape = '\u001B'; private const char Delete = '\u007F'; -#if !TARGET_WASI private const char VtSequenceEndTag = '~'; private const char ModifierSeparator = ';'; private const int MinimalSequenceLength = 3; @@ -309,9 +308,8 @@ static ConsoleModifiers MapRxvtModifiers(char modifier) static ConsoleKeyInfo Create(char keyChar, ConsoleKey key, ConsoleModifiers modifiers) => new(keyChar, key, (modifiers & ConsoleModifiers.Shift) != 0, (modifiers & ConsoleModifiers.Alt) != 0, (modifiers & ConsoleModifiers.Control) != 0); } -#endif - internal static ConsoleKeyInfo ParseFromSingleChar(char single, bool isAlt) + private static ConsoleKeyInfo ParseFromSingleChar(char single, bool isAlt) { bool isShift = false, isCtrl = false; char keyChar = single; diff --git a/src/libraries/System.Console/src/System/IO/StdInReader.cs b/src/libraries/System.Console/src/System/IO/StdInReader.cs index 009a4cb4c35497..801c0c78e53dda 100644 --- a/src/libraries/System.Console/src/System/IO/StdInReader.cs +++ b/src/libraries/System.Console/src/System/IO/StdInReader.cs @@ -15,10 +15,8 @@ namespace System.IO */ internal sealed class StdInReader : TextReader { -#if !TARGET_WASI private static string? s_moveLeftString; // string written to move the cursor to the left private static string? s_clearToEol; // string written to clear from cursor to end of line -#endif private readonly StringBuilder _readLineSB; // SB that holds readLine output. This is a field simply to enable reuse; it's only used in ReadLine. private readonly Stack _tmpKeys = new Stack(); // temporary working stack; should be empty outside of ReadLine @@ -200,7 +198,6 @@ private bool ReadLineCore(bool consumeKeys) removed = _tmpKeys.TryPop(out _); } -#if !TARGET_WASI if (removed && freshKeys) { // The ReadLine input may wrap across terminal rows and we need to handle that. @@ -226,7 +223,6 @@ private bool ReadLineCore(bool consumeKeys) Console.Write(s_moveLeftString); } } -#endif } else if (keyInfo.Key == ConsoleKey.Tab) { @@ -298,21 +294,12 @@ private int ReadOrPeek(bool peek) return -1; } -#if TARGET_WASI -#pragma warning disable IDE0060 - private static bool IsEol(char c) - { - return false; // TODOWASI - } -#pragma warning restore IDE0060 -#else private static bool IsEol(char c) { return c != ConsolePal.s_posixDisableValue && (c == ConsolePal.s_veolCharacter || c == ConsolePal.s_veol2Character || c == ConsolePal.s_veofCharacter); } -#endif /// /// Try to intercept the key pressed. @@ -358,24 +345,15 @@ private unsafe ConsoleKeyInfo ReadKey() // Could be empty if EOL entered on its own. Pick one of the EOL characters we have, // or just use 0 if none are available. return new ConsoleKeyInfo((char) -#if TARGET_WASI - 0, // TODOWASI -#else (ConsolePal.s_veolCharacter != ConsolePal.s_posixDisableValue ? ConsolePal.s_veolCharacter : ConsolePal.s_veol2Character != ConsolePal.s_posixDisableValue ? ConsolePal.s_veol2Character : ConsolePal.s_veofCharacter != ConsolePal.s_posixDisableValue ? ConsolePal.s_veofCharacter : 0), -#endif default(ConsoleKey), false, false, false); } } -#if TARGET_WASI - // TODOWASI - return KeyParser.ParseFromSingleChar(_unprocessedBufferToBeRead[_startIndex++], false); -#else return KeyParser.Parse(_unprocessedBufferToBeRead, ConsolePal.TerminalFormatStringsInstance, ConsolePal.s_posixDisableValue, ConsolePal.s_veraseCharacter, ref _startIndex, _endIndex); -#endif } finally { diff --git a/src/libraries/System.IO.Compression/src/CompatibilitySuppressions.xml b/src/libraries/System.IO.Compression/src/CompatibilitySuppressions.xml index bc19b537639ae1..ab6a0f2afe9988 100644 --- a/src/libraries/System.IO.Compression/src/CompatibilitySuppressions.xml +++ b/src/libraries/System.IO.Compression/src/CompatibilitySuppressions.xml @@ -4,28 +4,5 @@ CP0001 T:System.IO.Compression.ZLibException -<<<<<<< HEAD - ref/net7.0/System.IO.Compression.dll - runtimes/browser/lib/net7.0/System.IO.Compression.dll - - - CP0001 - T:System.IO.Compression.ZLibException - ref/net7.0/System.IO.Compression.dll - runtimes/wasi/lib/net7.0/System.IO.Compression.dll - - - CP0001 - T:System.IO.Compression.ZLibException - ref/net7.0/System.IO.Compression.dll - runtimes/unix/lib/net7.0/System.IO.Compression.dll - - - CP0001 - T:System.IO.Compression.ZLibException - ref/net7.0/System.IO.Compression.dll - runtimes/win/lib/net7.0/System.IO.Compression.dll -======= ->>>>>>> main \ No newline at end of file diff --git a/src/libraries/System.Net.Primitives/src/CompatibilitySuppressions.xml b/src/libraries/System.Net.Primitives/src/CompatibilitySuppressions.xml index c80ab9870a60cc..28abd7533b17f3 100644 --- a/src/libraries/System.Net.Primitives/src/CompatibilitySuppressions.xml +++ b/src/libraries/System.Net.Primitives/src/CompatibilitySuppressions.xml @@ -5,49 +5,8 @@ CP0001 T:System.Net.CookieVariant - - CP0001 - T:System.Net.CookieVariant - ref/net7.0/System.Net.Primitives.dll - runtimes/wasi/lib/net7.0/System.Net.Primitives.dll - - - CP0001 - T:System.Net.PathList -<<<<<<< HEAD - ref/net7.0/System.Net.Primitives.dll - runtimes/browser/lib/net7.0/System.Net.Primitives.dll - - - CP0001 - T:System.Net.PathList - ref/net7.0/System.Net.Primitives.dll - runtimes/wasi/lib/net7.0/System.Net.Primitives.dll - - - CP0001 - T:System.Net.CookieVariant - ref/net7.0/System.Net.Primitives.dll - runtimes/unix/lib/net7.0/System.Net.Primitives.dll - - - CP0001 - T:System.Net.PathList - ref/net7.0/System.Net.Primitives.dll - runtimes/unix/lib/net7.0/System.Net.Primitives.dll - - - CP0001 - T:System.Net.CookieVariant - ref/net7.0/System.Net.Primitives.dll - runtimes/win/lib/net7.0/System.Net.Primitives.dll - CP0001 T:System.Net.PathList - ref/net7.0/System.Net.Primitives.dll - runtimes/win/lib/net7.0/System.Net.Primitives.dll -======= ->>>>>>> main \ No newline at end of file diff --git a/src/native/libs/Common/pal_config.h.in b/src/native/libs/Common/pal_config.h.in index 8ccc221b39a3f6..8fe750b16871ee 100644 --- a/src/native/libs/Common/pal_config.h.in +++ b/src/native/libs/Common/pal_config.h.in @@ -59,8 +59,6 @@ #cmakedefine01 HAVE_SIGNAL_KILL #cmakedefine01 HAVE_SYS_RESOURCE_H #cmakedefine01 HAVE_GETRUSAGE -#cmakedefine01 HAVE_GETRLIMIT -#cmakedefine01 HAVE_SETRLIMIT #cmakedefine01 HAVE_SYS_SOCKIO_H #cmakedefine01 HAVE_ETHTOOL_H #cmakedefine01 HAVE_SYS_POLL_H diff --git a/src/native/libs/System.Native/CMakeLists.txt b/src/native/libs/System.Native/CMakeLists.txt index d5037d5557d555..aa64c923d6468b 100644 --- a/src/native/libs/System.Native/CMakeLists.txt +++ b/src/native/libs/System.Native/CMakeLists.txt @@ -15,28 +15,43 @@ if (CLR_CMAKE_TARGET_OSX) endif () set(NATIVE_SOURCES - pal_dynamicload.c pal_errno.c pal_interfaceaddresses.c pal_io.c pal_maphardwaretype.c pal_memory.c - pal_mount.c - pal_networking.c pal_networkstatistics.c - pal_process.c pal_random.c pal_runtimeinformation.c - pal_signal.c pal_string.c pal_tcpstate.c - pal_threading.c pal_time.c - pal_uid.c pal_datetime.c pal_sysctl.c ) +if (NOT CLR_CMAKE_TARGET_WASI) + list (APPEND NATIVE_SOURCES + pal_dynamicload.c + pal_mount.c + pal_networking.c + pal_process.c + pal_signal.c + pal_threading.c + pal_uid.c + ) +else() + list (APPEND NATIVE_SOURCES + pal_dynamicload_wasi.c + pal_mount_wasi.c + pal_networking_wasi.c + pal_process_wasi.c + pal_signal_wasi.c + pal_threading_wasi.c + pal_uid_wasi.c + ) +endif() + if (CLR_CMAKE_TARGET_OSX OR CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS) list (APPEND NATIVE_SOURCES pal_autoreleasepool.m) set_source_files_properties(pal_autoreleasepool.m PROPERTIES COMPILE_FLAGS -fno-objc-arc) @@ -64,6 +79,11 @@ elseif (CLR_CMAKE_TARGET_OSX) pal_searchpath.m pal_console.c pal_log.c) +elseif (CLR_CMAKE_TARGET_WASI) + list (APPEND NATIVE_SOURCES + pal_searchpath.c + pal_console_wasi.c + pal_log.c) else () list (APPEND NATIVE_SOURCES pal_searchpath.c diff --git a/src/native/libs/System.Native/pal_console.c b/src/native/libs/System.Native/pal_console.c index e7ce2a7e13a7c6..d217075e5a276b 100644 --- a/src/native/libs/System.Native/pal_console.c +++ b/src/native/libs/System.Native/pal_console.c @@ -13,14 +13,10 @@ #include #include #include -#if HAVE_TERMIOS_H #include -#endif #include #include -#if HAVE_PTHREAD_H #include -#endif #include int32_t SystemNative_GetWindowSize(WinSize* windowSize) @@ -91,7 +87,6 @@ void SystemNative_SetKeypadXmit(const char* terminfoString) WriteKeypadXmit(); } -#if !defined(TARGET_WASI) static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER; // prevents races when initializing and changing the terminal. static bool g_signalForBreak = true; // tracks whether the terminal should send signals for breaks, such that attributes have been changed @@ -230,11 +225,9 @@ void UninitializeTerminal(void) pthread_mutex_unlock(&g_lock); } } -#endif /* TARGET_WASI */ void SystemNative_InitializeConsoleBeforeRead(uint8_t minChars, uint8_t decisecondsTimeout) { -#if !defined(TARGET_WASI) if (pthread_mutex_lock(&g_lock) == 0) { g_reading = true; @@ -243,24 +236,20 @@ void SystemNative_InitializeConsoleBeforeRead(uint8_t minChars, uint8_t deciseco pthread_mutex_unlock(&g_lock); } -#endif /* TARGET_WASI */ } void SystemNative_UninitializeConsoleAfterRead(void) { -#if !defined(TARGET_WASI) if (pthread_mutex_lock(&g_lock) == 0) { g_reading = false; pthread_mutex_unlock(&g_lock); } -#endif /* TARGET_WASI */ } void SystemNative_ConfigureTerminalForChildProcess(int32_t childUsesTerminal) { -#if !defined(TARGET_WASI) assert(childUsesTerminal == 0 || childUsesTerminal == 1); if (pthread_mutex_lock(&g_lock) == 0) @@ -292,10 +281,8 @@ void SystemNative_ConfigureTerminalForChildProcess(int32_t childUsesTerminal) pthread_mutex_unlock(&g_lock); } -#endif /* TARGET_WASI */ } -#if !defined(TARGET_WASI) static int TranslatePalControlCharacterName(int name) { switch (name) @@ -354,7 +341,6 @@ static int TranslatePalControlCharacterName(int name) default: return -1; } } -#endif /* TARGET_WASI */ void SystemNative_GetControlCharacters( int32_t* controlCharacterNames, uint8_t* controlCharacterValues, int32_t controlCharacterLength, @@ -373,7 +359,6 @@ void SystemNative_GetControlCharacters( memset(controlCharacterValues, *posixDisableValue, sizeof(uint8_t) * Int32ToSizeT(controlCharacterLength)); -#if HAVE_TERMIOS_H if (controlCharacterLength > 0) { struct termios newTermios; @@ -391,7 +376,6 @@ void SystemNative_GetControlCharacters( } } } -#endif } int32_t SystemNative_StdinReady(void) @@ -421,18 +405,13 @@ int32_t SystemNative_ReadStdin(void* buffer, int32_t bufferSize) int32_t SystemNative_GetSignalForBreak(void) { -#if !defined(TARGET_WASI) return g_signalForBreak; -#else /* TARGET_WASI */ - return false; -#endif /* TARGET_WASI */ } int32_t SystemNative_SetSignalForBreak(int32_t signalForBreak) { assert(signalForBreak == 0 || signalForBreak == 1); -#if !defined(TARGET_WASI) int rv = 0; if (pthread_mutex_lock(&g_lock) == 0) @@ -447,9 +426,6 @@ int32_t SystemNative_SetSignalForBreak(int32_t signalForBreak) } return rv; -#else /* TARGET_WASI */ - return 0; -#endif /* TARGET_WASI */ } void ReinitializeTerminal(void) @@ -457,7 +433,6 @@ void ReinitializeTerminal(void) // Restores the state of the terminal after being suspended. // pal_signal.cpp calls this on SIGCONT from the signal handling thread. -#if !defined(TARGET_WASI) if (pthread_mutex_lock(&g_lock) == 0) { if (!g_childUsesTerminal) @@ -472,10 +447,8 @@ void ReinitializeTerminal(void) pthread_mutex_unlock(&g_lock); } -#endif /* TARGET_WASI */ } -#if !defined(TARGET_WASI) static void InitializeTerminalCore(void) { bool haveInitTermios = tcgetattr(STDIN_FILENO, &g_initTermios) >= 0; @@ -494,11 +467,9 @@ static void InitializeTerminalCore(void) g_signalForBreak = true; } } -#endif /* TARGET_WASI */ int32_t SystemNative_InitializeTerminalAndSignalHandling(void) { -#if !defined(TARGET_WASI) static int32_t initialized = 0; // The Process, Console and PosixSignalRegistration classes call this method for initialization. @@ -513,7 +484,4 @@ int32_t SystemNative_InitializeTerminalAndSignalHandling(void) } return initialized; -#else /* TARGET_WASI */ - return true; -#endif /* TARGET_WASI */ } diff --git a/src/native/libs/System.Native/pal_console_wasi.c b/src/native/libs/System.Native/pal_console_wasi.c new file mode 100644 index 00000000000000..e467df32bfe1a1 --- /dev/null +++ b/src/native/libs/System.Native/pal_console_wasi.c @@ -0,0 +1,127 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "pal_config.h" +#include "pal_console.h" +#include "pal_utilities.h" +#include "pal_signal.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int32_t SystemNative_GetWindowSize(WinSize* windowSize) +{ + assert(windowSize != NULL); + memset(windowSize, 0, sizeof(WinSize)); // managed out param must be initialized + errno = ENOTSUP; + return -1; +} + +int32_t SystemNative_SetWindowSize(WinSize* windowSize) +{ + assert(windowSize != NULL); + (void)windowSize; + errno = ENOTSUP; + return -1; +} + +int32_t SystemNative_IsATty(intptr_t fd) +{ + return isatty(ToFileDescriptor(fd)); +} + +__attribute__((noreturn)) +void SystemNative_SetKeypadXmit(const char* terminfoString) +{ + (void)terminfoString; //unused + assert(terminfoString != NULL); + assert_msg(false, "Not supported on WASI", 0); +} + +__attribute__((noreturn)) +void SystemNative_InitializeConsoleBeforeRead(uint8_t minChars, uint8_t decisecondsTimeout) +{ + (void)minChars; //unused + (void)decisecondsTimeout; //unused + assert_msg(false, "Not supported on WASI", 0); +} + +__attribute__((noreturn)) +void SystemNative_UninitializeConsoleAfterRead(void) +{ + assert_msg(false, "Not supported on WASI", 0); +} + +__attribute__((noreturn)) +void SystemNative_ConfigureTerminalForChildProcess(int32_t childUsesTerminal) +{ + (void)childUsesTerminal; //unused + assert_msg(false, "Not supported on WASI", 0); +} + +__attribute__((noreturn)) +void SystemNative_GetControlCharacters( + int32_t* controlCharacterNames, uint8_t* controlCharacterValues, int32_t controlCharacterLength, + uint8_t* posixDisableValue) +{ + assert(controlCharacterNames != NULL); + assert(controlCharacterValues != NULL); + assert(controlCharacterLength >= 0); + assert(posixDisableValue != NULL); + + (void)controlCharacterNames; //unused + (void)controlCharacterValues; //unused + (void)controlCharacterLength; //unused + (void)posixDisableValue; //unused + assert_msg(false, "Not supported on WASI", 0); +} + +int32_t SystemNative_StdinReady(void) +{ + struct pollfd fd = { .fd = STDIN_FILENO, .events = POLLIN }; + int rv = poll(&fd, 1, 0) > 0 ? 1 : 0; + return rv; +} + +int32_t SystemNative_ReadStdin(void* buffer, int32_t bufferSize) +{ + assert(buffer != NULL || bufferSize == 0); + assert(bufferSize >= 0); + + if (bufferSize < 0) + { + errno = EINVAL; + return -1; + } + + ssize_t count; + while (CheckInterrupted(count = read(STDIN_FILENO, buffer, Int32ToSizeT(bufferSize)))); + return (int32_t)count; +} + +int32_t SystemNative_GetSignalForBreak(void) +{ + return false; +} + +int32_t SystemNative_SetSignalForBreak(int32_t signalForBreak) +{ + assert(signalForBreak == 0 || signalForBreak == 1); + assert_msg(false, "Not supported on WASI", 0); + return -1; +} + + + +int32_t SystemNative_InitializeTerminalAndSignalHandling(void) +{ + return true; +} diff --git a/src/native/libs/System.Native/pal_dynamicload.c b/src/native/libs/System.Native/pal_dynamicload.c index 9025b10f43f16f..76f9c56678af5c 100644 --- a/src/native/libs/System.Native/pal_dynamicload.c +++ b/src/native/libs/System.Native/pal_dynamicload.c @@ -4,11 +4,8 @@ #include "pal_config.h" #include "pal_dynamicload.h" -#if HAVE_DLFCN_H #include -#endif #include -#include #if HAVE_GNU_LIBNAMES_H #include @@ -16,7 +13,6 @@ void* SystemNative_LoadLibrary(const char* filename) { -#if !defined(TARGET_WASI) // Check whether we have been requested to load 'libc'. If that's the case, then: // * For Linux, use the full name of the library that is defined in by the // LIBC_SO constant. The problem is that calling dlopen("libc.so") will fail for libc even @@ -40,45 +36,26 @@ void* SystemNative_LoadLibrary(const char* filename) } return dlopen(filename, RTLD_LAZY); -#else /* TARGET_WASI */ - return NULL; -#endif /* TARGET_WASI */ } void* SystemNative_GetLoadLibraryError(void) { -#if !defined(TARGET_WASI) return dlerror(); -#else /* TARGET_WASI */ - return NULL; -#endif /* TARGET_WASI */ } void* SystemNative_GetProcAddress(void* handle, const char* symbol) { -#if !defined(TARGET_WASI) // We're not trying to disambiguate between "symbol was not found" and "symbol found, but // the value is null". .NET does not define a behavior for DllImports of null entrypoints, // so we might as well take the "not found" path on the managed side. return dlsym(handle, symbol); -#else /* TARGET_WASI */ - return NULL; -#endif /* TARGET_WASI */ } void SystemNative_FreeLibrary(void* handle) { -#if !defined(TARGET_WASI) dlclose(handle); -#endif /* TARGET_WASI */ } -#if defined TARGET_WASI -void* SystemNative_GetDefaultSearchOrderPseudoHandle(void) -{ - return NULL; -} -#else static void* volatile g_defaultSearchOrderPseudoHandle = NULL; void* SystemNative_GetDefaultSearchOrderPseudoHandle(void) { @@ -99,4 +76,3 @@ void* SystemNative_GetDefaultSearchOrderPseudoHandle(void) } return defaultSearchOrderPseudoHandle; } -#endif diff --git a/src/native/libs/System.Native/pal_dynamicload_wasi.c b/src/native/libs/System.Native/pal_dynamicload_wasi.c new file mode 100644 index 00000000000000..7fce6cf151aa3b --- /dev/null +++ b/src/native/libs/System.Native/pal_dynamicload_wasi.c @@ -0,0 +1,39 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "pal_config.h" +#include "pal_dynamicload.h" +#include "pal_utilities.h" + +#include +#include + + +void* SystemNative_LoadLibrary(const char* filename) +{ + assert_msg(false, "Not supported on WASI", 0); + (void)filename; // unused + return NULL; +} + +void* SystemNative_GetLoadLibraryError(void) +{ + assert_msg(false, "Not supported on WASI", 0); + return NULL; +} + +void* SystemNative_GetProcAddress(void* handle, const char* symbol) +{ + assert_msg(false, "Not supported on WASI", 0); + return NULL; +} + +void SystemNative_FreeLibrary(void* handle) +{ +} + +void* SystemNative_GetDefaultSearchOrderPseudoHandle(void) +{ + assert_msg(false, "Not supported on WASI", 0); + return NULL; +} diff --git a/src/native/libs/System.Native/pal_io.c b/src/native/libs/System.Native/pal_io.c index dd683bc7959098..9a44586c77beb2 100644 --- a/src/native/libs/System.Native/pal_io.c +++ b/src/native/libs/System.Native/pal_io.c @@ -107,7 +107,6 @@ extern int getpeereid(int, uid_t *__restrict__, gid_t *__restrict__); #define lstat_ lstat #endif /* HAVE_STAT64 */ -#if !defined(TARGET_WASI) // These numeric values are specified by POSIX. // Validate that our definitions match. c_static_assert(PAL_S_IRWXU == S_IRWXU); @@ -129,15 +128,16 @@ c_static_assert(PAL_S_ISGID == S_ISGID); // are common to our current targets. If these static asserts fail, // ConvertFileStatus needs to be updated to twiddle mode bits // accordingly. +#if !defined(TARGET_WASI) c_static_assert(PAL_S_IFMT == S_IFMT); c_static_assert(PAL_S_IFIFO == S_IFIFO); +#endif /* TARGET_WASI */ c_static_assert(PAL_S_IFBLK == S_IFBLK); c_static_assert(PAL_S_IFCHR == S_IFCHR); c_static_assert(PAL_S_IFDIR == S_IFDIR); c_static_assert(PAL_S_IFREG == S_IFREG); c_static_assert(PAL_S_IFLNK == S_IFLNK); c_static_assert(PAL_S_IFSOCK == S_IFSOCK); -#endif /* TARGET_WASI */ // Validate that our enum for inode types is the same as what is // declared by the dirent.h header on the local system. @@ -889,6 +889,7 @@ intptr_t SystemNative_MksTemps(char* pathTemplate, int32_t suffixLength) pathTemplate[firstSuffixIndex] = firstSuffixChar; } #elif TARGET_WASI + assert_msg(false, "Not supported on WASI", 0); result = -1; #else #error "Cannot find mkstemps nor mkstemp on this platform" @@ -1055,7 +1056,7 @@ int32_t SystemNative_MSync(void* address, uint64_t length, int32_t flags) return -1; } -#if !defined(TARGET_WASI) +#if defined(TARGET_WASI) return msync(address, (size_t)length, flags); #else return -1; @@ -1926,4 +1927,3 @@ int64_t SystemNative_PWriteV(intptr_t fd, IOVector* vectors, int32_t vectorCount assert(count >= -1); return count; } - diff --git a/src/native/libs/System.Native/pal_maphardwaretype.c b/src/native/libs/System.Native/pal_maphardwaretype.c index 2a37864b1eaaf9..2a9e78216074ae 100644 --- a/src/native/libs/System.Native/pal_maphardwaretype.c +++ b/src/native/libs/System.Native/pal_maphardwaretype.c @@ -114,7 +114,6 @@ uint16_t MapHardwareType(uint16_t nativeType) return NetworkInterfaceType_Unknown; } #elif defined(TARGET_WASI) - // TODOWASI return NetworkInterfaceType_Unknown; #endif } diff --git a/src/native/libs/System.Native/pal_mount.c b/src/native/libs/System.Native/pal_mount.c index 269a1c1cae026d..2453bdfe9ede3f 100644 --- a/src/native/libs/System.Native/pal_mount.c +++ b/src/native/libs/System.Native/pal_mount.c @@ -12,27 +12,22 @@ // Check if we should use getmntinfo or /proc/mounts #if HAVE_MNTINFO #include -#else /* HAVE_MNTINFO */ -#if HAVE_STATFS +#else #include -#endif /* HAVE_STATFS */ #if HAVE_SYS_MNTENT_H #include #include -#if HAVE_SYS_STATVFS_H #include -#endif /* HAVE_SYS_STATVFS_H */ -#else /* HAVE_SYS_MNTENT_H */ -#if HAVE_MNTENT_H +#else #include +#endif #define STRING_BUFFER_SIZE 8192 + // Android does not define MNTOPT_RO #ifndef MNTOPT_RO #define MNTOPT_RO "r" -#endif /* MNTOPT_RO */ -#endif /* HAVE_MNTENT_H */ -#endif /* HAVE_SYS_MNTENT_H */ -#endif /* HAVE_MNTINFO */ +#endif +#endif int32_t SystemNative_GetAllMountPoints(MountPointFound onFound, void* context) { @@ -73,7 +68,7 @@ int32_t SystemNative_GetAllMountPoints(MountPointFound onFound, void* context) return result; } -#elif HAVE_MNTENT_H +#else int result = -1; FILE* fp = setmntent("/proc/mounts", MNTOPT_RO); if (fp != NULL) @@ -95,9 +90,6 @@ int32_t SystemNative_GetAllMountPoints(MountPointFound onFound, void* context) return result; } -#else - return -1; -} #endif @@ -111,15 +103,12 @@ int32_t SystemNative_GetSpaceInfoForMountPoint(const char* name, MountPointInfor memset(&stats, 0, sizeof(struct statfs)); int result = statfs(name, &stats); -#elif HAVE_MNTENT_H +#else struct statvfs stats; memset(&stats, 0, sizeof(struct statvfs)); int result = statvfs(name, &stats); -#else - return -1; #endif -#if HAVE_NON_LEGACY_STATFS || HAVE_MNTENT_H if (result == 0) { // Note that these have signed integer types on some platforms but mustn't be negative. @@ -140,7 +129,6 @@ int32_t SystemNative_GetSpaceInfoForMountPoint(const char* name, MountPointInfor } return result; -#endif /* HAVE_NON_LEGACY_STATFS || HAVE_MNTENT_H */ } int32_t @@ -152,11 +140,9 @@ SystemNative_GetFormatInfoForMountPoint(const char* name, char* formatNameBuffer #if HAVE_NON_LEGACY_STATFS struct statfs stats; int result = statfs(name, &stats); -#elif HAVE_MNTENT_H +#else struct statvfs stats; int result = statvfs(name, &stats); -#else - int result = -1; #endif if (result == 0) { diff --git a/src/native/libs/System.Native/pal_mount_wasi.c b/src/native/libs/System.Native/pal_mount_wasi.c new file mode 100644 index 00000000000000..6ca1f40f7463d4 --- /dev/null +++ b/src/native/libs/System.Native/pal_mount_wasi.c @@ -0,0 +1,38 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "pal_config.h" +#include "pal_mount.h" +#include "pal_utilities.h" +#include +#include +#include +#include + +int32_t SystemNative_GetAllMountPoints(MountPointFound onFound, void* context) +{ + (void)onFound; // unused + (void)context; // unused + return -1; +} + +int32_t SystemNative_GetSpaceInfoForMountPoint(const char* name, MountPointInformation* mpi) +{ + assert(name != NULL); + assert(mpi != NULL); + (void)name; // unused + (void)mpi; // unused + return -1; +} + +int32_t +SystemNative_GetFormatInfoForMountPoint(const char* name, char* formatNameBuffer, int32_t bufferLength, int64_t* formatType) +{ + assert((formatNameBuffer != NULL) && (formatType != NULL)); + assert(bufferLength > 0); + (void)name; // unused + (void)formatNameBuffer; // unused + (void)bufferLength; // unused + (void)formatType; // unused + return -1; +} diff --git a/src/native/libs/System.Native/pal_networkchange.c b/src/native/libs/System.Native/pal_networkchange.c index 56391820123dd0..b4386a762f3f08 100644 --- a/src/native/libs/System.Native/pal_networkchange.c +++ b/src/native/libs/System.Native/pal_networkchange.c @@ -9,9 +9,7 @@ #include "pal_utilities.h" #include -#if HAVE_NET_IF_H #include -#endif #include #include #include diff --git a/src/native/libs/System.Native/pal_networking.c b/src/native/libs/System.Native/pal_networking.c index a831bd9a6f99fe..e6413d276e4b50 100644 --- a/src/native/libs/System.Native/pal_networking.c +++ b/src/native/libs/System.Native/pal_networking.c @@ -10,9 +10,7 @@ #include #include -#if HAVE_PTHREAD_H #include -#endif #include #include #include @@ -32,9 +30,7 @@ #include #include #include -#if HAVE_NET_IF_H #include -#endif #include #include #include @@ -51,9 +47,7 @@ #include #endif #include -#if HAVE_PWD_H #include -#endif #if HAVE_SENDFILE_4 #include #elif HAVE_SENDFILE_6 @@ -118,7 +112,7 @@ static uint16_t GetKeventFlags(uint32_t flags) #endif #endif -#if !HAVE_IN_PKTINFO && !defined(IP_PKTINFO) +#if !HAVE_IN_PKTINFO // On platforms, such as FreeBSD, where in_pktinfo // is not available, fallback to custom definition // with required members. @@ -137,7 +131,6 @@ struct in_pktinfo #define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP #endif -#if !defined(TARGET_WASI) enum { #if defined(__APPLE__) && __APPLE__ @@ -146,21 +139,18 @@ enum LINGER_OPTION_NAME = SO_LINGER, #endif }; -#endif /* TARGET_WASI */ enum { INET6_ADDRSTRLEN_MANAGED = 65 // Managed code has a longer max IPv6 string length }; -#if !defined(TARGET_WASI) c_static_assert(GetHostErrorCodes_HOST_NOT_FOUND == HOST_NOT_FOUND); c_static_assert(GetHostErrorCodes_TRY_AGAIN == TRY_AGAIN); c_static_assert(GetHostErrorCodes_NO_RECOVERY == NO_RECOVERY); c_static_assert(GetHostErrorCodes_NO_DATA == NO_DATA); c_static_assert(GetHostErrorCodes_NO_ADDRESS == NO_ADDRESS); c_static_assert(sizeof(uint8_t) == sizeof(char)); // We make casts from uint8_t to char so make sure it's legal -#endif /* TARGET_WASI */ // sizeof_member(struct foo, bar) is not valid C++. // The fix is to remove struct. That is not valid C. @@ -272,7 +262,6 @@ static void ConvertByteArrayToSockAddrIn6(struct sockaddr_in6* addr, const uint8 // Mark that this is INET6 addr->sin6_family = AF_INET6; } -#if !defined(TARGET_WASI) static void ConvertByteArrayToInAddr(struct in_addr* addr, const uint8_t* buffer, int32_t bufferLength) { @@ -299,29 +288,19 @@ static int32_t ConvertGetAddrInfoAndGetNameInfoErrorsToPal(int32_t error) { case 0: return 0; -#ifdef EAI_AGAIN case EAI_AGAIN: return GetAddrInfoErrorFlags_EAI_AGAIN; -#endif -#ifdef EAI_BADFLAGS case EAI_BADFLAGS: return GetAddrInfoErrorFlags_EAI_BADFLAGS; -#endif #ifdef EAI_FAIL case EAI_FAIL: return GetAddrInfoErrorFlags_EAI_FAIL; #endif -#ifdef EAI_FAMILY case EAI_FAMILY: return GetAddrInfoErrorFlags_EAI_FAMILY; -#endif -#ifdef EAI_MEMORY case EAI_MEMORY: return GetAddrInfoErrorFlags_EAI_MEMORY; -#endif -#ifdef EAI_NONAME case EAI_NONAME: -#endif #ifdef EAI_NODATA case EAI_NODATA: #endif @@ -354,7 +333,6 @@ static int32_t CopySockAddrToIPAddress(sockaddr* addr, sa_family_t family, IPAdd return -1; } -#endif /* TARGET_WASI */ int32_t SystemNative_GetHostEntryForName(const uint8_t* address, int32_t addressFamily, HostEntry* entry) { @@ -362,7 +340,6 @@ int32_t SystemNative_GetHostEntryForName(const uint8_t* address, int32_t address { return GetAddrInfoErrorFlags_EAI_BADARG; } -#if !defined(TARGET_WASI) int32_t ret = GetAddrInfoErrorFlags_EAI_SUCCESS; @@ -539,9 +516,6 @@ int32_t SystemNative_GetHostEntryForName(const uint8_t* address, int32_t address } return ret; -#else /* TARGET_WASI */ - return -1; -#endif /* TARGET_WASI */ } void SystemNative_FreeHostEntry(HostEntry* entry) @@ -564,7 +538,6 @@ typedef int32_t NativeFlagsType; typedef uint32_t NativeFlagsType; #endif -#if !defined(TARGET_WASI) static inline NativeFlagsType ConvertGetNameInfoFlagsToNative(int32_t flags) { NativeFlagsType outFlags = 0; @@ -579,7 +552,6 @@ static inline NativeFlagsType ConvertGetNameInfoFlagsToNative(int32_t flags) return outFlags; } -#endif int32_t SystemNative_GetNameInfo(const uint8_t* address, int32_t addressLength, @@ -595,7 +567,6 @@ int32_t SystemNative_GetNameInfo(const uint8_t* address, assert((host != NULL) || (service != NULL)); assert((hostLength > 0) || (serviceLength > 0)); -#if !defined(TARGET_WASI) NativeFlagsType nativeFlags = ConvertGetNameInfoFlagsToNative(flags); int32_t result; @@ -627,9 +598,6 @@ int32_t SystemNative_GetNameInfo(const uint8_t* address, } return ConvertGetAddrInfoAndGetNameInfoErrorsToPal(result); -#else /* TARGET_WASI */ - return Error_EINVAL; -#endif /* TARGET_WASI */ } int32_t SystemNative_GetDomainName(uint8_t* name, int32_t nameLength) @@ -929,7 +897,6 @@ SystemNative_SetIPv6Address(uint8_t* socketAddress, int32_t socketAddressLen, ui return Error_SUCCESS; } -#if !defined(TARGET_WASI) static int8_t IsStreamSocket(int socket) { int type; @@ -956,21 +923,15 @@ static void ConvertMessageHeaderToMsghdr(struct msghdr* header, const MessageHea header->msg_controllen = (uint32_t)messageHeader->ControlBufferLen; header->msg_flags = 0; } -#endif /* TARGET_WASI */ int32_t SystemNative_GetControlMessageBufferSize(int32_t isIPv4, int32_t isIPv6) { -#if defined(CMSG_SPACE) // Note: it is possible that the address family of the socket is neither // AF_INET nor AF_INET6. In this case both inputs will be 0 and // the control message buffer size should be zero. return (isIPv4 != 0 ? CMSG_SPACE(sizeof(struct in_pktinfo)) : 0) + (isIPv6 != 0 ? CMSG_SPACE(sizeof(struct in6_pktinfo)) : 0); -#else /* CMSG_SPACE */ - return Error_EINVAL; -#endif /* CMSG_SPACE */ } -#if !defined(TARGET_WASI) static int32_t GetIPv4PacketInformation(struct cmsghdr* controlMessage, IPPacketInformation* packetInfo) { assert(controlMessage != NULL); @@ -1049,7 +1010,6 @@ static struct cmsghdr* GET_CMSG_NXTHDR(struct msghdr* mhdr, struct cmsghdr* cmsg #pragma clang diagnostic pop #endif } -#endif /* TARGET_WASI */ int32_t SystemNative_TryGetIPPacketInformation(MessageHeader* messageHeader, int32_t isIPv4, IPPacketInformation* packetInfo) @@ -1059,7 +1019,6 @@ SystemNative_TryGetIPPacketInformation(MessageHeader* messageHeader, int32_t isI return 0; } -#if !defined(TARGET_WASI) struct msghdr header; ConvertMessageHeaderToMsghdr(&header, messageHeader, -1); @@ -1088,9 +1047,6 @@ SystemNative_TryGetIPPacketInformation(MessageHeader* messageHeader, int32_t isI } return 0; -#else /* TARGET_WASI */ - return Error_EINVAL; -#endif /* TARGET_WASI */ } static int8_t GetMulticastOptionName(int32_t multicastOption, int8_t isIPv6, int* optionName) @@ -1160,7 +1116,6 @@ int32_t SystemNative_SetIPv4MulticastOption(intptr_t socket, int32_t multicastOp return Error_EFAULT; } -#if !defined(TARGET_WASI) int fd = ToFileDescriptor(socket); int optionName; @@ -1187,9 +1142,6 @@ int32_t SystemNative_SetIPv4MulticastOption(intptr_t socket, int32_t multicastOp #endif int err = setsockopt(fd, IPPROTO_IP, optionName, &opt, sizeof(opt)); return err == 0 ? Error_SUCCESS : SystemNative_ConvertErrorPlatformToPal(errno); -#else /* TARGET_WASI */ - return Error_EINVAL; -#endif /* TARGET_WASI */ } int32_t SystemNative_GetIPv6MulticastOption(intptr_t socket, int32_t multicastOption, IPv6MulticastOption* option) @@ -1226,7 +1178,6 @@ int32_t SystemNative_SetIPv6MulticastOption(intptr_t socket, int32_t multicastOp { return Error_EFAULT; } -#if !defined(TARGET_WASI) int fd = ToFileDescriptor(socket); @@ -1250,12 +1201,8 @@ int32_t SystemNative_SetIPv6MulticastOption(intptr_t socket, int32_t multicastOp int err = setsockopt(fd, IPPROTO_IPV6, optionName, &opt, sizeof(opt)); return err == 0 ? Error_SUCCESS : SystemNative_ConvertErrorPlatformToPal(errno); -#else /* TARGET_WASI */ - return Error_EINVAL; -#endif /* TARGET_WASI */ } -#if !defined(TARGET_WASI) #if defined(__APPLE__) && __APPLE__ static int32_t GetMaxLingerTime(void) { @@ -1292,7 +1239,6 @@ static int32_t GetMaxLingerTime(void) return Min(65535U, (1U << (sizeof_member(linger, l_linger) * 8 - 1)) - 1); } #endif -#endif /* TARGET_WASI */ int32_t SystemNative_GetLingerOption(intptr_t socket, LingerOption* option) { @@ -1301,7 +1247,6 @@ int32_t SystemNative_GetLingerOption(intptr_t socket, LingerOption* option) return Error_EFAULT; } -#if !defined(TARGET_WASI) int fd = ToFileDescriptor(socket); struct linger opt; @@ -1316,10 +1261,6 @@ int32_t SystemNative_GetLingerOption(intptr_t socket, LingerOption* option) option->OnOff = opt.l_onoff; option->Seconds = opt.l_linger; return Error_SUCCESS; -#else /* TARGET_WASI */ - memset(option, 0, sizeof(LingerOption)); - return Error_EINVAL; -#endif /* TARGET_WASI */ } int32_t SystemNative_SetLingerOption(intptr_t socket, LingerOption* option) @@ -1329,7 +1270,6 @@ int32_t SystemNative_SetLingerOption(intptr_t socket, LingerOption* option) return Error_EFAULT; } -#if !defined(TARGET_WASI) if (option->OnOff != 0 && (option->Seconds < 0 || option->Seconds > GetMaxLingerTime())) { return Error_EINVAL; @@ -1354,12 +1294,8 @@ int32_t SystemNative_SetLingerOption(intptr_t socket, LingerOption* option) #endif return err == 0 ? Error_SUCCESS : SystemNative_ConvertErrorPlatformToPal(errno); -#else /* TARGET_WASI */ - return Error_EINVAL; -#endif /* TARGET_WASI */ } -#if !defined(TARGET_WASI) static int32_t SetTimeoutOption(int32_t socket, int32_t millisecondsTimeout, int optionName) { if (millisecondsTimeout < 0) @@ -1374,24 +1310,15 @@ static int32_t SetTimeoutOption(int32_t socket, int32_t millisecondsTimeout, int int err = setsockopt(socket, SOL_SOCKET, optionName, &timeout, sizeof(timeout)); return err == 0 ? Error_SUCCESS : SystemNative_ConvertErrorPlatformToPal(errno); } -#endif /* TARGET_WASI */ int32_t SystemNative_SetReceiveTimeout(intptr_t socket, int32_t millisecondsTimeout) { -#if !defined(TARGET_WASI) return SetTimeoutOption(ToFileDescriptor(socket), millisecondsTimeout, SO_RCVTIMEO); -#else /* TARGET_WASI */ - return Error_EINVAL; -#endif /* TARGET_WASI */ } int32_t SystemNative_SetSendTimeout(intptr_t socket, int32_t millisecondsTimeout) { -#if !defined(TARGET_WASI) return SetTimeoutOption(ToFileDescriptor(socket), millisecondsTimeout, SO_SNDTIMEO); -#else /* TARGET_WASI */ - return Error_EINVAL; -#endif /* TARGET_WASI */ } static int8_t ConvertSocketFlagsPalToPlatform(int32_t palFlags, int* platformFlags) @@ -1403,44 +1330,26 @@ static int8_t ConvertSocketFlagsPalToPlatform(int32_t palFlags, int* platformFla return false; } - *platformFlags = -#ifdef MSG_OOB - ((palFlags & SocketFlags_MSG_OOB) == 0 ? 0 : MSG_OOB) | -#endif /* MSG_OOB */ + *platformFlags = ((palFlags & SocketFlags_MSG_OOB) == 0 ? 0 : MSG_OOB) | ((palFlags & SocketFlags_MSG_PEEK) == 0 ? 0 : MSG_PEEK) | -#ifdef MSG_DONTROUTE ((palFlags & SocketFlags_MSG_DONTROUTE) == 0 ? 0 : MSG_DONTROUTE) | -#endif /* MSG_DONTROUTE */ -#if defined(MSG_TRUNC) && !defined(TARGET_WASI) // https://github.com/WebAssembly/wasi-libc/issues/305 ((palFlags & SocketFlags_MSG_TRUNC) == 0 ? 0 : MSG_TRUNC) | -#endif /* MSG_TRUNC */ -#ifdef MSG_CTRUNC - ((palFlags & SocketFlags_MSG_CTRUNC) == 0 ? 0 : MSG_CTRUNC) | -#endif /* MSG_CTRUNC */ - (0); + ((palFlags & SocketFlags_MSG_CTRUNC) == 0 ? 0 : MSG_CTRUNC); return true; } -#if !defined(TARGET_WASI) static int32_t ConvertSocketFlagsPlatformToPal(int platformFlags) { - return -#ifdef MSG_OOB - ((platformFlags & MSG_OOB) == 0 ? 0 : SocketFlags_MSG_OOB) | -#endif /* MSG_OOB */ -#ifdef MSG_DONTROUTE + const int SupportedFlagsMask = MSG_OOB | MSG_DONTROUTE | MSG_TRUNC | MSG_CTRUNC; + + platformFlags &= SupportedFlagsMask; + + return ((platformFlags & MSG_OOB) == 0 ? 0 : SocketFlags_MSG_OOB) | ((platformFlags & MSG_DONTROUTE) == 0 ? 0 : SocketFlags_MSG_DONTROUTE) | -#endif /* MSG_DONTROUTE */ -#if defined(MSG_TRUNC) && !defined(TARGET_WASI) // https://github.com/WebAssembly/wasi-libc/issues/305 ((platformFlags & MSG_TRUNC) == 0 ? 0 : SocketFlags_MSG_TRUNC) | -#endif /* MSG_TRUNC */ -#ifdef MSG_CTRUNC - ((platformFlags & MSG_CTRUNC) == 0 ? 0 : SocketFlags_MSG_CTRUNC) | -#endif /* MSG_CTRUNC */ - (0); + ((platformFlags & MSG_CTRUNC) == 0 ? 0 : SocketFlags_MSG_CTRUNC); } -#endif /* TARGET_WASI */ int32_t SystemNative_Receive(intptr_t socket, void* buffer, int32_t bufferLen, int32_t flags, int32_t* received) { @@ -1478,7 +1387,6 @@ int32_t SystemNative_ReceiveMessage(intptr_t socket, MessageHeader* messageHeade return Error_EFAULT; } -#if !defined(TARGET_WASI) int fd = ToFileDescriptor(socket); int socketFlags; @@ -1512,9 +1420,6 @@ int32_t SystemNative_ReceiveMessage(intptr_t socket, MessageHeader* messageHeade *received = 0; return SystemNative_ConvertErrorPlatformToPal(errno); -#else /* TARGET_WASI */ - return Error_EINVAL; -#endif /* TARGET_WASI */ } int32_t SystemNative_Send(intptr_t socket, void* buffer, int32_t bufferLen, int32_t flags, int32_t* sent) @@ -1524,7 +1429,6 @@ int32_t SystemNative_Send(intptr_t socket, void* buffer, int32_t bufferLen, int3 return Error_EFAULT; } -#if !defined(TARGET_WASI) int fd = ToFileDescriptor(socket); int socketFlags; @@ -1551,9 +1455,6 @@ int32_t SystemNative_Send(intptr_t socket, void* buffer, int32_t bufferLen, int3 *sent = 0; return SystemNative_ConvertErrorPlatformToPal(errno); -#else /* TARGET_WASI */ - return Error_EINVAL; -#endif /* TARGET_WASI */ } int32_t SystemNative_SendMessage(intptr_t socket, MessageHeader* messageHeader, int32_t flags, int64_t* sent) @@ -1564,7 +1465,6 @@ int32_t SystemNative_SendMessage(intptr_t socket, MessageHeader* messageHeader, return Error_EFAULT; } -#if !defined(TARGET_WASI) int fd = ToFileDescriptor(socket); int socketFlags; @@ -1594,9 +1494,6 @@ int32_t SystemNative_SendMessage(intptr_t socket, MessageHeader* messageHeader, *sent = 0; return SystemNative_ConvertErrorPlatformToPal(errno); -#else /* TARGET_WASI */ - return Error_EINVAL; -#endif /* TARGET_WASI */ } int32_t SystemNative_Accept(intptr_t socket, uint8_t* socketAddress, int32_t* socketAddressLen, intptr_t* acceptedSocket) @@ -1657,7 +1554,6 @@ int32_t SystemNative_Bind(intptr_t socket, int32_t protocolType, uint8_t* socket return Error_EFAULT; } -#if !defined(TARGET_WASI) int fd = ToFileDescriptor(socket); // On Windows, Bind during TCP_WAIT is allowed. @@ -1674,9 +1570,6 @@ int32_t SystemNative_Bind(intptr_t socket, int32_t protocolType, uint8_t* socket (socklen_t)socketAddressLen); return err == 0 ? Error_SUCCESS : SystemNative_ConvertErrorPlatformToPal(errno); -#else /* TARGET_WASI */ - return Error_EINVAL; -#endif /* TARGET_WASI */ } int32_t SystemNative_Connect(intptr_t socket, uint8_t* socketAddress, int32_t socketAddressLen) @@ -1686,15 +1579,11 @@ int32_t SystemNative_Connect(intptr_t socket, uint8_t* socketAddress, int32_t so return Error_EFAULT; } -#if !defined(TARGET_WASI) int fd = ToFileDescriptor(socket); int err; while ((err = connect(fd, (struct sockaddr*)socketAddress, (socklen_t)socketAddressLen)) < 0 && errno == EINTR); return err == 0 ? Error_SUCCESS : SystemNative_ConvertErrorPlatformToPal(errno); -#else /* TARGET_WASI */ - return Error_EINVAL; -#endif /* TARGET_WASI */ } int32_t SystemNative_GetPeerName(intptr_t socket, uint8_t* socketAddress, int32_t* socketAddressLen) @@ -1704,7 +1593,6 @@ int32_t SystemNative_GetPeerName(intptr_t socket, uint8_t* socketAddress, int32_ return Error_EFAULT; } -#if !defined(TARGET_WASI) int fd = ToFileDescriptor(socket); socklen_t addrLen = (socklen_t)*socketAddressLen; @@ -1716,9 +1604,6 @@ int32_t SystemNative_GetPeerName(intptr_t socket, uint8_t* socketAddress, int32_ *socketAddressLen = (int32_t)addrLen; return Error_SUCCESS; -#else /* TARGET_WASI */ - return Error_EINVAL; -#endif /* TARGET_WASI */ } int32_t SystemNative_GetSockName(intptr_t socket, uint8_t* socketAddress, int32_t* socketAddressLen) @@ -1728,7 +1613,6 @@ int32_t SystemNative_GetSockName(intptr_t socket, uint8_t* socketAddress, int32_ return Error_EFAULT; } -#if !defined(TARGET_WASI) int fd = ToFileDescriptor(socket); socklen_t addrLen = (socklen_t)*socketAddressLen; @@ -1741,20 +1625,13 @@ int32_t SystemNative_GetSockName(intptr_t socket, uint8_t* socketAddress, int32_ assert(addrLen <= (socklen_t)*socketAddressLen); *socketAddressLen = (int32_t)addrLen; return Error_SUCCESS; -#else /* TARGET_WASI */ - return Error_EINVAL; -#endif /* TARGET_WASI */ } int32_t SystemNative_Listen(intptr_t socket, int32_t backlog) { -#if !defined(TARGET_WASI) int fd = ToFileDescriptor(socket); int err = listen(fd, backlog); return err == 0 ? Error_SUCCESS : SystemNative_ConvertErrorPlatformToPal(errno); -#else /* TARGET_WASI */ - return Error_EINVAL; -#endif /* TARGET_WASI */ } int32_t SystemNative_Shutdown(intptr_t socket, int32_t socketShutdown) @@ -1769,7 +1646,6 @@ int32_t SystemNative_GetSocketErrorOption(intptr_t socket, int32_t* error) return Error_EFAULT; } -#if !defined(TARGET_WASI) int fd = ToFileDescriptor(socket); int socketErrno; @@ -1783,9 +1659,6 @@ int32_t SystemNative_GetSocketErrorOption(intptr_t socket, int32_t* error) assert(optLen == sizeof(socketErrno)); *error = SystemNative_ConvertErrorPlatformToPal(socketErrno); return Error_SUCCESS; -#else /* TARGET_WASI */ - return Error_EINVAL; -#endif /* TARGET_WASI */ } static bool TryGetPlatformSocketOption(int32_t socketOptionLevel, int32_t socketOptionName, int* optLevel, int* optName) @@ -1797,107 +1670,75 @@ static bool TryGetPlatformSocketOption(int32_t socketOptionLevel, int32_t socket switch (socketOptionName) { -#ifdef SO_DEBUG case SocketOptionName_SO_DEBUG: *optName = SO_DEBUG; return true; -#endif -#ifdef SO_ACCEPTCONN case SocketOptionName_SO_ACCEPTCONN: *optName = SO_ACCEPTCONN; return true; -#endif -#ifdef SO_REUSEADDR case SocketOptionName_SO_REUSEADDR: *optName = SO_REUSEADDR; return true; -#endif -#ifdef SO_KEEPALIVE case SocketOptionName_SO_KEEPALIVE: *optName = SO_KEEPALIVE; return true; -#endif -#ifdef SO_DONTROUTE case SocketOptionName_SO_DONTROUTE: *optName = SO_DONTROUTE; return true; -#endif -#ifdef SO_BROADCAST case SocketOptionName_SO_BROADCAST: *optName = SO_BROADCAST; return true; -#endif // case SocketOptionName_SO_USELOOPBACK: -#ifdef SO_LINGER case SocketOptionName_SO_LINGER: *optName = SO_LINGER; return true; -#endif -#ifdef SO_OOBINLINE case SocketOptionName_SO_OOBINLINE: *optName = SO_OOBINLINE; return true; -#endif // case SocketOptionName_SO_DONTLINGER: // case SocketOptionName_SO_EXCLUSIVEADDRUSE: -#ifdef SO_SNDBUF case SocketOptionName_SO_SNDBUF: *optName = SO_SNDBUF; return true; -#endif -#ifdef SO_RCVBUF case SocketOptionName_SO_RCVBUF: *optName = SO_RCVBUF; return true; -#endif -#ifdef SO_SNDLOWAT case SocketOptionName_SO_SNDLOWAT: *optName = SO_SNDLOWAT; return true; -#endif -#ifdef SO_RCVLOWAT case SocketOptionName_SO_RCVLOWAT: *optName = SO_RCVLOWAT; return true; -#endif -#ifdef SO_SNDTIMEO case SocketOptionName_SO_SNDTIMEO: *optName = SO_SNDTIMEO; return true; -#endif -#ifdef SO_RCVTIMEO case SocketOptionName_SO_RCVTIMEO: *optName = SO_RCVTIMEO; return true; -#endif -#ifdef SO_ERROR case SocketOptionName_SO_ERROR: *optName = SO_ERROR; return true; -#endif -#ifdef SO_TYPE case SocketOptionName_SO_TYPE: *optName = SO_TYPE; return true; -#endif // case SocketOptionName_SO_MAXCONN: @@ -2089,11 +1930,10 @@ static bool TryConvertSocketTypePlatformToPal(int platformSocketType, int32_t* p case SOCK_DGRAM: *palSocketType = SocketType_SOCK_DGRAM; return true; -#ifdef SOCK_RAW + case SOCK_RAW: *palSocketType = SocketType_SOCK_RAW; return true; -#endif #ifdef SOCK_RDM case SOCK_RDM: @@ -2101,11 +1941,9 @@ static bool TryConvertSocketTypePlatformToPal(int platformSocketType, int32_t* p return true; #endif -#ifdef SOCK_SEQPACKET case SOCK_SEQPACKET: *palSocketType = SocketType_SOCK_SEQPACKET; return true; -#endif default: *palSocketType = (int32_t)platformSocketType; @@ -2261,7 +2099,6 @@ SystemNative_SetSockOpt(intptr_t socket, int32_t socketOptionLevel, int32_t sock return Error_EFAULT; } -#if !defined(TARGET_WASI) int fd = ToFileDescriptor(socket); // @@ -2338,9 +2175,6 @@ SystemNative_SetSockOpt(intptr_t socket, int32_t socketOptionLevel, int32_t sock int err = setsockopt(fd, optLevel, optName, optionValue, (socklen_t)optionLen); return err == 0 ? Error_SUCCESS : SystemNative_ConvertErrorPlatformToPal(errno); -#else /* TARGET_WASI */ - return Error_EINVAL; -#endif /* TARGET_WASI */ } int32_t SystemNative_SetRawSockOpt( @@ -2351,15 +2185,10 @@ int32_t SystemNative_SetRawSockOpt( return Error_EFAULT; } -#if !defined(TARGET_WASI) int err = setsockopt(ToFileDescriptor(socket), socketOptionLevel, socketOptionName, optionValue, (socklen_t)optionLen); return err == 0 ? Error_SUCCESS : SystemNative_ConvertErrorPlatformToPal(errno); -#else /* TARGET_WASI */ - return Error_EINVAL; -#endif /* TARGET_WASI */ } -#if !defined(TARGET_WASI) static bool TryConvertSocketTypePalToPlatform(int32_t palSocketType, int* platformSocketType) { assert(platformSocketType != NULL); @@ -2374,11 +2203,9 @@ static bool TryConvertSocketTypePalToPlatform(int32_t palSocketType, int* platfo *platformSocketType = SOCK_DGRAM; return true; -#ifdef SOCK_RAW case SocketType_SOCK_RAW: *platformSocketType = SOCK_RAW; return true; -#endif #ifdef SOCK_RDM case SocketType_SOCK_RDM: @@ -2386,11 +2213,9 @@ static bool TryConvertSocketTypePalToPlatform(int32_t palSocketType, int* platfo return true; #endif -#ifdef SOCK_SEQPACKET case SocketType_SOCK_SEQPACKET: *platformSocketType = SOCK_SEQPACKET; return true; -#endif default: *platformSocketType = (int)palSocketType; @@ -2445,11 +2270,10 @@ static bool TryConvertProtocolTypePalToPlatform(int32_t palAddressFamily, int32_ case ProtocolType_PT_UDP: *platformProtocolType = IPPROTO_UDP; return true; -#ifdef IPPROTO_IGMP + case ProtocolType_PT_IGMP: *platformProtocolType = IPPROTO_IGMP; return true; -#endif case ProtocolType_PT_RAW: *platformProtocolType = IPPROTO_RAW; @@ -2467,12 +2291,10 @@ static bool TryConvertProtocolTypePalToPlatform(int32_t palAddressFamily, int32_ *platformProtocolType = 0; return true; -#ifdef IPPROTO_ICMPV6 case ProtocolType_PT_ICMPV6: case ProtocolType_PT_ICMP: *platformProtocolType = IPPROTO_ICMPV6; return true; -#endif case ProtocolType_PT_TCP: *platformProtocolType = IPPROTO_TCP; @@ -2482,39 +2304,29 @@ static bool TryConvertProtocolTypePalToPlatform(int32_t palAddressFamily, int32_ *platformProtocolType = IPPROTO_UDP; return true; -#ifdef IPPROTO_IGMP case ProtocolType_PT_IGMP: *platformProtocolType = IPPROTO_IGMP; return true; -#endif case ProtocolType_PT_RAW: *platformProtocolType = IPPROTO_RAW; return true; -#ifdef IPPROTO_DSTOPTS case ProtocolType_PT_DSTOPTS: *platformProtocolType = IPPROTO_DSTOPTS; return true; -#endif -#ifdef IPPROTO_NONE case ProtocolType_PT_NONE: *platformProtocolType = IPPROTO_NONE; return true; -#endif -#ifdef IPPROTO_ROUTING case ProtocolType_PT_ROUTING: *platformProtocolType = IPPROTO_ROUTING; return true; -#endif -#ifdef IPPROTO_FRAGMENT case ProtocolType_PT_FRAGMENT: *platformProtocolType = IPPROTO_FRAGMENT; return true; -#endif default: *platformProtocolType = (int)palProtocolType; @@ -2582,11 +2394,9 @@ static bool TryConvertProtocolTypePlatformToPal(int32_t palAddressFamily, int pl *palProtocolType = ProtocolType_PT_UDP; return true; -#ifdef IPPROTO_IGMP case IPPROTO_IGMP: *palProtocolType = ProtocolType_PT_IGMP; return true; -#endif case IPPROTO_RAW: *palProtocolType = ProtocolType_PT_RAW; @@ -2604,11 +2414,9 @@ static bool TryConvertProtocolTypePlatformToPal(int32_t palAddressFamily, int pl *palProtocolType = ProtocolType_PT_UNSPECIFIED; return true; -#ifdef IPPROTO_ICMPV6 case IPPROTO_ICMPV6: *palProtocolType = ProtocolType_PT_ICMPV6; return true; -#endif case IPPROTO_TCP: *palProtocolType = ProtocolType_PT_TCP; @@ -2618,39 +2426,29 @@ static bool TryConvertProtocolTypePlatformToPal(int32_t palAddressFamily, int pl *palProtocolType = ProtocolType_PT_UDP; return true; -#ifdef IPPROTO_IGMP case IPPROTO_IGMP: *palProtocolType = ProtocolType_PT_IGMP; return true; -#endif case IPPROTO_RAW: *palProtocolType = ProtocolType_PT_RAW; return true; -#ifdef IPPROTO_DSTOPTS case IPPROTO_DSTOPTS: *palProtocolType = ProtocolType_PT_DSTOPTS; return true; -#endif -#ifdef IPPROTO_NONE case IPPROTO_NONE: *palProtocolType = ProtocolType_PT_NONE; return true; -#endif -#ifdef IPPROTO_ROUTING case IPPROTO_ROUTING: *palProtocolType = ProtocolType_PT_ROUTING; return true; -#endif -#ifdef IPPROTO_FRAGMENT case IPPROTO_FRAGMENT: *palProtocolType = ProtocolType_PT_FRAGMENT; return true; -#endif default: *palProtocolType = (int)platformProtocolType; @@ -2669,7 +2467,6 @@ static bool TryConvertProtocolTypePlatformToPal(int32_t palAddressFamily, int pl } } } -#endif /* TARGET_WASI */ int32_t SystemNative_Socket(int32_t addressFamily, int32_t socketType, int32_t protocolType, intptr_t* createdSocket) { @@ -2678,7 +2475,6 @@ int32_t SystemNative_Socket(int32_t addressFamily, int32_t socketType, int32_t p return Error_EFAULT; } -#if !defined(TARGET_WASI) sa_family_t platformAddressFamily; int platformSocketType, platformProtocolType; @@ -2713,9 +2509,6 @@ int32_t SystemNative_Socket(int32_t addressFamily, int32_t socketType, int32_t p fcntl(ToFileDescriptor(*createdSocket), F_SETFD, FD_CLOEXEC); // ignore any failures; this is best effort #endif return Error_SUCCESS; -#else /* TARGET_WASI */ - return Error_EINVAL; -#endif /* TARGET_WASI */ } int32_t SystemNative_GetSocketType(intptr_t socket, int32_t* addressFamily, int32_t* socketType, int32_t* protocolType, int32_t* isListening) @@ -2783,7 +2576,6 @@ int32_t SystemNative_GetSocketType(intptr_t socket, int32_t* addressFamily, int3 int listeningValue; socklen_t listeningLength = sizeof(int); -#ifdef SO_ACCEPTCONN if (getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &listeningValue, &listeningLength) == 0) { *isListening = (listeningValue != 0); @@ -2792,9 +2584,6 @@ int32_t SystemNative_GetSocketType(intptr_t socket, int32_t* addressFamily, int3 { *isListening = 0; } -#else - *isListening = 0; -#endif #endif return Error_SUCCESS; } @@ -2806,7 +2595,6 @@ int32_t SystemNative_GetAtOutOfBandMark(intptr_t socket, int32_t* atMark) return Error_EFAULT; } -#if !defined(TARGET_WASI) int fd = ToFileDescriptor(socket); int result; @@ -2820,9 +2608,6 @@ int32_t SystemNative_GetAtOutOfBandMark(intptr_t socket, int32_t* atMark) *atMark = (int32_t)result; return Error_SUCCESS; -#else /* TARGET_WASI */ - return Error_EINVAL; -#endif /* TARGET_WASI */ } int32_t SystemNative_GetBytesAvailable(intptr_t socket, int32_t* available) @@ -3142,13 +2927,10 @@ static int32_t WaitForSocketEventsInner(int32_t port, SocketEvent* buffer, int32 #else static const size_t SocketEventBufferElementSize = 0; -#if !defined(TARGET_WASI) static SocketEvents GetSocketEvents(int16_t filter, uint16_t flags) { return SocketEvents_SA_NONE; } -#endif /* TARGET_WASI */ - static int32_t CloseSocketEventPortInner(int32_t port) { return Error_ENOSYS; @@ -3254,7 +3036,6 @@ int32_t SystemNative_PlatformSupportsDualModeIPv4PacketInfo(void) #endif } -#if !defined(TARGET_WASI) static char* GetNameFromUid(uid_t uid) { size_t bufferLength = 512; @@ -3291,23 +3072,17 @@ static char* GetNameFromUid(uid_t uid) bufferLength = tmpBufferLength; } } -#endif /* TARGET_WASI */ char* SystemNative_GetPeerUserName(intptr_t socket) { -#if !defined(TARGET_WASI) uid_t euid; return SystemNative_GetPeerID(socket, &euid) == 0 ? GetNameFromUid(euid) : NULL; -#else /* TARGET_WASI */ - return NULL; -#endif /* TARGET_WASI */ } void SystemNative_GetDomainSocketSizes(int32_t* pathOffset, int32_t* pathSize, int32_t* addressSize) { -#if !defined(TARGET_WASI) assert(pathOffset != NULL); assert(pathSize != NULL); assert(addressSize != NULL); @@ -3317,11 +3092,6 @@ void SystemNative_GetDomainSocketSizes(int32_t* pathOffset, int32_t* pathSize, i *pathOffset = offsetof(struct sockaddr_un, sun_path); *pathSize = sizeof(domainSocket.sun_path); *addressSize = sizeof(domainSocket); -#else /* TARGET_WASI */ - *pathOffset = -1; - *pathSize = -1; - *addressSize = -1; -#endif /* TARGET_WASI */ } int32_t SystemNative_GetMaximumAddressSize(void) @@ -3496,12 +3266,7 @@ int32_t SystemNative_SendFile(intptr_t out_fd, intptr_t in_fd, int64_t offset, i uint32_t SystemNative_InterfaceNameToIndex(char* interfaceName) { assert(interfaceName != NULL); -#if !defined(TARGET_WASI) if (interfaceName[0] == '%') interfaceName++; return if_nametoindex(interfaceName); -#else /* TARGET_WASI */ - return Error_EINVAL; -#endif /* TARGET_WASI */ } - diff --git a/src/native/libs/System.Native/pal_networking_wasi.c b/src/native/libs/System.Native/pal_networking_wasi.c new file mode 100644 index 00000000000000..3cad50780daecb --- /dev/null +++ b/src/native/libs/System.Native/pal_networking_wasi.c @@ -0,0 +1,449 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "pal_config.h" +#include "pal_networking.h" +#include "pal_safecrt.h" +#include "pal_utilities.h" +#include +#include + +#include +#include +int32_t SystemNative_GetHostEntryForName(const uint8_t* address, int32_t addressFamily, HostEntry* entry) +{ + return -1; +} + +void SystemNative_FreeHostEntry(HostEntry* entry) +{ + if (entry != NULL) + { + free(entry->CanonicalName); + free(entry->IPAddressList); + + entry->CanonicalName = NULL; + entry->IPAddressList = NULL; + entry->IPAddressCount = 0; + } +} + +int32_t SystemNative_GetNameInfo(const uint8_t* address, + int32_t addressLength, + int8_t isIPv6, + uint8_t* host, + int32_t hostLength, + uint8_t* service, + int32_t serviceLength, + int32_t flags) +{ + assert(address != NULL); + assert(addressLength > 0); + assert((host != NULL) || (service != NULL)); + assert((hostLength > 0) || (serviceLength > 0)); + + return Error_EINVAL; +} + +int32_t SystemNative_GetDomainName(uint8_t* name, int32_t nameLength) +{ + assert(name != NULL); + assert(nameLength > 0); + return Error_EFAULT; +} + +int32_t SystemNative_GetHostName(uint8_t* name, int32_t nameLength) +{ + assert(name != NULL); + assert(nameLength > 0); + + size_t unsignedSize = (uint32_t)nameLength; + return gethostname((char*)name, unsignedSize); +} + +int32_t SystemNative_GetIPSocketAddressSizes(int32_t* ipv4SocketAddressSize, int32_t* ipv6SocketAddressSize) +{ + return Error_EFAULT; +} + +int32_t SystemNative_GetAddressFamily(const uint8_t* socketAddress, int32_t socketAddressLen, int32_t* addressFamily) +{ + return Error_EFAULT; +} + +int32_t SystemNative_SetAddressFamily(uint8_t* socketAddress, int32_t socketAddressLen, int32_t addressFamily) +{ + return Error_EFAULT; +} + +int32_t SystemNative_GetPort(const uint8_t* socketAddress, int32_t socketAddressLen, uint16_t* port) +{ + return Error_EFAULT; +} + +int32_t SystemNative_SetPort(uint8_t* socketAddress, int32_t socketAddressLen, uint16_t port) +{ + return Error_EFAULT; +} + +int32_t SystemNative_GetIPv4Address(const uint8_t* socketAddress, int32_t socketAddressLen, uint32_t* address) +{ + return Error_EFAULT; +} + +int32_t SystemNative_SetIPv4Address(uint8_t* socketAddress, int32_t socketAddressLen, uint32_t address) +{ + return Error_EFAULT; +} + +int32_t SystemNative_GetIPv6Address( + const uint8_t* socketAddress, int32_t socketAddressLen, uint8_t* address, int32_t addressLen, uint32_t* scopeId) +{ + return Error_EFAULT; +} + +int32_t +SystemNative_SetIPv6Address(uint8_t* socketAddress, int32_t socketAddressLen, uint8_t* address, int32_t addressLen, uint32_t scopeId) +{ + return Error_EFAULT; +} + +int32_t SystemNative_GetControlMessageBufferSize(int32_t isIPv4, int32_t isIPv6) +{ + return Error_EFAULT; +} + + +int32_t +SystemNative_TryGetIPPacketInformation(MessageHeader* messageHeader, int32_t isIPv4, IPPacketInformation* packetInfo) +{ + if (messageHeader == NULL || packetInfo == NULL) + { + return 0; + } + + return Error_EINVAL; +} + +int32_t SystemNative_GetIPv4MulticastOption(intptr_t socket, int32_t multicastOption, IPv4MulticastOption* option) +{ + return Error_EINVAL; +} + +int32_t SystemNative_SetIPv4MulticastOption(intptr_t socket, int32_t multicastOption, IPv4MulticastOption* option) +{ + if (option == NULL) + { + return Error_EFAULT; + } + + return Error_EINVAL; +} + +int32_t SystemNative_GetIPv6MulticastOption(intptr_t socket, int32_t multicastOption, IPv6MulticastOption* option) +{ + if (option == NULL) + { + return Error_EFAULT; + } + + return Error_EINVAL; +} + +int32_t SystemNative_SetIPv6MulticastOption(intptr_t socket, int32_t multicastOption, IPv6MulticastOption* option) +{ + if (option == NULL) + { + return Error_EFAULT; + } + return Error_EINVAL; +} + + +int32_t SystemNative_GetLingerOption(intptr_t socket, LingerOption* option) +{ + if (option == NULL) + { + return Error_EFAULT; + } + + return Error_EINVAL; +} + +int32_t SystemNative_SetLingerOption(intptr_t socket, LingerOption* option) +{ + if (option == NULL) + { + return Error_EFAULT; + } + + return Error_EINVAL; +} + +int32_t SystemNative_SetReceiveTimeout(intptr_t socket, int32_t millisecondsTimeout) +{ + return Error_EINVAL; +} + +int32_t SystemNative_SetSendTimeout(intptr_t socket, int32_t millisecondsTimeout) +{ + return Error_EINVAL; +} +int32_t SystemNative_Receive(intptr_t socket, void* buffer, int32_t bufferLen, int32_t flags, int32_t* received) +{ + if (buffer == NULL || bufferLen < 0 || received == NULL) + { + return Error_EFAULT; + } + + return Error_EINVAL; +} + +int32_t SystemNative_ReceiveMessage(intptr_t socket, MessageHeader* messageHeader, int32_t flags, int64_t* received) +{ + if (messageHeader == NULL || received == NULL || messageHeader->SocketAddressLen < 0 || + messageHeader->ControlBufferLen < 0 || messageHeader->IOVectorCount < 0) + { + return Error_EFAULT; + } + + return Error_EINVAL; +} + +int32_t SystemNative_Send(intptr_t socket, void* buffer, int32_t bufferLen, int32_t flags, int32_t* sent) +{ + return Error_EINVAL; +} + +int32_t SystemNative_SendMessage(intptr_t socket, MessageHeader* messageHeader, int32_t flags, int64_t* sent) +{ + return Error_EINVAL; +} + +int32_t SystemNative_Accept(intptr_t socket, uint8_t* socketAddress, int32_t* socketAddressLen, intptr_t* acceptedSocket) +{ + if (socketAddress == NULL || socketAddressLen == NULL || acceptedSocket == NULL || *socketAddressLen < 0) + { + return Error_EFAULT; + } + + return Error_EINVAL; +} + +int32_t SystemNative_Bind(intptr_t socket, int32_t protocolType, uint8_t* socketAddress, int32_t socketAddressLen) +{ + if (socketAddress == NULL || socketAddressLen < 0) + { + return Error_EFAULT; + } + + return Error_EINVAL; +} + +int32_t SystemNative_Connect(intptr_t socket, uint8_t* socketAddress, int32_t socketAddressLen) +{ + return Error_EINVAL; +} + +int32_t SystemNative_GetPeerName(intptr_t socket, uint8_t* socketAddress, int32_t* socketAddressLen) +{ + if (socketAddress == NULL || socketAddressLen == NULL || *socketAddressLen < 0) + { + return Error_EFAULT; + } + + return Error_EINVAL; +} + +int32_t SystemNative_GetSockName(intptr_t socket, uint8_t* socketAddress, int32_t* socketAddressLen) +{ + if (socketAddress == NULL || socketAddressLen == NULL || *socketAddressLen < 0) + { + return Error_EFAULT; + } + + return Error_EINVAL; +} + +int32_t SystemNative_Listen(intptr_t socket, int32_t backlog) +{ + return Error_EINVAL; +} + +int32_t SystemNative_Shutdown(intptr_t socket, int32_t socketShutdown) +{ + return Error_EINVAL; +} + +int32_t SystemNative_GetSocketErrorOption(intptr_t socket, int32_t* error) +{ + if (error == NULL) + { + return Error_EFAULT; + } + + return Error_EINVAL; +} + +int32_t SystemNative_GetSockOpt( + intptr_t socket, int32_t socketOptionLevel, int32_t socketOptionName, uint8_t* optionValue, int32_t* optionLen) +{ + if (optionLen == NULL || *optionLen < 0) + { + return Error_EFAULT; + } + + return Error_EINVAL; +} + +int32_t SystemNative_GetRawSockOpt( + intptr_t socket, int32_t socketOptionLevel, int32_t socketOptionName, uint8_t* optionValue, int32_t* optionLen) +{ + if (optionLen == NULL || *optionLen < 0) + { + return Error_EFAULT; + } + + return Error_EINVAL; +} + +int32_t +SystemNative_SetSockOpt(intptr_t socket, int32_t socketOptionLevel, int32_t socketOptionName, uint8_t* optionValue, int32_t optionLen) +{ + return Error_EINVAL; +} + +int32_t SystemNative_SetRawSockOpt( + intptr_t socket, int32_t socketOptionLevel, int32_t socketOptionName, uint8_t* optionValue, int32_t optionLen) +{ + if (optionLen < 0 || optionValue == NULL) + { + return Error_EFAULT; + } + + return Error_EINVAL; +} + +int32_t SystemNative_Socket(int32_t addressFamily, int32_t socketType, int32_t protocolType, intptr_t* createdSocket) +{ + if (createdSocket == NULL) + { + return Error_EFAULT; + } + + return Error_EINVAL; +} + +int32_t SystemNative_GetSocketType(intptr_t socket, int32_t* addressFamily, int32_t* socketType, int32_t* protocolType, int32_t* isListening) +{ + if (addressFamily == NULL || socketType == NULL || protocolType == NULL || isListening == NULL) + { + return Error_EFAULT; + } + + return Error_EINVAL; +} + +int32_t SystemNative_GetAtOutOfBandMark(intptr_t socket, int32_t* atMark) +{ + if (atMark == NULL) + { + return Error_EFAULT; + } + + return Error_EINVAL; +} + +int32_t SystemNative_GetBytesAvailable(intptr_t socket, int32_t* available) +{ + if (available == NULL) + { + return Error_EFAULT; + } + + return Error_EINVAL; +} + +int32_t SystemNative_CreateSocketEventPort(intptr_t* port) +{ + if (port == NULL) + { + return Error_EFAULT; + } + + return Error_EINVAL; +} + +int32_t SystemNative_CloseSocketEventPort(intptr_t port) +{ + return Error_EINVAL; +} + +int32_t SystemNative_CreateSocketEventBuffer(int32_t count, SocketEvent** buffer) +{ + if (buffer == NULL || count < 0) + { + return Error_EFAULT; + } + + return Error_EINVAL; +} + +int32_t SystemNative_FreeSocketEventBuffer(SocketEvent* buffer) +{ + free(buffer); + return Error_SUCCESS; +} + +int32_t +SystemNative_TryChangeSocketEventRegistration(intptr_t port, intptr_t socket, int32_t currentEvents, int32_t newEvents, uintptr_t data) +{ + return Error_EINVAL; +} + +int32_t SystemNative_WaitForSocketEvents(intptr_t port, SocketEvent* buffer, int32_t* count) +{ + return Error_EINVAL; +} + +int32_t SystemNative_PlatformSupportsDualModeIPv4PacketInfo(void) +{ + return 0; +} + + +char* SystemNative_GetPeerUserName(intptr_t socket) +{ + return NULL; +} + +void SystemNative_GetDomainSocketSizes(int32_t* pathOffset, int32_t* pathSize, int32_t* addressSize) +{ + *pathOffset = -1; + *pathSize = -1; + *addressSize = -1; +} + +int32_t SystemNative_GetMaximumAddressSize(void) +{ + return sizeof(struct sockaddr_storage); +} + +int32_t SystemNative_Disconnect(intptr_t socket) +{ + return Error_EINVAL; +} + +int32_t SystemNative_SendFile(intptr_t out_fd, intptr_t in_fd, int64_t offset, int64_t count, int64_t* sent) +{ + assert(sent != NULL); + + return Error_EINVAL; +} + +uint32_t SystemNative_InterfaceNameToIndex(char* interfaceName) +{ + assert(interfaceName != NULL); + return Error_EINVAL; +} + diff --git a/src/native/libs/System.Native/pal_process.c b/src/native/libs/System.Native/pal_process.c index cc0291519737a8..509049b2fdcd7a 100644 --- a/src/native/libs/System.Native/pal_process.c +++ b/src/native/libs/System.Native/pal_process.c @@ -8,20 +8,14 @@ #include #include -#if HAVE_GRP_H #include -#endif #include #include #include #include #include -#if HAVE_SYS_WAIT_H #include -#endif -#if HAVE_SYSLOG_H #include -#endif #include #if HAVE_CRT_EXTERNS_H #include @@ -29,9 +23,7 @@ #if HAVE_PIPE2 #include #endif -#if HAVE_PTHREAD_H #include -#endif #if HAVE_SCHED_SETAFFINITY || HAVE_SCHED_GETAFFINITY #include @@ -49,7 +41,6 @@ #include -#if !defined(TARGET_WASI) // Validate that our SysLogPriority values are correct for the platform c_static_assert(PAL_LOG_EMERG == LOG_EMERG); c_static_assert(PAL_LOG_ALERT == LOG_ALERT); @@ -217,7 +208,6 @@ handler_from_sigaction (struct sigaction *sa) return sa->sa_handler; } } -#endif /* TARGET_WASI */ int32_t SystemNative_ForkAndExecProcess(const char* filename, char* const argv[], @@ -521,7 +511,6 @@ done:; #endif } -#if !defined(TARGET_WASI) // Each platform type has it's own RLIMIT values but the same name, so we need // to convert our standard types into the platform specific ones. static int32_t ConvertRLimitResourcesPalToPlatform(RLimitResources value) @@ -530,14 +519,10 @@ static int32_t ConvertRLimitResourcesPalToPlatform(RLimitResources value) { case PAL_RLIMIT_CPU: return RLIMIT_CPU; -#ifdef RLIMIT_FSIZE case PAL_RLIMIT_FSIZE: return RLIMIT_FSIZE; -#endif -#ifdef RLIMIT_DATA case PAL_RLIMIT_DATA: return RLIMIT_DATA; -#endif case PAL_RLIMIT_STACK: return RLIMIT_STACK; case PAL_RLIMIT_CORE: @@ -620,12 +605,11 @@ typedef __priority_which_t priorityWhich; typedef int rlimitResource; typedef int priorityWhich; #endif -#endif /* TARGET_WASI */ int32_t SystemNative_GetRLimit(RLimitResources resourceType, RLimit* limits) { assert(limits != NULL); -#if HAVE_GETRLIMIT + int32_t platformLimit = ConvertRLimitResourcesPalToPlatform(resourceType); struct rlimit internalLimit; int result = getrlimit((rlimitResource)platformLimit, &internalLimit); @@ -637,10 +621,6 @@ int32_t SystemNative_GetRLimit(RLimitResources resourceType, RLimit* limits) { memset(limits, 0, sizeof(RLimit)); } -#else /* HAVE_SYS_RESOURCE_H */ - int result = -1; - memset(limits, 0, sizeof(RLimit)); -#endif return result; } @@ -649,21 +629,14 @@ int32_t SystemNative_SetRLimit(RLimitResources resourceType, const RLimit* limit { assert(limits != NULL); -#if HAVE_SETRLIMIT int32_t platformLimit = ConvertRLimitResourcesPalToPlatform(resourceType); struct rlimit internalLimit; ConvertFromRLimitManagedToPal(limits, &internalLimit); return setrlimit((rlimitResource)platformLimit, &internalLimit); -#else /* HAVE_SYS_RESOURCE_H */ - (void)resourceType; // unused - (void)limits; // unused - return -1; -#endif } int32_t SystemNative_Kill(int32_t pid, int32_t signal) { -#if HAVE_SIGNAL_KILL switch (signal) { case PAL_NONE: @@ -685,39 +658,25 @@ int32_t SystemNative_Kill(int32_t pid, int32_t signal) } return kill(pid, signal); -#else /* HAVE_SIGNAL_KILL */ - return -1; -#endif /* HAVE_SIGNAL_KILL */ } int32_t SystemNative_GetPid(void) { -#if !defined(TARGET_WASI) return getpid(); -#else /* TARGET_WASI */ - return -1; -#endif /* TARGET_WASI */ } int32_t SystemNative_GetSid(int32_t pid) { -#if !defined(TARGET_WASI) return getsid(pid); -#else /* TARGET_WASI */ - return -1; -#endif /* TARGET_WASI */ } void SystemNative_SysLog(SysLogPriority priority, const char* message, const char* arg1) { -#if !defined(TARGET_WASI) syslog((int)(LOG_USER | priority), message, arg1); -#endif /* TARGET_WASI */ } int32_t SystemNative_WaitIdAnyExitedNoHangNoWait(void) { -#if !defined(TARGET_WASI) siginfo_t siginfo; memset(&siginfo, 0, sizeof(siginfo)); int32_t result; @@ -737,14 +696,10 @@ int32_t SystemNative_WaitIdAnyExitedNoHangNoWait(void) result = 0; } return result; -#else /* TARGET_WASI */ - return -1; -#endif /* TARGET_WASI */ } int32_t SystemNative_WaitPidExitedNoHang(int32_t pid, int32_t* exitCode) { -#if !defined(TARGET_WASI) assert(exitCode != NULL); int32_t result; @@ -768,9 +723,6 @@ int32_t SystemNative_WaitPidExitedNoHang(int32_t pid, int32_t* exitCode) } } return result; -#else /* TARGET_WASI */ - return -1; -#endif /* TARGET_WASI */ } int64_t SystemNative_PathConf(const char* path, PathConfName name) @@ -819,7 +771,6 @@ int64_t SystemNative_PathConf(const char* path, PathConfName name) int32_t SystemNative_GetPriority(PriorityWhich which, int32_t who) { -#if !defined(TARGET_WASI) // GetPriority uses errno 0 to show success to make sure we don't have a stale value errno = 0; #if PRIORITY_REQUIRES_INT_WHO @@ -827,22 +778,15 @@ int32_t SystemNative_GetPriority(PriorityWhich which, int32_t who) #else return getpriority((priorityWhich)which, (id_t)who); #endif -#else /* TARGET_WASI */ - return -1; -#endif /* TARGET_WASI */ } int32_t SystemNative_SetPriority(PriorityWhich which, int32_t who, int32_t nice) { -#if !defined(TARGET_WASI) #if PRIORITY_REQUIRES_INT_WHO return setpriority((priorityWhich)which, who, nice); #else return setpriority((priorityWhich)which, (id_t)who, nice); #endif -#else /* TARGET_WASI */ - return -1; -#endif /* TARGET_WASI */ } char* SystemNative_GetCwd(char* buffer, int32_t bufferSize) diff --git a/src/native/libs/System.Native/pal_process_wasi.c b/src/native/libs/System.Native/pal_process_wasi.c new file mode 100644 index 00000000000000..2c650f6bb11bd9 --- /dev/null +++ b/src/native/libs/System.Native/pal_process_wasi.c @@ -0,0 +1,163 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "pal_config.h" +#include "pal_process.h" +#include "pal_io.h" +#include "pal_utilities.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +int32_t SystemNative_ForkAndExecProcess(const char* filename, + char* const argv[], + char* const envp[], + const char* cwd, + int32_t redirectStdin, + int32_t redirectStdout, + int32_t redirectStderr, + int32_t setCredentials, + uint32_t userId, + uint32_t groupId, + uint32_t* groups, + int32_t groupsLength, + int32_t* childPid, + int32_t* stdinFd, + int32_t* stdoutFd, + int32_t* stderrFd) +{ + (void)filename; // unused + (void)argv; // unused + (void)envp; // unused + (void)cwd; // unused + (void)redirectStdin; // unused + (void)redirectStdout; // unused + (void)redirectStderr; // unused + (void)setCredentials; // unused + (void)userId; // unused + (void)groupId; // unused + (void)groups; // unused + (void)groupsLength; // unused + (void)childPid; // unused + (void)stdinFd; // unused + (void)stdoutFd; // unused + (void)stderrFd; // unused + return -1; +} + +int32_t SystemNative_GetRLimit(RLimitResources resourceType, RLimit* limits) +{ + assert(limits != NULL); + int result = -1; + memset(limits, 0, sizeof(RLimit)); + (void)resourceType; // unused + return result; +} + +int32_t SystemNative_SetRLimit(RLimitResources resourceType, const RLimit* limits) +{ + assert(limits != NULL); + (void)resourceType; // unused + (void)limits; // unused + return -1; +} + +int32_t SystemNative_Kill(int32_t pid, int32_t signal) +{ + return -1; +} + +int32_t SystemNative_GetPid(void) +{ + return -1; +} + +int32_t SystemNative_GetSid(int32_t pid) +{ + return -1; +} + +__attribute__((noreturn)) +void SystemNative_SysLog(SysLogPriority priority, const char* message, const char* arg1) +{ + assert_msg(false, "Not supported on WASI", 0); + (void)priority; // unused + (void)message; // unused + (void)arg1; // unused +} + +int32_t SystemNative_WaitIdAnyExitedNoHangNoWait(void) +{ + return -1; +} + +int32_t SystemNative_WaitPidExitedNoHang(int32_t pid, int32_t* exitCode) +{ + (void)pid; // unused + (void)exitCode; // unused + return -1; +} + +int64_t SystemNative_PathConf(const char* path, PathConfName name) +{ + (void)path; // unused + (void)name; // unused + return -1; +} + +int32_t SystemNative_GetPriority(PriorityWhich which, int32_t who) +{ + (void)which; // unused + (void)who; // unused + return -1; +} + +int32_t SystemNative_SetPriority(PriorityWhich which, int32_t who, int32_t nice) +{ + (void)which; // unused + (void)who; // unused + (void)nice; // unused + return -1; +} + +char* SystemNative_GetCwd(char* buffer, int32_t bufferSize) +{ + assert(bufferSize >= 0); + + if (bufferSize < 0) + { + errno = EINVAL; + return NULL; + } + + return getcwd(buffer, Int32ToSizeT(bufferSize)); +} + +int32_t SystemNative_SchedSetAffinity(int32_t pid, intptr_t* mask) +{ + (void)pid; + (void)mask; + errno = ENOTSUP; + return -1; +} + +int32_t SystemNative_SchedGetAffinity(int32_t pid, intptr_t* mask) +{ + (void)pid; + (void)mask; + errno = ENOTSUP; + return -1; +} + +char* SystemNative_GetProcessPath(void) +{ + return minipal_getexepath(); +} diff --git a/src/native/libs/System.Native/pal_signal.c b/src/native/libs/System.Native/pal_signal.c index f09b45ff33f0b4..257969dc67a945 100644 --- a/src/native/libs/System.Native/pal_signal.c +++ b/src/native/libs/System.Native/pal_signal.c @@ -9,19 +9,13 @@ #include #include -#if HAVE_PTHREAD_H #include -#endif #include #include #include -#if HAVE_SYS_WAIT_H #include -#endif #include -#if !defined(TARGET_WASI) - static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; // Saved signal handlers @@ -186,6 +180,14 @@ int32_t SystemNative_GetPlatformSignalNumber(PosixSignal signal) return 0; } +void SystemNative_SetPosixSignalHandler(PosixSignalHandler signalHandler) +{ + assert(signalHandler); + assert(g_posixSignalHandler == NULL || g_posixSignalHandler == signalHandler); + + g_posixSignalHandler = signalHandler; +} + static struct sigaction* OrigActionFor(int sig) { return &g_origSigHandler[sig - 1]; @@ -242,21 +244,8 @@ static void SignalHandler(int sig, siginfo_t* siginfo, void* context) } } -#endif /* TARGET_WASI */ - -void SystemNative_SetPosixSignalHandler(PosixSignalHandler signalHandler) -{ - assert(signalHandler); -#if !defined(TARGET_WASI) - assert(g_posixSignalHandler == NULL || g_posixSignalHandler == signalHandler); - - g_posixSignalHandler = signalHandler; -#endif /* TARGET_WASI */ -} - void SystemNative_HandleNonCanceledPosixSignal(int32_t signalCode) { -#if !defined(TARGET_WASI) switch (signalCode) { case SIGCONT: @@ -310,10 +299,8 @@ void SystemNative_HandleNonCanceledPosixSignal(int32_t signalCode) kill(g_pid, signalCode); break; } -#endif /* TARGET_WASI */ } -#if !defined(TARGET_WASI) // Entrypoint for the thread that handles signals where our handling // isn't signal-safe. Those signal handlers write the signal to a pipe, // which this loop reads and processes. @@ -484,12 +471,10 @@ static bool InstallSignalHandler(int sig, int flags) *isInstalled = true; return true; } -#endif /* TARGET_WASI */ void SystemNative_SetTerminalInvalidationHandler(TerminalInvalidationCallback callback) { assert(callback != NULL); -#if !defined(TARGET_WASI) assert(g_terminalInvalidationCallback == NULL); bool installed = false; (void)installed; // only used for assert @@ -506,13 +491,11 @@ void SystemNative_SetTerminalInvalidationHandler(TerminalInvalidationCallback ca assert(installed); } pthread_mutex_unlock(&lock); -#endif /* TARGET_WASI */ } void SystemNative_RegisterForSigChld(SigChldCallback callback) { assert(callback != NULL); -#if !defined(TARGET_WASI) assert(g_sigChldCallback == NULL); bool installed = false; (void)installed; // only used for assert @@ -525,19 +508,15 @@ void SystemNative_RegisterForSigChld(SigChldCallback callback) assert(installed); } pthread_mutex_unlock(&lock); -#endif /* TARGET_WASI */ } void SystemNative_SetDelayedSigChildConsoleConfigurationHandler(void (*callback)(void)) { -#if !defined(TARGET_WASI) assert(g_sigChldConsoleConfigurationCallback == NULL); g_sigChldConsoleConfigurationCallback = callback; -#endif /* TARGET_WASI */ } -#if !defined(TARGET_WASI) static bool CreateSignalHandlerThread(int* readFdPtr) { pthread_attr_t attr; @@ -635,11 +614,9 @@ int32_t InitializeSignalHandlingCore(void) return 1; } -#endif /* TARGET_WASI */ int32_t SystemNative_EnablePosixSignalHandling(int signalCode) { -#if !defined(TARGET_WASI) assert(g_posixSignalHandler != NULL); assert(signalCode > 0 && signalCode <= GetSignalMax()); @@ -653,14 +630,10 @@ int32_t SystemNative_EnablePosixSignalHandling(int signalCode) pthread_mutex_unlock(&lock); return installed ? 1 : 0; -#else /* TARGET_WASI */ - return false; -#endif /* TARGET_WASI */ } void SystemNative_DisablePosixSignalHandling(int signalCode) { -#if !defined(TARGET_WASI) assert(signalCode > 0 && signalCode <= GetSignalMax()); pthread_mutex_lock(&lock); @@ -682,10 +655,8 @@ void SystemNative_DisablePosixSignalHandling(int signalCode) } } pthread_mutex_unlock(&lock); -#endif /* TARGET_WASI */ } -#if !defined(TARGET_WASI) void InstallTTOUHandlerForConsole(ConsoleSigTtouHandler handler) { bool installed; @@ -746,5 +717,4 @@ int32_t SystemNative_InitializeTerminalAndSignalHandling(void) return initialized; } -#endif /* !HAS_CONSOLE_SIGNALS */ -#endif /* !TARGET_WASI */ +#endif diff --git a/src/native/libs/System.Native/pal_signal_wasi.c b/src/native/libs/System.Native/pal_signal_wasi.c new file mode 100644 index 00000000000000..22016cd9689abf --- /dev/null +++ b/src/native/libs/System.Native/pal_signal_wasi.c @@ -0,0 +1,66 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "pal_config.h" +#include "pal_console.h" +#include "pal_signal.h" +#include "pal_io.h" +#include "pal_utilities.h" + +#include +#include +#include +#include +#include +#include + +__attribute__((noreturn)) +void SystemNative_SetPosixSignalHandler(PosixSignalHandler signalHandler) +{ + assert(signalHandler); + (void)signalHandler; + assert_msg(false, "Not supported on WASI", 0); +} + +__attribute__((noreturn)) +void SystemNative_HandleNonCanceledPosixSignal(int32_t signalCode) +{ + (void)signalCode; + assert_msg(false, "Not supported on WASI", 0); +} + + +__attribute__((noreturn)) +void SystemNative_SetTerminalInvalidationHandler(TerminalInvalidationCallback callback) +{ + assert(callback != NULL); + assert_msg(false, "Not supported on WASI", 0); + (void)callback; +} + +__attribute__((noreturn)) +void SystemNative_RegisterForSigChld(SigChldCallback callback) +{ + assert(callback != NULL); + assert_msg(false, "Not supported on WASI", 0); + (void)callback; +} + +__attribute__((noreturn)) +void SystemNative_SetDelayedSigChildConsoleConfigurationHandler(void (*callback)(void)) +{ + assert(callback == NULL); + assert_msg(false, "Not supported on WASI", 0); + (void)callback; +} + +int32_t SystemNative_EnablePosixSignalHandling(int signalCode) +{ + (void)signalCode; + return false; +} + +void SystemNative_DisablePosixSignalHandling(int signalCode) +{ + (void)signalCode; +} diff --git a/src/native/libs/System.Native/pal_threading.c b/src/native/libs/System.Native/pal_threading.c index 09d49be20fb07d..b524327ef820b4 100644 --- a/src/native/libs/System.Native/pal_threading.c +++ b/src/native/libs/System.Native/pal_threading.c @@ -4,7 +4,6 @@ #include "pal_config.h" #include "pal_threading.h" -#include #include #include #include @@ -21,9 +20,7 @@ // So we can use the declaration of pthread_cond_timedwait_relative_np #undef _XOPEN_SOURCE #endif -#if HAVE_PTHREAD_H #include -#endif #if defined(TARGET_OSX) #define _XOPEN_SOURCE #endif @@ -33,12 +30,8 @@ struct LowLevelMonitor { -#if !defined(TARGET_WASI) pthread_mutex_t Mutex; pthread_cond_t Condition; -#else /* !TARGET_WASI */ - bool Dummy; -#endif /* !TARGET_WASI */ #ifdef DEBUG bool IsLocked; #endif @@ -62,7 +55,6 @@ LowLevelMonitor* SystemNative_LowLevelMonitor_Create(void) { return NULL; } -#if !defined(TARGET_WASI) int error; @@ -113,16 +105,12 @@ LowLevelMonitor* SystemNative_LowLevelMonitor_Create(void) assert(error == 0); free(monitor); return NULL; -#else /* !TARGET_WASI */ - return monitor; -#endif /* !TARGET_WASI */ } void SystemNative_LowLevelMonitor_Destroy(LowLevelMonitor* monitor) { assert(monitor != NULL); -#if !defined(TARGET_WASI) int error; error = pthread_cond_destroy(&monitor->Condition); @@ -133,7 +121,6 @@ void SystemNative_LowLevelMonitor_Destroy(LowLevelMonitor* monitor) (void)error; // unused in release build -#endif /* !TARGET_WASI */ free(monitor); } @@ -141,11 +128,9 @@ void SystemNative_LowLevelMonitor_Acquire(LowLevelMonitor* monitor) { assert(monitor != NULL); -#if !defined(TARGET_WASI) int error = pthread_mutex_lock(&monitor->Mutex); assert(error == 0); (void)error; // unused in release build -#endif /* !TARGET_WASI */ SetIsLocked(monitor, true); } @@ -156,11 +141,9 @@ void SystemNative_LowLevelMonitor_Release(LowLevelMonitor* monitor) SetIsLocked(monitor, false); -#if !defined(TARGET_WASI) int error = pthread_mutex_unlock(&monitor->Mutex); assert(error == 0); (void)error; // unused in release build -#endif /* !TARGET_WASI */ } void SystemNative_LowLevelMonitor_Wait(LowLevelMonitor* monitor) @@ -169,11 +152,9 @@ void SystemNative_LowLevelMonitor_Wait(LowLevelMonitor* monitor) SetIsLocked(monitor, false); -#if !defined(TARGET_WASI) int error = pthread_cond_wait(&monitor->Condition, &monitor->Mutex); assert(error == 0); (void)error; // unused in release build -#endif /* !TARGET_WASI */ SetIsLocked(monitor, true); } @@ -184,7 +165,6 @@ int32_t SystemNative_LowLevelMonitor_TimedWait(LowLevelMonitor *monitor, int32_t SetIsLocked(monitor, false); -#if !defined(TARGET_WASI) int error; // Calculate the time at which a timeout should occur, and wait. Older versions of OSX don't support clock_gettime with @@ -219,16 +199,12 @@ int32_t SystemNative_LowLevelMonitor_TimedWait(LowLevelMonitor *monitor, int32_t SetIsLocked(monitor, true); return error == 0; -#else /* !TARGET_WASI */ - return true; -#endif /* !TARGET_WASI */ } void SystemNative_LowLevelMonitor_Signal_Release(LowLevelMonitor* monitor) { assert(monitor != NULL); -#if !defined(TARGET_WASI) int error; error = pthread_cond_signal(&monitor->Condition); @@ -240,13 +216,11 @@ void SystemNative_LowLevelMonitor_Signal_Release(LowLevelMonitor* monitor) assert(error == 0); (void)error; // unused in release build -#endif /* !TARGET_WASI */ } int32_t SystemNative_CreateThread(uintptr_t stackSize, void *(*startAddress)(void*), void *parameter) { bool result = false; -#if !defined(TARGET_WASI) pthread_attr_t attrs; int error = pthread_attr_init(&attrs); @@ -287,7 +261,6 @@ int32_t SystemNative_CreateThread(uintptr_t stackSize, void *(*startAddress)(voi CreateThreadExit: error = pthread_attr_destroy(&attrs); assert(error == 0); -#endif /* !TARGET_WASI */ return result; } diff --git a/src/native/libs/System.Native/pal_threading_wasi.c b/src/native/libs/System.Native/pal_threading_wasi.c new file mode 100644 index 00000000000000..52d9e326ae0f21 --- /dev/null +++ b/src/native/libs/System.Native/pal_threading_wasi.c @@ -0,0 +1,88 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "pal_config.h" +#include "pal_threading.h" + +#include +#include +#include +#include +#include +#include + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// LowLevelMonitor - Represents a non-recursive mutex and condition + +struct LowLevelMonitor +{ + bool Dummy; +}; + +LowLevelMonitor* SystemNative_LowLevelMonitor_Create(void) +{ + return (LowLevelMonitor *)malloc(sizeof(LowLevelMonitor)); +} + +void SystemNative_LowLevelMonitor_Destroy(LowLevelMonitor* monitor) +{ + assert(monitor != NULL); + free(monitor); +} + +void SystemNative_LowLevelMonitor_Acquire(LowLevelMonitor* monitor) +{ + assert(monitor != NULL); + (void)monitor; // unused in release build +} + +void SystemNative_LowLevelMonitor_Release(LowLevelMonitor* monitor) +{ + assert(monitor != NULL); + (void)monitor; // unused in release build +} + +void SystemNative_LowLevelMonitor_Wait(LowLevelMonitor* monitor) +{ + assert(monitor != NULL); + (void)monitor; // unused in release build +} + +int32_t SystemNative_LowLevelMonitor_TimedWait(LowLevelMonitor *monitor, int32_t timeoutMilliseconds) +{ + assert(timeoutMilliseconds >= 0); + (void)monitor; // unused in release build + (void)timeoutMilliseconds; // unused in release build + return true; +} + +void SystemNative_LowLevelMonitor_Signal_Release(LowLevelMonitor* monitor) +{ + assert(monitor != NULL); + (void)monitor; // unused in release build +} + +int32_t SystemNative_CreateThread(uintptr_t stackSize, void *(*startAddress)(void*), void *parameter) +{ + (void)stackSize; + (void)startAddress; + (void)parameter; + return false; +} + +int32_t SystemNative_SchedGetCpu(void) +{ + return -1; +} + +__attribute__((noreturn)) +void SystemNative_Exit(int32_t exitCode) +{ + exit(exitCode); +} + +__attribute__((noreturn)) +void SystemNative_Abort(void) +{ + abort(); +} diff --git a/src/native/libs/System.Native/pal_uid.c b/src/native/libs/System.Native/pal_uid.c index e2cf3a24fb3213..0f94484cafec4d 100644 --- a/src/native/libs/System.Native/pal_uid.c +++ b/src/native/libs/System.Native/pal_uid.c @@ -11,27 +11,20 @@ #include #include #include -#if HAVE_GRP_H #include -#endif -#if HAVE_PWD_H #include -#endif // Linux c-libraries (glibc, musl) provide a thread-safe getgrouplist. // OSX man page mentions explicitly the implementation is not thread safe, // due to using getgrent. -#if !defined(__linux__) && !defined(TARGET_WASI) +#ifndef __linux__ #define USE_GROUPLIST_LOCK #endif #if defined(USE_GROUPLIST_LOCK) || !HAVE_GETGRGID_R -#if HAVE_PTHREAD_H #include #endif -#endif -#if !defined(TARGET_WASI) static int32_t ConvertNativePasswdToPalPasswd(int error, struct passwd* nativePwd, struct passwd* result, Passwd* pwd) { // positive error number returned -> failure other than entry-not-found @@ -60,7 +53,6 @@ static int32_t ConvertNativePasswdToPalPasswd(int error, struct passwd* nativePw pwd->Shell = nativePwd->pw_shell; return 0; } -#endif /* !TARGET_WASI */ int32_t SystemNative_GetPwUidR(uint32_t uid, Passwd* pwd, char* buf, int32_t buflen) { @@ -71,16 +63,12 @@ int32_t SystemNative_GetPwUidR(uint32_t uid, Passwd* pwd, char* buf, int32_t buf if (buflen < 0) return EINVAL; -#if !defined(TARGET_WASI) struct passwd nativePwd; struct passwd* result; int error; while ((error = getpwuid_r(uid, &nativePwd, buf, Int32ToSizeT(buflen), &result)) == EINTR); return ConvertNativePasswdToPalPasswd(error, &nativePwd, result, pwd); -#else /* !TARGET_WASI */ - return EINVAL; -#endif /* !TARGET_WASI */ } int32_t SystemNative_GetPwNamR(const char* name, Passwd* pwd, char* buf, int32_t buflen) @@ -92,50 +80,34 @@ int32_t SystemNative_GetPwNamR(const char* name, Passwd* pwd, char* buf, int32_t if (buflen < 0) return EINVAL; -#if !defined(TARGET_WASI) struct passwd nativePwd; struct passwd* result; int error; while ((error = getpwnam_r(name, &nativePwd, buf, Int32ToSizeT(buflen), &result)) == EINTR); return ConvertNativePasswdToPalPasswd(error, &nativePwd, result, pwd); -#else /* !TARGET_WASI */ - return EINVAL; -#endif /* !TARGET_WASI */ } uint32_t SystemNative_GetEUid(void) { -#if !defined(TARGET_WASI) return geteuid(); -#else /* !TARGET_WASI */ - return EINVAL; -#endif /* !TARGET_WASI */ } uint32_t SystemNative_GetEGid(void) { -#if !defined(TARGET_WASI) return getegid(); -#else /* !TARGET_WASI */ - return EINVAL; -#endif /* !TARGET_WASI */ } int32_t SystemNative_SetEUid(uint32_t euid) { -#if !defined(TARGET_WASI) return seteuid(euid); -#else /* !TARGET_WASI */ - return EINVAL; -#endif /* !TARGET_WASI */ } #ifdef USE_GROUPLIST_LOCK static pthread_mutex_t s_groupLock = PTHREAD_MUTEX_INITIALIZER; #endif -#if !HAVE_GETGROUPLIST && !defined(TARGET_WASI) +#if !HAVE_GETGROUPLIST int getgrouplist(const char *uname, gid_t agroup, gid_t *groups, int *groupCount) { int ngroups = 1; @@ -232,10 +204,8 @@ int32_t SystemNative_GetGroupList(const char* name, uint32_t group, uint32_t* gr #ifdef __APPLE__ // On OSX groups are passed as a signed int. rv = getgrouplist(name, (int)group, (int*)groups, &groupsAvailable); -#elif HAVE_GETGROUPLIST - rv = getgrouplist(name, group, groups, &groupsAvailable); #else - rv = 0; + rv = getgrouplist(name, group, groups, &groupsAvailable); #endif #ifdef USE_GROUPLIST_LOCK @@ -266,14 +236,10 @@ int32_t SystemNative_GetGroups(int32_t ngroups, uint32_t* groups) assert(ngroups >= 0); assert(groups != NULL); -#if !defined(TARGET_WASI) return getgroups(ngroups, groups); -#else /* TARGET_WASI */ - return -1; -#endif /* TARGET_WASI */ } -#if !HAVE_GETGRGID_R && !defined(TARGET_WASI) +#if !HAVE_GETGRGID_R // Need to call getgrgid which is not thread-safe, and protect it with a mutex static pthread_mutex_t s_getgrgid_lock = PTHREAD_MUTEX_INITIALIZER; #endif @@ -316,7 +282,7 @@ char* SystemNative_GetGroupName(uint32_t gid) } bufferLength = tmpBufferLength; } -#elif !defined(TARGET_WASI) +#else // Platforms like Android API level < 24 do not have getgrgid_r available int rv = pthread_mutex_lock(&s_getgrgid_lock); if (rv != 0) @@ -334,7 +300,5 @@ char* SystemNative_GetGroupName(uint32_t gid) char* name = strdup(result->gr_name); pthread_mutex_unlock(&s_getgrgid_lock); return name; -#else - return NULL; #endif } diff --git a/src/native/libs/System.Native/pal_uid_wasi.c b/src/native/libs/System.Native/pal_uid_wasi.c new file mode 100644 index 00000000000000..f57d552240b31d --- /dev/null +++ b/src/native/libs/System.Native/pal_uid_wasi.c @@ -0,0 +1,83 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "pal_config.h" +#include "pal_safecrt.h" +#include "pal_uid.h" +#include "pal_utilities.h" + +#include +#include +#include +#include +#include + + +int32_t SystemNative_GetPwUidR(uint32_t uid, Passwd* pwd, char* buf, int32_t buflen) +{ + assert(pwd != NULL); + assert(buf != NULL); + assert(buflen >= 0); + (void)uid; + (void)pwd; + (void)buf; + (void)buflen; + + return EINVAL; +} + +int32_t SystemNative_GetPwNamR(const char* name, Passwd* pwd, char* buf, int32_t buflen) +{ + assert(pwd != NULL); + assert(buf != NULL); + assert(buflen >= 0); + (void)name; + (void)pwd; + (void)buf; + (void)buflen; + + return EINVAL; +} + +uint32_t SystemNative_GetEUid(void) +{ + return EINVAL; +} + +uint32_t SystemNative_GetEGid(void) +{ + return EINVAL; +} + +int32_t SystemNative_SetEUid(uint32_t euid) +{ + return EINVAL; +} +int32_t SystemNative_GetGroupList(const char* name, uint32_t group, uint32_t* groups, int32_t* ngroups) +{ + assert(name != NULL); + assert(groups != NULL); + assert(ngroups != NULL); + assert(*ngroups >= 0); + (void)name; + (void)group; + (void)groups; + (void)ngroups; + return EINVAL; +} + +int32_t SystemNative_GetGroups(int32_t ngroups, uint32_t* groups) +{ + assert(ngroups >= 0); + assert(groups != NULL); + (void)groups; + (void)ngroups; + + return EINVAL; +} + +char* SystemNative_GetGroupName(uint32_t gid) +{ + (void)gid; + return NULL; +} From db5754053e4dcd14133e71b75f9d7f2244f64124 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Tue, 6 Dec 2022 18:13:26 +0100 Subject: [PATCH 18/39] wip --- .../libs/System.Native/pal_console_wasi.c | 25 +++++------ .../libs/System.Native/pal_dynamicload_wasi.c | 1 - .../libs/System.Native/pal_mount_wasi.c | 8 ---- .../libs/System.Native/pal_process_wasi.c | 43 +++---------------- .../libs/System.Native/pal_signal_wasi.c | 23 +++++----- .../libs/System.Native/pal_threading_wasi.c | 20 +++------ src/native/libs/System.Native/pal_uid_wasi.c | 15 ------- 7 files changed, 36 insertions(+), 99 deletions(-) diff --git a/src/native/libs/System.Native/pal_console_wasi.c b/src/native/libs/System.Native/pal_console_wasi.c index e467df32bfe1a1..cb77505bc9a707 100644 --- a/src/native/libs/System.Native/pal_console_wasi.c +++ b/src/native/libs/System.Native/pal_console_wasi.c @@ -17,6 +17,12 @@ #include #include +#ifdef DEBUG +#define DEBUGNOTRETURN __attribute__((noreturn)) +#else +#define DEBUGNOTRETURN +#endif + int32_t SystemNative_GetWindowSize(WinSize* windowSize) { assert(windowSize != NULL); @@ -28,7 +34,6 @@ int32_t SystemNative_GetWindowSize(WinSize* windowSize) int32_t SystemNative_SetWindowSize(WinSize* windowSize) { assert(windowSize != NULL); - (void)windowSize; errno = ENOTSUP; return -1; } @@ -38,36 +43,32 @@ int32_t SystemNative_IsATty(intptr_t fd) return isatty(ToFileDescriptor(fd)); } -__attribute__((noreturn)) +DEBUGNOTRETURN void SystemNative_SetKeypadXmit(const char* terminfoString) { - (void)terminfoString; //unused assert(terminfoString != NULL); assert_msg(false, "Not supported on WASI", 0); } -__attribute__((noreturn)) +DEBUGNOTRETURN void SystemNative_InitializeConsoleBeforeRead(uint8_t minChars, uint8_t decisecondsTimeout) { - (void)minChars; //unused - (void)decisecondsTimeout; //unused assert_msg(false, "Not supported on WASI", 0); } -__attribute__((noreturn)) +DEBUGNOTRETURN void SystemNative_UninitializeConsoleAfterRead(void) { assert_msg(false, "Not supported on WASI", 0); } -__attribute__((noreturn)) +DEBUGNOTRETURN void SystemNative_ConfigureTerminalForChildProcess(int32_t childUsesTerminal) { - (void)childUsesTerminal; //unused assert_msg(false, "Not supported on WASI", 0); } -__attribute__((noreturn)) +DEBUGNOTRETURN void SystemNative_GetControlCharacters( int32_t* controlCharacterNames, uint8_t* controlCharacterValues, int32_t controlCharacterLength, uint8_t* posixDisableValue) @@ -77,10 +78,6 @@ void SystemNative_GetControlCharacters( assert(controlCharacterLength >= 0); assert(posixDisableValue != NULL); - (void)controlCharacterNames; //unused - (void)controlCharacterValues; //unused - (void)controlCharacterLength; //unused - (void)posixDisableValue; //unused assert_msg(false, "Not supported on WASI", 0); } diff --git a/src/native/libs/System.Native/pal_dynamicload_wasi.c b/src/native/libs/System.Native/pal_dynamicload_wasi.c index 7fce6cf151aa3b..c4425b8eefbae4 100644 --- a/src/native/libs/System.Native/pal_dynamicload_wasi.c +++ b/src/native/libs/System.Native/pal_dynamicload_wasi.c @@ -12,7 +12,6 @@ void* SystemNative_LoadLibrary(const char* filename) { assert_msg(false, "Not supported on WASI", 0); - (void)filename; // unused return NULL; } diff --git a/src/native/libs/System.Native/pal_mount_wasi.c b/src/native/libs/System.Native/pal_mount_wasi.c index 6ca1f40f7463d4..61b776160eace6 100644 --- a/src/native/libs/System.Native/pal_mount_wasi.c +++ b/src/native/libs/System.Native/pal_mount_wasi.c @@ -11,8 +11,6 @@ int32_t SystemNative_GetAllMountPoints(MountPointFound onFound, void* context) { - (void)onFound; // unused - (void)context; // unused return -1; } @@ -20,8 +18,6 @@ int32_t SystemNative_GetSpaceInfoForMountPoint(const char* name, MountPointInfor { assert(name != NULL); assert(mpi != NULL); - (void)name; // unused - (void)mpi; // unused return -1; } @@ -30,9 +26,5 @@ SystemNative_GetFormatInfoForMountPoint(const char* name, char* formatNameBuffer { assert((formatNameBuffer != NULL) && (formatType != NULL)); assert(bufferLength > 0); - (void)name; // unused - (void)formatNameBuffer; // unused - (void)bufferLength; // unused - (void)formatType; // unused return -1; } diff --git a/src/native/libs/System.Native/pal_process_wasi.c b/src/native/libs/System.Native/pal_process_wasi.c index 2c650f6bb11bd9..1d3d6f998ec4e2 100644 --- a/src/native/libs/System.Native/pal_process_wasi.c +++ b/src/native/libs/System.Native/pal_process_wasi.c @@ -17,6 +17,12 @@ #include +#ifdef DEBUG +#define DEBUGNOTRETURN __attribute__((noreturn)) +#else +#define DEBUGNOTRETURN +#endif + int32_t SystemNative_ForkAndExecProcess(const char* filename, char* const argv[], char* const envp[], @@ -34,22 +40,6 @@ int32_t SystemNative_ForkAndExecProcess(const char* filename, int32_t* stdoutFd, int32_t* stderrFd) { - (void)filename; // unused - (void)argv; // unused - (void)envp; // unused - (void)cwd; // unused - (void)redirectStdin; // unused - (void)redirectStdout; // unused - (void)redirectStderr; // unused - (void)setCredentials; // unused - (void)userId; // unused - (void)groupId; // unused - (void)groups; // unused - (void)groupsLength; // unused - (void)childPid; // unused - (void)stdinFd; // unused - (void)stdoutFd; // unused - (void)stderrFd; // unused return -1; } @@ -58,15 +48,12 @@ int32_t SystemNative_GetRLimit(RLimitResources resourceType, RLimit* limits) assert(limits != NULL); int result = -1; memset(limits, 0, sizeof(RLimit)); - (void)resourceType; // unused return result; } int32_t SystemNative_SetRLimit(RLimitResources resourceType, const RLimit* limits) { assert(limits != NULL); - (void)resourceType; // unused - (void)limits; // unused return -1; } @@ -85,13 +72,10 @@ int32_t SystemNative_GetSid(int32_t pid) return -1; } -__attribute__((noreturn)) +DEBUGNOTRETURN void SystemNative_SysLog(SysLogPriority priority, const char* message, const char* arg1) { assert_msg(false, "Not supported on WASI", 0); - (void)priority; // unused - (void)message; // unused - (void)arg1; // unused } int32_t SystemNative_WaitIdAnyExitedNoHangNoWait(void) @@ -101,30 +85,21 @@ int32_t SystemNative_WaitIdAnyExitedNoHangNoWait(void) int32_t SystemNative_WaitPidExitedNoHang(int32_t pid, int32_t* exitCode) { - (void)pid; // unused - (void)exitCode; // unused return -1; } int64_t SystemNative_PathConf(const char* path, PathConfName name) { - (void)path; // unused - (void)name; // unused return -1; } int32_t SystemNative_GetPriority(PriorityWhich which, int32_t who) { - (void)which; // unused - (void)who; // unused return -1; } int32_t SystemNative_SetPriority(PriorityWhich which, int32_t who, int32_t nice) { - (void)which; // unused - (void)who; // unused - (void)nice; // unused return -1; } @@ -143,16 +118,12 @@ char* SystemNative_GetCwd(char* buffer, int32_t bufferSize) int32_t SystemNative_SchedSetAffinity(int32_t pid, intptr_t* mask) { - (void)pid; - (void)mask; errno = ENOTSUP; return -1; } int32_t SystemNative_SchedGetAffinity(int32_t pid, intptr_t* mask) { - (void)pid; - (void)mask; errno = ENOTSUP; return -1; } diff --git a/src/native/libs/System.Native/pal_signal_wasi.c b/src/native/libs/System.Native/pal_signal_wasi.c index 22016cd9689abf..71b23867388841 100644 --- a/src/native/libs/System.Native/pal_signal_wasi.c +++ b/src/native/libs/System.Native/pal_signal_wasi.c @@ -14,53 +14,52 @@ #include #include -__attribute__((noreturn)) +#ifdef DEBUG +#define DEBUGNOTRETURN __attribute__((noreturn)) +#else +#define DEBUGNOTRETURN +#endif + +DEBUGNOTRETURN void SystemNative_SetPosixSignalHandler(PosixSignalHandler signalHandler) { assert(signalHandler); - (void)signalHandler; assert_msg(false, "Not supported on WASI", 0); } -__attribute__((noreturn)) +DEBUGNOTRETURN void SystemNative_HandleNonCanceledPosixSignal(int32_t signalCode) { - (void)signalCode; assert_msg(false, "Not supported on WASI", 0); } -__attribute__((noreturn)) +DEBUGNOTRETURN void SystemNative_SetTerminalInvalidationHandler(TerminalInvalidationCallback callback) { assert(callback != NULL); assert_msg(false, "Not supported on WASI", 0); - (void)callback; } -__attribute__((noreturn)) +DEBUGNOTRETURN void SystemNative_RegisterForSigChld(SigChldCallback callback) { assert(callback != NULL); assert_msg(false, "Not supported on WASI", 0); - (void)callback; } -__attribute__((noreturn)) +DEBUGNOTRETURN void SystemNative_SetDelayedSigChildConsoleConfigurationHandler(void (*callback)(void)) { assert(callback == NULL); assert_msg(false, "Not supported on WASI", 0); - (void)callback; } int32_t SystemNative_EnablePosixSignalHandling(int signalCode) { - (void)signalCode; return false; } void SystemNative_DisablePosixSignalHandling(int signalCode) { - (void)signalCode; } diff --git a/src/native/libs/System.Native/pal_threading_wasi.c b/src/native/libs/System.Native/pal_threading_wasi.c index 52d9e326ae0f21..1f82d256ef7ac8 100644 --- a/src/native/libs/System.Native/pal_threading_wasi.c +++ b/src/native/libs/System.Native/pal_threading_wasi.c @@ -11,8 +11,11 @@ #include #include -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// LowLevelMonitor - Represents a non-recursive mutex and condition +#ifdef DEBUG +#define DEBUGNOTRETURN __attribute__((noreturn)) +#else +#define DEBUGNOTRETURN +#endif struct LowLevelMonitor { @@ -33,40 +36,31 @@ void SystemNative_LowLevelMonitor_Destroy(LowLevelMonitor* monitor) void SystemNative_LowLevelMonitor_Acquire(LowLevelMonitor* monitor) { assert(monitor != NULL); - (void)monitor; // unused in release build } void SystemNative_LowLevelMonitor_Release(LowLevelMonitor* monitor) { assert(monitor != NULL); - (void)monitor; // unused in release build } void SystemNative_LowLevelMonitor_Wait(LowLevelMonitor* monitor) { assert(monitor != NULL); - (void)monitor; // unused in release build } int32_t SystemNative_LowLevelMonitor_TimedWait(LowLevelMonitor *monitor, int32_t timeoutMilliseconds) { assert(timeoutMilliseconds >= 0); - (void)monitor; // unused in release build - (void)timeoutMilliseconds; // unused in release build return true; } void SystemNative_LowLevelMonitor_Signal_Release(LowLevelMonitor* monitor) { assert(monitor != NULL); - (void)monitor; // unused in release build } int32_t SystemNative_CreateThread(uintptr_t stackSize, void *(*startAddress)(void*), void *parameter) { - (void)stackSize; - (void)startAddress; - (void)parameter; return false; } @@ -75,13 +69,13 @@ int32_t SystemNative_SchedGetCpu(void) return -1; } -__attribute__((noreturn)) +DEBUGNOTRETURN void SystemNative_Exit(int32_t exitCode) { exit(exitCode); } -__attribute__((noreturn)) +DEBUGNOTRETURN void SystemNative_Abort(void) { abort(); diff --git a/src/native/libs/System.Native/pal_uid_wasi.c b/src/native/libs/System.Native/pal_uid_wasi.c index f57d552240b31d..1cf93b13d1f4bd 100644 --- a/src/native/libs/System.Native/pal_uid_wasi.c +++ b/src/native/libs/System.Native/pal_uid_wasi.c @@ -18,10 +18,6 @@ int32_t SystemNative_GetPwUidR(uint32_t uid, Passwd* pwd, char* buf, int32_t buf assert(pwd != NULL); assert(buf != NULL); assert(buflen >= 0); - (void)uid; - (void)pwd; - (void)buf; - (void)buflen; return EINVAL; } @@ -31,10 +27,6 @@ int32_t SystemNative_GetPwNamR(const char* name, Passwd* pwd, char* buf, int32_t assert(pwd != NULL); assert(buf != NULL); assert(buflen >= 0); - (void)name; - (void)pwd; - (void)buf; - (void)buflen; return EINVAL; } @@ -59,10 +51,6 @@ int32_t SystemNative_GetGroupList(const char* name, uint32_t group, uint32_t* gr assert(groups != NULL); assert(ngroups != NULL); assert(*ngroups >= 0); - (void)name; - (void)group; - (void)groups; - (void)ngroups; return EINVAL; } @@ -70,14 +58,11 @@ int32_t SystemNative_GetGroups(int32_t ngroups, uint32_t* groups) { assert(ngroups >= 0); assert(groups != NULL); - (void)groups; - (void)ngroups; return EINVAL; } char* SystemNative_GetGroupName(uint32_t gid) { - (void)gid; return NULL; } From 04343638fb50c02c0bb09202cfa51f8a8b472d57 Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Tue, 6 Dec 2022 18:30:44 +0100 Subject: [PATCH 19/39] fix --- src/native/libs/System.Native/pal_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/native/libs/System.Native/pal_io.c b/src/native/libs/System.Native/pal_io.c index 9a44586c77beb2..607eac9a170e28 100644 --- a/src/native/libs/System.Native/pal_io.c +++ b/src/native/libs/System.Native/pal_io.c @@ -1056,7 +1056,7 @@ int32_t SystemNative_MSync(void* address, uint64_t length, int32_t flags) return -1; } -#if defined(TARGET_WASI) +#if !defined(TARGET_WASI) return msync(address, (size_t)length, flags); #else return -1; From 8a3c728a4380555e173113a216568c908b32446c Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Tue, 6 Dec 2022 18:35:44 +0100 Subject: [PATCH 20/39] container --- eng/pipelines/common/templates/pipeline-with-resources.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/pipelines/common/templates/pipeline-with-resources.yml b/eng/pipelines/common/templates/pipeline-with-resources.yml index 9de181cce75421..62faaec1ee43dd 100644 --- a/eng/pipelines/common/templates/pipeline-with-resources.yml +++ b/eng/pipelines/common/templates/pipeline-with-resources.yml @@ -61,7 +61,7 @@ resources: image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-webassembly - container: wasi_wasm - image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-20.04-webassembly + image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-20.04-webassembly-staging - container: FreeBSD_x64 image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-cross-freebsd-12 From d494becd6d0e58ab3a4af80fa96628d3026b6e0d Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Wed, 7 Dec 2022 11:13:28 +0100 Subject: [PATCH 21/39] fix --- src/native/libs/Common/pal_config.h.in | 6 ---- src/native/libs/configure.cmake | 40 ++++++++++---------------- 2 files changed, 15 insertions(+), 31 deletions(-) diff --git a/src/native/libs/Common/pal_config.h.in b/src/native/libs/Common/pal_config.h.in index 8fe750b16871ee..a8a9dff3df213f 100644 --- a/src/native/libs/Common/pal_config.h.in +++ b/src/native/libs/Common/pal_config.h.in @@ -55,9 +55,6 @@ #cmakedefine01 HAVE_FDS_BITS #cmakedefine01 HAVE_PRIVATE_FDS_BITS #cmakedefine01 HAVE_STATFS -#cmakedefine01 HAVE_MNTENT_H -#cmakedefine01 HAVE_SIGNAL_KILL -#cmakedefine01 HAVE_SYS_RESOURCE_H #cmakedefine01 HAVE_GETRUSAGE #cmakedefine01 HAVE_SYS_SOCKIO_H #cmakedefine01 HAVE_ETHTOOL_H @@ -135,12 +132,9 @@ #cmakedefine01 HAVE_CFMAKERAW #cmakedefine01 HAVE_GETGROUPLIST #cmakedefine01 HAVE_SYSLOG_H -#cmakedefine01 HAVE_PWD_H -#cmakedefine01 HAVE_GRP_H #cmakedefine01 HAVE_TERMIOS_H #cmakedefine01 HAVE_DLFCN_H #cmakedefine01 HAVE_PTHREAD_H -#cmakedefine01 HAVE_SYS_WAIT_H #cmakedefine01 HAVE_SYS_STATVFS_H #cmakedefine01 HAVE_NET_IF_H #cmakedefine01 HAVE_SYS_PROCINFO_H diff --git a/src/native/libs/configure.cmake b/src/native/libs/configure.cmake index cd9c49d6d7e536..4fb18884b471e9 100644 --- a/src/native/libs/configure.cmake +++ b/src/native/libs/configure.cmake @@ -180,6 +180,11 @@ check_symbol_exists( unistd.h HAVE_VFORK) +check_symbol_exists( + pipe + unistd.h + HAVE_PIPE) + check_symbol_exists( pipe2 unistd.h @@ -372,19 +377,6 @@ check_symbol_exists( ${STATFS_INCLUDES} HAVE_STATFS) -check_symbol_exists( - "kill" - "signal.h" - HAVE_SIGNAL_KILL) - -check_include_files( - "mntent.h" - HAVE_MNTENT_H) - -check_include_files( - "sys/resource.h" - HAVE_SYS_RESOURCE_H) - check_symbol_exists( "getrusage" "sys/resource.h" @@ -708,6 +700,16 @@ check_symbol_exists( sys/stat.h HAVE_FUTIMENS) +check_symbol_exists( + fchmod + sys/stat.h + HAVE_FCHMOD) + +check_symbol_exists( + chmod + sys/stat.h + HAVE_CHMOD) + check_symbol_exists( utimensat sys/stat.h @@ -907,18 +909,10 @@ check_symbol_exists( "unistd.h;grp.h" HAVE_GETGROUPLIST) -check_include_files( - "grp.h" - HAVE_GRP_H) - check_include_files( "syslog.h" HAVE_SYSLOG_H) -check_include_files( - "pwd.h" - HAVE_PWD_H) - check_include_files( "termios.h" HAVE_TERMIOS_H) @@ -927,10 +921,6 @@ check_include_files( "dlfcn.h" HAVE_DLFCN_H) -check_include_files( - "sys/wait.h" - HAVE_SYS_WAIT_H) - check_include_files( "sys/statvfs.h" HAVE_SYS_STATVFS_H) From f80e897fddc88d6da201aaf703094e1dbfdc3a82 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Mon, 12 Dec 2022 20:45:41 +0000 Subject: [PATCH 22/39] wasm-library-tests: re-enable tests - And remove the wasi/linker job --- .../common/templates/wasm-library-tests.yml | 7 +++ .../libraries/helix-queues-setup.yml | 2 +- eng/pipelines/runtime-linker-tests.yml | 48 ------------------- eng/pipelines/runtime.yml | 1 - 4 files changed, 8 insertions(+), 50 deletions(-) diff --git a/eng/pipelines/common/templates/wasm-library-tests.yml b/eng/pipelines/common/templates/wasm-library-tests.yml index a05ca0bf166813..dfc447572863f0 100644 --- a/eng/pipelines/common/templates/wasm-library-tests.yml +++ b/eng/pipelines/common/templates/wasm-library-tests.yml @@ -70,3 +70,10 @@ jobs: or( eq(variables['alwaysRunVar'], true), eq(variables['isDefaultPipeline'], variables['shouldRunOnDefaultPipelines'])) + # extra steps, run tests + extraStepsTemplate: /eng/pipelines/libraries/helix.yml + extraStepsParameters: + creator: dotnet-bot + testRunNamePrefixSuffix: Mono_$(_BuildConfig) + extraHelixArguments: /p:BrowserHost=$(_hostedOs) $(_wasmRunSmokeTestsOnlyArg) ${{ parameters.extraHelixArgs }} + scenarios: ${{ parameters.scenarios }} diff --git a/eng/pipelines/libraries/helix-queues-setup.yml b/eng/pipelines/libraries/helix-queues-setup.yml index 2253a0bb55d3a3..0da0eb9b5fff2a 100644 --- a/eng/pipelines/libraries/helix-queues-setup.yml +++ b/eng/pipelines/libraries/helix-queues-setup.yml @@ -190,7 +190,7 @@ jobs: # - Windows.11.Arm64.Open # Browser WebAssembly - - ${{ if eq(parameters.platform, 'Browser_wasm') }}: + - ${{ if in(parameters.platform, 'Browser_wasm', 'wasi_wasm') }}: - Ubuntu.1804.Amd64.Open # Browser WebAssembly Firefox diff --git a/eng/pipelines/runtime-linker-tests.yml b/eng/pipelines/runtime-linker-tests.yml index bfe756fb690a7b..6ae1be06dd0c66 100644 --- a/eng/pipelines/runtime-linker-tests.yml +++ b/eng/pipelines/runtime-linker-tests.yml @@ -103,51 +103,3 @@ extends: eq(variables['isRollingBuild'], true)) buildArgs: -s clr+libs -c $(_BuildConfig) extraStepsTemplate: /eng/pipelines/libraries/execute-trimming-tests-steps.yml - - # - # Build Release config vertical for Browser-wasm - # - - template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/common/global-build-job.yml - buildConfig: release - platforms: - - Browser_wasm - jobParameters: - testGroup: innerloop - timeoutInMinutes: 120 - nameSuffix: Runtime_Release - buildArgs: -s mono+libs -c $(_BuildConfig) -p:WasmBuildNative=false - condition: - or( - eq(variables['isRollingBuild'], true), - eq(dependencies.evaluate_paths.outputs['SetPathVars_wasm_libraries.containsChange'], true), - eq(dependencies.evaluate_paths.outputs['SetPathVars_wasm.containsChange'], true), - eq(dependencies.evaluate_paths.outputs['DarcDependenciesChanged.Microsoft_NET_ILLink_Tasks'], true)) - extraStepsTemplate: /eng/pipelines/libraries/execute-trimming-tests-steps.yml - extraStepsParameters: - extraTestArgs: '/p:WasmBuildNative=false' - - # - # Build Release config vertical for WASI-wasm - # - - template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/common/global-build-job.yml - buildConfig: release - platforms: - - wasi_wasm - jobParameters: - testGroup: innerloop - timeoutInMinutes: 120 - nameSuffix: Runtime_Release - buildArgs: -s mono+libs -c $(_BuildConfig) -p:WasmBuildNative=false - condition: - or( - eq(variables['isRollingBuild'], true), - eq(dependencies.evaluate_paths.outputs['SetPathVars_wasm_libraries.containsChange'], true), - eq(dependencies.evaluate_paths.outputs['SetPathVars_wasm.containsChange'], true), - eq(dependencies.evaluate_paths.outputs['DarcDependenciesChanged.Microsoft_NET_ILLink_Tasks'], true)) - extraStepsTemplate: /eng/pipelines/libraries/execute-trimming-tests-steps.yml - extraStepsParameters: - extraTestArgs: '/p:WasmBuildNative=false' diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index c190c476561609..f2821a938f03ce 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -461,7 +461,6 @@ extends: parameters: platforms: - wasi_wasm - extraBuildArgs: /p:WasmEnableThreads=true alwaysRun: ${{ variables.isRollingBuild }} # From 596689ab0ee2c96c95940c093f625eabe339cbce Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Mon, 12 Dec 2022 23:07:56 +0000 Subject: [PATCH 23/39] Add back wasm linker-tests job --- eng/pipelines/runtime-linker-tests.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/eng/pipelines/runtime-linker-tests.yml b/eng/pipelines/runtime-linker-tests.yml index 6ae1be06dd0c66..4a75a0be9f90b2 100644 --- a/eng/pipelines/runtime-linker-tests.yml +++ b/eng/pipelines/runtime-linker-tests.yml @@ -103,3 +103,27 @@ extends: eq(variables['isRollingBuild'], true)) buildArgs: -s clr+libs -c $(_BuildConfig) extraStepsTemplate: /eng/pipelines/libraries/execute-trimming-tests-steps.yml + + # + # Build Release config vertical for Browser-wasm + # + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + buildConfig: release + platforms: + - Browser_wasm + jobParameters: + testGroup: innerloop + timeoutInMinutes: 120 + nameSuffix: Runtime_Release + buildArgs: -s mono+libs -c $(_BuildConfig) -p:WasmBuildNative=false + condition: + or( + eq(variables['isRollingBuild'], true), + eq(dependencies.evaluate_paths.outputs['SetPathVars_wasm_libraries.containsChange'], true), + eq(dependencies.evaluate_paths.outputs['SetPathVars_wasm.containsChange'], true), + eq(dependencies.evaluate_paths.outputs['DarcDependenciesChanged.Microsoft_NET_ILLink_Tasks'], true)) + extraStepsTemplate: /eng/pipelines/libraries/execute-trimming-tests-steps.yml + extraStepsParameters: + extraTestArgs: '/p:WasmBuildNative=false' From 033164b35943adf3a201d88760ebfa644116e1ce Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Mon, 12 Dec 2022 23:14:53 +0000 Subject: [PATCH 24/39] getrusage isn't available --- src/native/libs/CMakeLists.txt | 2 ++ src/native/libs/Common/pal_config.h.in | 5 ++++- src/native/libs/System.Native/CMakeLists.txt | 4 ++-- src/native/libs/configure.cmake | 5 ----- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/native/libs/CMakeLists.txt b/src/native/libs/CMakeLists.txt index 13c06f11493d75..5e874a74f40c47 100644 --- a/src/native/libs/CMakeLists.txt +++ b/src/native/libs/CMakeLists.txt @@ -54,11 +54,13 @@ if (CLR_CMAKE_TARGET_UNIX OR CLR_CMAKE_TARGET_BROWSER OR CLR_CMAKE_TARGET_WASI) endif () if (CLR_CMAKE_TARGET_WASI) + set(HOST_WASI 1) add_compile_options(-I${CLR_REPO_ROOT_DIR}/src/mono/wasi/include/) add_compile_options(-I${CLR_REPO_ROOT_DIR}/src/mono/wasi/libs-include/) add_compile_options(-Wno-unused-variable) add_compile_options(-Wno-unused-parameter) add_compile_options(-Wno-gnu-statement-expression) + add_compile_options(-DHOST_WASI) add_compile_options(-D_WASI_EMULATED_PROCESS_CLOCKS) add_compile_options(-D_WASI_EMULATED_SIGNAL) add_compile_options(-D_WASI_EMULATED_MMAN) diff --git a/src/native/libs/Common/pal_config.h.in b/src/native/libs/Common/pal_config.h.in index a8a9dff3df213f..536796944fd22c 100644 --- a/src/native/libs/Common/pal_config.h.in +++ b/src/native/libs/Common/pal_config.h.in @@ -55,7 +55,6 @@ #cmakedefine01 HAVE_FDS_BITS #cmakedefine01 HAVE_PRIVATE_FDS_BITS #cmakedefine01 HAVE_STATFS -#cmakedefine01 HAVE_GETRUSAGE #cmakedefine01 HAVE_SYS_SOCKIO_H #cmakedefine01 HAVE_ETHTOOL_H #cmakedefine01 HAVE_SYS_POLL_H @@ -148,6 +147,10 @@ #cmakedefine01 HAVE_MAKEDEV_SYSMACROSH #cmakedefine01 HAVE_GETGRGID_R +#ifndef HOST_WASI +#cmakedefine01 HAVE_GETRUSAGE +#endif + // Mac OS X has stat64, but it is deprecated since plain stat now // provides the same 64-bit aware struct when targeting OS X > 10.5 // and not passing _DARWIN_NO_64_BIT_INODE. diff --git a/src/native/libs/System.Native/CMakeLists.txt b/src/native/libs/System.Native/CMakeLists.txt index aa64c923d6468b..d44823c951354c 100644 --- a/src/native/libs/System.Native/CMakeLists.txt +++ b/src/native/libs/System.Native/CMakeLists.txt @@ -31,7 +31,7 @@ set(NATIVE_SOURCES ) if (NOT CLR_CMAKE_TARGET_WASI) - list (APPEND NATIVE_SOURCES + list (APPEND NATIVE_SOURCES pal_dynamicload.c pal_mount.c pal_networking.c @@ -41,7 +41,7 @@ if (NOT CLR_CMAKE_TARGET_WASI) pal_uid.c ) else() - list (APPEND NATIVE_SOURCES + list (APPEND NATIVE_SOURCES pal_dynamicload_wasi.c pal_mount_wasi.c pal_networking_wasi.c diff --git a/src/native/libs/configure.cmake b/src/native/libs/configure.cmake index 4fb18884b471e9..3c7ba69d32f10d 100644 --- a/src/native/libs/configure.cmake +++ b/src/native/libs/configure.cmake @@ -377,11 +377,6 @@ check_symbol_exists( ${STATFS_INCLUDES} HAVE_STATFS) -check_symbol_exists( - "getrusage" - "sys/resource.h" - HAVE_GETRUSAGE) - check_symbol_exists( "getrlimit" "sys/resource.h" From a9fd1ad4f7bc21ec61b86485cb32bdde9cdfa939 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Wed, 14 Dec 2022 12:31:18 +0100 Subject: [PATCH 25/39] fix --- src/native/libs/CMakeLists.txt | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/native/libs/CMakeLists.txt b/src/native/libs/CMakeLists.txt index 5e874a74f40c47..6dde2f698bda74 100644 --- a/src/native/libs/CMakeLists.txt +++ b/src/native/libs/CMakeLists.txt @@ -67,14 +67,6 @@ if (CLR_CMAKE_TARGET_UNIX OR CLR_CMAKE_TARGET_BROWSER OR CLR_CMAKE_TARGET_WASI) add_link_options(-Wl,-z,stack-size=1048576,--initial-memory=5242880,--max-memory=52428800,-lwasi-emulated-process-clocks,-lwasi-emulated-signal,-lwasi-emulated-mman) endif () - if (CLR_CMAKE_TARGET_TVOS) - # with -fembed-bitcode passing -headerpad_max_install_names is not allowed so remove it from the CMake flags - string(REPLACE "-Wl,-headerpad_max_install_names" "" CMAKE_C_LINK_FLAGS ${CMAKE_C_LINK_FLAGS}) - string(REPLACE "-Wl,-headerpad_max_install_names" "" CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS}) - add_compile_options(-fembed-bitcode) - add_link_options(-fembed-bitcode) - endif () - if (CLR_CMAKE_TARGET_ANDROID) if (CROSS_ROOTFS) include_directories(SYSTEM "${CROSS_ROOTFS}/usr/include") From bd8fb9ee52ae76912fa445ff96d03b63c2d0a753 Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Mon, 19 Dec 2022 15:20:36 +0100 Subject: [PATCH 26/39] Update eng/pipelines/common/templates/pipeline-with-resources.yml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Alexander Köplinger --- eng/pipelines/common/templates/pipeline-with-resources.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/pipelines/common/templates/pipeline-with-resources.yml b/eng/pipelines/common/templates/pipeline-with-resources.yml index 62faaec1ee43dd..9de181cce75421 100644 --- a/eng/pipelines/common/templates/pipeline-with-resources.yml +++ b/eng/pipelines/common/templates/pipeline-with-resources.yml @@ -61,7 +61,7 @@ resources: image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-webassembly - container: wasi_wasm - image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-20.04-webassembly-staging + image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-20.04-webassembly - container: FreeBSD_x64 image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-cross-freebsd-12 From 9bb5faff84b2d891cc29ab3bf227df2618e16baa Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Mon, 19 Dec 2022 15:21:45 +0100 Subject: [PATCH 27/39] Update src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/RuntimeInformation.Browser.cs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Alexander Köplinger --- .../Runtime/InteropServices/RuntimeInformation.Browser.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/RuntimeInformation.Browser.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/RuntimeInformation.Browser.cs index 7f9aff89b0aba8..04e9d251c31f5b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/RuntimeInformation.Browser.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/RuntimeInformation.Browser.cs @@ -5,9 +5,9 @@ namespace System.Runtime.InteropServices { public static partial class RuntimeInformation { -#if TARGET_WASI +#if TARGET_BROWSER public static string OSDescription => "Browser"; -#elif TARGET_BROWSER +#elif TARGET_WASI public static string OSDescription => "WASI"; #else #error From d4ba0b2a58e465a16cf3a4e71f94cf0d31a71bac Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Mon, 19 Dec 2022 15:22:09 +0100 Subject: [PATCH 28/39] Update src/libraries/System.Private.CoreLib/src/System/Threading/Overlapped.cs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Alexander Köplinger --- .../System.Private.CoreLib/src/System/Threading/Overlapped.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Overlapped.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Overlapped.cs index f7f0cff5894cd6..29446e444073c4 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Overlapped.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Overlapped.cs @@ -184,7 +184,7 @@ public static void Free(NativeOverlapped* nativeOverlappedPtr) _pNativeOverlapped = pNativeOverlapped; #if FEATURE_PERFTRACING -#if !((TARGET_BROWSER || TARGET_WASI) && !FEATURE_WASM_THREADS) +#if !((TARGET_BROWSER || TARGET_WASI) && !FEATURE_WASM_THREADS) if (NativeRuntimeEventSource.Log.IsEnabled()) NativeRuntimeEventSource.Log.ThreadPoolIOPack(pNativeOverlapped); #endif From 829ae38b7b9083929d2716a1bdb971b5536acef1 Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Mon, 19 Dec 2022 15:22:47 +0100 Subject: [PATCH 29/39] Update src/mono/Directory.Build.props MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Alexander Köplinger --- src/mono/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/Directory.Build.props b/src/mono/Directory.Build.props index 72f3885bbe4b33..09483349598d8b 100644 --- a/src/mono/Directory.Build.props +++ b/src/mono/Directory.Build.props @@ -46,7 +46,7 @@ - $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'wasi-sdk')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsObjDir)', 'wasi-sdk')) $(ProvisionWasiSdkDir.Replace('\', '/')) true true From d640c985099c311450e115ce50c674dc9039c2af Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Mon, 19 Dec 2022 15:23:18 +0100 Subject: [PATCH 30/39] Update Directory.Build.props MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Alexander Köplinger --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index e4d26d9bf1d371..5d19bd46a49405 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -131,7 +131,7 @@ $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'coreclr', '$(TargetOS).$(TargetArchitecture).$(Configuration)')) $(CoreCLRToolPath) - $([MSBuild]::NormalizeDirectory($(ArtifactsBinDir), 'wasmtime')) + $([MSBuild]::NormalizeDirectory($(ArtifactsObjDir), 'wasmtime')) From 1dc21c6e8be6575d7a40264af9a1c375aecd34c2 Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Mon, 19 Dec 2022 15:23:59 +0100 Subject: [PATCH 31/39] Update src/mono/cmake/configure.cmake MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Alexander Köplinger --- src/mono/cmake/configure.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/cmake/configure.cmake b/src/mono/cmake/configure.cmake index 56b092e0add08b..6403054d1fe756 100644 --- a/src/mono/cmake/configure.cmake +++ b/src/mono/cmake/configure.cmake @@ -93,7 +93,7 @@ else () endif() if (HOST_WASI) - # sysctl is deprecated on Linux and doesn't work on Browser + # sysctl is deprecated on Linux and doesn't work on WASI set(HAVE_GETRUSAGE 0) endif() From 17f90437ea1aa11b29b0eff3bd64e3b3721b8c70 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Tue, 20 Dec 2022 15:32:03 +0100 Subject: [PATCH 32/39] feedback --- eng/pipelines/libraries/helix-queues-setup.yml | 2 +- src/mono/CMakeLists.txt | 1 - src/mono/wasi/.gitignore | 2 -- src/native/libs/Common/pal_config.h.in | 4 ---- src/native/libs/System.Native/pal_io.c | 3 ++- src/native/libs/System.Native/pal_time.c | 6 ------ 6 files changed, 3 insertions(+), 15 deletions(-) delete mode 100644 src/mono/wasi/.gitignore diff --git a/eng/pipelines/libraries/helix-queues-setup.yml b/eng/pipelines/libraries/helix-queues-setup.yml index 6424fde82c2d4f..b4b5fc82ffc6bb 100644 --- a/eng/pipelines/libraries/helix-queues-setup.yml +++ b/eng/pipelines/libraries/helix-queues-setup.yml @@ -189,7 +189,7 @@ jobs: # TODO: Uncomment once there is HW deployed to service Win11 ARM64 queue # - Windows.11.Arm64.Open - # Browser WebAssembly + # Browser/WASI WebAssembly - ${{ if in(parameters.platform, 'Browser_wasm', 'wasi_wasm') }}: - Ubuntu.1804.Amd64.Open diff --git a/src/mono/CMakeLists.txt b/src/mono/CMakeLists.txt index db55748912e328..bfc8bdce279b4c 100644 --- a/src/mono/CMakeLists.txt +++ b/src/mono/CMakeLists.txt @@ -245,7 +245,6 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "WASI") add_definitions(-DDISABLE_EGD_SOCKET) add_definitions(-DDISABLE_EVENTPIPE) set(ENABLE_PERFTRACING 0) - add_compile_options(-Wl,--allow-undefined) set(DISABLE_SHARED_LIBS 1) set(INTERNAL_ZLIB 1) set(DISABLE_EXECUTABLES 1) diff --git a/src/mono/wasi/.gitignore b/src/mono/wasi/.gitignore deleted file mode 100644 index c2313f66ee085a..00000000000000 --- a/src/mono/wasi/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -wasi-sdk/** -wasmtime/** diff --git a/src/native/libs/Common/pal_config.h.in b/src/native/libs/Common/pal_config.h.in index 536796944fd22c..7d78597da3861c 100644 --- a/src/native/libs/Common/pal_config.h.in +++ b/src/native/libs/Common/pal_config.h.in @@ -147,10 +147,6 @@ #cmakedefine01 HAVE_MAKEDEV_SYSMACROSH #cmakedefine01 HAVE_GETGRGID_R -#ifndef HOST_WASI -#cmakedefine01 HAVE_GETRUSAGE -#endif - // Mac OS X has stat64, but it is deprecated since plain stat now // provides the same 64-bit aware struct when targeting OS X > 10.5 // and not passing _DARWIN_NO_64_BIT_INODE. diff --git a/src/native/libs/System.Native/pal_io.c b/src/native/libs/System.Native/pal_io.c index 607eac9a170e28..a0b33a5d43a548 100644 --- a/src/native/libs/System.Native/pal_io.c +++ b/src/native/libs/System.Native/pal_io.c @@ -352,7 +352,8 @@ intptr_t SystemNative_Dup(intptr_t oldfd) // do CLOEXEC here too fcntl(result, F_SETFD, FD_CLOEXEC); #else - // https://github.com/bytecodealliance/wasmtime/blob/main/docs/WASI-rationale.md#why-no-dup + // The main use cases for dup are setting up the classic Unix dance of setting up file descriptors in advance of performing a fork. Since WASI has no fork, these don't apply. + // https://github.com/bytecodealliance/wasmtime/blob/b2fefe77148582a9b8013e34fe5808ada82b6efc/docs/WASI-rationale.md#why-no-dup result = oldfd; #endif return result; diff --git a/src/native/libs/System.Native/pal_time.c b/src/native/libs/System.Native/pal_time.c index 51b463c76a605d..04ffd55865d301 100644 --- a/src/native/libs/System.Native/pal_time.c +++ b/src/native/libs/System.Native/pal_time.c @@ -121,7 +121,6 @@ int64_t SystemNative_GetBootTimeTicks(void) double SystemNative_GetCpuUtilization(ProcessCpuInformation* previousCpuInfo) { -#ifdef HAVE_GETRUSAGE uint64_t kernelTime = 0; uint64_t userTime = 0; @@ -170,9 +169,4 @@ double SystemNative_GetCpuUtilization(ProcessCpuInformation* previousCpuInfo) previousCpuInfo->lastRecordedKernelTime = kernelTime; return cpuUtilization; -#else - (void)previousCpuInfo; // unused - assert(false); - return 0; -#endif } From 92f9bc872788c4cb1212cb01920fccc0b0951c64 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Tue, 20 Dec 2022 15:36:19 +0100 Subject: [PATCH 33/39] wip --- src/mono/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/CMakeLists.txt b/src/mono/CMakeLists.txt index bfc8bdce279b4c..d22bb112b3ee45 100644 --- a/src/mono/CMakeLists.txt +++ b/src/mono/CMakeLists.txt @@ -238,7 +238,7 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Emscripten") set(INTERNAL_ZLIB 1) elseif(CMAKE_SYSTEM_NAME STREQUAL "WASI") set(HOST_WASI 1) - add_definitions(-D_WASI_EMULATED_SIGNAL -D_WASI_EMULATED_MMAN -DHOST_WASI) + add_definitions(-D_WASI_EMULATED_PROCESS_CLOCKS -D_WASI_EMULATED_SIGNAL -D_WASI_EMULATED_MMAN -DHOST_WASI) add_definitions(-DNO_GLOBALIZATION_SHIM) add_definitions(-D_THREAD_SAFE) add_definitions(-DDISABLE_SOCKET_TRANSPORT) From 9d26f1d3076ad26c5129f75ec6390170127280ba Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Tue, 20 Dec 2022 15:49:20 +0100 Subject: [PATCH 34/39] wip --- src/mono/cmake/configure.cmake | 2 +- src/mono/mono/utils/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mono/cmake/configure.cmake b/src/mono/cmake/configure.cmake index 6403054d1fe756..db78672ce68920 100644 --- a/src/mono/cmake/configure.cmake +++ b/src/mono/cmake/configure.cmake @@ -104,7 +104,7 @@ if(NOT HOST_DARWIN) ac_check_funcs (getentropy) endif() -if(NOT HOST_WASI) +if(NOT DISABLE_THREADS) find_package(Threads) endif() # Needed to find pthread_ symbols diff --git a/src/mono/mono/utils/CMakeLists.txt b/src/mono/mono/utils/CMakeLists.txt index f4011f0e6f9586..4d552b6e033dd9 100644 --- a/src/mono/mono/utils/CMakeLists.txt +++ b/src/mono/mono/utils/CMakeLists.txt @@ -217,7 +217,7 @@ elseif(TARGET_RISCV64) set(utils_arch_sources "${utils_arch_sources};mono-hwcap-riscv.c") elseif(TARGET_S390X) set(utils_arch_sources "${utils_arch_sources};mono-hwcap-s390x.c") -elseif(TARGET_BROWSER OR TARGET_WASI) +elseif(TARGET_WASM) set(utils_arch_sources "${utils_arch_sources};mono-hwcap-wasm.c;mono-mmap-wasm.c") elseif(TARGET_POWERPC OR TARGET_POWERPC64) set(utils_arch_sources "${utils_arch_sources};mono-hwcap-ppc.c") From 80261077773f392e2bb6794cc1236befe77fcf6d Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Tue, 20 Dec 2022 16:07:53 +0100 Subject: [PATCH 35/39] feedback --- src/mono/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mono/CMakeLists.txt b/src/mono/CMakeLists.txt index d22bb112b3ee45..9948d9e5b99f4b 100644 --- a/src/mono/CMakeLists.txt +++ b/src/mono/CMakeLists.txt @@ -320,7 +320,6 @@ elseif(TARGET_SYSTEM_NAME STREQUAL "Emscripten") endif() elseif(TARGET_SYSTEM_NAME STREQUAL "WASI") set(TARGET_WASI 1) - set(DISABLE_THREADS 1) if (CMAKE_BUILD_TYPE STREQUAL "Release") add_compile_options(-Os) endif() From 99065d9e4baf63db5f851cdbf3ef540665bcd725 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Wed, 21 Dec 2022 12:01:15 +0100 Subject: [PATCH 36/39] feedback --- src/native/libs/Common/pal_utilities.h | 2 +- src/native/libs/configure.cmake | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/native/libs/Common/pal_utilities.h b/src/native/libs/Common/pal_utilities.h index babb42bc4ceccd..3fece3a08aa3e8 100644 --- a/src/native/libs/Common/pal_utilities.h +++ b/src/native/libs/Common/pal_utilities.h @@ -83,7 +83,7 @@ inline static int ToFileDescriptorUnchecked(intptr_t fd) */ inline static int ToFileDescriptor(intptr_t fd) { -#ifndef TARGET_WASI +#ifndef TARGET_WASI // the valid range of file descriptors is probably INT32_MIN <= fd && fd <= INT32_MAX, the negative handles are valid for console. assert(0 <= fd && fd < sysconf(_SC_OPEN_MAX)); #endif diff --git a/src/native/libs/configure.cmake b/src/native/libs/configure.cmake index 3c7ba69d32f10d..87a4b430e4a10f 100644 --- a/src/native/libs/configure.cmake +++ b/src/native/libs/configure.cmake @@ -1152,12 +1152,10 @@ if (NOT HAVE_MAKEDEV_FILEH AND NOT HAVE_MAKEDEV_SYSMACROSH AND NOT CLR_CMAKE_TAR message(FATAL_ERROR "Cannot find the makedev function on this platform.") endif() -if (NOT CLR_CMAKE_TARGET_WASI) - check_symbol_exists( - getgrgid_r - grp.h - HAVE_GETGRGID_R) -endif() +check_symbol_exists( + getgrgid_r + grp.h + HAVE_GETGRGID_R) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/Common/pal_config.h.in From edfe354b035abebf5d9daf4b22cdc93afaa294de Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Tue, 3 Jan 2023 11:20:00 +0100 Subject: [PATCH 37/39] feedback --- eng/native/gen-buildsys.cmd | 2 ++ 1 file changed, 2 insertions(+) diff --git a/eng/native/gen-buildsys.cmd b/eng/native/gen-buildsys.cmd index 1259cbde4265f2..fb70a4e0c29bf7 100644 --- a/eng/native/gen-buildsys.cmd +++ b/eng/native/gen-buildsys.cmd @@ -55,6 +55,7 @@ if /i "%__Arch%" == "wasm" ( set EMSDK_PATH=%__repoRoot%\src\mono\wasm\emsdk ) + :: replace backslash with forward slash and append last slash set "EMSDK_PATH=!EMSDK_PATH:\=/!" if not "!EMSDK_PATH:~-1!" == "/" set "EMSDK_PATH=!EMSDK_PATH!/" @@ -70,6 +71,7 @@ if /i "%__Arch%" == "wasm" ( set WASI_SDK_PATH=%__repoRoot%src\mono\wasi\wasi-sdk ) + :: replace backslash with forward slash and append last slash set "WASI_SDK_PATH=!WASI_SDK_PATH:\=/!" if not "!WASI_SDK_PATH:~-1!" == "/" set "WASI_SDK_PATH=!WASI_SDK_PATH!/" set __CmakeGenerator=Ninja From 3a273db45422d39ee6889137e0496b5c303a3479 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Fri, 6 Jan 2023 13:01:13 +0100 Subject: [PATCH 38/39] fix merge --- src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj index 0aec023b88dfd3..411da5e3901a54 100644 --- a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -121,8 +121,8 @@ $(DefineConstants);MONO_FEATURE_SRE true - true - true + true + true true true true From c1b834db4d949ce95c64f2619342c935e96cb060 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Fri, 6 Jan 2023 14:24:30 +0100 Subject: [PATCH 39/39] fix --- src/mono/mono/component/debugger-agent.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/mono/mono/component/debugger-agent.c b/src/mono/mono/component/debugger-agent.c index 6134e86e0d30b2..6956c42ab28b25 100644 --- a/src/mono/mono/component/debugger-agent.c +++ b/src/mono/mono/component/debugger-agent.c @@ -5575,12 +5575,11 @@ decode_value_compute_size (MonoType *t, int type, MonoDomain *domain, guint8 *bu decode_int (buf, &buf, limit); //not used } } else if (type == MONO_TYPE_VALUETYPE) { - MonoClass *klass; MonoDomain *d; decode_byte (buf, &buf, limit); if (CHECK_PROTOCOL_VERSION(2, 61)) decode_byte (buf, &buf, limit); //ignore is boxed - klass = decode_typeid (buf, &buf, limit, &d, &err); + decode_typeid (buf, &buf, limit, &d, &err); ret += decode_vtype_compute_size (NULL, domain, buf, &buf, limit, from_by_ref_value_type); } else { goto end;