On Wed, Oct 12, 2005 at 07:17:28PM +0300, Janne Blomqvist wrote:
No, not really. Your patch still touches fd_seek(). Attached patch is
my proposal for a fix.
Is this really necessary? This breaks one of the aims of your
original patch, which was to provide >2GB- records on 64-bit
systems.
If possible, I would prefer the following patch. This only uses
a single read() for special files (like terminals) and do_read()
otherwise.
This is regression-tested on i686-pc-linux-gnu. I would appreciate
if somebody could test it on a BSD-derived system to see that this
does fix the original problem.
Adding a test case for this bug will be ... interesting, requiring
integration of Dejagnu and pseudo terminals. Ugh. I hope everybody
agrees that we should waive the need for a test case here.
Thomas
------------------------------------------------------------------------
Index: unix.c
===================================================================
RCS file: /cvs/gcc/gcc/libgfortran/io/unix.c,v
retrieving revision 1.43
diff -c -p -r1.43 unix.c
*** unix.c 7 Oct 2005 20:02:28 -0000 1.43
--- unix.c 12 Oct 2005 21:46:38 -0000
*************** static char *
*** 440,446 ****
fd_alloc_r_at (unix_stream * s, int *len, gfc_offset where)
{
gfc_offset m;
- size_t n;
if (where == -1)
where = s->logical_offset;
--- 440,445 ----
*************** fd_alloc_r_at (unix_stream * s, int *len
*** 462,474 ****
if (s->physical_offset != m && lseek (s->fd, m, SEEK_SET) < 0)
return NULL;
! n = s->len - s->active;
! if (do_read (s, s->buffer + s->active, &n) != 0)
! return NULL;
! s->physical_offset = where + n;
- s->active += n;
if (s->active < *len)
*len = s->active; /* Bytes actually available */
--- 461,489 ----
if (s->physical_offset != m && lseek (s->fd, m, SEEK_SET) < 0)
return NULL;
! if (s->special_file)
! {
! int n;
!
! n = s->len - s->active;
! n = read (s->fd, s->buffer + s->active, s->len - s->active);
! if (n < 0)
! return NULL;
!
! s->physical_offset = where + n;
! s->active += n;
! }
! else
! {
! size_t n;
! n = s->len - s->active;
! if (do_read (s, s->buffer + s->active, &n) != 0)
! return NULL;
! s->physical_offset = where + n;
! s->active += n;
! }
if (s->active < *len)
*len = s->active; /* Bytes actually available */