diff --git a/src/libraries/Common/src/Interop/Unix/System.Native/Interop.GetWindowWidth.cs b/src/libraries/Common/src/Interop/Unix/System.Native/Interop.GetWindowWidth.cs index ea3ef66dea4483..73f35d6a5ed65c 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Native/Interop.GetWindowWidth.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Native/Interop.GetWindowWidth.cs @@ -19,5 +19,8 @@ internal struct WinSize [LibraryImport(Libraries.SystemNative, EntryPoint = "SystemNative_GetWindowSize", SetLastError = true)] internal static partial int GetWindowSize(out WinSize winSize); + + [LibraryImport(Libraries.SystemNative, EntryPoint = "SystemNative_SetWindowSize", SetLastError = true)] + internal static partial int SetWindowSize(in WinSize winSize); } } diff --git a/src/libraries/System.Console/ref/System.Console.cs b/src/libraries/System.Console/ref/System.Console.cs index 9a4c6b10f40870..dfcce82fb96b85 100644 --- a/src/libraries/System.Console/ref/System.Console.cs +++ b/src/libraries/System.Console/ref/System.Console.cs @@ -69,10 +69,18 @@ public static partial class Console [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static bool TreatControlCAsInput { get { throw null; } set { } } - public static int WindowHeight { [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android"), System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser"), System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios"), System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + public static int WindowHeight { get { throw null; } set { } } public static int WindowLeft { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } public static int WindowTop { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } - public static int WindowWidth { [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android"), System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser"), System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios"), System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + public static int WindowWidth { get { throw null; } set { } } [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] @@ -147,7 +155,10 @@ public static void SetIn(System.IO.TextReader newIn) { } public static void SetOut(System.IO.TextWriter newOut) { } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public static void SetWindowPosition(int left, int top) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] public static void SetWindowSize(int width, int height) { } public static void Write(bool value) { } public static void Write(char value) { } diff --git a/src/libraries/System.Console/src/Resources/Strings.resx b/src/libraries/System.Console/src/Resources/Strings.resx index d6b48e2da57fe8..980613c28a5ffd 100644 --- a/src/libraries/System.Console/src/Resources/Strings.resx +++ b/src/libraries/System.Console/src/Resources/Strings.resx @@ -194,6 +194,9 @@ Cannot read keys when either application does not have a console or when console input has been redirected. Try Console.Read. + + Cannot set window size when console output has been redirected. + The home directory of the current user could not be determined. diff --git a/src/libraries/System.Console/src/System/Console.cs b/src/libraries/System.Console/src/System/Console.cs index a4b4cc969db183..3f860825910464 100644 --- a/src/libraries/System.Console/src/System/Console.cs +++ b/src/libraries/System.Console/src/System/Console.cs @@ -392,26 +392,50 @@ public static int WindowTop set { ConsolePal.WindowTop = value; } } + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] public static int WindowWidth { - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("browser")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] get { return ConsolePal.WindowWidth; } - [SupportedOSPlatform("windows")] - set { ConsolePal.WindowWidth = value; } + set + { + if (Console.IsOutputRedirected) + { + throw new IOException(SR.InvalidOperation_SetWindowSize); + } + + if (value <= 0) + { + throw new ArgumentOutOfRangeException(nameof(value), value, SR.ArgumentOutOfRange_NeedPosNum); + } + + ConsolePal.WindowWidth = value; + } } + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] public static int WindowHeight { - [UnsupportedOSPlatform("android")] - [UnsupportedOSPlatform("browser")] - [UnsupportedOSPlatform("ios")] - [UnsupportedOSPlatform("tvos")] get { return ConsolePal.WindowHeight; } - [SupportedOSPlatform("windows")] - set { ConsolePal.WindowHeight = value; } + set + { + if (Console.IsOutputRedirected) + { + throw new IOException(SR.InvalidOperation_SetWindowSize); + } + + if (value <= 0) + { + throw new ArgumentOutOfRangeException(nameof(value), value, SR.ArgumentOutOfRange_NeedPosNum); + } + + ConsolePal.WindowHeight = value; + } } [SupportedOSPlatform("windows")] @@ -420,9 +444,27 @@ public static void SetWindowPosition(int left, int top) ConsolePal.SetWindowPosition(left, top); } - [SupportedOSPlatform("windows")] + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] public static void SetWindowSize(int width, int height) { + if (Console.IsOutputRedirected) + { + throw new IOException(SR.InvalidOperation_SetWindowSize); + } + + if (width <= 0) + { + throw new ArgumentOutOfRangeException(nameof(width), width, SR.ArgumentOutOfRange_NeedPosNum); + } + + if (height <= 0) + { + throw new ArgumentOutOfRangeException(nameof(height), height, SR.ArgumentOutOfRange_NeedPosNum); + } + ConsolePal.SetWindowSize(width, height); } diff --git a/src/libraries/System.Console/src/System/ConsolePal.Unix.cs b/src/libraries/System.Console/src/System/ConsolePal.Unix.cs index 8ba71f36f30631..428fcbab0e7010 100644 --- a/src/libraries/System.Console/src/System/ConsolePal.Unix.cs +++ b/src/libraries/System.Console/src/System/ConsolePal.Unix.cs @@ -346,7 +346,7 @@ public static int WindowWidth GetWindowSize(out int width, out _); return width; } - set { throw new PlatformNotSupportedException(); } + set => SetWindowSize(value, WindowHeight); } public static int WindowHeight @@ -356,7 +356,7 @@ public static int WindowHeight GetWindowSize(out _, out int height); return height; } - set { throw new PlatformNotSupportedException(); } + set => SetWindowSize(WindowWidth, value); } private static void GetWindowSize(out int width, out int height) @@ -392,7 +392,24 @@ public static void SetWindowPosition(int left, int top) public static void SetWindowSize(int width, int height) { - throw new PlatformNotSupportedException(); + lock (Console.Out) + { + Interop.Sys.WinSize winsize = default; + winsize.Row = (ushort)height; + winsize.Col = (ushort)width; + if (Interop.Sys.SetWindowSize(in winsize) == 0) + { + s_windowWidth = winsize.Col; + s_windowHeight = winsize.Row; + } + else + { + Interop.ErrorInfo errorInfo = Interop.Sys.GetLastErrorInfo(); + throw errorInfo.Error == Interop.Error.ENOTSUP ? + new PlatformNotSupportedException() : + Interop.GetIOException(errorInfo); + } + } } public static bool CursorVisible diff --git a/src/libraries/System.Console/src/System/ConsolePal.Windows.cs b/src/libraries/System.Console/src/System/ConsolePal.Windows.cs index 28b74832466c70..d8e43d55a9cce1 100644 --- a/src/libraries/System.Console/src/System/ConsolePal.Windows.cs +++ b/src/libraries/System.Console/src/System/ConsolePal.Windows.cs @@ -948,11 +948,6 @@ public static unsafe void SetWindowPosition(int left, int top) public static unsafe void SetWindowSize(int width, int height) { - if (width <= 0) - throw new ArgumentOutOfRangeException(nameof(width), width, SR.ArgumentOutOfRange_NeedPosNum); - if (height <= 0) - throw new ArgumentOutOfRangeException(nameof(height), height, SR.ArgumentOutOfRange_NeedPosNum); - // Get the position of the current console window Interop.Kernel32.CONSOLE_SCREEN_BUFFER_INFO csbi = GetBufferInfo(); diff --git a/src/libraries/System.Console/tests/ManualTests/ManualTests.cs b/src/libraries/System.Console/tests/ManualTests/ManualTests.cs index ce69b2fad7d500..a4eb87d0f8b817 100644 --- a/src/libraries/System.Console/tests/ManualTests/ManualTests.cs +++ b/src/libraries/System.Console/tests/ManualTests/ManualTests.cs @@ -5,7 +5,9 @@ using System.Diagnostics; using System.Threading.Tasks; using System.IO; +using System.Runtime.InteropServices; using System.Text; +using System.Threading; using Xunit; namespace System @@ -321,6 +323,37 @@ public static void EncodingTest() AssertUserExpectedResults("Pi and Sigma or question marks"); } + [ConditionalFact(nameof(ManualTestsEnabled))] + [SkipOnPlatform(TestPlatforms.Browser | TestPlatforms.iOS | TestPlatforms.MacCatalyst | TestPlatforms.tvOS, "Not supported on Browser, iOS, MacCatalyst, or tvOS.")] + public static void ResizeTest() + { + bool wasResized = false; + + using (ManualResetEvent manualResetEvent = new(false)) + using (PosixSignalRegistration.Create(PosixSignal.SIGWINCH, + ctx => + { + wasResized = true; + Assert.Equal(PosixSignal.SIGWINCH, ctx.Signal); + manualResetEvent.Set(); + })) + { + int widthBefore = Console.WindowWidth; + int heightBefore = Console.WindowHeight; + + Assert.False(wasResized); + + Console.SetWindowSize(widthBefore / 2, heightBefore / 2); + + Assert.True(manualResetEvent.WaitOne(TimeSpan.FromMilliseconds(50))); + Assert.True(wasResized); + Assert.Equal(widthBefore / 2, Console.WindowWidth ); + Assert.Equal(heightBefore / 2, Console.WindowHeight ); + + Console.SetWindowSize(widthBefore, heightBefore); + } + } + private static void AssertUserExpectedResults(string expected) { Console.Write($"Did you see {expected}? [y/n] "); diff --git a/src/libraries/System.Console/tests/WindowAndCursorProps.cs b/src/libraries/System.Console/tests/WindowAndCursorProps.cs index f5ddc739def316..10d0371d9a9031 100644 --- a/src/libraries/System.Console/tests/WindowAndCursorProps.cs +++ b/src/libraries/System.Console/tests/WindowAndCursorProps.cs @@ -46,7 +46,7 @@ public static void SetBufferSize_Unix_ThrowsPlatformNotSupportedException() } [Theory] - [PlatformSpecific(TestPlatforms.Windows)] + [PlatformSpecific((TestPlatforms.Windows) | (TestPlatforms.AnyUnix & ~TestPlatforms.Browser & ~TestPlatforms.iOS & ~TestPlatforms.MacCatalyst & ~TestPlatforms.tvOS))] [InlineData(0)] [InlineData(-1)] public static void WindowWidth_SetInvalid_ThrowsArgumentOutOfRangeException(int value) @@ -71,14 +71,14 @@ public static void WindowWidth_GetUnix_Success() } [Fact] - [PlatformSpecific(TestPlatforms.AnyUnix & ~TestPlatforms.Browser)] // Expected behavior specific to Unix + [PlatformSpecific(TestPlatforms.iOS | TestPlatforms.MacCatalyst | TestPlatforms.tvOS)] // Expected behavior specific to Unix public static void WindowWidth_SetUnix_ThrowsPlatformNotSupportedException() { Assert.Throws(() => Console.WindowWidth = 100); } [Theory] - [PlatformSpecific(TestPlatforms.Windows)] // Expected behavior specific to Windows + [PlatformSpecific((TestPlatforms.Windows) | (TestPlatforms.AnyUnix & ~TestPlatforms.Browser & ~TestPlatforms.iOS & ~TestPlatforms.MacCatalyst & ~TestPlatforms.tvOS))] [InlineData(0)] [InlineData(-1)] public static void WindowHeight_SetInvalid_ThrowsArgumentOutOfRangeException(int value) @@ -102,13 +102,6 @@ public static void WindowHeight_GetUnix_Success() Helpers.RunInRedirectedOutput((data) => Console.WriteLine(Console.WindowHeight)); } - [Fact] - [PlatformSpecific(TestPlatforms.AnyUnix)] // Expected behavior specific to Unix - public static void WindowHeight_SetUnix_ThrowsPlatformNotSupportedException() - { - Assert.Throws(() => Console.WindowHeight = 100); - } - [Fact] [PlatformSpecific(TestPlatforms.AnyUnix & ~TestPlatforms.Browser & ~TestPlatforms.iOS & ~TestPlatforms.MacCatalyst & ~TestPlatforms.tvOS)] // Expected behavior specific to Unix public static void LargestWindowWidth_UnixGet_ReturnsExpected() @@ -117,6 +110,13 @@ public static void LargestWindowWidth_UnixGet_ReturnsExpected() Helpers.RunInRedirectedOutput((data) => Assert.Equal(Console.WindowWidth, Console.LargestWindowWidth)); } + [Fact] + [PlatformSpecific(TestPlatforms.Browser | TestPlatforms.iOS | TestPlatforms.MacCatalyst | TestPlatforms.tvOS)] // Expected behavior specific to Unix + public static void WindowHeight_SetUnix_ThrowsPlatformNotSupportedException() + { + Assert.Throws(() => Console.WindowHeight = 100); + } + [Fact] [PlatformSpecific(TestPlatforms.AnyUnix & ~TestPlatforms.Browser & ~TestPlatforms.iOS & ~TestPlatforms.MacCatalyst & ~TestPlatforms.tvOS)] // Expected behavior specific to Unix public static void LargestWindowHeight_UnixGet_ReturnsExpected() @@ -559,7 +559,7 @@ public void SetWindowPosition_Unix_ThrowsPlatformNotSupportedException() Assert.Throws(() => Console.SetWindowPosition(50, 50)); } - [PlatformSpecific(TestPlatforms.Windows)] + [PlatformSpecific((TestPlatforms.Windows) | (TestPlatforms.AnyUnix & ~TestPlatforms.Browser & ~TestPlatforms.iOS & ~TestPlatforms.MacCatalyst & ~TestPlatforms.tvOS))] [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoNorServerCore))] public void SetWindowSize_GetWindowSize_ReturnsExpected() { @@ -587,7 +587,7 @@ public void SetWindowSize_GetWindowSize_ReturnsExpected() } [Fact] - [PlatformSpecific(TestPlatforms.AnyUnix)] + [PlatformSpecific(TestPlatforms.Browser | TestPlatforms.iOS | TestPlatforms.MacCatalyst | TestPlatforms.tvOS)] public void SetWindowSize_Unix_ThrowsPlatformNotSupportedException() { Assert.Throws(() => Console.SetWindowSize(50, 50)); diff --git a/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs b/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs index b9ac1424bb9ded..65563b20d495b4 100644 --- a/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs +++ b/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs @@ -48,9 +48,6 @@ public ArgumentOutOfRangeException(string? message, Exception? innerException) HResult = HResults.COR_E_ARGUMENTOUTOFRANGE; } - // We will not use this in the classlibs, but we'll provide it for - // anyone that's really interested so they don't have to stick a bunch - // of printf's in their code. public ArgumentOutOfRangeException(string? paramName, object? actualValue, string? message) : base(message, paramName) { @@ -87,9 +84,6 @@ public override string Message } // Gets the value of the argument that caused the exception. - // Note - we don't set this anywhere in the class libraries in - // version 1, but it might come in handy for other developers who - // want to avoid sticking printf's in their code. public virtual object? ActualValue => _actualValue; } } diff --git a/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml b/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml index 21c4764e4c0236..b749cf0613b556 100644 --- a/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml +++ b/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml @@ -24,6 +24,36 @@ net6.0/mscorlib.dll net7.0/mscorlib.dll + + CP0014 + M:System.Console.get_WindowHeight:[T:System.Runtime.Versioning.UnsupportedOSPlatformAttribute] + net6.0/mscorlib.dll + net7.0/mscorlib.dll + + + CP0014 + M:System.Console.get_WindowWidth:[T:System.Runtime.Versioning.UnsupportedOSPlatformAttribute] + net6.0/mscorlib.dll + net7.0/mscorlib.dll + + + CP0014 + M:System.Console.set_WindowHeight(System.Int32):[T:System.Runtime.Versioning.SupportedOSPlatformAttribute] + net6.0/mscorlib.dll + net7.0/mscorlib.dll + + + CP0014 + M:System.Console.set_WindowWidth(System.Int32):[T:System.Runtime.Versioning.SupportedOSPlatformAttribute] + net6.0/mscorlib.dll + net7.0/mscorlib.dll + + + CP0014 + M:System.Console.SetWindowSize(System.Int32,System.Int32):[T:System.Runtime.Versioning.SupportedOSPlatformAttribute] + net6.0/mscorlib.dll + net7.0/mscorlib.dll + CP0014 M:System.Security.Cryptography.RandomNumberGenerator.Create(System.String):[T:System.Runtime.Versioning.UnsupportedOSPlatformAttribute] @@ -216,6 +246,36 @@ net6.0/netstandard.dll net7.0/netstandard.dll + + CP0014 + M:System.Console.get_WindowHeight:[T:System.Runtime.Versioning.UnsupportedOSPlatformAttribute] + net6.0/netstandard.dll + net7.0/netstandard.dll + + + CP0014 + M:System.Console.get_WindowWidth:[T:System.Runtime.Versioning.UnsupportedOSPlatformAttribute] + net6.0/netstandard.dll + net7.0/netstandard.dll + + + CP0014 + M:System.Console.set_WindowHeight(System.Int32):[T:System.Runtime.Versioning.SupportedOSPlatformAttribute] + net6.0/netstandard.dll + net7.0/netstandard.dll + + + CP0014 + M:System.Console.set_WindowWidth(System.Int32):[T:System.Runtime.Versioning.SupportedOSPlatformAttribute] + net6.0/netstandard.dll + net7.0/netstandard.dll + + + CP0014 + M:System.Console.SetWindowSize(System.Int32,System.Int32):[T:System.Runtime.Versioning.SupportedOSPlatformAttribute] + net6.0/netstandard.dll + net7.0/netstandard.dll + CP0014 M:System.Linq.EnumerableQuery`1.#ctor(System.Collections.Generic.IEnumerable{`0}):[T:System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute] @@ -450,6 +510,36 @@ net6.0/netstandard.dll net7.0/netstandard.dll + + CP0014 + M:System.Console.get_WindowHeight:[T:System.Runtime.Versioning.UnsupportedOSPlatformAttribute] + net6.0/System.Console.dll + net7.0/System.Console.dll + + + CP0014 + M:System.Console.get_WindowWidth:[T:System.Runtime.Versioning.UnsupportedOSPlatformAttribute] + net6.0/System.Console.dll + net7.0/System.Console.dll + + + CP0014 + M:System.Console.set_WindowHeight(System.Int32):[T:System.Runtime.Versioning.SupportedOSPlatformAttribute] + net6.0/System.Console.dll + net7.0/System.Console.dll + + + CP0014 + M:System.Console.set_WindowWidth(System.Int32):[T:System.Runtime.Versioning.SupportedOSPlatformAttribute] + net6.0/System.Console.dll + net7.0/System.Console.dll + + + CP0014 + M:System.Console.SetWindowSize(System.Int32,System.Int32):[T:System.Runtime.Versioning.SupportedOSPlatformAttribute] + net6.0/System.Console.dll + net7.0/System.Console.dll + CP0014 M:System.Linq.EnumerableQuery`1.#ctor(System.Collections.Generic.IEnumerable{`0}):[T:System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute] diff --git a/src/native/libs/Common/pal_config.h.in b/src/native/libs/Common/pal_config.h.in index 6243761d8600d0..acacfb33e34a3c 100644 --- a/src/native/libs/Common/pal_config.h.in +++ b/src/native/libs/Common/pal_config.h.in @@ -40,6 +40,7 @@ #cmakedefine01 KEVENT_REQUIRES_INT_PARAMS #cmakedefine01 HAVE_IOCTL #cmakedefine01 HAVE_TIOCGWINSZ +#cmakedefine01 HAVE_TIOCSWINSZ #cmakedefine01 HAVE_SCHED_GETAFFINITY #cmakedefine01 HAVE_SCHED_SETAFFINITY #cmakedefine01 HAVE_SCHED_GETCPU diff --git a/src/native/libs/System.Native/entrypoints.c b/src/native/libs/System.Native/entrypoints.c index e254f526a1a439..c4faf76ec7dace 100644 --- a/src/native/libs/System.Native/entrypoints.c +++ b/src/native/libs/System.Native/entrypoints.c @@ -35,6 +35,7 @@ static const Entry s_sysNative[] = { DllImportEntry(SystemNative_FStat) DllImportEntry(SystemNative_GetWindowSize) + DllImportEntry(SystemNative_SetWindowSize) DllImportEntry(SystemNative_IsATty) DllImportEntry(SystemNative_InitializeTerminalAndSignalHandling) DllImportEntry(SystemNative_SetKeypadXmit) diff --git a/src/native/libs/System.Native/pal_console.c b/src/native/libs/System.Native/pal_console.c index 5e13eb7b627b15..1c0c321f4e8a7c 100644 --- a/src/native/libs/System.Native/pal_console.c +++ b/src/native/libs/System.Native/pal_console.c @@ -39,6 +39,18 @@ int32_t SystemNative_GetWindowSize(WinSize* windowSize) #endif } +int32_t SystemNative_SetWindowSize(WinSize* windowSize) +{ + assert(windowSize != NULL); + +#if HAVE_IOCTL && HAVE_TIOCSWINSZ + return ioctl(STDOUT_FILENO, TIOCSWINSZ, windowSize); +#else + errno = ENOTSUP; + return -1; +#endif +} + int32_t SystemNative_IsATty(intptr_t fd) { return isatty(ToFileDescriptor(fd)); diff --git a/src/native/libs/System.Native/pal_console.h b/src/native/libs/System.Native/pal_console.h index ca837c55bc557d..46daa3d1ebe6df 100644 --- a/src/native/libs/System.Native/pal_console.h +++ b/src/native/libs/System.Native/pal_console.h @@ -44,10 +44,17 @@ typedef struct /** * Gets the windows size of the terminal * - * Returns 0 on success; otherwise, returns errorNo. + * Returns 0 on success; otherwise, returns -1 and sets errno. */ PALEXPORT int32_t SystemNative_GetWindowSize(WinSize* windowsSize); +/** + * Sets the windows size of the terminal + * + * Returns 0 on success; otherwise, returns -1 and sets errno. + */ +PALEXPORT int32_t SystemNative_SetWindowSize(WinSize* windowsSize); + /** * Gets whether the specified file descriptor is for a terminal. * diff --git a/src/native/libs/configure.cmake b/src/native/libs/configure.cmake index bc6c133fe89212..7c5b88e96d5d0f 100644 --- a/src/native/libs/configure.cmake +++ b/src/native/libs/configure.cmake @@ -254,6 +254,11 @@ check_symbol_exists( "sys/ioctl.h" HAVE_TIOCGWINSZ) +check_symbol_exists( + TIOCSWINSZ + "sys/ioctl.h" + HAVE_TIOCSWINSZ) + check_symbol_exists( tcgetattr termios.h