This is the mail archive of the glibc-bugs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug libc/1995] fprintf() + fmemopen() error (?)


------- Additional Comments From rsa at us dot ibm dot com  2006-04-11 22:49 -------
Michael Kerrisk,

Unfortunately you've been bitten by GLIBC default stream buffering, which is
_IOFBF, being 'fully buffered' which is synonymous in the manual pages with
'block buffered'.

This means that the stream has an internal buffer and it holds data in that
buffer until such time that it needs to write it to a file (which is 'buf[10]').
 It generally writes to the file when prompted via a fflush() or an fclose().

In your source code example only when the file is closed is the fmemopen_write()
function invoked.  The buffer buf[10] isn't ever overwritten because
fmemopen_write() prevents that from happening.

The invocation of fprintf() against the stream always succeeds because the
stream's internal buffer is large enough to hold all 19 characters.

To get fprintf() to report in the manner you desire you can set the stream
buffering mode to _IONBF, 'unbuffered' using setvbuf().  This will direct
fprintf() to write directly to the file (buf[10]), which will invoke
fmemopen_write() directly.  You'll get the '-1' return value from fprintf() that
you're looking for.  Otherwise do your own accounting on avail space in buf
before you call fprintf.

Please reference the following source:

#define _GNU_SOURCE
#include <stdio.h>

int main()
{
  char buf[10];
  FILE *fp;
  int ret;

  fp = fmemopen(&buf[0], sizeof(buf), "w");
  setvbuf(fp, (char *)NULL, _IONBF, 0);

  /* write 19 and see it fail */
  ret = fprintf(fp, "%s", "1234567890123456789");
  printf("ret = %d buf=%s\n", ret, buf);

  /* reset the stream pointer to the beginning. */
  (void)fseek(fp, 0L, SEEK_SET);
  /* write 9 exactly and see it succeed */
  ret = fprintf(fp, "%s", "abcdefghi");
  printf("ret =  %d buf=%s\n", ret, buf);

  fclose(fp);
  return 0;
}

There is no bug in glibc.

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |INVALID


http://sourceware.org/bugzilla/show_bug.cgi?id=1995

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]