From 150df4db4910efa32a5a73cbf6fe0919d35aedf4 Mon Sep 17 00:00:00 2001 From: Radek Zikmund Date: Wed, 15 Oct 2025 10:20:29 +0200 Subject: [PATCH 1/2] Don't assume all S_IFREG files are seekable --- .../Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs b/src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs index 4029e70cef29e8..b015316a0a4007 100644 --- a/src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs @@ -343,8 +343,13 @@ private bool Init(string path, FileMode mode, FileAccess access, FileShare share // we take advantage of the information provided by the fstat syscall // and for regular files (most common case) // avoid one extra sys call for determining whether file can be seeked - _canSeek = NullableBool.True; - Debug.Assert(Interop.Sys.LSeek(this, 0, Interop.Sys.SeekWhence.SEEK_CUR) >= 0); + // we exclude 0-length files because they may be actually pipes + // (e.g. /proc/net/route) and these are not seekable on all systems + if (status.Size > 0) + { + _canSeek = NullableBool.True; + Debug.Assert(Interop.Sys.LSeek(this, 0, Interop.Sys.SeekWhence.SEEK_CUR) >= 0); + } } fileLength = status.Size; From 5e39780273cdf352df55911a1beed9332e5decbd Mon Sep 17 00:00:00 2001 From: Radek Zikmund Date: Wed, 15 Oct 2025 12:57:54 +0200 Subject: [PATCH 2/2] Attempt 2 --- .../Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs b/src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs index b015316a0a4007..878eafb8c85291 100644 --- a/src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs @@ -343,13 +343,11 @@ private bool Init(string path, FileMode mode, FileAccess access, FileShare share // we take advantage of the information provided by the fstat syscall // and for regular files (most common case) // avoid one extra sys call for determining whether file can be seeked - // we exclude 0-length files because they may be actually pipes + _canSeek = NullableBool.True; + + // we exclude 0-length files from the assert because those may may be pseudofiles // (e.g. /proc/net/route) and these are not seekable on all systems - if (status.Size > 0) - { - _canSeek = NullableBool.True; - Debug.Assert(Interop.Sys.LSeek(this, 0, Interop.Sys.SeekWhence.SEEK_CUR) >= 0); - } + Debug.Assert(status.Size == 0 || Interop.Sys.LSeek(this, 0, Interop.Sys.SeekWhence.SEEK_CUR) >= 0); } fileLength = status.Size;