[patch, libgfortran] Fix PR20257 End of record occurs when writing large arrays

Jerry DeLisle jvdelisle@verizon.net
Thu Apr 20 23:19:00 GMT 2006


:ADDPATCH fortran:

This patch fixes the PR.  When bytes_left is less then the requested read or 
write size, a check for preconnected units (stdin, stdout, stderr) is made 
before generating an error and the bytes_left is reset to the dafault record 
length.  In such a case the error is skipped and the I/O allowed to proceed 
normally.

This bypassing of the error is only allowed if the units assigned record length 
is equal to the default which is very large.  So the bypass will only occur 
every blue moon.  If the user has set the record length deliberately to 
something other than the default, then it is assumed they mean it and the error 
will not be skipped.

You will notice an absurd unit number being assigned to internal units.  It 
turns out that the stderr unit number is zero.  To avoid mistaking an internal 
unit as preconnected I set it to 135790.  This also eliminates a case of 
accessing an uninitialized value pointed out by valgrind.

While at it, I also fixed a few cases of flushing with internal units and 
cleaned up free_mem use for internal units, consolidating and cleaning up the 
code.  This eliminates several errors noted by valgrind.

I tested the error bypass by artificially setting the default record length to 
something smaller.  I had to do this to test because I don't have enough memory 
in my machine here to set such a large array without getting into disk swapping.

The final patch has been regression tested on i686, NIST tested, many I/O tested 
and checked with valgrind on a few cases that valgrind noted had problems.  All 
looks solid on this end.  (I even got a little progress on tonto-1.0 with it)

OK for trunk and then later 4.1.1?

A test case is somewhat impractical for this feature. (open to suggestions) 
Could someone who likes to do things with very large arrays/files test this?

Best regards,

Jerry

2006-04-20  Jerry DeLisle  <jvdelisle@gcc.gnu.org>

	PR libgfortran/20257
	* io/io.h: Add prototypes for get_internal_unit and free_internal_unit.
	* io/unit.c (get_internal_unit): Initialize unit number, not zero.
	(free_internal_unit): New function to consolidate freeing memory.
	(get_unit): Initialize internal_unit_desc to NULL when unit is
	external.
	* io/unix.c (mem_close): Check for not NULL before freeing memory.
	* io/transfer.c (read_block): Reset bytes_left and skip error if unit
	is preconnected if default record length is reached.
	(read_block_direct): Ditto.
	(write_block): Ditto.
	(write_buf): Ditto.
	(data_transfer_init): Only flush if not internal unit.
	(finalize_transfer): Ditto and delete code to free memory used by
	internal units.
	(st_read_done): Use new function - free_internal_unit.
	(st_write_done): Use new function - free_internal unit.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pr20257-3.diff
Type: text/x-patch
Size: 9685 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/fortran/attachments/20060420/d04f13be/attachment.bin>


More information about the Fortran mailing list