Subject: B20.1: setvbuf implementation incorrect for <mode> == _IONBF
From: [email-masked] (Tom Shields)

16 Jan 1999 06:34:30 -0800
Message-ID: <[email-masked]>
Mime-Version: 1.0
Content-Type: multipart/mixed;
 boundary="------------C24A60FEE63478A8BB04F23A"
To: [email-masked]

This is a multi-part message in MIME format.
--------------C24A60FEE63478A8BB04F23A
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

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====
--------------C24A60FEE63478A8BB04F23A
Content-Type: text/x-vcard; charset=us-ascii;
 name="Shields.vcf"
Content-Transfer-Encoding: 7bit
Content-Description: Card for Tom Shields
Content-Disposition: attachment;
 filename="Shields.vcf"

begin:vcard 
n:Shields;Tom
x-mozilla-html:TRUE
org:The Mars Hotel
adr:;;;;;;
version:2.1
email;internet:[email-masked]
title:Inn Keeper
x-mozilla-cpt:;-31952
fn:Shields, Tom
end:vcard

--------------C24A60FEE63478A8BB04F23A--

-
For help on using this list (especially unsubscribing), send a message to
"[email-masked]" with one line of text: "help".