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] for bug 1814


Greetings,

While I know that some might not be all that excited about fixing this one 
I'd rather follow the POSIX spec which I believe we are currently not 
doing for dlerror. 

Enclosed is a patch to fix that which in the non error case does result in 
an optimization since the old code always went out to the thread specific
buffer or the static buffer needlessly.

2005-11-08  Tom Gall <tom_gall@vnet.ibm.com>

	* dlfcn/dlerror.c: Change dlerror to update dl_action_result only 
	in case of error.

--- libc/dlfcn/dlerror.c	2005-11-08 14:11:17.603631512 -0500
+++ libc-dlerror/dlfcn/dlerror.c	2005-11-08 14:43:49.191530104 -0500
@@ -124,50 +124,67 @@
 internal_function
 _dlerror_run (void (*operate) (void *), void *args)
 {
+  struct dl_action_result tmpresult;
   struct dl_action_result *result;
 
   /* If we have not yet initialized the buffer do it now.  */
   __libc_once (once, init);
 
-  /* Get error string and number.  */
-  if (static_buf != NULL)
-    result = static_buf;
-  else
+  /* stuff result into tmp location under the presumption
+     there will be no error and thus it'll just be thrown away */
+  tmpresult.errcode = GLRO(dl_catch_error) (&(tmpresult.objname), 
+                                            &(tmpresult.errstring),
+                                            &(tmpresult.malloced), 
+                                            operate, args);
+
+  /* if we have an error copy error data into the right and proper place
+     otherwise, do nothing */
+  if (tmpresult.errstring != NULL)
     {
-      /* We don't use the static buffer and so we have a key.  Use it
-	 to get the thread-specific buffer.  */
-      result = __libc_getspecific (key);
-      if (result == NULL)
-	{
-	  result = (struct dl_action_result *) calloc (1, sizeof (*result));
-	  if (result == NULL)
-	    /* We are out of memory.  Since this is no really critical
-	       situation we carry on by using the global variable.
-	       This might lead to conflicts between the threads but
-	       they soon all will have memory problems.  */
-	    result = &last_result;
-	  else
-	    /* Set the tsd.  */
-	    __libc_setspecific (key, result);
-	}
-    }
 
-  if (result->errstring != NULL)
-    {
-      /* Free the error string from the last failed command.  This can
-	 happen if `dlerror' was not run after an error was found.  */
-      if (result->malloced)
-	free ((char *) result->errstring);
-      result->errstring = NULL;
-    }
+      /* if we have an error copy error data into the right and proper place
+         otherwise, do nothing */
 
-  result->errcode = GLRO(dl_catch_error) (&result->objname, &result->errstring,
-					  &result->malloced, operate, args);
-
-  /* If no error we mark that no error string is available.  */
-  result->returned = result->errstring == NULL;
+      /* Get error string and number.  */
+      if (static_buf != NULL)
+        result = static_buf;
+      else
+        {
+          /* We don't use the static buffer and so we have a key.  Use it
+	     to get the thread-specific buffer.  */
+          result = __libc_getspecific (key);
+          if (result == NULL)
+            {
+	      result = (struct dl_action_result *) calloc (1, sizeof (*result));
+	      if (result == NULL)
+	        /* We are out of memory.  Since this is not really critical
+	           situation we carry on by using the global variable.
+	           This might lead to conflicts between the threads but
+	           they soon all will have memory problems.  */
+	        result = &last_result;
+	      else
+	        /* Set the tsd.  */
+	        __libc_setspecific (key, result);
+	    }
+        }
+
+      if (result->errstring != NULL)
+        {
+          /* Free the error string from the last failed command.  This can
+	     happen if `dlerror' was not run after an error was found.  */
+          if (result->malloced)
+	    free ((char *) result->errstring);
+          result->errstring = NULL;
+        }
+
+      result->returned = tmpresult.errstring == NULL;
+      result->errcode = tmpresult.errcode;
+      result->objname = tmpresult.objname;
+      result->malloced = tmpresult.malloced;
+      result->errstring = tmpresult.errstring;
+    }
 
-  return result->errstring != NULL;
+  return tmpresult.errstring != NULL;
 }
 
 


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