diff --git a/Terminal.Gui/Drivers/UnixHelpers/UnixIOHelper.cs b/Terminal.Gui/Drivers/UnixHelpers/UnixIOHelper.cs index 6126fe6bc4..ecaa7600e7 100644 --- a/Terminal.Gui/Drivers/UnixHelpers/UnixIOHelper.cs +++ b/Terminal.Gui/Drivers/UnixHelpers/UnixIOHelper.cs @@ -236,7 +236,20 @@ public static bool IsInputAvailable (Pollfd [] pollMap, int timeoutMs = 0) { int n = poll (pollMap, (uint)pollMap.Length, timeoutMs); - return n > 0; + if (n <= 0) + { + return false; + } + + foreach (Pollfd pollfd in pollMap) + { + if ((pollfd.revents & (short)Condition.PollIn) != 0) + { + return true; + } + } + + return false; } catch { diff --git a/Tests/UnitTestsParallelizable/Drivers/UnixIOHelperTests.cs b/Tests/UnitTestsParallelizable/Drivers/UnixIOHelperTests.cs new file mode 100644 index 0000000000..e3d91b0900 --- /dev/null +++ b/Tests/UnitTestsParallelizable/Drivers/UnixIOHelperTests.cs @@ -0,0 +1,85 @@ +using System.Runtime.InteropServices; +using Terminal.Gui.Drivers; + +namespace DriverTests; + +/// +/// Tests for polling semantics on Unix-like platforms. +/// +[Collection ("Driver Tests")] +public class UnixIOHelperTests +{ + [DllImport ("libc", SetLastError = true)] + private static extern int pipe (int [] pipefd); + + [DllImport ("libc", SetLastError = true)] + private static extern int close (int fd); + + [Fact] + // Copilot + public void IsInputAvailable_ReturnsTrue_WhenPollReportsReadableData () + { + if (!OperatingSystem.IsLinux () && !OperatingSystem.IsMacOS () && !OperatingSystem.IsFreeBSD ()) + { + return; + } + + int [] pipeFds = new int [2]; + Assert.Equal (0, pipe (pipeFds)); + + try + { + byte [] payload = [0x41]; + Assert.Equal (1, UnixIOHelper.write (pipeFds [1], payload, payload.Length)); + + UnixIOHelper.Pollfd [] pollMap = + [ + new () + { + fd = pipeFds [0], + events = (short)UnixIOHelper.Condition.PollIn + } + ]; + + Assert.True (UnixIOHelper.IsInputAvailable (pollMap, 0)); + } + finally + { + close (pipeFds [0]); + close (pipeFds [1]); + } + } + + [Fact] + // Copilot + public void IsInputAvailable_ReturnsFalse_WhenPollReportsNonReadableEvent () + { + if (!OperatingSystem.IsLinux () && !OperatingSystem.IsMacOS () && !OperatingSystem.IsFreeBSD ()) + { + return; + } + + int [] pipeFds = new int [2]; + Assert.Equal (0, pipe (pipeFds)); + + try + { + Assert.Equal (0, close (pipeFds [0])); + + UnixIOHelper.Pollfd [] pollMap = + [ + new () + { + fd = pipeFds [0], + events = (short)UnixIOHelper.Condition.PollIn + } + ]; + + Assert.False (UnixIOHelper.IsInputAvailable (pollMap, 0)); + } + finally + { + close (pipeFds [1]); + } + } +}