B20.1: setvbuf implementation incorrect for <mode> == _IONBF

Tom Shields Shields@cmpu.net
Sun Jan 31 23:52:00 GMT 1999


The implementation of setvbuf in the B20.1 source release is
incorrect if the mode parameter is _IONBF (unbuffered IO); it
doesn't deallocate the current buffer (there will be one), which
is a cause of memory leaks, but more importantly it overwrites
the buffer heap pointer but leaves the __SMBF flag set indicating
that there is a heap allocated buffer, so that when fclose is
invoked, it eventually tries to free a non-heap pointer value,
which causes the run-time exception STATUS_ACCESS_VIOLATION.

I've appended a simple fix - the invocation of fflush is unnecessary
for this case, since setvbuf is supposed to be called prior to
doing any IO on the file, but this fix is the least perturbation
to the source.

I rebuilt b20.1, and put cygwin1.dll in my test app's directory
(PATH includes ".") for verification, but I'm experiencing wierd
behavior now: my test app craters immediately with another
STATUS_ACCESS_VIOLATION if I run it from the bash command line
(as opposed to cratering at the end of execution with the fclose),
but if I run the test app under gdb it works perfectly now (no
STATUS_ACCESS_VIOLATION in the fclose)!

Can someone explain what is going on? I'm hesitant to install
the rebuilt b20.1 environment due to this strange behavior.

Thanks

Tom Shields

====snip====snip====snip====snip====snip====snip====snip====snip====snip====
*** newlib/libc/stdio/setvbuf.c.orig	Tue Oct 15 09:01:30 1996
--- newlib/libc/stdio/setvbuf.c	Wed Jan 13 23:37:28 1999
***************
*** 113,121 ****
    if ((mode != _IOFBF && mode != _IOLBF && mode != _IONBF) ||
(int)(_POINTER_INT) size < 0)
      return (EOF);
  
-   if (mode == _IONBF)
-     goto nbf;
- 
    /*
     * Write current buffer, if any; drop read count, if any.
     * Make sure putc() will not think fp is line buffered.
--- 113,118 ----
***************
*** 129,134 ****
--- 126,134 ----
    if (fp->_flags & __SMBF)
      _free_r (fp->_data, (void *) fp->_bf._base);
    fp->_flags &= ~(__SLBF | __SNBF | __SMBF);
+ 
+   if (mode == _IONBF)
+     goto nbf;
  
    /*
     * Allocate buffer if needed. */
====snip====snip====snip====snip====snip====snip====snip====snip====snip====
begin:vcard 
n:Shields;Tom
x-mozilla-html:TRUE
org:The Mars Hotel
adr:;;;;;;
version:2.1
email;internet:Shields@CMPU.NET
title:Inn Keeper
x-mozilla-cpt:;-31952
fn:Shields, Tom
end:vcard


More information about the Cygwin mailing list