提交 a9e85c0a 编写于 作者: R Rich Felker

make dlerror conform to posix

the error status is required to be sticky after failure of dlopen or
dlsym until cleared by dlerror. applications and especially libraries
should never rely on this since it is not thread-safe and subject to
race conditions, but glib does anyway.
上级 494ba80e
#ifdef __PIC__
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
...@@ -18,6 +17,10 @@ ...@@ -18,6 +17,10 @@
#include <ctype.h> #include <ctype.h>
#include <dlfcn.h> #include <dlfcn.h>
static int errflag;
#ifdef __PIC__
#include "reloc.h" #include "reloc.h"
#if ULONG_MAX == 0xffffffff #if ULONG_MAX == 0xffffffff
...@@ -631,12 +634,13 @@ void *dlopen(const char *file, int mode) ...@@ -631,12 +634,13 @@ void *dlopen(const char *file, int mode)
tail = orig_tail; tail = orig_tail;
tail->next = 0; tail->next = 0;
p = 0; p = 0;
} else p = load_library(file);
if (!p) {
errflag = 1;
goto end; goto end;
} }
p = load_library(file);
if (!p) goto end;
/* First load handling */ /* First load handling */
if (!p->deps) { if (!p->deps) {
load_deps(p); load_deps(p);
...@@ -674,8 +678,11 @@ static void *do_dlsym(struct dso *p, const char *s, void *ra) ...@@ -674,8 +678,11 @@ static void *do_dlsym(struct dso *p, const char *s, void *ra)
if (!p) p=head; if (!p) p=head;
p=p->next; p=p->next;
} }
if (p == head || p == RTLD_DEFAULT) if (p == head || p == RTLD_DEFAULT) {
return find_sym(head, s, 0); void *res = find_sym(head, s, 0);
if (!res) errflag = 1;
return res;
}
h = hash(s); h = hash(s);
sym = lookup(s, h, p->syms, p->hashtab, p->strings); sym = lookup(s, h, p->syms, p->hashtab, p->strings);
if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES)) if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES))
...@@ -686,6 +693,7 @@ static void *do_dlsym(struct dso *p, const char *s, void *ra) ...@@ -686,6 +693,7 @@ static void *do_dlsym(struct dso *p, const char *s, void *ra)
if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES)) if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES))
return p->deps[i]->base + sym->st_value; return p->deps[i]->base + sym->st_value;
} }
errflag = 1;
return 0; return 0;
} }
...@@ -710,6 +718,8 @@ void *__dlsym(void *p, const char *s, void *ra) ...@@ -710,6 +718,8 @@ void *__dlsym(void *p, const char *s, void *ra)
char *dlerror() char *dlerror()
{ {
if (!errflag) return 0;
errflag = 0;
return "unknown error"; return "unknown error";
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册