From d40150cc3c1e85a9cbbaebb2679b6bac7a62ecbc Mon Sep 17 00:00:00 2001 From: Jerry DeLisle Date: Sun, 15 Jul 2007 05:29:29 +0000 Subject: [PATCH] re PR libfortran/32752 (Segfault on WRITE with modified unix_stream structure) 2007-07-14 Jerry DeLisle PR libgfortran/32752 * io/unix.c (unix_stream): Move buffer pointer adjacent to small_buffer. * io/transfer.c (formatted_transfer_scalar): If stream I/O, set bytes_used to zero. Fix off by one error in calculation of pos and skips. Eliminate duplicate pending_spaces check. From-SVN: r126652 --- libgfortran/ChangeLog | 8 ++++++++ libgfortran/io/transfer.c | 13 +++++++------ libgfortran/io/unix.c | 4 ++-- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 7f4a815a6b9..25bb24bfb19 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,11 @@ +2007-07-14 Jerry DeLisle + + PR libgfortran/32752 + * io/unix.c (unix_stream): Move buffer pointer adjacent to small_buffer. + * io/transfer.c (formatted_transfer_scalar): If stream I/O, set + bytes_used to zero. Fix off by one error in calculation of pos and + skips. Eliminate duplicate pending_spaces check. + 2007-07-15 Francois-Xavier Coudert PR fortran/32357 diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c index a1c774e1dfd..067a065f9cf 100644 --- a/libgfortran/io/transfer.c +++ b/libgfortran/io/transfer.c @@ -949,7 +949,10 @@ formatted_transfer_scalar (st_parameter_dt *dtp, bt type, void *p, int len, } bytes_used = (int)(dtp->u.p.current_unit->recl - - dtp->u.p.current_unit->bytes_left); + - dtp->u.p.current_unit->bytes_left); + + if (is_stream_io(dtp)) + bytes_used = 0; switch (t) { @@ -1156,9 +1159,9 @@ formatted_transfer_scalar (st_parameter_dt *dtp, bt type, void *p, int len, case FMT_TR: consume_data_flag = 0; - pos = bytes_used + f->u.n + dtp->u.p.skips; - dtp->u.p.skips = f->u.n + dtp->u.p.skips; - dtp->u.p.pending_spaces = pos - dtp->u.p.max_pos; + dtp->u.p.skips += f->u.n; + pos = bytes_used + dtp->u.p.skips - 1; + dtp->u.p.pending_spaces = pos - dtp->u.p.max_pos + 1; /* Writes occur just before the switch on f->format, above, so that trailing blanks are suppressed, unless we are doing a @@ -1188,8 +1191,6 @@ formatted_transfer_scalar (st_parameter_dt *dtp, bt type, void *p, int len, if (bytes_used == 0) { dtp->u.p.pending_spaces -= f->u.n; - dtp->u.p.pending_spaces = dtp->u.p.pending_spaces < 0 ? 0 - : dtp->u.p.pending_spaces; dtp->u.p.skips -= f->u.n; dtp->u.p.skips = dtp->u.p.skips < 0 ? 0 : dtp->u.p.skips; } diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c index bdfd245a533..ded0d053d9c 100644 --- a/libgfortran/io/unix.c +++ b/libgfortran/io/unix.c @@ -97,7 +97,6 @@ typedef struct gfc_offset dirty_offset; /* Start of modified bytes in buffer */ gfc_offset file_length; /* Length of the file, -1 if not seekable. */ - char *buffer; int len; /* Physical length of the current buffer */ int active; /* Length of valid bytes in the buffer */ @@ -108,6 +107,7 @@ typedef struct int unbuffered; /* =1 if the stream is not buffered */ + char *buffer; char small_buffer[BUFFER_SIZE]; } unix_stream; @@ -587,7 +587,7 @@ fd_alloc_w_at (unix_stream * s, int *len, gfc_offset where) s->ndirty = where + *len - start; else s->ndirty = s->dirty_offset + s->ndirty - start; - s->dirty_offset = start; + s->dirty_offset = start; } s->logical_offset = where + *len;