From b10922766de8f6237d86026dc3938517b1eb9b3f Mon Sep 17 00:00:00 2001 From: EgorBo Date: Fri, 20 Mar 2020 01:15:57 +0300 Subject: [PATCH 01/13] Add iOS version of System.Console --- .../System.Console/src/System.Console.csproj | 8 +- .../src/System/ConsolePal.iOS.cs | 201 ++++++++++++++++++ src/mono/netcore/sample/iOS/Makefile | 37 ++-- src/mono/netcore/sample/iOS/Program.cs | 3 +- src/mono/netcore/sample/iOS/runtime.m | 13 ++ 5 files changed, 237 insertions(+), 25 deletions(-) create mode 100644 src/libraries/System.Console/src/System/ConsolePal.iOS.cs diff --git a/src/libraries/System.Console/src/System.Console.csproj b/src/libraries/System.Console/src/System.Console.csproj index c24b37c5cfb1d..eeb466273813c 100644 --- a/src/libraries/System.Console/src/System.Console.csproj +++ b/src/libraries/System.Console/src/System.Console.csproj @@ -3,7 +3,7 @@ System.Console System.Console true - $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix + $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-iOS enable @@ -21,6 +21,10 @@ Common\System\Text\ConsoleEncoding.cs + + + + @@ -164,7 +168,7 @@ - + diff --git a/src/libraries/System.Console/src/System/ConsolePal.iOS.cs b/src/libraries/System.Console/src/System/ConsolePal.iOS.cs new file mode 100644 index 0000000000000..290c0b9c049b8 --- /dev/null +++ b/src/libraries/System.Console/src/System/ConsolePal.iOS.cs @@ -0,0 +1,201 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.IO; +using System.Text; +using System.Runtime.InteropServices; + +namespace System +{ + internal class NSLogStream : Stream + { + private bool _error; + + public NSLogStream(bool error) + { + _error = error; + } + + public override void Flush() { } + + public override int Read(byte[] buffer, int offset, int count) => throw new PlatformNotSupportedException(); + + public override long Seek(long offset, SeekOrigin origin) => throw new PlatformNotSupportedException(); + + public override void SetLength(long value) => throw new PlatformNotSupportedException(); + + // call NSLog + [DllImport("__Internal")] + private static unsafe extern void mono_log(byte* str, int count, bool isError); + + public override unsafe void Write(byte[] buffer, int offset, int count) + { + fixed (byte* ptr = buffer) + { + mono_log(ptr + offset, count, _error); + } + } + + public override bool CanRead => false; + + public override bool CanSeek => false; + + public override bool CanWrite => true; + + public override long Length => throw new PlatformNotSupportedException(); + + public override long Position + { + get => throw new PlatformNotSupportedException(); + set => throw new PlatformNotSupportedException(); + } + } + + // Provides Windows-based support for System.Console. + internal static class ConsolePal + { + public static Stream OpenStandardInput() => throw new PlatformNotSupportedException(); + + public static Stream OpenStandardOutput() => new NSLogStream(false); + + public static Stream OpenStandardError() => new NSLogStream(true); + + public static Encoding InputEncoding => throw new PlatformNotSupportedException(); + + public static void SetConsoleInputEncoding(Encoding enc) => throw new PlatformNotSupportedException(); + + public static Encoding OutputEncoding => Encoding.UTF8; + + public static void SetConsoleOutputEncoding(Encoding enc) => throw new PlatformNotSupportedException(); + + /// Gets whether Console.In is targeting a terminal display. + public static bool IsInputRedirectedCore() => throw new PlatformNotSupportedException(); + + /// Gets whether Console.Out is targeting a terminal display. + public static bool IsOutputRedirectedCore() => throw new PlatformNotSupportedException(); + + /// Gets whether Console.In is targeting a terminal display. + public static bool IsErrorRedirectedCore() => throw new PlatformNotSupportedException(); + + internal static TextReader GetOrCreateReader() => throw new PlatformNotSupportedException(); + + public static bool NumberLock => throw new PlatformNotSupportedException(); + + public static bool CapsLock => throw new PlatformNotSupportedException(); + + public static bool KeyAvailable => throw new PlatformNotSupportedException(); + + public static ConsoleKeyInfo ReadKey(bool intercept) => throw new PlatformNotSupportedException(); + + public static bool TreatControlCAsInput + { + get => throw new PlatformNotSupportedException(); + set => throw new PlatformNotSupportedException(); + } + + public static ConsoleColor BackgroundColor + { + get => throw new PlatformNotSupportedException(); + set => throw new PlatformNotSupportedException(); + } + + public static ConsoleColor ForegroundColor + { + get => throw new PlatformNotSupportedException(); + set => throw new PlatformNotSupportedException(); + } + + public static void ResetColor() => throw new PlatformNotSupportedException(); + + public static int CursorSize + { + get => throw new PlatformNotSupportedException(); + set => throw new PlatformNotSupportedException(); + } + + public static bool CursorVisible + { + get => throw new PlatformNotSupportedException(); + set => throw new PlatformNotSupportedException(); + } + + public static int CursorLeft => throw new PlatformNotSupportedException(); + + public static int CursorTop => 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 Beep(int frequency, int duration) => 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 Clear() => throw new PlatformNotSupportedException(); + + public static void SetCursorPosition(int left, int top) => throw new PlatformNotSupportedException(); + + public static int BufferWidth + { + get => throw new PlatformNotSupportedException(); + set => throw new PlatformNotSupportedException(); + } + + public static int BufferHeight + { + get => throw new PlatformNotSupportedException(); + set => throw new PlatformNotSupportedException(); + } + + public static void SetBufferSize(int width, int height) => throw new PlatformNotSupportedException(); + + public static int LargestWindowWidth => throw new PlatformNotSupportedException(); + + public static int LargestWindowHeight => throw new PlatformNotSupportedException(); + + public static int WindowLeft + { + get => throw new PlatformNotSupportedException(); + set => throw new PlatformNotSupportedException(); + } + + public static int WindowTop + { + get => throw new PlatformNotSupportedException(); + set => throw new PlatformNotSupportedException(); + } + + public static int WindowWidth + { + get => throw new PlatformNotSupportedException(); + set => throw new PlatformNotSupportedException(); + } + + public static int WindowHeight + { + get => throw new PlatformNotSupportedException(); + set => throw new PlatformNotSupportedException(); + } + + public static void SetWindowPosition(int left, int top) => throw new PlatformNotSupportedException(); + + public static void SetWindowSize(int width, int height) => throw new PlatformNotSupportedException(); + + internal sealed class ControlCHandlerRegistrar + { + internal ControlCHandlerRegistrar() => throw new PlatformNotSupportedException(); + + internal void Register() => throw new PlatformNotSupportedException(); + + internal void Unregister() => throw new PlatformNotSupportedException(); + } + } +} \ No newline at end of file diff --git a/src/mono/netcore/sample/iOS/Makefile b/src/mono/netcore/sample/iOS/Makefile index f2cbc1b36edc4..f5f4930045977 100644 --- a/src/mono/netcore/sample/iOS/Makefile +++ b/src/mono/netcore/sample/iOS/Makefile @@ -9,22 +9,25 @@ ARTIFACTS_MONO=$(ARTIFACTS_BIN)/mono/iOS.$(MONO_ARCH).$(MONO_CONFIG) DOTNET := $(shell cd ../../ && bash init-tools.sh | tail -1) SYSROOT := $(shell xcrun --sdk iphoneos --show-sdk-path) +BCL_LIBS = \ + System.Runtime.dll \ + System.Runtime.Extensions.dll \ + System.Collections.dll \ + System.Core.dll \ + System.Threading.dll \ + System.Threading.Tasks.dll \ + System.Linq.dll \ + System.Memory.dll \ + System.Runtime.InteropServices.dll \ + System.Text.Encoding.Extensions.dll \ + Microsoft.Win32.Primitives.dll \ + System.Console.dll + # once a new library is added here it should also be # added in mono_ios_register_modules() (runtime.m) all: prepare make aot-lib-${MONO_ARCH} LIB=$(ARTIFACTS_MONO)/System.Private.CoreLib.dll - make aot-lib-${MONO_ARCH} LIB=$(ARTIFACTS_BCL)/System.Runtime.dll - make aot-lib-${MONO_ARCH} LIB=$(ARTIFACTS_BCL)/System.Runtime.Extensions.dll - make aot-lib-${MONO_ARCH} LIB=$(ARTIFACTS_BCL)/System.Collections.dll - make aot-lib-${MONO_ARCH} LIB=$(ARTIFACTS_BCL)/System.Core.dll - make aot-lib-${MONO_ARCH} LIB=$(ARTIFACTS_BCL)/System.Threading.dll - make aot-lib-${MONO_ARCH} LIB=$(ARTIFACTS_BCL)/System.Threading.Tasks.dll - make aot-lib-${MONO_ARCH} LIB=$(ARTIFACTS_BCL)/System.Linq.dll - make aot-lib-${MONO_ARCH} LIB=$(ARTIFACTS_BCL)/System.Memory.dll - make aot-lib-${MONO_ARCH} LIB=$(ARTIFACTS_BCL)/System.Runtime.InteropServices.dll - make aot-lib-${MONO_ARCH} LIB=$(ARTIFACTS_BCL)/System.Text.Encoding.Extensions.dll - make aot-lib-${MONO_ARCH} LIB=$(ARTIFACTS_BCL)/Microsoft.Win32.Primitives.dll - make aot-lib-${MONO_ARCH} LIB=$(ARTIFACTS_BCL)/System.Console.dll + for lib in $(BCL_LIBS); do make aot-lib-${MONO_ARCH} LIB=$(ARTIFACTS_BCL)/$$lib; done make Program.dll.o # recompile Program.cs AOT @@ -34,15 +37,7 @@ Program.dll.o: bin/Program.dll Makefile # we need to copy some BCL libs to ARTIFACTS_MONO # to be able to aot other bcl libs prepare: - cp $(ARTIFACTS_BCL)/System.Memory.dll $(ARTIFACTS_MONO) - cp $(ARTIFACTS_BCL)/System.Collections.dll $(ARTIFACTS_MONO) - cp $(ARTIFACTS_BCL)/System.Threading.dll $(ARTIFACTS_MONO) - cp $(ARTIFACTS_BCL)/System.Threading.Thread.dll $(ARTIFACTS_MONO) - cp $(ARTIFACTS_BCL)/System.Runtime.dll $(ARTIFACTS_MONO) - cp $(ARTIFACTS_BCL)/System.Runtime.InteropServices.dll $(ARTIFACTS_MONO) - cp $(ARTIFACTS_BCL)/System.Text.Encoding.Extensions.dll $(ARTIFACTS_MONO) - cp $(ARTIFACTS_BCL)/Microsoft.Win32.Primitives.dll $(ARTIFACTS_MONO) - cp $(ARTIFACTS_BCL)/System.Console.dll $(ARTIFACTS_MONO) + for lib in $(BCL_LIBS); do cp $(ARTIFACTS_BCL)/$$lib $(ARTIFACTS_MONO); done bin/Program.dll: Program.cs $(DOTNET) build -c Debug Program.csproj diff --git a/src/mono/netcore/sample/iOS/Program.cs b/src/mono/netcore/sample/iOS/Program.cs index 6e3571df6f1d0..c1f99af192632 100644 --- a/src/mono/netcore/sample/iOS/Program.cs +++ b/src/mono/netcore/sample/iOS/Program.cs @@ -25,7 +25,7 @@ public static class Program // Called by native code, see main.m [MonoPInvokeCallback(typeof(Action))] - private static async void OnButtonClick() + private static void OnButtonClick() { ios_set_text("OnButtonClick! #" + counter++); } @@ -44,7 +44,6 @@ public static async Task Main(string[] args) await Task.Delay(100); } - // TODO: https://github.com/dotnet/runtime/issues/33667 Console.WriteLine("Done!"); } } \ No newline at end of file diff --git a/src/mono/netcore/sample/iOS/runtime.m b/src/mono/netcore/sample/iOS/runtime.m index a83f7589ad659..f33e5a5e90735 100644 --- a/src/mono/netcore/sample/iOS/runtime.m +++ b/src/mono/netcore/sample/iOS/runtime.m @@ -247,6 +247,8 @@ void mono_ios_setup_execution_mode (void) { // for now, only Invariant Mode is supported (FIXME: integrate ICU) setenv ("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT", "1", TRUE); + //setenv ("MONO_LOG_LEVEL", "debug", TRUE); + //setenv ("MONO_LOG_MASK", "all", TRUE); stdout_log = os_log_create ("net.dot.mono", "stdout"); @@ -293,3 +295,14 @@ void mono_ios_setup_execution_mode (void) os_log_info (OS_LOG_DEFAULT, "Exit code: %d.", res); } +// icalls for BCL: + +// NSLogStream.mono_log (ConsolePal.iOS.cs) +void mono_log(char* str, int len, bool is_error) +{ + NSString *msg = [NSString stringWithUTF8String:(char *)str]; + if (is_error) + os_log_error (stdout_log, "%{public}@", msg); + else + os_log_info (stdout_log, "%{public}@", msg); +} From 9c8abf777894ffe8d5f59aba8476bd22059d9324 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Fri, 20 Mar 2020 15:26:25 +0300 Subject: [PATCH 02/13] Move impl to System.Native --- .../Interop/iOS/System.Native/Interop.Log.cs | 15 +++++ .../Native/Unix/System.Native/CMakeLists.txt | 10 ++++ .../Native/Unix/System.Native/ios/pal_sys.h | 11 ++++ .../Native/Unix/System.Native/ios/pal_sys.m | 57 +++++++++++++++++++ .../System.Console/src/System.Console.csproj | 6 ++ .../src/System/ConsolePal.iOS.cs | 41 +++++-------- 6 files changed, 113 insertions(+), 27 deletions(-) create mode 100644 src/libraries/Common/src/Interop/iOS/System.Native/Interop.Log.cs create mode 100644 src/libraries/Native/Unix/System.Native/ios/pal_sys.h create mode 100644 src/libraries/Native/Unix/System.Native/ios/pal_sys.m diff --git a/src/libraries/Common/src/Interop/iOS/System.Native/Interop.Log.cs b/src/libraries/Common/src/Interop/iOS/System.Native/Interop.Log.cs new file mode 100644 index 0000000000000..5fb87fcf34ef0 --- /dev/null +++ b/src/libraries/Common/src/Interop/iOS/System.Native/Interop.Log.cs @@ -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. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Sys + { + [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_Log")] + internal static extern unsafe bool Log(IntPtr buffer, int count); + } +} diff --git a/src/libraries/Native/Unix/System.Native/CMakeLists.txt b/src/libraries/Native/Unix/System.Native/CMakeLists.txt index e491a59ae97aa..2a925580ea3b2 100644 --- a/src/libraries/Native/Unix/System.Native/CMakeLists.txt +++ b/src/libraries/Native/Unix/System.Native/CMakeLists.txt @@ -23,6 +23,12 @@ set(NATIVE_SOURCES pal_sysctl.c ) +if (CLR_CMAKE_TARGET_IOS) + set(NATIVE_SOURCES ${NATIVE_SOURCES} ios/pal_sys.m) +else () + set(NATIVE_SOURCES ${NATIVE_SOURCES} pal_console.c) +endif () + if (CLR_CMAKE_TARGET_LINUX) set(NATIVE_SOURCES ${NATIVE_SOURCES} pal_networkchange.c) @@ -62,6 +68,10 @@ add_library(System.Native-Static ${NATIVE_SOURCES} ) +if (CLR_CMAKE_TARGET_IOS) + target_link_libraries(System.Native "-framework Foundation") +endif () + set_target_properties(System.Native-Static PROPERTIES OUTPUT_NAME System.Native CLEAN_DIRECT_OUTPUT 1) install (TARGETS System.Native-Static DESTINATION .) diff --git a/src/libraries/Native/Unix/System.Native/ios/pal_sys.h b/src/libraries/Native/Unix/System.Native/ios/pal_sys.h new file mode 100644 index 0000000000000..1934d67820442 --- /dev/null +++ b/src/libraries/Native/Unix/System.Native/ios/pal_sys.h @@ -0,0 +1,11 @@ + +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#pragma once + +#include "pal_compiler.h" +#include "pal_types.h" + +PALEXPORT void SystemNative_Log(uint8_t* buffer, int32_t length); \ No newline at end of file diff --git a/src/libraries/Native/Unix/System.Native/ios/pal_sys.m b/src/libraries/Native/Unix/System.Native/ios/pal_sys.m new file mode 100644 index 0000000000000..196929cacec8d --- /dev/null +++ b/src/libraries/Native/Unix/System.Native/ios/pal_sys.m @@ -0,0 +1,57 @@ + +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#include "pal_sys.h" +#import + +void SystemNative_Log (uint8_t* buffer, int32_t length) +{ + // COOP: no managed memory access: any mode. + NSString *msg = [[NSString alloc] initWithBytes: buffer length: length encoding: NSUTF16LittleEndianStringEncoding]; + +// TODO: TARGET_OS_WATCH is not supported yet +#if TARGET_OS_WATCH && defined (__arm__) + const char* utf8 = [msg UTF8String]; + size_t len = strlen (utf8); + fwrite (utf8, 1, len, stdout); + if (len == 0 || utf8 [len - 1] != '\n') + { + fwrite ("\n", 1, 1, stdout); + } + fflush (stdout); +#else + if (length > 4096) + { + // Write in chunks of max 4096 characters; older versions of iOS seems to have a bug where NSLog may hang with long strings (!). + // https://github.com/xamarin/maccore/issues/1014 + const char* utf8 = [msg UTF8String]; + size_t len = strlen (utf8); + const size_t max_size = 4096; + while (len > 0) + { + size_t chunk_size = len > max_size ? max_size : len; + + // Try to not break in the middle of a line, by looking backwards for a newline + while (chunk_size > 0 && utf8 [chunk_size] != 0 && utf8 [chunk_size] != '\n') + { + chunk_size--; + } + if (chunk_size == 0) + { + // No newline found, break in the middle. + chunk_size = len > max_size ? max_size : len; + } + NSLog (@"%.*s", (int) chunk_size, utf8); + len -= chunk_size; + utf8 += chunk_size; + } + } + else + { + NSLog (@"%@", msg); + } +#endif + [msg release]; +} \ No newline at end of file diff --git a/src/libraries/System.Console/src/System.Console.csproj b/src/libraries/System.Console/src/System.Console.csproj index eeb466273813c..17283bae21ab9 100644 --- a/src/libraries/System.Console/src/System.Console.csproj +++ b/src/libraries/System.Console/src/System.Console.csproj @@ -24,6 +24,12 @@ + + Common\Interop\iOS\Interop.iOS.cs + + + Common\Interop\Unix\Interop.Libraries.cs + diff --git a/src/libraries/System.Console/src/System/ConsolePal.iOS.cs b/src/libraries/System.Console/src/System/ConsolePal.iOS.cs index 290c0b9c049b8..3d38190ddfae3 100644 --- a/src/libraries/System.Console/src/System/ConsolePal.iOS.cs +++ b/src/libraries/System.Console/src/System/ConsolePal.iOS.cs @@ -4,36 +4,27 @@ using System.IO; using System.Text; -using System.Runtime.InteropServices; namespace System { internal class NSLogStream : Stream { - private bool _error; - - public NSLogStream(bool error) - { - _error = error; - } - public override void Flush() { } - public override int Read(byte[] buffer, int offset, int count) => throw new PlatformNotSupportedException(); + public override int Read(byte[] buffer, int offset, int count) => throw new NotSupportedException(); - public override long Seek(long offset, SeekOrigin origin) => throw new PlatformNotSupportedException(); + public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException(); - public override void SetLength(long value) => throw new PlatformNotSupportedException(); - - // call NSLog - [DllImport("__Internal")] - private static unsafe extern void mono_log(byte* str, int count, bool isError); + public override void SetLength(long value) => throw new NotSupportedException(); public override unsafe void Write(byte[] buffer, int offset, int count) { - fixed (byte* ptr = buffer) + if (count > 0 && buffer.Length >= offset + count) { - mono_log(ptr + offset, count, _error); + fixed (byte* ptr = buffer) + { + Interop.Sys.Log((IntPtr)(ptr + offset), count); + } } } @@ -43,39 +34,35 @@ public override unsafe void Write(byte[] buffer, int offset, int count) public override bool CanWrite => true; - public override long Length => throw new PlatformNotSupportedException(); + public override long Length => throw new NotSupportedException(); public override long Position { - get => throw new PlatformNotSupportedException(); - set => throw new PlatformNotSupportedException(); + get => throw new NotSupportedException(); + set => throw new NotSupportedException(); } } - // Provides Windows-based support for System.Console. internal static class ConsolePal { public static Stream OpenStandardInput() => throw new PlatformNotSupportedException(); - public static Stream OpenStandardOutput() => new NSLogStream(false); + public static Stream OpenStandardOutput() => new NSLogStream(); - public static Stream OpenStandardError() => new NSLogStream(true); + public static Stream OpenStandardError() => new NSLogStream(); public static Encoding InputEncoding => throw new PlatformNotSupportedException(); public static void SetConsoleInputEncoding(Encoding enc) => throw new PlatformNotSupportedException(); - public static Encoding OutputEncoding => Encoding.UTF8; + public static Encoding OutputEncoding => Encoding.Unicode; public static void SetConsoleOutputEncoding(Encoding enc) => throw new PlatformNotSupportedException(); - /// Gets whether Console.In is targeting a terminal display. public static bool IsInputRedirectedCore() => throw new PlatformNotSupportedException(); - /// Gets whether Console.Out is targeting a terminal display. public static bool IsOutputRedirectedCore() => throw new PlatformNotSupportedException(); - /// Gets whether Console.In is targeting a terminal display. public static bool IsErrorRedirectedCore() => throw new PlatformNotSupportedException(); internal static TextReader GetOrCreateReader() => throw new PlatformNotSupportedException(); From e9947ad9409df4de55df93a077722cf14a549c42 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Fri, 20 Mar 2020 15:55:22 +0300 Subject: [PATCH 03/13] Address feedback --- .../src/Interop/iOS/System.Native/Interop.Log.cs | 2 +- .../Native/Unix/System.Native/ios/pal_sys.m | 13 ------------- .../System.Console/src/System/ConsolePal.iOS.cs | 2 +- 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/src/libraries/Common/src/Interop/iOS/System.Native/Interop.Log.cs b/src/libraries/Common/src/Interop/iOS/System.Native/Interop.Log.cs index 5fb87fcf34ef0..2a2637190d5d8 100644 --- a/src/libraries/Common/src/Interop/iOS/System.Native/Interop.Log.cs +++ b/src/libraries/Common/src/Interop/iOS/System.Native/Interop.Log.cs @@ -10,6 +10,6 @@ internal static partial class Interop internal static partial class Sys { [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_Log")] - internal static extern unsafe bool Log(IntPtr buffer, int count); + internal static extern bool Log(IntPtr buffer, int count); } } diff --git a/src/libraries/Native/Unix/System.Native/ios/pal_sys.m b/src/libraries/Native/Unix/System.Native/ios/pal_sys.m index 196929cacec8d..2ab1df034189c 100644 --- a/src/libraries/Native/Unix/System.Native/ios/pal_sys.m +++ b/src/libraries/Native/Unix/System.Native/ios/pal_sys.m @@ -10,18 +10,6 @@ void SystemNative_Log (uint8_t* buffer, int32_t length) { // COOP: no managed memory access: any mode. NSString *msg = [[NSString alloc] initWithBytes: buffer length: length encoding: NSUTF16LittleEndianStringEncoding]; - -// TODO: TARGET_OS_WATCH is not supported yet -#if TARGET_OS_WATCH && defined (__arm__) - const char* utf8 = [msg UTF8String]; - size_t len = strlen (utf8); - fwrite (utf8, 1, len, stdout); - if (len == 0 || utf8 [len - 1] != '\n') - { - fwrite ("\n", 1, 1, stdout); - } - fflush (stdout); -#else if (length > 4096) { // Write in chunks of max 4096 characters; older versions of iOS seems to have a bug where NSLog may hang with long strings (!). @@ -52,6 +40,5 @@ void SystemNative_Log (uint8_t* buffer, int32_t length) { NSLog (@"%@", msg); } -#endif [msg release]; } \ No newline at end of file diff --git a/src/libraries/System.Console/src/System/ConsolePal.iOS.cs b/src/libraries/System.Console/src/System/ConsolePal.iOS.cs index 3d38190ddfae3..5084532e6ebc1 100644 --- a/src/libraries/System.Console/src/System/ConsolePal.iOS.cs +++ b/src/libraries/System.Console/src/System/ConsolePal.iOS.cs @@ -7,7 +7,7 @@ namespace System { - internal class NSLogStream : Stream + internal sealed class NSLogStream : Stream { public override void Flush() { } From 770e45cd64422855b2e57728b1b9e7215961fc65 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Fri, 20 Mar 2020 15:58:20 +0300 Subject: [PATCH 04/13] Address feedback --- .../src/Interop/{iOS => OSX}/System.Native/Interop.Log.cs | 0 src/libraries/System.Console/src/System.Console.csproj | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/libraries/Common/src/Interop/{iOS => OSX}/System.Native/Interop.Log.cs (100%) diff --git a/src/libraries/Common/src/Interop/iOS/System.Native/Interop.Log.cs b/src/libraries/Common/src/Interop/OSX/System.Native/Interop.Log.cs similarity index 100% rename from src/libraries/Common/src/Interop/iOS/System.Native/Interop.Log.cs rename to src/libraries/Common/src/Interop/OSX/System.Native/Interop.Log.cs diff --git a/src/libraries/System.Console/src/System.Console.csproj b/src/libraries/System.Console/src/System.Console.csproj index 17283bae21ab9..c1c6a05fc6820 100644 --- a/src/libraries/System.Console/src/System.Console.csproj +++ b/src/libraries/System.Console/src/System.Console.csproj @@ -24,8 +24,8 @@ - - Common\Interop\iOS\Interop.iOS.cs + + Common\Interop\OSX\Interop.Log.cs Common\Interop\Unix\Interop.Libraries.cs From 3072234c71d4e1572e308cb1a2ab3247499d5726 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Fri, 20 Mar 2020 16:00:26 +0300 Subject: [PATCH 05/13] Update runtime.m --- src/mono/netcore/sample/iOS/runtime.m | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/mono/netcore/sample/iOS/runtime.m b/src/mono/netcore/sample/iOS/runtime.m index f33e5a5e90735..05f4dd2c488c9 100644 --- a/src/mono/netcore/sample/iOS/runtime.m +++ b/src/mono/netcore/sample/iOS/runtime.m @@ -247,8 +247,10 @@ void mono_ios_setup_execution_mode (void) { // for now, only Invariant Mode is supported (FIXME: integrate ICU) setenv ("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT", "1", TRUE); - //setenv ("MONO_LOG_LEVEL", "debug", TRUE); - //setenv ("MONO_LOG_MASK", "all", TRUE); + // uncomment for debug output: + // + // setenv ("MONO_LOG_LEVEL", "debug", TRUE); + // setenv ("MONO_LOG_MASK", "all", TRUE); stdout_log = os_log_create ("net.dot.mono", "stdout"); @@ -294,15 +296,3 @@ void mono_ios_setup_execution_mode (void) // Print this so apps parsing logs can detect when we exited os_log_info (OS_LOG_DEFAULT, "Exit code: %d.", res); } - -// icalls for BCL: - -// NSLogStream.mono_log (ConsolePal.iOS.cs) -void mono_log(char* str, int len, bool is_error) -{ - NSString *msg = [NSString stringWithUTF8String:(char *)str]; - if (is_error) - os_log_error (stdout_log, "%{public}@", msg); - else - os_log_info (stdout_log, "%{public}@", msg); -} From beca65bef03c7c952f8fc19f97d784e486066ab3 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Fri, 20 Mar 2020 16:53:52 +0300 Subject: [PATCH 06/13] Address feedback --- src/libraries/Native/Unix/System.Native/CMakeLists.txt | 3 +-- .../Native/Unix/System.Native/{ios/pal_sys.h => pal_log.h} | 1 - .../Native/Unix/System.Native/{ios/pal_sys.m => pal_log.m} | 1 - src/libraries/System.Console/src/System.Console.csproj | 2 +- src/libraries/System.Console/src/System/ConsolePal.iOS.cs | 2 +- 5 files changed, 3 insertions(+), 6 deletions(-) rename src/libraries/Native/Unix/System.Native/{ios/pal_sys.h => pal_log.h} (99%) rename src/libraries/Native/Unix/System.Native/{ios/pal_sys.m => pal_log.m} (99%) diff --git a/src/libraries/Native/Unix/System.Native/CMakeLists.txt b/src/libraries/Native/Unix/System.Native/CMakeLists.txt index 2a925580ea3b2..7bf8031bcb616 100644 --- a/src/libraries/Native/Unix/System.Native/CMakeLists.txt +++ b/src/libraries/Native/Unix/System.Native/CMakeLists.txt @@ -1,7 +1,6 @@ project(System.Native C) set(NATIVE_SOURCES - pal_console.c pal_errno.c pal_interfaceaddresses.c pal_io.c @@ -24,7 +23,7 @@ set(NATIVE_SOURCES ) if (CLR_CMAKE_TARGET_IOS) - set(NATIVE_SOURCES ${NATIVE_SOURCES} ios/pal_sys.m) + set(NATIVE_SOURCES ${NATIVE_SOURCES} pal_log.m) else () set(NATIVE_SOURCES ${NATIVE_SOURCES} pal_console.c) endif () diff --git a/src/libraries/Native/Unix/System.Native/ios/pal_sys.h b/src/libraries/Native/Unix/System.Native/pal_log.h similarity index 99% rename from src/libraries/Native/Unix/System.Native/ios/pal_sys.h rename to src/libraries/Native/Unix/System.Native/pal_log.h index 1934d67820442..0f3858cda83f3 100644 --- a/src/libraries/Native/Unix/System.Native/ios/pal_sys.h +++ b/src/libraries/Native/Unix/System.Native/pal_log.h @@ -1,4 +1,3 @@ - // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. diff --git a/src/libraries/Native/Unix/System.Native/ios/pal_sys.m b/src/libraries/Native/Unix/System.Native/pal_log.m similarity index 99% rename from src/libraries/Native/Unix/System.Native/ios/pal_sys.m rename to src/libraries/Native/Unix/System.Native/pal_log.m index 2ab1df034189c..eac7aab81db37 100644 --- a/src/libraries/Native/Unix/System.Native/ios/pal_sys.m +++ b/src/libraries/Native/Unix/System.Native/pal_log.m @@ -1,4 +1,3 @@ - // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. diff --git a/src/libraries/System.Console/src/System.Console.csproj b/src/libraries/System.Console/src/System.Console.csproj index c1c6a05fc6820..39c094f262172 100644 --- a/src/libraries/System.Console/src/System.Console.csproj +++ b/src/libraries/System.Console/src/System.Console.csproj @@ -174,7 +174,7 @@ - + diff --git a/src/libraries/System.Console/src/System/ConsolePal.iOS.cs b/src/libraries/System.Console/src/System/ConsolePal.iOS.cs index 5084532e6ebc1..398e1a4f269cb 100644 --- a/src/libraries/System.Console/src/System/ConsolePal.iOS.cs +++ b/src/libraries/System.Console/src/System/ConsolePal.iOS.cs @@ -19,7 +19,7 @@ internal sealed class NSLogStream : Stream public override unsafe void Write(byte[] buffer, int offset, int count) { - if (count > 0 && buffer.Length >= offset + count) + if (count > 0 && count <= buffer.Length - offset) { fixed (byte* ptr = buffer) { From bc91e3d3cfb296858ec89989621b9c3bd33fb5ed Mon Sep 17 00:00:00 2001 From: EgorBo Date: Fri, 20 Mar 2020 17:31:42 +0300 Subject: [PATCH 07/13] fix build issue --- src/libraries/Native/Unix/System.Native/pal_log.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Native/Unix/System.Native/pal_log.m b/src/libraries/Native/Unix/System.Native/pal_log.m index eac7aab81db37..7c8968b71371f 100644 --- a/src/libraries/Native/Unix/System.Native/pal_log.m +++ b/src/libraries/Native/Unix/System.Native/pal_log.m @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#include "pal_sys.h" +#include "pal_log.h" #import void SystemNative_Log (uint8_t* buffer, int32_t length) From 87e175703dc37d27a025e626096c0eaf2cf1f779 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Fri, 20 Mar 2020 17:37:24 +0300 Subject: [PATCH 08/13] Add missing symbols --- src/libraries/Native/Unix/System.Native/pal_log.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libraries/Native/Unix/System.Native/pal_log.h b/src/libraries/Native/Unix/System.Native/pal_log.h index 0f3858cda83f3..bf6f680ce375c 100644 --- a/src/libraries/Native/Unix/System.Native/pal_log.h +++ b/src/libraries/Native/Unix/System.Native/pal_log.h @@ -7,4 +7,8 @@ #include "pal_compiler.h" #include "pal_types.h" -PALEXPORT void SystemNative_Log(uint8_t* buffer, int32_t length); \ No newline at end of file +PALEXPORT void SystemNative_Log(uint8_t* buffer, int32_t length); + +// Called by pal_signal.cpp to reinitialize the console on SIGCONT/SIGCHLD. +void ReinitializeTerminal(void) {} +void UninitializeTerminal(void) {} \ No newline at end of file From 172499ce2cee349c109af1db161871cb18e3b193 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Fri, 20 Mar 2020 17:57:10 +0300 Subject: [PATCH 09/13] return false for some APIs --- .../System.Console/src/System/ConsolePal.iOS.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Console/src/System/ConsolePal.iOS.cs b/src/libraries/System.Console/src/System/ConsolePal.iOS.cs index 398e1a4f269cb..0793c2d0d2e11 100644 --- a/src/libraries/System.Console/src/System/ConsolePal.iOS.cs +++ b/src/libraries/System.Console/src/System/ConsolePal.iOS.cs @@ -57,21 +57,22 @@ internal static class ConsolePal public static Encoding OutputEncoding => Encoding.Unicode; + // underlying API expects only utf-16 public static void SetConsoleOutputEncoding(Encoding enc) => throw new PlatformNotSupportedException(); - public static bool IsInputRedirectedCore() => throw new PlatformNotSupportedException(); + public static bool IsInputRedirectedCore() => false; - public static bool IsOutputRedirectedCore() => throw new PlatformNotSupportedException(); + public static bool IsOutputRedirectedCore() => false; - public static bool IsErrorRedirectedCore() => throw new PlatformNotSupportedException(); + public static bool IsErrorRedirectedCore() => false; internal static TextReader GetOrCreateReader() => throw new PlatformNotSupportedException(); - public static bool NumberLock => throw new PlatformNotSupportedException(); + public static bool NumberLock => false; - public static bool CapsLock => throw new PlatformNotSupportedException(); + public static bool CapsLock => false; - public static bool KeyAvailable => throw new PlatformNotSupportedException(); + public static bool KeyAvailable => false; public static ConsoleKeyInfo ReadKey(bool intercept) => throw new PlatformNotSupportedException(); From 1ef7abff2e0e1bd8c392cce88f29b5fe9bf1d13d Mon Sep 17 00:00:00 2001 From: EgorBo Date: Fri, 20 Mar 2020 18:31:11 +0300 Subject: [PATCH 10/13] Address feedback --- .../Common/src/Interop/OSX/System.Native/Interop.Log.cs | 2 +- src/libraries/Native/Unix/System.Native/pal_log.m | 1 - src/libraries/System.Console/src/System/ConsolePal.iOS.cs | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libraries/Common/src/Interop/OSX/System.Native/Interop.Log.cs b/src/libraries/Common/src/Interop/OSX/System.Native/Interop.Log.cs index 2a2637190d5d8..f6674b988d70e 100644 --- a/src/libraries/Common/src/Interop/OSX/System.Native/Interop.Log.cs +++ b/src/libraries/Common/src/Interop/OSX/System.Native/Interop.Log.cs @@ -10,6 +10,6 @@ internal static partial class Interop internal static partial class Sys { [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_Log")] - internal static extern bool Log(IntPtr buffer, int count); + internal static extern unsafe bool Log(byte* buffer, int count); } } diff --git a/src/libraries/Native/Unix/System.Native/pal_log.m b/src/libraries/Native/Unix/System.Native/pal_log.m index 7c8968b71371f..9f70d250c3d60 100644 --- a/src/libraries/Native/Unix/System.Native/pal_log.m +++ b/src/libraries/Native/Unix/System.Native/pal_log.m @@ -7,7 +7,6 @@ void SystemNative_Log (uint8_t* buffer, int32_t length) { - // COOP: no managed memory access: any mode. NSString *msg = [[NSString alloc] initWithBytes: buffer length: length encoding: NSUTF16LittleEndianStringEncoding]; if (length > 4096) { diff --git a/src/libraries/System.Console/src/System/ConsolePal.iOS.cs b/src/libraries/System.Console/src/System/ConsolePal.iOS.cs index 0793c2d0d2e11..5218b61638fac 100644 --- a/src/libraries/System.Console/src/System/ConsolePal.iOS.cs +++ b/src/libraries/System.Console/src/System/ConsolePal.iOS.cs @@ -23,7 +23,7 @@ public override unsafe void Write(byte[] buffer, int offset, int count) { fixed (byte* ptr = buffer) { - Interop.Sys.Log((IntPtr)(ptr + offset), count); + Interop.Sys.Log(ptr + offset, count); } } } From 770ca45636cf1fdcf2aceece37ee53a45773f085 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Fri, 20 Mar 2020 19:54:01 +0300 Subject: [PATCH 11/13] Use ValidateWrite to validate args --- .../System.Console/src/System/ConsolePal.iOS.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.Console/src/System/ConsolePal.iOS.cs b/src/libraries/System.Console/src/System/ConsolePal.iOS.cs index 5218b61638fac..d9fa43072a50f 100644 --- a/src/libraries/System.Console/src/System/ConsolePal.iOS.cs +++ b/src/libraries/System.Console/src/System/ConsolePal.iOS.cs @@ -19,12 +19,11 @@ internal sealed class NSLogStream : Stream public override unsafe void Write(byte[] buffer, int offset, int count) { - if (count > 0 && count <= buffer.Length - offset) + ValidateWrite(buffer, offset, count); + + fixed (byte* ptr = buffer) { - fixed (byte* ptr = buffer) - { - Interop.Sys.Log(ptr + offset, count); - } + Interop.Sys.Log(ptr + offset, count); } } From 0dcc8a93674661b7a3bca9de9c4a4e99810caf9a Mon Sep 17 00:00:00 2001 From: EgorBo Date: Fri, 20 Mar 2020 20:30:33 +0300 Subject: [PATCH 12/13] Use ConsoleStream --- .../src/System/ConsolePal.iOS.cs | 24 +++---------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/src/libraries/System.Console/src/System/ConsolePal.iOS.cs b/src/libraries/System.Console/src/System/ConsolePal.iOS.cs index d9fa43072a50f..1815beb8fe6a8 100644 --- a/src/libraries/System.Console/src/System/ConsolePal.iOS.cs +++ b/src/libraries/System.Console/src/System/ConsolePal.iOS.cs @@ -7,15 +7,11 @@ namespace System { - internal sealed class NSLogStream : Stream + internal sealed class NSLogStream : ConsoleStream { - public override void Flush() { } + public NSLogStream() : base(FileAccess.Write) {} - public override int Read(byte[] buffer, int offset, int count) => throw new NotSupportedException(); - - public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException(); - - public override void SetLength(long value) => throw new NotSupportedException(); + public override int Read(byte[] buffer, int offset, int count) => throw Error.GetReadNotSupported(); public override unsafe void Write(byte[] buffer, int offset, int count) { @@ -26,20 +22,6 @@ public override unsafe void Write(byte[] buffer, int offset, int count) Interop.Sys.Log(ptr + offset, count); } } - - public override bool CanRead => false; - - public override bool CanSeek => false; - - public override bool CanWrite => true; - - public override long Length => throw new NotSupportedException(); - - public override long Position - { - get => throw new NotSupportedException(); - set => throw new NotSupportedException(); - } } internal static class ConsolePal From b7c0bcca9a8fd7cdbf1b29dcb8233bb74dba17a7 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 21 Mar 2020 01:22:31 +0300 Subject: [PATCH 13/13] Update pal_log.m --- src/libraries/Native/Unix/System.Native/pal_log.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Native/Unix/System.Native/pal_log.m b/src/libraries/Native/Unix/System.Native/pal_log.m index 9f70d250c3d60..e63bf4e8bd83a 100644 --- a/src/libraries/Native/Unix/System.Native/pal_log.m +++ b/src/libraries/Native/Unix/System.Native/pal_log.m @@ -13,7 +13,7 @@ void SystemNative_Log (uint8_t* buffer, int32_t length) // Write in chunks of max 4096 characters; older versions of iOS seems to have a bug where NSLog may hang with long strings (!). // https://github.com/xamarin/maccore/issues/1014 const char* utf8 = [msg UTF8String]; - size_t len = strlen (utf8); + size_t len = utf8 == NULL ? 0 : strlen (utf8); const size_t max_size = 4096; while (len > 0) {