change `ffi-lib' to not make library symbols global by default
This commit is contained in:
parent
ab9607b35a
commit
13a5b0c623
|
@ -93,7 +93,8 @@
|
|||
ffi-lib? ffi-lib-name)
|
||||
(define (get-ffi-lib name [version/s ""]
|
||||
#:fail [fail #f]
|
||||
#:get-lib-dirs [get-lib-dirs get-lib-search-dirs])
|
||||
#:get-lib-dirs [get-lib-dirs get-lib-search-dirs]
|
||||
#:global? [global? #f])
|
||||
(cond
|
||||
[(not name) (ffi-lib name)] ; #f => NULL => open this executable
|
||||
[(not (or (string? name) (path? name)))
|
||||
|
@ -123,7 +124,7 @@
|
|||
(string-append name0 "." lib-suffix v)
|
||||
(string-append name0 v "." lib-suffix))))
|
||||
versions)]
|
||||
[ffi-lib* (lambda (name) (ffi-lib name #t))])
|
||||
[ffi-lib* (lambda (name) (ffi-lib name #t global?))])
|
||||
(or ;; try to look in our library paths first
|
||||
(and (not absolute?)
|
||||
(ormap (lambda (dir)
|
||||
|
@ -145,8 +146,8 @@
|
|||
(if fail
|
||||
(fail)
|
||||
(if (pair? names)
|
||||
(ffi-lib (car names))
|
||||
(ffi-lib name0)))))]))
|
||||
(ffi-lib (car names) #f global?)
|
||||
(ffi-lib name0 #f global?)))))]))
|
||||
|
||||
(define (get-ffi-lib-internal x)
|
||||
(if (ffi-lib? x) x (get-ffi-lib x)))
|
||||
|
|
|
@ -17,7 +17,8 @@ Returns @racket[#t] if @racket[v] is a @deftech{foreign-library value},
|
|||
@defproc[(ffi-lib [path (or/c path-string? #f)]
|
||||
[version (or/c string? (listof (or/c string? #f)) #f) #f]
|
||||
[#:get-lib-dirs get-lib-dirs (-> (listof path?)) get-lib-search-dirs]
|
||||
[#:fail fail (or/c #f (-> any)) #f])
|
||||
[#:fail fail (or/c #f (-> any)) #f]
|
||||
[#:global? global? any/c #f])
|
||||
any]{
|
||||
|
||||
Returns a @tech{foreign-library value} or the result of @racket[fail].
|
||||
|
@ -96,6 +97,15 @@ by the run-time system (as described in @|InsideRacket|). The
|
|||
@racket[version] argument is ignored when @racket[path] is
|
||||
@racket[#f].
|
||||
|
||||
If @racket[path] is not @racket[#f], @racket[global?] is true, and the
|
||||
operating system supports opening a library in ``global'' mode so that
|
||||
the library's symbols are used for resolving references from libraries
|
||||
that are loaded later, then global mode is used to open the
|
||||
library. Otherwise, the library is opened in ``local'' mode, where the
|
||||
library's symbols are not made available for future resolution. This
|
||||
local-versus-global choice does not affect whether the library's
|
||||
symbols are available via @racket[(ffi-lib #f)].
|
||||
|
||||
Due to the way the operating system performs dynamic binding, loaded
|
||||
libraries are associated with Racket (or DrRacket) for the duration of
|
||||
the process. Re-evaluating @racket[ffi-lib] (or hitting the
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
Version 5.2.1.4
|
||||
Changed ffi-lib to open libraries in local mode by default
|
||||
|
||||
Version 5.2.1, January 2012
|
||||
Changed I/O scheduling to use epoll()/kqueue() when available
|
||||
Cross-module inline trivial functions, plus map, for-each,
|
||||
|
|
|
@ -168,6 +168,7 @@ typedef struct ffi_lib_struct {
|
|||
NON_GCBALE_PTR(void) handle;
|
||||
Scheme_Object* name;
|
||||
Scheme_Hash_Table* objects;
|
||||
int is_global;
|
||||
} ffi_lib_struct;
|
||||
#define SCHEME_FFILIBP(x) (SCHEME_TYPE(x)==ffi_lib_tag)
|
||||
#define MYNAME "ffi-lib?"
|
||||
|
@ -199,17 +200,18 @@ END_XFORM_SKIP;
|
|||
|
||||
THREAD_LOCAL_DECL(static Scheme_Hash_Table *opened_libs);
|
||||
|
||||
/* (ffi-lib filename no-error?) -> ffi-lib */
|
||||
/* (ffi-lib filename no-error? global?) -> ffi-lib */
|
||||
#define MYNAME "ffi-lib"
|
||||
static Scheme_Object *foreign_ffi_lib(int argc, Scheme_Object *argv[])
|
||||
{
|
||||
char *name;
|
||||
Scheme_Object *path, *hashname;
|
||||
void *handle;
|
||||
int null_ok = 0;
|
||||
int null_ok = 0, as_global = 0;
|
||||
ffi_lib_struct *lib;
|
||||
if (!(SCHEME_PATH_STRINGP(argv[0]) || SCHEME_FALSEP(argv[0])))
|
||||
scheme_wrong_type(MYNAME, "string-or-false", 0, argc, argv);
|
||||
as_global = ((argc > 2) && SCHEME_TRUEP(argv[2]));
|
||||
/* leave the filename as given, the system will look for it */
|
||||
/* (`#f' means open the executable) */
|
||||
path = SCHEME_FALSEP(argv[0]) ? NULL : TO_PATH(argv[0]);
|
||||
|
@ -226,7 +228,7 @@ static Scheme_Object *foreign_ffi_lib(int argc, Scheme_Object *argv[])
|
|||
} else
|
||||
handle = LoadLibraryW(WIDE_PATH(name));
|
||||
# else /* WINDOWS_DYNAMIC_LOAD undefined */
|
||||
handle = dlopen(name, RTLD_NOW | RTLD_GLOBAL);
|
||||
handle = dlopen(name, RTLD_NOW | (as_global ? RTLD_GLOBAL : RTLD_LOCAL));
|
||||
# endif /* WINDOWS_DYNAMIC_LOAD */
|
||||
if (handle == NULL && !null_ok) {
|
||||
if (argc > 1 && SCHEME_TRUEP(argv[1])) return scheme_false;
|
||||
|
@ -248,6 +250,7 @@ static Scheme_Object *foreign_ffi_lib(int argc, Scheme_Object *argv[])
|
|||
lib->handle = (handle);
|
||||
lib->name = (argv[0]);
|
||||
lib->objects = (ht);
|
||||
lib->is_global = (!name);
|
||||
scheme_hash_set(opened_libs, hashname, (Scheme_Object*)lib);
|
||||
/* no dlclose finalizer - since the hash table always keeps a reference */
|
||||
/* maybe add some explicit unload at some point */
|
||||
|
@ -309,7 +312,7 @@ static Scheme_Object *foreign_ffi_obj(int argc, Scheme_Object *argv[])
|
|||
{
|
||||
ffi_obj_struct *obj;
|
||||
void *dlobj;
|
||||
ffi_lib_struct *lib = NULL;
|
||||
ffi_lib_struct *lib = NULL, *lib2;
|
||||
char *dlname;
|
||||
if (SCHEME_FFILIBP(argv[1]))
|
||||
lib = (ffi_lib_struct*)argv[1];
|
||||
|
@ -361,6 +364,17 @@ static Scheme_Object *foreign_ffi_obj(int argc, Scheme_Object *argv[])
|
|||
}
|
||||
# else /* WINDOWS_DYNAMIC_LOAD undefined */
|
||||
dlobj = dlsym(lib->handle, dlname);
|
||||
if (!dlobj && lib->is_global) {
|
||||
/* Try every handle in the table of opened libraries. */
|
||||
int i;
|
||||
for (i = opened_libs->size; i--; ) {
|
||||
if (opened_libs->vals[i]) {
|
||||
lib2 = (ffi_lib_struct *)opened_libs->vals[i];
|
||||
dlobj = dlsym(lib2->handle, dlname);
|
||||
if (dlobj) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!dlobj) {
|
||||
const char *err;
|
||||
err = dlerror();
|
||||
|
@ -3430,7 +3444,7 @@ void scheme_init_foreign(Scheme_Env *env)
|
|||
scheme_add_global("ffi-lib?",
|
||||
scheme_make_prim_w_arity(foreign_ffi_lib_p, "ffi-lib?", 1, 1), menv);
|
||||
scheme_add_global("ffi-lib",
|
||||
scheme_make_prim_w_arity(foreign_ffi_lib, "ffi-lib", 1, 2), menv);
|
||||
scheme_make_prim_w_arity(foreign_ffi_lib, "ffi-lib", 1, 3), menv);
|
||||
scheme_add_global("ffi-lib-name",
|
||||
scheme_make_prim_w_arity(foreign_ffi_lib_name, "ffi-lib-name", 1, 1), menv);
|
||||
scheme_add_global("ffi-obj?",
|
||||
|
@ -3743,7 +3757,7 @@ void scheme_init_foreign(Scheme_Env *env)
|
|||
scheme_add_global("ffi-lib?",
|
||||
scheme_make_prim_w_arity((Scheme_Prim *)unimplemented, "ffi-lib?", 1, 1), menv);
|
||||
scheme_add_global("ffi-lib",
|
||||
scheme_make_prim_w_arity((Scheme_Prim *)unimplemented, "ffi-lib", 1, 2), menv);
|
||||
scheme_make_prim_w_arity((Scheme_Prim *)unimplemented, "ffi-lib", 1, 3), menv);
|
||||
scheme_add_global("ffi-lib-name",
|
||||
scheme_make_prim_w_arity((Scheme_Prim *)unimplemented, "ffi-lib-name", 1, 1), menv);
|
||||
scheme_add_global("ffi-obj?",
|
||||
|
|
|
@ -165,21 +165,23 @@ END_XFORM_SKIP;
|
|||
/* Library objects */
|
||||
|
||||
@cdefstruct[ffi-lib
|
||||
[handle "NON_GCBALE_PTR(void)"]
|
||||
[name "Scheme_Object*"]
|
||||
[objects "Scheme_Hash_Table*"]]
|
||||
[handle "NON_GCBALE_PTR(void)"]
|
||||
[name "Scheme_Object*"]
|
||||
[objects "Scheme_Hash_Table*"]
|
||||
[is_global "int"]]
|
||||
|
||||
THREAD_LOCAL_DECL(static Scheme_Hash_Table *opened_libs);
|
||||
|
||||
/* (ffi-lib filename no-error?) -> ffi-lib */
|
||||
@cdefine[ffi-lib 1 2]{
|
||||
/* (ffi-lib filename no-error? global?) -> ffi-lib */
|
||||
@cdefine[ffi-lib 1 3]{
|
||||
char *name;
|
||||
Scheme_Object *path, *hashname;
|
||||
void *handle;
|
||||
int null_ok = 0;
|
||||
int null_ok = 0, as_global = 0;
|
||||
ffi_lib_struct *lib;
|
||||
if (!(SCHEME_PATH_STRINGP(argv[0]) || SCHEME_FALSEP(argv[0])))
|
||||
scheme_wrong_type(MYNAME, "string-or-false", 0, argc, argv);
|
||||
as_global = ((argc > 2) && SCHEME_TRUEP(argv[2]));
|
||||
/* leave the filename as given, the system will look for it */
|
||||
/* (`#f' means open the executable) */
|
||||
path = SCHEME_FALSEP(argv[0]) ? NULL : TO_PATH(argv[0]);
|
||||
|
@ -196,7 +198,7 @@ THREAD_LOCAL_DECL(static Scheme_Hash_Table *opened_libs);
|
|||
} else
|
||||
handle = LoadLibraryW(WIDE_PATH(name));
|
||||
}{
|
||||
handle = dlopen(name, RTLD_NOW | RTLD_GLOBAL);
|
||||
handle = dlopen(name, RTLD_NOW | (as_global ? RTLD_GLOBAL : RTLD_LOCAL));
|
||||
}
|
||||
if (handle == NULL && !null_ok) {
|
||||
if (argc > 1 && SCHEME_TRUEP(argv[1])) return scheme_false;
|
||||
|
@ -213,7 +215,7 @@ THREAD_LOCAL_DECL(static Scheme_Hash_Table *opened_libs);
|
|||
}
|
||||
}
|
||||
ht = scheme_make_hash_table(SCHEME_hash_string);
|
||||
@cmake["lib" ffi-lib "handle" "argv[0]" "ht"]
|
||||
@cmake["lib" ffi-lib "handle" "argv[0]" "ht" "!name"]
|
||||
scheme_hash_set(opened_libs, hashname, (Scheme_Object*)lib);
|
||||
/* no dlclose finalizer - since the hash table always keeps a reference */
|
||||
/* maybe add some explicit unload at some point */
|
||||
|
@ -240,7 +242,7 @@ THREAD_LOCAL_DECL(static Scheme_Hash_Table *opened_libs);
|
|||
@cdefine[ffi-obj 2]{
|
||||
ffi_obj_struct *obj;
|
||||
void *dlobj;
|
||||
ffi_lib_struct *lib = NULL;
|
||||
ffi_lib_struct *lib = NULL, *lib2;
|
||||
char *dlname;
|
||||
if (SCHEME_FFILIBP(argv[1]))
|
||||
lib = (ffi_lib_struct*)argv[1];
|
||||
|
@ -292,6 +294,17 @@ THREAD_LOCAL_DECL(static Scheme_Hash_Table *opened_libs);
|
|||
}
|
||||
}{
|
||||
dlobj = dlsym(lib->handle, dlname);
|
||||
if (!dlobj && lib->is_global) {
|
||||
/* Try every handle in the table of opened libraries. */
|
||||
int i;
|
||||
for (i = opened_libs->size; i--; ) {
|
||||
if (opened_libs->vals[i]) {
|
||||
lib2 = (ffi_lib_struct *)opened_libs->vals[i];
|
||||
dlobj = dlsym(lib2->handle, dlname);
|
||||
if (dlobj) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!dlobj) {
|
||||
const char *err;
|
||||
err = dlerror();
|
||||
|
|
|
@ -13,12 +13,12 @@
|
|||
consistently.)
|
||||
*/
|
||||
|
||||
#define MZSCHEME_VERSION "5.2.1.3"
|
||||
#define MZSCHEME_VERSION "5.2.1.4"
|
||||
|
||||
#define MZSCHEME_VERSION_X 5
|
||||
#define MZSCHEME_VERSION_Y 2
|
||||
#define MZSCHEME_VERSION_Z 1
|
||||
#define MZSCHEME_VERSION_W 3
|
||||
#define MZSCHEME_VERSION_W 4
|
||||
|
||||
#define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y)
|
||||
#define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W)
|
||||
|
|
Loading…
Reference in New Issue
Block a user