mirror of git://gcc.gnu.org/git/gcc.git
re PR libfortran/15472 (implicit open for unformatted file causes run-time error)
2004-07-04 Bud Davis <bdavis9659@comcast.net>
Paul Brook <paul@codesourcery.com>
PR fortran/15472
* io/transfer.c(us_write): set recl for seq unform writes to max size.
* io/transfer.c(data_transfer_init): handle un-opened seq unform unit.
* io/unix.c(fd_alloc_w_at): handle requests at start, fd_flush at
right time.
* io/unix.c(is_seekable): set based upon the file/device, not the
method being used to access it (fd or mmap).
* io/unix.c(fd_flush): don't set file_size if !seekable.
* io/unix.c(fd_truncate: ditto.
* gfortran.fortran-torture/execute/seq_io.f90: New test.
Co-Authored-By: Paul Brook <paul@codesourcery.com>
From-SVN: r84104
This commit is contained in:
parent
91a8b4596b
commit
bf1df0a046
|
|
@ -1,3 +1,7 @@
|
||||||
|
2004-07-04 Bud Davis <bdavis9659@comcast.net>
|
||||||
|
|
||||||
|
* gfortran.fortran-torture/execute/seq_io.f90: New test.
|
||||||
|
|
||||||
2004-07-04 Neil Booth <neil@duron.akihabara.co.uk>
|
2004-07-04 Neil Booth <neil@duron.akihabara.co.uk>
|
||||||
|
|
||||||
* gcc.dg/cpp/if-mop.c: Two new testcases.
|
* gcc.dg/cpp/if-mop.c: Two new testcases.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
! pr 15472
|
||||||
|
! sequential access files
|
||||||
|
!
|
||||||
|
! this test verifies the most basic sequential unformatted I/O
|
||||||
|
! write 3 records of various sizes
|
||||||
|
! then read them back
|
||||||
|
! and compare with what was written
|
||||||
|
!
|
||||||
|
implicit none
|
||||||
|
integer size
|
||||||
|
parameter(size=100)
|
||||||
|
logical debug
|
||||||
|
data debug /.FALSE./
|
||||||
|
! set debug to true for help in debugging failures.
|
||||||
|
integer m(2)
|
||||||
|
integer n
|
||||||
|
real*4 r(size)
|
||||||
|
integer i
|
||||||
|
m(1) = Z'11111111'
|
||||||
|
m(2) = Z'22222222'
|
||||||
|
n = Z'33333333'
|
||||||
|
do i = 1,size
|
||||||
|
r(i) = i
|
||||||
|
end do
|
||||||
|
write(9)m ! an array of 2
|
||||||
|
write(9)n ! an integer
|
||||||
|
write(9)r ! an array of reals
|
||||||
|
! zero all the results so we can compare after they are read back
|
||||||
|
do i = 1,size
|
||||||
|
r(i) = 0
|
||||||
|
end do
|
||||||
|
m(1) = 0
|
||||||
|
m(2) = 0
|
||||||
|
n = 0
|
||||||
|
|
||||||
|
rewind(9)
|
||||||
|
read(9)m
|
||||||
|
read(9)n
|
||||||
|
read(9)r
|
||||||
|
!
|
||||||
|
! check results
|
||||||
|
if (m(1).ne.Z'11111111') then
|
||||||
|
if (debug) then
|
||||||
|
print '(A,Z8)','m(1) incorrect. m(1) = ',m(1)
|
||||||
|
else
|
||||||
|
call abort
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if (m(2).ne.Z'22222222') then
|
||||||
|
if (debug) then
|
||||||
|
print '(A,Z8)','m(2) incorrect. m(2) = ',m(2)
|
||||||
|
else
|
||||||
|
call abort
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if (n.ne.Z'33333333') then
|
||||||
|
if (debug) then
|
||||||
|
print '(A,Z8)','n incorrect. n = ',n
|
||||||
|
else
|
||||||
|
call abort
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
do i = 1,size
|
||||||
|
if (int(r(i)).ne.i) then
|
||||||
|
if (debug) then
|
||||||
|
print*,'element ',i,' was ',r(i),' should be ',i
|
||||||
|
else
|
||||||
|
call abort
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
end do
|
||||||
|
! use hexdump to look at the file "fort.9"
|
||||||
|
if (debug) then
|
||||||
|
close(9)
|
||||||
|
else
|
||||||
|
close(9,status='DELETE')
|
||||||
|
endif
|
||||||
|
end
|
||||||
|
|
@ -1,3 +1,16 @@
|
||||||
|
2004-07-04 Bud Davis <bdavis9659@comcast.net>
|
||||||
|
Paul Brook <paul@codesourcery.com>
|
||||||
|
|
||||||
|
PR fortran/15472
|
||||||
|
* io/transfer.c(us_write): set recl for seq unform writes to max size.
|
||||||
|
* io/transfer.c(data_transfer_init): handle un-opened seq unform unit.
|
||||||
|
* io/unix.c(fd_alloc_w_at): handle requests at start, fd_flush at
|
||||||
|
right time.
|
||||||
|
* io/unix.c(is_seekable): set based upon the file/device, not the
|
||||||
|
method being used to access it (fd or mmap).
|
||||||
|
* io/unix.c(fd_flush): don't set file_size if !seekable.
|
||||||
|
* io/unix.c(fd_truncate: ditto.
|
||||||
|
|
||||||
2004-07-04 Janne Blomqvist <jblomqvi@cc.hut.fi>
|
2004-07-04 Janne Blomqvist <jblomqvi@cc.hut.fi>
|
||||||
Paul Brook <paul@codesourcery.com>
|
Paul Brook <paul@codesourcery.com>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -835,6 +835,11 @@ us_write (void)
|
||||||
if (sfree (current_unit->s) == FAILURE)
|
if (sfree (current_unit->s) == FAILURE)
|
||||||
generate_error (ERROR_OS, NULL);
|
generate_error (ERROR_OS, NULL);
|
||||||
|
|
||||||
|
/* for sequential unformatted, we write until we have more bytes than
|
||||||
|
can fit in the record markers. if disk space runs out first it will
|
||||||
|
error on the write */
|
||||||
|
current_unit->recl = g.max_offset;
|
||||||
|
|
||||||
current_unit->bytes_left = current_unit->recl;
|
current_unit->bytes_left = current_unit->recl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -890,6 +895,10 @@ data_transfer_init (int read_flag)
|
||||||
memset (&u_flags, '\0', sizeof (u_flags));
|
memset (&u_flags, '\0', sizeof (u_flags));
|
||||||
u_flags.access = ACCESS_SEQUENTIAL;
|
u_flags.access = ACCESS_SEQUENTIAL;
|
||||||
u_flags.action = ACTION_READWRITE;
|
u_flags.action = ACTION_READWRITE;
|
||||||
|
/* is it unformatted ?*/
|
||||||
|
if (ioparm.format == NULL && !ioparm.list_format)
|
||||||
|
u_flags.form = FORM_UNFORMATTED;
|
||||||
|
else
|
||||||
u_flags.form = FORM_UNSPECIFIED;
|
u_flags.form = FORM_UNSPECIFIED;
|
||||||
u_flags.delim = DELIM_UNSPECIFIED;
|
u_flags.delim = DELIM_UNSPECIFIED;
|
||||||
u_flags.blank = BLANK_UNSPECIFIED;
|
u_flags.blank = BLANK_UNSPECIFIED;
|
||||||
|
|
|
||||||
|
|
@ -280,7 +280,9 @@ fd_flush (unix_stream * s)
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
|
|
||||||
s->physical_offset = s->dirty_offset + s->ndirty;
|
s->physical_offset = s->dirty_offset + s->ndirty;
|
||||||
if (s->physical_offset > s->file_length)
|
|
||||||
|
/* don't increment file_length if the file is non-seekable */
|
||||||
|
if (s->file_length != -1 && s->physical_offset > s->file_length)
|
||||||
s->file_length = s->physical_offset;
|
s->file_length = s->physical_offset;
|
||||||
s->ndirty = 0;
|
s->ndirty = 0;
|
||||||
|
|
||||||
|
|
@ -406,18 +408,28 @@ fd_alloc_w_at (unix_stream * s, int *len, gfc_offset where)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return a position within the current buffer */
|
/* Return a position within the current buffer */
|
||||||
|
if (s->ndirty == 0
|
||||||
if (s->ndirty == 0)
|
|| where > s->dirty_offset + s->ndirty
|
||||||
{ /* First write into a clean buffer */
|
|| s->dirty_offset > where + *len)
|
||||||
|
{ /* Discontiguous blocks, start with a clean buffer. */
|
||||||
|
/* Flush the buffer. */
|
||||||
|
if (s->ndirty != 0)
|
||||||
|
fd_flush (s);
|
||||||
s->dirty_offset = where;
|
s->dirty_offset = where;
|
||||||
s->ndirty = *len;
|
s->ndirty = *len;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (s->dirty_offset + s->ndirty == where)
|
gfc_offset start; /* Merge with the existing data. */
|
||||||
s->ndirty += *len;
|
if (where < s->dirty_offset)
|
||||||
|
start = where;
|
||||||
else
|
else
|
||||||
fd_flush (s); /* Can't combine two dirty blocks */
|
start = s->dirty_offset;
|
||||||
|
if (where + *len > s->dirty_offset + s->ndirty)
|
||||||
|
s->ndirty = where + *len - start;
|
||||||
|
else
|
||||||
|
s->ndirty = s->dirty_offset + s->ndirty - start;
|
||||||
|
s->dirty_offset = start;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->logical_offset = where + *len;
|
s->logical_offset = where + *len;
|
||||||
|
|
@ -461,14 +473,19 @@ static try
|
||||||
fd_truncate (unix_stream * s)
|
fd_truncate (unix_stream * s)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (ftruncate (s->fd, s->logical_offset))
|
if (lseek (s->fd, s->logical_offset, SEEK_SET) == -1)
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
|
|
||||||
|
/* non-seekable files, like terminals and fifo's fail the lseek.
|
||||||
|
the fd is a regular file at this point */
|
||||||
|
|
||||||
|
if (ftruncate (s->fd, s->logical_offset))
|
||||||
|
{
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
s->physical_offset = s->file_length = s->logical_offset;
|
s->physical_offset = s->file_length = s->logical_offset;
|
||||||
|
|
||||||
if (lseek (s->fd, s->file_length, SEEK_SET) == -1)
|
|
||||||
return FAILURE;
|
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1390,8 +1407,10 @@ file_position (stream * s)
|
||||||
int
|
int
|
||||||
is_seekable (stream * s)
|
is_seekable (stream * s)
|
||||||
{
|
{
|
||||||
|
/* by convention, if file_length == -1, the file is not seekable
|
||||||
return ((unix_stream *) s)->mmaped;
|
note that a mmapped file is always seekable, an fd_ file may
|
||||||
|
or may not be. */
|
||||||
|
return ((unix_stream *) s)->file_length!=-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue