|
Boost : |
Subject: [boost] [iostreams]mapped_file bug on Win32?
From: Nelson, Erik - 2 (erik.l.nelson_at_[hidden])
Date: 2010-02-19 13:22:32
Or maybe a feature? Or maybe I'm just using it incorrectly.
I'm trying to create a new file of a certain size, regardless of whether
or not a file of the same name exists.
If I run a test program along the lines of
boost::iostreams::mapped_file file;
boost::iostreams::mapped_file_params p("test.txt");
p.new_file_size = 1201;
p.length = 1;
p.mode = ios_base::in | ios_base::out;
file.open(p);
It fails with the error
'failed setting file size: Cannot create a file when that file already
exists.' if file 'test.txt' already exists.
It seems to me that this error is a bug caused by incorrect error
checking in mapped_file.cpp in function mapped_file_impl::open_file.
At the call to CreateFileA, dwCreationDisposition=CREATE_ALWAYS and a
valid handle value is returned. The Win32 docs say that in this case
the call to CreateFileA has succeeded and the last-error code is set to
ERROR_ALREADY_EXISTS.
http://msdn.microsoft.com/en-us/library/aa363858%28VS.85%29.aspx
Immediately after the call to CreateFileA, the handle is checked for
validity but the last-error code is not reset.
Shortly thereafter is a call to SetFilePointer. The docs say that the
proper way to check for an error from SetFilePointer is to compare its
return value to INVALID_SET_VALUE_POINTER.
http://msdn.microsoft.com/en-us/library/aa365541%28VS.85%29.aspx
This isn't done in the code... Instead, GetLastError() is called, which
apparently returns the ERROR_ALREADY_EXISTS code generated by
CreateFileA, which wasn't an error at all.
It seems to me that a couple of things need to be changed to make this
correct-
1) after the check for valid handle creation by CreateFileA, call
SetLastError(NO_ERROR)
2) when resizing the file the code
if (::GetLastError() != NO_ERROR || !::SetEndOfFile(handle_))
should be something like
if (::SetFilePointer(handle_, sizelow, &sizehigh, FILE_BEGIN) ==
INVALID_SET_VALUE_POINTER || !::SetEndOfFile(handle_))
Does that make sense? Or am I just setting the mapped_file_params
incorrectly to force creation of a new file?
Erik
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk