PR# 19380 [er] RAW_FILE.go/retrieved with VC 14
Problem Report Summary
Submitter: axarosenberg
Category: Runtime
Priority: Low
Date: 2017/07/26
Class: Bug
Severity: Serious
Number: 19380
Release: 17.05
Confidential: No
Status: Analyzed
Responsible:
Environment: win
Synopsis: [er] RAW_FILE.go/retrieved with VC 14
Description
The following code works fine when the generated C code is compiled with VC 12, but fails with a IO_FAILURE exception in `retrieved' when compiled with VC 14. make local l_file: RAW_FILE do create l_file.make ("storable.sto") l_file.open_write l_file.independent_store ("foo") l_file.close create l_file.make ("storable.sto") l_file.open_read l_file.read_stream (2) l_file.go (0) print (l_file.retrieved) end It looks like "go (0)" does not do what it should do when compiled with VC 14. -- Eric Bezault
To Reproduce
Problem Report Interactions
To be safe, closing and opening the file would be probably the best solution in general. However, calling lseek in addition to fseek would work. However it suffers from the same limitations as solution #3 which is that once you call it, you should not use the FILE routines to read the file anymore.
To give you more context, this is what we are doing with storable files. We write some metadata in human readable form before the actual storable data in the file. When we retrieve a storable file, we first look at the first few bytes. (a) If we figure out that it's metadata, we either read it or skip it using FILE.go to jump to the location in the file where the actual storable data is. (b) If the first bytes that we read are not metadata, then we call FILE.go (0) before trying to read the actual storable data. Case (b) could be easily replaced by just closing and re-opening the file. Case (a) would be more problematic if FILE.go would not let us skip the metadata and jump directly to the location of the actual storable data. Can we use something else than fseek to skip the metadata? Would lseek work? Or should we just close and reopen the file and then call `read' with the number of metadata characters we wand to skip so that the file pointer is now at the location of the storable data? What wa .... Output truncated, Click download to get the full message
Looks like Microsoft broke their C run-time by migrating some C routines to their corresponding large file version that have a different behavior than what we used to. The issue is that read_stream is read using the C FILE pointer and it reads the first N bytes of the file into a buffer and moves the internal pointer to the end of the file. When you call `go` it actually does not update the actual location of the pointer, just the location in the buffer. So when we start retrieving we do not use the buffer but the direct low level access to the file except that the internal pointer is at the end not at position 0 so trying to read more returns 0 byte. The problem lie in the call to the C function fseek which is now implemented like fseeki64 was in previous runtime which did not update the cursor position. If we had used fseeki64 in our runtime you would also have the same problem with older versions of the C compiler. There are no good workaround for this problem apart from asking Microsoft to fix t .... Output truncated, Click download to get the full message