re PR libfortran/32752 (Segfault on WRITE with modified unix_stream structure)
authorJerry DeLisle <jvdelisle@gcc.gnu.org>
Sun, 15 Jul 2007 05:29:29 +0000 (05:29 +0000)
committerJerry DeLisle <jvdelisle@gcc.gnu.org>
Sun, 15 Jul 2007 05:29:29 +0000 (05:29 +0000)
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

libgfortran/ChangeLog
libgfortran/io/transfer.c
libgfortran/io/unix.c

index 7f4a815a6b91f8da5d6245bbcbbf4315f05d582a..25bb24bfb1951a6d91c1ab3fb527b319232e7bb8 100644 (file)
@@ -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
index a1c774e1dfd6313eda35193b6957d7496e6d8d16..067a065f9cfcb37045c5b36205aef0dda4272e9f 100644 (file)
@@ -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;
                }
index bdfd245a5331aa64277e487f022dcaed0feb3042..ded0d053d9ce5ed4f95bcaddfdd28e6ed973a260 100644 (file)
@@ -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;