aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerry DeLisle <jvdelisle@gcc.gnu.org>2007-07-15 05:29:29 +0000
committerJerry DeLisle <jvdelisle@gcc.gnu.org>2007-07-15 05:29:29 +0000
commitd40150cc3c1e85a9cbbaebb2679b6bac7a62ecbc (patch)
treedf8dbebd175229f5dd9969678dbf00c011fd21d9
parent6816e2e17db97a384cac3f66247a4acb37c4432a (diff)
downloadgcc-d40150cc3c1e85a9cbbaebb2679b6bac7a62ecbc.zip
gcc-d40150cc3c1e85a9cbbaebb2679b6bac7a62ecbc.tar.gz
gcc-d40150cc3c1e85a9cbbaebb2679b6bac7a62ecbc.tar.bz2
re PR libfortran/32752 (Segfault on WRITE with modified unix_stream structure)
2007-07-14 Jerry DeLisle <jvdelisle@gcc.gnu.org> 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
-rw-r--r--libgfortran/ChangeLog8
-rw-r--r--libgfortran/io/transfer.c13
-rw-r--r--libgfortran/io/unix.c4
3 files changed, 17 insertions, 8 deletions
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index 7f4a815..25bb24b 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,11 @@
+2007-07-14 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ 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 <fxcoudert@gcc.gnu.org>
PR fortran/32357
diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c
index a1c774e..067a065 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 bdfd245..ded0d05 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;