From 0ff6db25273a8a2d3006cc06129a05d5ad9aed6c Mon Sep 17 00:00:00 2001 From: Alex Fort Date: Tue, 26 Oct 2010 14:52:21 -0400 Subject: [PATCH 1/2] [Fix] Don't enforce a minimum size for zero-length buffers, fixing #645193 InitBuffer was forcing the length of any buffer smaller than 8 to be 8, but for zero-size buffers, this isn't correct. --- mcs/class/corlib/System.IO/FileStream.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mcs/class/corlib/System.IO/FileStream.cs b/mcs/class/corlib/System.IO/FileStream.cs index 0f84656c364a..0b3f3dc6b13a 100644 --- a/mcs/class/corlib/System.IO/FileStream.cs +++ b/mcs/class/corlib/System.IO/FileStream.cs @@ -108,7 +108,7 @@ internal FileStream (IntPtr handle, FileAccess access, bool ownsHandle, int buff if (isZeroSize) bufferSize = 1; - InitBuffer (bufferSize); + InitBuffer (bufferSize, isZeroSize); if (canseek) { buf_start = MonoIO.Seek (handle, 0, SeekOrigin.Current, out error); @@ -335,7 +335,7 @@ internal FileStream (string path, FileMode mode, FileAccess access, FileShare sh } } - InitBuffer (bufferSize); + InitBuffer (bufferSize, false); if (mode==FileMode.Append) { this.Seek (0, SeekOrigin.End); @@ -1089,12 +1089,14 @@ private int ReadData (IntPtr handle, byte[] buf, int offset, return(amount); } - void InitBuffer (int size) + void InitBuffer (int size, bool isZeroSize) { if (size <= 0) throw new ArgumentOutOfRangeException ("bufferSize", "Positive number required."); - size = Math.Max (size, 8); + // Don't enforce a minimum size for zero-size buffers + if (!isZeroSize) + size = Math.Max (size, 8); // // Instead of allocating a new default buffer use the From 78e4c747e195250be6d5eff24802c5fa572195e2 Mon Sep 17 00:00:00 2001 From: Alex Fort Date: Fri, 29 Oct 2010 11:22:35 -0400 Subject: [PATCH 2/2] Don't use a buffer size of 1 for zero-length buffers Using a size of 1 for zero length buffers causes (on linux) the last character to be eaten by the buffer until the next flush. --- mcs/class/corlib/System.IO/FileStream.cs | 46 ++++++++++++------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/mcs/class/corlib/System.IO/FileStream.cs b/mcs/class/corlib/System.IO/FileStream.cs index 0b3f3dc6b13a..f0c7ddfda89c 100644 --- a/mcs/class/corlib/System.IO/FileStream.cs +++ b/mcs/class/corlib/System.IO/FileStream.cs @@ -105,9 +105,6 @@ internal FileStream (IntPtr handle, FileAccess access, bool ownsHandle, int buff #else this.anonymous = false; #endif - if (isZeroSize) - bufferSize = 1; - InitBuffer (bufferSize, isZeroSize); if (canseek) { @@ -1091,30 +1088,33 @@ private int ReadData (IntPtr handle, byte[] buf, int offset, void InitBuffer (int size, bool isZeroSize) { - if (size <= 0) - throw new ArgumentOutOfRangeException ("bufferSize", "Positive number required."); - - // Don't enforce a minimum size for zero-size buffers - if (!isZeroSize) + if (isZeroSize) { + size = 0; + buf = new byte[1]; + } else { + if (size <= 0) + throw new ArgumentOutOfRangeException ("bufferSize", "Positive number required."); + size = Math.Max (size, 8); - - // - // Instead of allocating a new default buffer use the - // last one if there is any available - // - if (size <= DefaultBufferSize && buf_recycle != null) { - lock (buf_recycle_lock) { - if (buf_recycle != null) { - buf = buf_recycle; - buf_recycle = null; + + // + // Instead of allocating a new default buffer use the + // last one if there is any available + // + if (size <= DefaultBufferSize && buf_recycle != null) { + lock (buf_recycle_lock) { + if (buf_recycle != null) { + buf = buf_recycle; + buf_recycle = null; + } } } + + if (buf == null) + buf = new byte [size]; + else + Array.Clear (buf, 0, size); } - - if (buf == null) - buf = new byte [size]; - else - Array.Clear (buf, 0, size); buf_size = size; // buf_start = 0;