summaryrefslogtreecommitdiff
path: root/libstore
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2003-08-04 18:05:21 +0000
committerRoland McGrath <roland@gnu.org>2003-08-04 18:05:21 +0000
commita05d8963b42a475266fc826464f57a2a187ac16f (patch)
treeeae43c6466728df8cd9137e4adaf6f6a4074fa94 /libstore
parent141e4b353e0b1a461a6187adbf2c4e3227c508b4 (diff)
2003-08-04 Roland McGrath <roland@frob.com>
* typed.c (store_find_class): Use dlopen/dlclose on the names found by looking through the list instead of passing list elements directly to dlsym, which is not kosher.
Diffstat (limited to 'libstore')
-rw-r--r--libstore/typed.c44
1 files changed, 28 insertions, 16 deletions
diff --git a/libstore/typed.c b/libstore/typed.c
index 42b27bd5..814d6a05 100644
--- a/libstore/typed.c
+++ b/libstore/typed.c
@@ -1,6 +1,6 @@
/* Support for opening `typed' stores
- Copyright (C) 1997,98,2001,02,03 Free Software Foundation, Inc.
+ Copyright (C) 1997,1998,2001,2002,2003 Free Software Foundation, Inc.
Written by Miles Bader <miles@gnu.org>
This file is part of the GNU Hurd.
@@ -64,32 +64,44 @@ store_find_class (const char *name, const char *clname_end,
and examine each one's "store_std_classes" section. */
# pragma weak _r_debug
# pragma weak dlsym
+# pragma weak dlopen
+# pragma weak dlclose
# pragma weak dlerror
if (dlsym)
{
struct link_map *map;
for (map = _r_debug.r_map; map != 0; map = map->l_next)
{
- const struct store_class *const *start;
- const struct store_class *const *stop;
- start = dlsym (map, "__start_store_std_classes");
- if (start == 0)
+ const struct store_class *const *start, *const *stop;
+
+ /* We cannot just use MAP directly because it may not have been
+ opened by dlopen such that its data structures are fully set
+ up for dlsym. */
+ void *module = dlopen (map->l_name, RTLD_NOLOAD);
+ if (module == 0)
{
- (void) dlerror (); /* Required to avoid a leak! */
+ (void) dlerror (); /* Required to avoid a leak! */
continue;
}
- if (start == __start_store_std_classes)
- continue;
- stop = dlsym (map, "__stop_store_std_classes");
- if (stop == 0)
+
+ start = dlsym (map, "__start_store_std_classes");
+ if (start == 0)
+ (void) dlerror (); /* Required to avoid a leak! */
+ else if (start != __start_store_std_classes) /* */
{
- (void) dlerror (); /* Required to avoid a leak! */
- continue;
+ stop = dlsym (map, "__stop_store_std_classes");
+ if (stop == 0)
+ (void) dlerror (); /* Required to avoid a leak! */
+ else
+ for (cl = start; cl < stop; ++cl)
+ if (strlen ((*cl)->name) == (clname_end - name)
+ && strncmp (name, (*cl)->name, (clname_end - name)) == 0)
+ {
+ dlclose (module);
+ return *cl;
+ }
}
- for (cl = start; cl < stop; ++cl)
- if (strlen ((*cl)->name) == (clname_end - name)
- && strncmp (name, (*cl)->name, (clname_end - name)) == 0)
- return *cl;
+ dlclose (module);
}
}