From eb1d810a41f2f9bb44876b1250fdbb69d233dd4b Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Fri, 13 Feb 2026 16:49:47 +0100 Subject: [PATCH 1/3] rebase --- eng/native/configureplatform.cmake | 10 + eng/native/tryrun.browser.cmake | 6 +- .../System/Net/SocketAddressPal.Browser.cs | 72 +++ .../src/System.Net.Primitives.csproj | 8 +- .../System.Net.Primitives.Pal.Tests.csproj | 10 +- .../src/System.Net.Sockets.csproj | 6 +- src/mono/mono/mini/cfgdump.c | 2 + src/mono/mono/profiler/aot.c | 5 +- src/mono/mono/profiler/helper.c | 4 +- src/mono/mono/profiler/log.c | 2 +- .../browserhost/libBrowserHost.footer.js | 22 - src/native/libs/System.Native/CMakeLists.txt | 12 +- .../pal_interfaceaddresses_browser.c | 48 ++ .../System.Native/pal_networking_browser.c | 548 ++++++++++++++++++ .../pal_networkstatistics_wasm.c | 89 +++ 15 files changed, 807 insertions(+), 37 deletions(-) create mode 100644 src/libraries/Common/src/System/Net/SocketAddressPal.Browser.cs create mode 100644 src/native/libs/System.Native/pal_interfaceaddresses_browser.c create mode 100644 src/native/libs/System.Native/pal_networking_browser.c create mode 100644 src/native/libs/System.Native/pal_networkstatistics_wasm.c diff --git a/eng/native/configureplatform.cmake b/eng/native/configureplatform.cmake index f6d773236e9254..23fbf67e6f0a74 100644 --- a/eng/native/configureplatform.cmake +++ b/eng/native/configureplatform.cmake @@ -498,6 +498,16 @@ else() add_link_options(-Wno-unused-command-line-argument) add_link_options(-Wl,-error-limit=0) + add_link_options(-nostdlib) + add_link_options(-lbulkmemory) + add_link_options(-lstubs) + add_link_options(-lc) + add_link_options(-lmalloc) + add_link_options(-lcompiler_rt) + add_link_options(-lc++) + add_link_options(-lc++abi) + add_link_options(-lunwind) + add_compile_options(-fwasm-exceptions) add_compile_options(-mbulk-memory) add_compile_options(-msimd128) diff --git a/eng/native/tryrun.browser.cmake b/eng/native/tryrun.browser.cmake index 60438de23a0fab..ed8ac60a55a576 100644 --- a/eng/native/tryrun.browser.cmake +++ b/eng/native/tryrun.browser.cmake @@ -21,6 +21,10 @@ # Automatically applied when building for browser-wasm. No special flags needed: # ./build.sh -subset clr.runtime -os browser -arch wasm -c Debug # +# OVERRIDES: +# We don't want to use all emulators which are available in Emscripten. +# - HAVE_SYS_SOCKET_H +# # VERSION TRACKING: # The TRYRUN_BROWSER_EMSCRIPTEN_VERSION variable at the top of this file tracks # which Emscripten version this cache was generated for. The build system @@ -326,7 +330,7 @@ set(HAVE_SYS_POLL_H "" CACHE INTERNAL "") set(HAVE_SYS_PROCINFO_H "" CACHE INTERNAL "") set(HAVE_SYS_PTRACE_H "" CACHE INTERNAL "") set(HAVE_SYS_SDT_H "" CACHE INTERNAL "") -set(HAVE_SYS_SOCKET_H 1 CACHE INTERNAL "") +set(HAVE_SYS_SOCKET_H "" CACHE INTERNAL "") set(HAVE_SYS_SOCKIO_H "" CACHE INTERNAL "") set(HAVE_SYS_STATFS_H 1 CACHE INTERNAL "") set(HAVE_SYS_STATVFS_H 1 CACHE INTERNAL "") diff --git a/src/libraries/Common/src/System/Net/SocketAddressPal.Browser.cs b/src/libraries/Common/src/System/Net/SocketAddressPal.Browser.cs new file mode 100644 index 00000000000000..b4d7fdafe1566b --- /dev/null +++ b/src/libraries/Common/src/System/Net/SocketAddressPal.Browser.cs @@ -0,0 +1,72 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Buffers.Binary; +using System.Net.Sockets; + +namespace System.Net +{ + internal static class SocketAddressPal + { + public const int IPv6AddressSize = 28; + public const int IPv4AddressSize = 16; + public const int UdsAddressSize = 110; + public const int MaxAddressSize = 128; + + public static AddressFamily GetAddressFamily(ReadOnlySpan buffer) + { + return (AddressFamily)BinaryPrimitives.ReadUInt16LittleEndian(buffer); + } + + public static void SetAddressFamily(Span buffer, AddressFamily family) + { + if ((int)(family) > ushort.MaxValue) + { + // For legacy values family maps directly to Winsock value. + // Other values will need mapping if/when supported. + throw new PlatformNotSupportedException(); + } + + BinaryPrimitives.WriteUInt16LittleEndian(buffer, (ushort)family); + } + + public static ushort GetPort(ReadOnlySpan buffer) + => BinaryPrimitives.ReadUInt16BigEndian(buffer.Slice(2)); + + public static void SetPort(Span buffer, ushort port) + => BinaryPrimitives.WriteUInt16BigEndian(buffer.Slice(2), port); + + public static uint GetIPv4Address(ReadOnlySpan buffer) + => BinaryPrimitives.ReadUInt32LittleEndian(buffer.Slice(4)); + + public static void GetIPv6Address(ReadOnlySpan buffer, Span address, out uint scope) + { + buffer.Slice(8, address.Length).CopyTo(address); + scope = BinaryPrimitives.ReadUInt32LittleEndian(buffer.Slice(24)); + } + + public static void SetIPv4Address(Span buffer, uint address) + { + BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(4), address); + } + + public static void SetIPv6Address(Span buffer, Span address, uint scope) + { + // No handling for Flow Information + BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(4), 0); + + // Scope serialization + BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(24), scope); + + // Address serialization + address.CopyTo(buffer.Slice(8)); + } + + public static void Clear(Span buffer) + { + AddressFamily family = GetAddressFamily(buffer); + buffer.Clear(); + SetAddressFamily(buffer, family); + } + } +} 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 ee2be350bb7387..cde7d325ba6d7d 100644 --- a/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj +++ b/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj @@ -125,7 +125,8 @@ + Link="Common\System\Net\SocketAddressPal.Unix.cs" + Condition="'$(TargetPlatformIdentifier)' != 'browser'" /> + + + + diff --git a/src/libraries/System.Net.Primitives/tests/PalTests/System.Net.Primitives.Pal.Tests.csproj b/src/libraries/System.Net.Primitives/tests/PalTests/System.Net.Primitives.Pal.Tests.csproj index 1be77d19cb07e5..54f2aa577fffdb 100644 --- a/src/libraries/System.Net.Primitives/tests/PalTests/System.Net.Primitives.Pal.Tests.csproj +++ b/src/libraries/System.Net.Primitives/tests/PalTests/System.Net.Primitives.Pal.Tests.csproj @@ -95,7 +95,8 @@ + Link="Common\System\Net\SocketAddressPal.Unix.cs" + Condition="'$(TargetPlatformIdentifier)' != 'browser'" /> + Link="ProductionCode\Common\Interop\Unix\System.Native\Interop.SocketAddress.cs" + Condition="'$(TargetPlatformIdentifier)' != 'browser'" /> + + + diff --git a/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj b/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj index 2426a84e8a225c..bdb03b5a7b5548 100644 --- a/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj +++ b/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj @@ -1,7 +1,7 @@  - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-unix;$(NetCoreAppCurrent)-osx;$(NetCoreAppCurrent)-ios;$(NetCoreAppCurrent)-tvos;$(NetCoreAppCurrent)-wasi;$(NetCoreAppCurrent) + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-unix;$(NetCoreAppCurrent)-osx;$(NetCoreAppCurrent)-ios;$(NetCoreAppCurrent)-tvos;$(NetCoreAppCurrent)-browser;$(NetCoreAppCurrent)-wasi;$(NetCoreAppCurrent) true @@ -12,12 +12,12 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) - SR.SystemNetSockets_PlatformNotSupported + SR.SystemNetSockets_PlatformNotSupported true $(DefineConstants);SYSTEM_NET_SOCKETS_APPLE_PLATFROM - + diff --git a/src/mono/mono/mini/cfgdump.c b/src/mono/mono/mini/cfgdump.c index 64e0377f45caa8..bbf588b43bc4ec 100644 --- a/src/mono/mono/mini/cfgdump.c +++ b/src/mono/mono/mini/cfgdump.c @@ -13,7 +13,9 @@ #include #include +#ifdef HAVE_SYS_SOCKET_H #include +#endif #include #include #include diff --git a/src/mono/mono/profiler/aot.c b/src/mono/mono/profiler/aot.c index 3fd9128eb6b7d4..0453ddd15a7f18 100644 --- a/src/mono/mono/profiler/aot.c +++ b/src/mono/mono/profiler/aot.c @@ -28,9 +28,10 @@ #include #include #include -#ifndef HOST_WIN32 +#ifdef HAVE_SYS_SOCKET_H #include -#else +#endif +#ifdef HOST_WIN32 #define sleep(t) Sleep((t) * 1000) #endif #include diff --git a/src/mono/mono/profiler/helper.c b/src/mono/mono/profiler/helper.c index 05fc31b6708403..382baf2a6c2967 100644 --- a/src/mono/mono/profiler/helper.c +++ b/src/mono/mono/profiler/helper.c @@ -18,10 +18,10 @@ #include #include -#ifndef HOST_WIN32 +#ifdef HAVE_NETINET_IN_H #include #endif -#ifndef HOST_WIN32 +#ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HOST_WIN32 diff --git a/src/mono/mono/profiler/log.c b/src/mono/mono/profiler/log.c index 24d3834296604f..021c7e2f1421d8 100644 --- a/src/mono/mono/profiler/log.c +++ b/src/mono/mono/profiler/log.c @@ -68,7 +68,7 @@ #ifdef HAVE_SYS_MMAN_H #include #endif -#ifndef HOST_WIN32 +#ifdef HAVE_SYS_SOCKET_H #include #endif #ifndef DISABLE_LOG_PROFILER_GZ diff --git a/src/native/corehost/browserhost/libBrowserHost.footer.js b/src/native/corehost/browserhost/libBrowserHost.footer.js index bf9eb0489485f1..b42073d47ae8f9 100644 --- a/src/native/corehost/browserhost/libBrowserHost.footer.js +++ b/src/native/corehost/browserhost/libBrowserHost.footer.js @@ -66,28 +66,6 @@ function libBrowserHostFactory() { autoAddDeps(mergeBrowserHost, "$BROWSER_HOST"); addToLibrary(mergeBrowserHost); - - function trim() { - return -1; - } - - // TODO-WASM: fix PAL https://github.com/dotnet/runtime/issues/122506 - if (LibraryManager.library.__syscall_pipe) { - LibraryManager.library.__syscall_pipe = trim; - delete LibraryManager.library.__syscall_pipe__deps; - } - if (LibraryManager.library.__syscall_connect) { - LibraryManager.library.__syscall_connect = trim; - delete LibraryManager.library.__syscall_connect__deps; - } - if (LibraryManager.library.__syscall_sendto) { - LibraryManager.library.__syscall_sendto = trim; - delete LibraryManager.library.__syscall_sendto__deps; - } - if (LibraryManager.library.__syscall_socket) { - LibraryManager.library.__syscall_socket = trim; - delete LibraryManager.library.__syscall_socket__deps; - } } libBrowserHostFactory(); diff --git a/src/native/libs/System.Native/CMakeLists.txt b/src/native/libs/System.Native/CMakeLists.txt index 975e7c5d7c2bdf..0b0078492eae5f 100644 --- a/src/native/libs/System.Native/CMakeLists.txt +++ b/src/native/libs/System.Native/CMakeLists.txt @@ -6,12 +6,9 @@ endif () set(NATIVE_SOURCES pal_errno.c - pal_interfaceaddresses.c pal_io.c pal_maphardwaretype.c pal_memory.c - pal_networking.c - pal_networkstatistics.c pal_random.c pal_runtimeinformation.c pal_string.c @@ -24,7 +21,10 @@ set(NATIVE_SOURCES if (NOT CLR_CMAKE_TARGET_BROWSER AND NOT CLR_CMAKE_TARGET_WASI) list (APPEND NATIVE_SOURCES pal_dynamicload.c + pal_interfaceaddresses.c pal_mount.c + pal_networking.c + pal_networkstatistics.c pal_process.c pal_signal.c pal_threading.c @@ -33,7 +33,10 @@ if (NOT CLR_CMAKE_TARGET_BROWSER AND NOT CLR_CMAKE_TARGET_WASI) elseif (CLR_CMAKE_TARGET_BROWSER) list (APPEND NATIVE_SOURCES pal_dynamicload_wasm.c + pal_interfaceaddresses_browser.c pal_mount.c + pal_networking_browser.c + pal_networkstatistics_wasm.c pal_process.c pal_signal_wasm.c pal_threading.c @@ -42,7 +45,10 @@ elseif (CLR_CMAKE_TARGET_BROWSER) else() # WASI list (APPEND NATIVE_SOURCES pal_dynamicload_wasm.c + pal_interfaceaddresses.c pal_mount_wasi.c + pal_networking.c + pal_networkstatistics_wasm.c pal_process_wasi.c pal_signal_wasm.c pal_threading_wasi.c diff --git a/src/native/libs/System.Native/pal_interfaceaddresses_browser.c b/src/native/libs/System.Native/pal_interfaceaddresses_browser.c new file mode 100644 index 00000000000000..825b4808a744d1 --- /dev/null +++ b/src/native/libs/System.Native/pal_interfaceaddresses_browser.c @@ -0,0 +1,48 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Stub implementations of interface address functions for browser target. + +#include "pal_config.h" +#include "pal_interfaceaddresses.h" +#include "pal_utilities.h" + +#include +#include +#include + +int32_t SystemNative_EnumerateInterfaceAddresses( + void* context, IPv4AddressFound onIpv4Found, IPv6AddressFound onIpv6Found, LinkLayerAddressFound onLinkLayerFound) +{ + (void)context; + (void)onIpv4Found; + (void)onIpv6Found; + (void)onLinkLayerFound; + // Return success but don't enumerate any interfaces + return 0; +} + +int32_t SystemNative_GetNetworkInterfaces(int32_t* interfaceCount, NetworkInterfaceInfo** interfaces, int32_t* addressCount, IpAddressInfo** addressList) +{ + if (interfaceCount == NULL || interfaces == NULL || addressCount == NULL || addressList == NULL) + { + errno = EFAULT; + return -1; + } + + // Return empty lists + *interfaceCount = 0; + *interfaces = NULL; + *addressCount = 0; + *addressList = NULL; + return 0; +} + +int32_t SystemNative_EnumerateGatewayAddressesForInterface(void* context, uint32_t interfaceIndex, GatewayAddressFound onGatewayFound) +{ + (void)context; + (void)interfaceIndex; + (void)onGatewayFound; + // Return success but don't enumerate any gateways + return 0; +} diff --git a/src/native/libs/System.Native/pal_networking_browser.c b/src/native/libs/System.Native/pal_networking_browser.c new file mode 100644 index 00000000000000..a31456ac4d951e --- /dev/null +++ b/src/native/libs/System.Native/pal_networking_browser.c @@ -0,0 +1,548 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Stub implementations of networking functions for browser target. + +#include "pal_config.h" +#include "pal_networking.h" +#include "pal_utilities.h" +#include "pal_errno.h" + +#include +#include +#include +#include + +int32_t SystemNative_GetHostEntryForName(const uint8_t* address, int32_t addressFamily, HostEntry* entry) +{ + (void)address; + (void)addressFamily; + (void)entry; + return Error_ENOTSUP; +} + +void SystemNative_FreeHostEntry(HostEntry* entry) +{ + (void)entry; +} + +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) +{ + (void)address; + (void)addressLength; + (void)isIPv6; + (void)host; + (void)hostLength; + (void)service; + (void)serviceLength; + (void)flags; + return Error_ENOTSUP; +} + +int32_t SystemNative_GetDomainName(uint8_t* name, int32_t nameLength) +{ + (void)name; + (void)nameLength; + errno = ENOTSUP; + return -1; +} + +int32_t SystemNative_GetHostName(uint8_t* name, int32_t nameLength) +{ + (void)name; + (void)nameLength; + errno = ENOTSUP; + return -1; +} + +int32_t SystemNative_GetSocketAddressSizes(int32_t* ipv4SocketAddressSize, int32_t* ipv6SocketAddressSize, int32_t* udsSocketAddressSize, int32_t* maxSocketAddressSize) +{ + (void)ipv4SocketAddressSize; + (void)ipv6SocketAddressSize; + (void)udsSocketAddressSize; + (void)maxSocketAddressSize; + return Error_ENOTSUP; +} + +int32_t SystemNative_GetAddressFamily(const uint8_t* socketAddress, int32_t socketAddressLen, int32_t* addressFamily) +{ + (void)socketAddress; + (void)socketAddressLen; + (void)addressFamily; + return Error_ENOTSUP; +} + +int32_t SystemNative_SetAddressFamily(uint8_t* socketAddress, int32_t socketAddressLen, int32_t addressFamily) +{ + (void)socketAddress; + (void)socketAddressLen; + (void)addressFamily; + return Error_ENOTSUP; +} + +int32_t SystemNative_GetPort(const uint8_t* socketAddress, int32_t socketAddressLen, uint16_t* port) +{ + (void)socketAddress; + (void)socketAddressLen; + (void)port; + return Error_ENOTSUP; +} + +int32_t SystemNative_SetPort(uint8_t* socketAddress, int32_t socketAddressLen, uint16_t port) +{ + (void)socketAddress; + (void)socketAddressLen; + (void)port; + return Error_ENOTSUP; +} + +int32_t SystemNative_GetIPv4Address(const uint8_t* socketAddress, int32_t socketAddressLen, uint32_t* address) +{ + (void)socketAddress; + (void)socketAddressLen; + (void)address; + return Error_ENOTSUP; +} + +int32_t SystemNative_SetIPv4Address(uint8_t* socketAddress, int32_t socketAddressLen, uint32_t address) +{ + (void)socketAddress; + (void)socketAddressLen; + (void)address; + return Error_ENOTSUP; +} + +int32_t SystemNative_GetIPv6Address( + const uint8_t* socketAddress, int32_t socketAddressLen, uint8_t* address, int32_t addressLen, uint32_t* scopeId) +{ + (void)socketAddress; + (void)socketAddressLen; + (void)address; + (void)addressLen; + (void)scopeId; + return Error_ENOTSUP; +} + +int32_t SystemNative_SetIPv6Address( + uint8_t* socketAddress, int32_t socketAddressLen, uint8_t* address, int32_t addressLen, uint32_t scopeId) +{ + (void)socketAddress; + (void)socketAddressLen; + (void)address; + (void)addressLen; + (void)scopeId; + return Error_ENOTSUP; +} + +int32_t SystemNative_GetControlMessageBufferSize(int32_t isIPv4, int32_t isIPv6) +{ + (void)isIPv4; + (void)isIPv6; + return 0; +} + +int32_t SystemNative_TryGetIPPacketInformation(MessageHeader* messageHeader, int32_t isIPv4, IPPacketInformation* packetInfo) +{ + (void)messageHeader; + (void)isIPv4; + (void)packetInfo; + return 0; // false +} + +int32_t SystemNative_GetIPv4MulticastOption(intptr_t socket, int32_t multicastOption, IPv4MulticastOption* option) +{ + (void)socket; + (void)multicastOption; + (void)option; + return Error_ENOTSUP; +} + +int32_t SystemNative_SetIPv4MulticastOption(intptr_t socket, int32_t multicastOption, IPv4MulticastOption* option) +{ + (void)socket; + (void)multicastOption; + (void)option; + return Error_ENOTSUP; +} + +int32_t SystemNative_GetIPv6MulticastOption(intptr_t socket, int32_t multicastOption, IPv6MulticastOption* option) +{ + (void)socket; + (void)multicastOption; + (void)option; + return Error_ENOTSUP; +} + +int32_t SystemNative_SetIPv6MulticastOption(intptr_t socket, int32_t multicastOption, IPv6MulticastOption* option) +{ + (void)socket; + (void)multicastOption; + (void)option; + return Error_ENOTSUP; +} + +int32_t SystemNative_GetLingerOption(intptr_t socket, LingerOption* option) +{ + (void)socket; + (void)option; + return Error_ENOTSUP; +} + +int32_t SystemNative_SetLingerOption(intptr_t socket, LingerOption* option) +{ + (void)socket; + (void)option; + return Error_ENOTSUP; +} + +int32_t SystemNative_SetReceiveTimeout(intptr_t socket, int32_t millisecondsTimeout) +{ + (void)socket; + (void)millisecondsTimeout; + return Error_ENOTSUP; +} + +int32_t SystemNative_SetSendTimeout(intptr_t socket, int32_t millisecondsTimeout) +{ + (void)socket; + (void)millisecondsTimeout; + return Error_ENOTSUP; +} + +int32_t SystemNative_Receive(intptr_t socket, void* buffer, int32_t bufferLen, int32_t flags, int32_t* received) +{ + (void)socket; + (void)buffer; + (void)bufferLen; + (void)flags; + (void)received; + return Error_ENOTSUP; +} + +int32_t SystemNative_ReceiveMessage(intptr_t socket, MessageHeader* messageHeader, int32_t flags, int64_t* received) +{ + (void)socket; + (void)messageHeader; + (void)flags; + (void)received; + return Error_ENOTSUP; +} + +int32_t SystemNative_ReceiveSocketError(intptr_t socket, MessageHeader* messageHeader) +{ + (void)socket; + (void)messageHeader; + return Error_ENOTSUP; +} + +int32_t SystemNative_Send(intptr_t socket, void* buffer, int32_t bufferLen, int32_t flags, int32_t* sent) +{ + (void)socket; + (void)buffer; + (void)bufferLen; + (void)flags; + (void)sent; + return Error_ENOTSUP; +} + +int32_t SystemNative_SendMessage(intptr_t socket, MessageHeader* messageHeader, int32_t flags, int64_t* sent) +{ + (void)socket; + (void)messageHeader; + (void)flags; + (void)sent; + return Error_ENOTSUP; +} + +int32_t SystemNative_Accept(intptr_t socket, uint8_t* socketAddress, int32_t* socketAddressLen, intptr_t* acceptedSocket) +{ + (void)socket; + (void)socketAddress; + (void)socketAddressLen; + (void)acceptedSocket; + return Error_ENOTSUP; +} + +int32_t SystemNative_Bind(intptr_t socket, int32_t protocolType, uint8_t* socketAddress, int32_t socketAddressLen) +{ + (void)socket; + (void)protocolType; + (void)socketAddress; + (void)socketAddressLen; + return Error_ENOTSUP; +} + +int32_t SystemNative_Connect(intptr_t socket, uint8_t* socketAddress, int32_t socketAddressLen) +{ + (void)socket; + (void)socketAddress; + (void)socketAddressLen; + return Error_ENOTSUP; +} + +int32_t SystemNative_Connectx(intptr_t socket, uint8_t* socketAddress, int32_t socketAddressLen, uint8_t* data, int32_t dataLen, int32_t tfo, int* sent) +{ + (void)socket; + (void)socketAddress; + (void)socketAddressLen; + (void)data; + (void)dataLen; + (void)tfo; + if (sent != NULL) + { + *sent = 0; + } + return Error_ENOTSUP; +} + +int32_t SystemNative_GetPeerName(intptr_t socket, uint8_t* socketAddress, int32_t* socketAddressLen) +{ + (void)socket; + (void)socketAddress; + (void)socketAddressLen; + return Error_ENOTSUP; +} + +int32_t SystemNative_GetSockName(intptr_t socket, uint8_t* socketAddress, int32_t* socketAddressLen) +{ + (void)socket; + (void)socketAddress; + (void)socketAddressLen; + return Error_ENOTSUP; +} + +int32_t SystemNative_Listen(intptr_t socket, int32_t backlog) +{ + (void)socket; + (void)backlog; + return Error_ENOTSUP; +} + +int32_t SystemNative_Shutdown(intptr_t socket, int32_t socketShutdown) +{ + (void)socket; + (void)socketShutdown; + return Error_ENOTSUP; +} + +int32_t SystemNative_GetSocketErrorOption(intptr_t socket, int32_t* error) +{ + (void)socket; + (void)error; + return Error_ENOTSUP; +} + +int32_t SystemNative_GetSockOpt( + intptr_t socket, int32_t socketOptionLevel, int32_t socketOptionName, uint8_t* optionValue, int32_t* optionLen) +{ + (void)socket; + (void)socketOptionLevel; + (void)socketOptionName; + (void)optionValue; + (void)optionLen; + return Error_ENOTSUP; +} + +int32_t SystemNative_GetRawSockOpt( + intptr_t socket, int32_t socketOptionLevel, int32_t socketOptionName, uint8_t* optionValue, int32_t* optionLen) +{ + (void)socket; + (void)socketOptionLevel; + (void)socketOptionName; + (void)optionValue; + (void)optionLen; + return Error_ENOTSUP; +} + +int32_t SystemNative_SetSockOpt( + intptr_t socket, int32_t socketOptionLevel, int32_t socketOptionName, uint8_t* optionValue, int32_t optionLen) +{ + (void)socket; + (void)socketOptionLevel; + (void)socketOptionName; + (void)optionValue; + (void)optionLen; + return Error_ENOTSUP; +} + +int32_t SystemNative_SetRawSockOpt( + intptr_t socket, int32_t socketOptionLevel, int32_t socketOptionName, uint8_t* optionValue, int32_t optionLen) +{ + (void)socket; + (void)socketOptionLevel; + (void)socketOptionName; + (void)optionValue; + (void)optionLen; + return Error_ENOTSUP; +} + +int32_t SystemNative_Socket(int32_t addressFamily, int32_t socketType, int32_t protocolType, intptr_t* createdSocket) +{ + (void)addressFamily; + (void)socketType; + (void)protocolType; + (void)createdSocket; + return Error_ENOTSUP; +} + +int32_t SystemNative_GetSocketType(intptr_t socket, int32_t* addressFamily, int32_t* socketType, int32_t* protocolType, int32_t* isListening) +{ + (void)socket; + (void)addressFamily; + (void)socketType; + (void)protocolType; + (void)isListening; + return Error_ENOTSUP; +} + +int32_t SystemNative_GetAtOutOfBandMark(intptr_t socket, int32_t* available) +{ + (void)socket; + (void)available; + return Error_ENOTSUP; +} + +int32_t SystemNative_GetBytesAvailable(intptr_t socket, int32_t* available) +{ + (void)socket; + (void)available; + return Error_ENOTSUP; +} + +int32_t SystemNative_GetWasiSocketDescriptor(intptr_t socket, void** entry) +{ + (void)socket; + (void)entry; + return Error_ENOTSUP; +} + +int32_t SystemNative_CreateSocketEventPort(intptr_t* port) +{ + (void)port; + return Error_ENOTSUP; +} + +int32_t SystemNative_CloseSocketEventPort(intptr_t port) +{ + (void)port; + return Error_ENOTSUP; +} + +int32_t SystemNative_CreateSocketEventBuffer(int32_t count, SocketEvent** buffer) +{ + (void)count; + (void)buffer; + return Error_ENOTSUP; +} + +int32_t SystemNative_FreeSocketEventBuffer(SocketEvent* buffer) +{ + (void)buffer; + return Error_ENOTSUP; +} + +int32_t SystemNative_TryChangeSocketEventRegistration( + intptr_t port, intptr_t socket, int32_t currentEvents, int32_t newEvents, uintptr_t data) +{ + (void)port; + (void)socket; + (void)currentEvents; + (void)newEvents; + (void)data; + return Error_ENOTSUP; +} + +int32_t SystemNative_WaitForSocketEvents(intptr_t port, SocketEvent* buffer, int32_t* count) +{ + (void)port; + (void)buffer; + (void)count; + return Error_ENOTSUP; +} + +int32_t SystemNative_PlatformSupportsDualModeIPv4PacketInfo(void) +{ + return 0; // false +} + +void SystemNative_GetDomainSocketSizes(int32_t* pathOffset, int32_t* pathSize, int32_t* addressSize) +{ + if (pathOffset != NULL) *pathOffset = 0; + if (pathSize != NULL) *pathSize = 0; + if (addressSize != NULL) *addressSize = 0; +} + +int32_t SystemNative_GetMaximumAddressSize(void) +{ + return 128; +} + +int32_t SystemNative_SendFile(intptr_t out_fd, intptr_t in_fd, int64_t offset, int64_t count, int64_t* sent) +{ + (void)out_fd; + (void)in_fd; + (void)offset; + (void)count; + (void)sent; + return Error_ENOTSUP; +} + +int32_t SystemNative_Disconnect(intptr_t socket) +{ + (void)socket; + return Error_ENOTSUP; +} + +uint32_t SystemNative_InterfaceNameToIndex(char* interfaceName) +{ + (void)interfaceName; + return 0; +} + +int32_t SystemNative_Select(int* readFds, int readFdsCount, int* writeFds, int writeFdsCount, int* errorFds, int errorFdsCount, int32_t microseconds, int32_t maxFd, int* triggered) +{ + (void)readFds; + (void)readFdsCount; + (void)writeFds; + (void)writeFdsCount; + (void)errorFds; + (void)errorFdsCount; + (void)microseconds; + (void)maxFd; + (void)triggered; + return Error_ENOTSUP; +} + +// To silence linker when linking with -nostdlib and dependency from libc/syslog +int socket(int domain, int type, int protocol) +{ + (void)domain; + (void)type; + (void)protocol; + return -1; +} + +int connect(int fd, const struct sockaddr *addr, socklen_t len) +{ + (void)fd; + (void)addr; + (void)len; + return -1; +} + +ssize_t send(int fd, const void *buf, size_t len, int flags) +{ + (void)fd; + (void)buf; + (void)len; + (void)flags; + return -1; +} + diff --git a/src/native/libs/System.Native/pal_networkstatistics_wasm.c b/src/native/libs/System.Native/pal_networkstatistics_wasm.c new file mode 100644 index 00000000000000..a669948d57af2d --- /dev/null +++ b/src/native/libs/System.Native/pal_networkstatistics_wasm.c @@ -0,0 +1,89 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Stub implementations of network statistics functions for WASM (browser) target. + +#include "pal_config.h" +#include "pal_types.h" +#include "pal_utilities.h" +#include "pal_networkstatistics.h" + +#include +#include + +int32_t SystemNative_GetTcpGlobalStatistics(TcpGlobalStatistics* retStats) +{ + (void)retStats; + errno = ENOTSUP; + return -1; // Not supported +} + +int32_t SystemNative_GetIPv4GlobalStatistics(IPv4GlobalStatistics* retStats) +{ + (void)retStats; + errno = ENOTSUP; + return -1; // Not supported +} + +int32_t SystemNative_GetUdpGlobalStatistics(UdpGlobalStatistics* retStats) +{ + (void)retStats; + errno = ENOTSUP; + return -1; // Not supported +} + +int32_t SystemNative_GetIcmpv4GlobalStatistics(Icmpv4GlobalStatistics* retStats) +{ + (void)retStats; + errno = ENOTSUP; + return -1; // Not supported +} + +int32_t SystemNative_GetIcmpv6GlobalStatistics(Icmpv6GlobalStatistics* retStats) +{ + (void)retStats; + errno = ENOTSUP; + return -1; // Not supported +} + +int32_t SystemNative_GetEstimatedTcpConnectionCount(void) +{ + errno = ENOTSUP; + return -1; +} + +int32_t SystemNative_GetActiveTcpConnectionInfos(NativeTcpConnectionInformation* infos, int32_t* infoCount) +{ + (void)infos; + (void)infoCount; + errno = ENOTSUP; + return -1; +} + +int32_t SystemNative_GetEstimatedUdpListenerCount(void) +{ + errno = ENOTSUP; + return -1; +} + +int32_t SystemNative_GetActiveUdpListeners(IPEndPointInfo* infos, int32_t* infoCount) +{ + (void)infos; + (void)infoCount; + errno = ENOTSUP; + return -1; +} + +int32_t SystemNative_GetNativeIPInterfaceStatistics(char* interfaceName, NativeIPInterfaceStatistics* retStats) +{ + (void)interfaceName; + (void)retStats; + errno = ENOTSUP; + return -1; // Not supported +} + +int32_t SystemNative_GetNumRoutes(void) +{ + errno = ENOTSUP; + return -1; +} From 5b53575754c3ad40af313b80022223b8560a3faf Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Wed, 18 Feb 2026 13:17:30 +0100 Subject: [PATCH 2/3] feedback --- src/native/libs/System.Native/pal_networking_browser.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/native/libs/System.Native/pal_networking_browser.c b/src/native/libs/System.Native/pal_networking_browser.c index a31456ac4d951e..3f1de935f0e5ed 100644 --- a/src/native/libs/System.Native/pal_networking_browser.c +++ b/src/native/libs/System.Native/pal_networking_browser.c @@ -526,6 +526,7 @@ int socket(int domain, int type, int protocol) (void)domain; (void)type; (void)protocol; + errno = ENOTSUP; return -1; } @@ -534,6 +535,7 @@ int connect(int fd, const struct sockaddr *addr, socklen_t len) (void)fd; (void)addr; (void)len; + errno = ENOTSUP; return -1; } @@ -543,6 +545,7 @@ ssize_t send(int fd, const void *buf, size_t len, int flags) (void)buf; (void)len; (void)flags; + errno = ENOTSUP; return -1; } From cfc74a2550a15407564b3b5f0573c1d431a7d1dc Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Wed, 18 Feb 2026 14:59:46 +0100 Subject: [PATCH 3/3] - fix FEATURE_SINGLE_THREADED - add test --- src/coreclr/clrdefinitions.cmake | 3 +++ src/coreclr/pal/src/CMakeLists.txt | 3 +++ .../NativeRebuildTests/FlagsChangeRebuildTest.cs | 11 ++++++++++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/coreclr/clrdefinitions.cmake b/src/coreclr/clrdefinitions.cmake index 2b3137b35641a0..fc8ded624d9607 100644 --- a/src/coreclr/clrdefinitions.cmake +++ b/src/coreclr/clrdefinitions.cmake @@ -100,6 +100,9 @@ endif(FEATURE_EVENTSOURCE_XPLAT) if(NOT CLR_CMAKE_TARGET_NETBSD AND NOT CLR_CMAKE_TARGET_ARCH_WASM) add_definitions(-DFEATURE_HIJACK) endif(NOT CLR_CMAKE_TARGET_NETBSD AND NOT CLR_CMAKE_TARGET_ARCH_WASM) +if(FEATURE_SINGLE_THREADED) + add_definitions(-DFEATURE_SINGLE_THREADED) +endif(FEATURE_SINGLE_THREADED) if (CLR_CMAKE_TARGET_WIN32 AND (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_I386 OR CLR_CMAKE_TARGET_ARCH_ARM64)) add_definitions(-DFEATURE_INTEROP_DEBUGGING) endif (CLR_CMAKE_TARGET_WIN32 AND (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_I386 OR CLR_CMAKE_TARGET_ARCH_ARM64)) diff --git a/src/coreclr/pal/src/CMakeLists.txt b/src/coreclr/pal/src/CMakeLists.txt index 970c9cb7dabef5..43bd3bbab3a37b 100644 --- a/src/coreclr/pal/src/CMakeLists.txt +++ b/src/coreclr/pal/src/CMakeLists.txt @@ -86,6 +86,9 @@ endif(CLR_CMAKE_TARGET_APPLE) if (FEATURE_ENABLE_NO_ADDRESS_SPACE_RANDOMIZATION) add_definitions(-DFEATURE_ENABLE_NO_ADDRESS_SPACE_RANDOMIZATION) endif(FEATURE_ENABLE_NO_ADDRESS_SPACE_RANDOMIZATION) +if(FEATURE_SINGLE_THREADED) + add_definitions(-DFEATURE_SINGLE_THREADED) +endif(FEATURE_SINGLE_THREADED) add_definitions(-DLP64COMPATIBLE) add_definitions(-DCORECLR) add_definitions(-DPIC) diff --git a/src/mono/wasm/Wasm.Build.Tests/NativeRebuildTests/FlagsChangeRebuildTest.cs b/src/mono/wasm/Wasm.Build.Tests/NativeRebuildTests/FlagsChangeRebuildTest.cs index 4d34b075949dc1..0c16c575dbb212 100644 --- a/src/mono/wasm/Wasm.Build.Tests/NativeRebuildTests/FlagsChangeRebuildTest.cs +++ b/src/mono/wasm/Wasm.Build.Tests/NativeRebuildTests/FlagsChangeRebuildTest.cs @@ -48,7 +48,16 @@ public async Task ExtraEmccFlagsSetButNoRealChange(Configuration config, bool ao var newStat = StatFilesAfterRebuild(pathsDict); CompareStat(originalStat, newStat, pathsDict); - + + // check that emscripten emulator for sockets and pipe was trimmed from dotnet.native.js + if (config == Configuration.Release) + { + Assert.True(newStat.TryGetValue("dotnet.native.js", out var dotnetNativeJsStat)); + var dotnetNativeJs = File.ReadAllText(dotnetNativeJsStat.FullPath); + Assert.DoesNotContain("var SOCKFS", dotnetNativeJs); + Assert.DoesNotContain("var PIPEFS", dotnetNativeJs); + } + // cflags: pinvoke get's compiled, but doesn't overwrite pinvoke.o // and thus doesn't cause relinking TestUtils.AssertSubstring("pinvoke.c -> pinvoke.o", output, contains: extraCFlags.Length > 0);