From 6dcb1ea0b7baca0f8d0da9b8f07a016b7b4fcc9d 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 7c92c4e081849a..0e1b39f01f8f9e 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 @@ -332,8 +332,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 0a149f2b25cb0c9a3a74f76dc8c2ab8558de4843 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 0e1b39f01f8f9e..ff5d30e6dc7ec4 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 @@ -332,13 +332,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;