This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] for bug 1814
- From: Tom Gall <tom_gall at vnet dot ibm dot com>
- To: libc-alpha at sources dot redhat dot com
- Cc: decimal at us dot ibm dot com
- Date: Tue, 8 Nov 2005 14:47:53 -0600 (CST)
- Subject: [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;
}