about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--NEWS5
-rw-r--r--libio/fmemopen.c11
3 files changed, 17 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 0975959dec..2415c65541 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2008-08-13  Ulrich Drepper  <drepper@redhat.com>
 
+	[BZ #6544]
+	* libio/fmemopen.c: Implement binary mode.  In this mode no NUL
+	byte gets added to writes and seeks from the end use the length of
+	the buffer and not the currently terminating NUL byte.
+
 	[BZ #6634]
 	* login/utmp_file.c (getutent_r_file): Take additional parameter.
 	Set to true if locking failed.
diff --git a/NEWS b/NEWS
index fd7f7c9151..c3ceaba42e 100644
--- a/NEWS
+++ b/NEWS
@@ -28,6 +28,11 @@ Version 2.9
 * Implement "e" option for popen to open file descriptor with the
   close-on-exec flag set.  Implemented by Ulrich Drepper.
 
+* Implement "b" mode for fmemopen.  In this mode writes writes don't
+  implicitly add a NUL byte and seeks from the end of the buffer really
+  use the buffer end, not the string length as the basis.
+  Implemented by Ulrich Drepper.
+
 * Many functions, exported and internal, now atomically set the close-on-exec
   flag when run on a sufficiently new kernel.  Implemented by Ulrich Drepper.
 
diff --git a/libio/fmemopen.c b/libio/fmemopen.c
index f3b280092c..b618ce585d 100644
--- a/libio/fmemopen.c
+++ b/libio/fmemopen.c
@@ -1,7 +1,7 @@
 /* Fmemopen implementation.
-   Copyright (C) 2000, 2002, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2002, 2005, 2006, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
-   Contributed by  Hanno Mueller, kontakt@hanno.de, 2000.
+   Contributed by Hanno Mueller, kontakt@hanno.de, 2000.
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -82,6 +82,7 @@ struct fmemopen_cookie_struct
 {
   char *buffer;
   int mybuffer;
+  int binmode;
   size_t size;
   _IO_off64_t pos;
   size_t maxpos;
@@ -120,7 +121,7 @@ fmemopen_write (void *cookie, const char *b, size_t s)
 
   c = (fmemopen_cookie_t *) cookie;
 
-  addnullc = s == 0 || b[s - 1] != '\0';
+  addnullc = c->binmode == 0 && (s == 0 || b[s - 1] != '\0');
 
   if (c->pos + s + addnullc > c->size)
     {
@@ -165,7 +166,7 @@ fmemopen_seek (void *cookie, _IO_off64_t *p, int w)
       break;
 
     case SEEK_END:
-      np = c->maxpos - *p;
+      np = (c->binmode ? c->size : c->maxpos) - *p;
       break;
 
     default:
@@ -248,6 +249,8 @@ fmemopen (void *buf, size_t len, const char *mode)
   else
     c->pos = 0;
 
+  c->binmode = mode[0] != '\0' && mode[1] == 'b';
+
   iof.read = fmemopen_read;
   iof.write = fmemopen_write;
   iof.seek = fmemopen_seek;