[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[commits] r9788 - in /fsf/trunk/libc: ChangeLog stdlib/setenv.c



Author: eglibc
Date: Wed Feb  3 00:03:01 2010
New Revision: 9788

Log:
Import glibc-mainline for 2010-02-03

Modified:
    fsf/trunk/libc/ChangeLog
    fsf/trunk/libc/stdlib/setenv.c

Modified: fsf/trunk/libc/ChangeLog
==============================================================================
--- fsf/trunk/libc/ChangeLog (original)
+++ fsf/trunk/libc/ChangeLog Wed Feb  3 00:03:01 2010
@@ -1,3 +1,9 @@
+2010-02-02  Ulrich Drepper  <drepper@xxxxxxxxxx>
+
+	* stdlib/setenv.c (__add_to_environ): Don't use alloca if
+	__libc_use_alloca tells us not to.  Fix memory leak in an error
+	situation.  Based partially on patch by Jim Meyering.
+
 2010-01-26  Samuel Thibault  <samuel.thibault@xxxxxxxxxxxx>
 
 	* sysdeps/mach/getsysstats.c (get_nprocs_conf, get_nprocs,

Modified: fsf/trunk/libc/stdlib/setenv.c
==============================================================================
--- fsf/trunk/libc/stdlib/setenv.c (original)
+++ fsf/trunk/libc/stdlib/setenv.c Wed Feb  3 00:03:01 2010
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992,1995-2001,2004, 2008 Free Software Foundation, Inc.
+/* Copyright (C) 1992,1995-2001,2004, 2008, 2010 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -136,6 +136,7 @@
 
   if (ep == NULL || __builtin_expect (*ep == NULL, 1))
     {
+      const size_t varlen = namelen + 1 + vallen;
       char **new_environ;
 
       /* We allocated this space; we can extend it.  */
@@ -156,11 +157,21 @@
 	{
 	  /* See whether the value is already known.  */
 #ifdef USE_TSEARCH
-# ifdef __GNUC__
-	  char new_value[namelen + 1 + vallen];
-# else
-	  char *new_value = (char *) alloca (namelen + 1 + vallen);
-# endif
+	  char *new_value;
+	  int use_alloca = __libc_use_alloca (varlen);
+	  if (__builtin_expect (use_alloca, 1))
+	    new_value = (char *) alloca (varlen);
+	  else
+	    {
+	      new_value = malloc (varlen);
+	      if (new_value == NULL)
+		{
+		  UNLOCK;
+		  if (last_environ == NULL)
+		    free (new_environ);
+		  return -1;
+		}
+	    }
 # ifdef _LIBC
 	  __mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1),
 		     value, vallen);
@@ -174,21 +185,28 @@
 	  if (__builtin_expect (new_environ[size] == NULL, 1))
 #endif
 	    {
-	      new_environ[size] = (char *) malloc (namelen + 1 + vallen);
-	      if (__builtin_expect (new_environ[size] == NULL, 0))
+#ifdef USE_TSEARCH
+	      if (__builtin_expect (! use_alloca, 0))
+		new_environ[size] = new_value;
+	      else
+#endif
 		{
-		  __set_errno (ENOMEM);
-		  UNLOCK;
-		  return -1;
+		  new_environ[size] = (char *) malloc (varlen);
+		  if (__builtin_expect (new_environ[size] == NULL, 0))
+		    {
+		      UNLOCK;
+		      return -1;
+		    }
+
+#ifdef USE_TSEARCH
+		  memcpy (new_environ[size], new_value, varlen);
+#else
+		  memcpy (new_environ[size], name, namelen);
+		  new_environ[size][namelen] = '=';
+		  memcpy (&new_environ[size][namelen + 1], value, vallen);
+#endif
 		}
 
-#ifdef USE_TSEARCH
-	      memcpy (new_environ[size], new_value, namelen + 1 + vallen);
-#else
-	      memcpy (new_environ[size], name, namelen);
-	      new_environ[size][namelen] = '=';
-	      memcpy (&new_environ[size][namelen + 1], value, vallen);
-#endif
 	      /* And save the value now.  We cannot do this when we remove
 		 the string since then we cannot decide whether it is a
 		 user string or not.  */
@@ -213,12 +231,21 @@
 	np = (char *) combined;
       else
 	{
-#ifdef USE_TSEARCH
-# ifdef __GNUC__
-	  char new_value[namelen + 1 + vallen];
-# else
-	  char *new_value = (char *) alloca (namelen + 1 + vallen);
-# endif
+	  const size_t varlen = namelen + 1 + vallen;
+#ifdef USE_TSEARCH
+	  char *new_value;
+	  int use_alloca = __libc_use_alloca (varlen);
+	  if (__builtin_expect (use_alloca, 1))
+	    new_value = (char *) alloca (varlen);
+	  else
+	    {
+	      new_value = malloc (varlen);
+	      if (new_value == NULL)
+		{
+		  UNLOCK;
+		  return -1;
+		}
+	    }
 # ifdef _LIBC
 	  __mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1),
 		     value, vallen);
@@ -232,20 +259,27 @@
 	  if (__builtin_expect (np == NULL, 1))
 #endif
 	    {
-	      np = malloc (namelen + 1 + vallen);
-	      if (__builtin_expect (np == NULL, 0))
+#ifdef USE_TSEARCH
+	      if (__builtin_expect (! use_alloca, 0))
+		np = new_value;
+	      else
+#endif
 		{
-		  UNLOCK;
-		  return -1;
+		  np = malloc (varlen);
+		  if (__builtin_expect (np == NULL, 0))
+		    {
+		      UNLOCK;
+		      return -1;
+		    }
+
+#ifdef USE_TSEARCH
+		  memcpy (np, new_value, varlen);
+#else
+		  memcpy (np, name, namelen);
+		  np[namelen] = '=';
+		  memcpy (&np[namelen + 1], value, vallen);
+#endif
 		}
-
-#ifdef USE_TSEARCH
-	      memcpy (np, new_value, namelen + 1 + vallen);
-#else
-	      memcpy (np, name, namelen);
-	      np[namelen] = '=';
-	      memcpy (&np[namelen + 1], value, vallen);
-#endif
 	      /* And remember the value.  */
 	      STORE_VALUE (np);
 	    }