This is the mail archive of the libc-alpha@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]

[PATCH] libio: Add small optimization on fmemopen


This patch uses C99 variable-lenght array on internal fmemopen cookie
allocation to avoid to use two mallocs for the case if an internal
buffer must be allocated.  No functional changes are done.

Tested on x86_64 and i686.

	* libio/fmemopen.c (fmemopen_cookie_t): Remove mybuffer and add
	variable-length array member.
	(fmemopen_close): Do no free the internal buffer.
	(__fmemopen): Use C99 variable-length array to allocate both the
	fmemopen cookie and internal buffer (for null arguments).
---
 libio/fmemopen.c | 40 ++++++++++++++++------------------------
 2 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/libio/fmemopen.c b/libio/fmemopen.c
index 0f65590..d7df1be 100644
--- a/libio/fmemopen.c
+++ b/libio/fmemopen.c
@@ -35,11 +35,11 @@ typedef struct fmemopen_cookie_struct fmemopen_cookie_t;
 struct fmemopen_cookie_struct
 {
   char        *buffer;   /* memory buffer.  */
-  int         mybuffer;  /* allocated my buffer?  */
   int         append;    /* buffer open for append?  */
   size_t      size;      /* buffer length in bytes.  */
   _IO_off64_t pos;       /* current position at the buffer.  */
   size_t      maxpos;    /* max position in buffer.  */
+  char        data[];
 };
 
 
@@ -136,11 +136,7 @@ fmemopen_seek (void *cookie, _IO_off64_t *p, int w)
 static int
 fmemopen_close (void *cookie)
 {
-  fmemopen_cookie_t *c = (fmemopen_cookie_t *) cookie;
-
-  if (c->mybuffer)
-    free (c->buffer);
-  free (c);
+  free (cookie);
 
   return 0;
 }
@@ -153,23 +149,24 @@ __fmemopen (void *buf, size_t len, const char *mode)
   fmemopen_cookie_t *c;
   FILE *result;
 
-  c = (fmemopen_cookie_t *) calloc (sizeof (fmemopen_cookie_t), 1);
-  if (c == NULL)
-    return NULL;
-
-  c->mybuffer = (buf == NULL);
-
-  if (c->mybuffer)
+  size_t clen = sizeof (fmemopen_cookie_t);
+  if (buf == NULL)
     {
-      c->buffer = (char *) malloc (len);
-      if (c->buffer == NULL)
+      if (__glibc_unlikely (len >= (SIZE_MAX - clen)))
 	{
-	  free (c);
+	  __set_errno (ENOMEM);
 	  return NULL;
 	}
-      c->buffer[0] = '\0';
+      clen += len;
     }
-  else
+
+  c = (fmemopen_cookie_t *) calloc (clen, 1);
+  if (c == NULL)
+    return NULL;
+
+  c->buffer = c->data;
+
+  if (buf != NULL)
     {
       if (__glibc_unlikely ((uintptr_t) len > -(uintptr_t) buf))
 	{
@@ -214,12 +211,7 @@ __fmemopen (void *buf, size_t len, const char *mode)
 
   result = _IO_fopencookie (c, mode, iof);
   if (__glibc_unlikely (result == NULL))
-    {
-      if (c->mybuffer)
-	free (c->buffer);
-
-      free (c);
-    }
+    free (c);
 
   return result;
 }
-- 
2.7.4


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