summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoakim Tjernlund <joakim.tjernlund@transmode.se>2005-04-23 16:54:05 +0000
committerJoakim Tjernlund <joakim.tjernlund@transmode.se>2005-04-23 16:54:05 +0000
commit52b5a52b480f35928fccdff7298edf92736564ed (patch)
tree9dafd4f83e3b34b56efa43034ee5ff071bc5cc66
parentfdaf1b4fa8a79ce82b0c5f5a840ae98c7cb74786 (diff)
Fix dlopen to handle circular dependency libs. Wouldn't surprise me if something else
broke. I hate libdl :(
-rw-r--r--ldso/libdl/libdl.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
index 222c7743f..0c744c210 100644
--- a/ldso/libdl/libdl.c
+++ b/ldso/libdl/libdl.c
@@ -255,15 +255,28 @@ void *dlopen(const char *libname, int flag)
}
if (tpnt1->init_flag & DL_OPENED) {
/* Used to record RTLD_LOCAL scope */
- tmp = alloca(sizeof(struct init_fini_list)); /* Allocates on stack, no need to free this memory */
+ tmp = alloca(sizeof(struct init_fini_list));
tmp->tpnt = tpnt1;
tmp->next = runp->tpnt->init_fini;
runp->tpnt->init_fini = tmp;
- runp2->next = alloca(sizeof(*runp)); /* Allocates on stack, no need to free this memory */
- runp2 = runp2->next;
- runp2->tpnt = tpnt1;
- runp2->next = NULL;
+ for (tmp=dep_list; tmp; tmp = tmp->next) {
+ if (tpnt1 == tmp->tpnt) { /* if match => cirular dependency, drop it */
+#ifdef __SUPPORT_LD_DEBUG__
+ if(_dl_debug)
+ fprintf(stderr, "Circular dependency, skipping '%s',\n",
+ tmp->tpnt->libname);
+#endif
+ tpnt1->usage_count--;
+ break;
+ }
+ }
+ if (!tmp) { /* Don't add if circular dependency detected */
+ runp2->next = alloca(sizeof(*runp));
+ runp2 = runp2->next;
+ runp2->tpnt = tpnt1;
+ runp2->next = NULL;
+ }
}
}
}