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)
|
ffi-lib? ffi-lib-name)
|
||||||
(define (get-ffi-lib name [version/s ""]
|
(define (get-ffi-lib name [version/s ""]
|
||||||
#:fail [fail #f]
|
#: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
|
(cond
|
||||||
[(not name) (ffi-lib name)] ; #f => NULL => open this executable
|
[(not name) (ffi-lib name)] ; #f => NULL => open this executable
|
||||||
[(not (or (string? name) (path? name)))
|
[(not (or (string? name) (path? name)))
|
||||||
|
@ -123,7 +124,7 @@
|
||||||
(string-append name0 "." lib-suffix v)
|
(string-append name0 "." lib-suffix v)
|
||||||
(string-append name0 v "." lib-suffix))))
|
(string-append name0 v "." lib-suffix))))
|
||||||
versions)]
|
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
|
(or ;; try to look in our library paths first
|
||||||
(and (not absolute?)
|
(and (not absolute?)
|
||||||
(ormap (lambda (dir)
|
(ormap (lambda (dir)
|
||||||
|
@ -145,8 +146,8 @@
|
||||||
(if fail
|
(if fail
|
||||||
(fail)
|
(fail)
|
||||||
(if (pair? names)
|
(if (pair? names)
|
||||||
(ffi-lib (car names))
|
(ffi-lib (car names) #f global?)
|
||||||
(ffi-lib name0)))))]))
|
(ffi-lib name0 #f global?)))))]))
|
||||||
|
|
||||||
(define (get-ffi-lib-internal x)
|
(define (get-ffi-lib-internal x)
|
||||||
(if (ffi-lib? x) x (get-ffi-lib 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)]
|
@defproc[(ffi-lib [path (or/c path-string? #f)]
|
||||||
[version (or/c string? (listof (or/c string? #f)) #f) #f]
|
[version (or/c string? (listof (or/c string? #f)) #f) #f]
|
||||||
[#:get-lib-dirs get-lib-dirs (-> (listof path?)) get-lib-search-dirs]
|
[#: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]{
|
any]{
|
||||||
|
|
||||||
Returns a @tech{foreign-library value} or the result of @racket[fail].
|
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[version] argument is ignored when @racket[path] is
|
||||||
@racket[#f].
|
@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
|
Due to the way the operating system performs dynamic binding, loaded
|
||||||
libraries are associated with Racket (or DrRacket) for the duration of
|
libraries are associated with Racket (or DrRacket) for the duration of
|
||||||
the process. Re-evaluating @racket[ffi-lib] (or hitting the
|
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
|
Version 5.2.1, January 2012
|
||||||
Changed I/O scheduling to use epoll()/kqueue() when available
|
Changed I/O scheduling to use epoll()/kqueue() when available
|
||||||
Cross-module inline trivial functions, plus map, for-each,
|
Cross-module inline trivial functions, plus map, for-each,
|
||||||
|
|
|
@ -168,6 +168,7 @@ typedef struct ffi_lib_struct {
|
||||||
NON_GCBALE_PTR(void) handle;
|
NON_GCBALE_PTR(void) handle;
|
||||||
Scheme_Object* name;
|
Scheme_Object* name;
|
||||||
Scheme_Hash_Table* objects;
|
Scheme_Hash_Table* objects;
|
||||||
|
int is_global;
|
||||||
} ffi_lib_struct;
|
} ffi_lib_struct;
|
||||||
#define SCHEME_FFILIBP(x) (SCHEME_TYPE(x)==ffi_lib_tag)
|
#define SCHEME_FFILIBP(x) (SCHEME_TYPE(x)==ffi_lib_tag)
|
||||||
#define MYNAME "ffi-lib?"
|
#define MYNAME "ffi-lib?"
|
||||||
|
@ -199,17 +200,18 @@ END_XFORM_SKIP;
|
||||||
|
|
||||||
THREAD_LOCAL_DECL(static Scheme_Hash_Table *opened_libs);
|
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"
|
#define MYNAME "ffi-lib"
|
||||||
static Scheme_Object *foreign_ffi_lib(int argc, Scheme_Object *argv[])
|
static Scheme_Object *foreign_ffi_lib(int argc, Scheme_Object *argv[])
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
Scheme_Object *path, *hashname;
|
Scheme_Object *path, *hashname;
|
||||||
void *handle;
|
void *handle;
|
||||||
int null_ok = 0;
|
int null_ok = 0, as_global = 0;
|
||||||
ffi_lib_struct *lib;
|
ffi_lib_struct *lib;
|
||||||
if (!(SCHEME_PATH_STRINGP(argv[0]) || SCHEME_FALSEP(argv[0])))
|
if (!(SCHEME_PATH_STRINGP(argv[0]) || SCHEME_FALSEP(argv[0])))
|
||||||
scheme_wrong_type(MYNAME, "string-or-false", 0, argc, argv);
|
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 */
|
/* leave the filename as given, the system will look for it */
|
||||||
/* (`#f' means open the executable) */
|
/* (`#f' means open the executable) */
|
||||||
path = SCHEME_FALSEP(argv[0]) ? NULL : TO_PATH(argv[0]);
|
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
|
} else
|
||||||
handle = LoadLibraryW(WIDE_PATH(name));
|
handle = LoadLibraryW(WIDE_PATH(name));
|
||||||
# else /* WINDOWS_DYNAMIC_LOAD undefined */
|
# 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 */
|
# endif /* WINDOWS_DYNAMIC_LOAD */
|
||||||
if (handle == NULL && !null_ok) {
|
if (handle == NULL && !null_ok) {
|
||||||
if (argc > 1 && SCHEME_TRUEP(argv[1])) return scheme_false;
|
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->handle = (handle);
|
||||||
lib->name = (argv[0]);
|
lib->name = (argv[0]);
|
||||||
lib->objects = (ht);
|
lib->objects = (ht);
|
||||||
|
lib->is_global = (!name);
|
||||||
scheme_hash_set(opened_libs, hashname, (Scheme_Object*)lib);
|
scheme_hash_set(opened_libs, hashname, (Scheme_Object*)lib);
|
||||||
/* no dlclose finalizer - since the hash table always keeps a reference */
|
/* no dlclose finalizer - since the hash table always keeps a reference */
|
||||||
/* maybe add some explicit unload at some point */
|
/* 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;
|
ffi_obj_struct *obj;
|
||||||
void *dlobj;
|
void *dlobj;
|
||||||
ffi_lib_struct *lib = NULL;
|
ffi_lib_struct *lib = NULL, *lib2;
|
||||||
char *dlname;
|
char *dlname;
|
||||||
if (SCHEME_FFILIBP(argv[1]))
|
if (SCHEME_FFILIBP(argv[1]))
|
||||||
lib = (ffi_lib_struct*)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 */
|
# else /* WINDOWS_DYNAMIC_LOAD undefined */
|
||||||
dlobj = dlsym(lib->handle, dlname);
|
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) {
|
if (!dlobj) {
|
||||||
const char *err;
|
const char *err;
|
||||||
err = dlerror();
|
err = dlerror();
|
||||||
|
@ -3430,7 +3444,7 @@ void scheme_init_foreign(Scheme_Env *env)
|
||||||
scheme_add_global("ffi-lib?",
|
scheme_add_global("ffi-lib?",
|
||||||
scheme_make_prim_w_arity(foreign_ffi_lib_p, "ffi-lib?", 1, 1), menv);
|
scheme_make_prim_w_arity(foreign_ffi_lib_p, "ffi-lib?", 1, 1), menv);
|
||||||
scheme_add_global("ffi-lib",
|
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_add_global("ffi-lib-name",
|
||||||
scheme_make_prim_w_arity(foreign_ffi_lib_name, "ffi-lib-name", 1, 1), menv);
|
scheme_make_prim_w_arity(foreign_ffi_lib_name, "ffi-lib-name", 1, 1), menv);
|
||||||
scheme_add_global("ffi-obj?",
|
scheme_add_global("ffi-obj?",
|
||||||
|
@ -3743,7 +3757,7 @@ void scheme_init_foreign(Scheme_Env *env)
|
||||||
scheme_add_global("ffi-lib?",
|
scheme_add_global("ffi-lib?",
|
||||||
scheme_make_prim_w_arity((Scheme_Prim *)unimplemented, "ffi-lib?", 1, 1), menv);
|
scheme_make_prim_w_arity((Scheme_Prim *)unimplemented, "ffi-lib?", 1, 1), menv);
|
||||||
scheme_add_global("ffi-lib",
|
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_add_global("ffi-lib-name",
|
||||||
scheme_make_prim_w_arity((Scheme_Prim *)unimplemented, "ffi-lib-name", 1, 1), menv);
|
scheme_make_prim_w_arity((Scheme_Prim *)unimplemented, "ffi-lib-name", 1, 1), menv);
|
||||||
scheme_add_global("ffi-obj?",
|
scheme_add_global("ffi-obj?",
|
||||||
|
|
|
@ -165,21 +165,23 @@ END_XFORM_SKIP;
|
||||||
/* Library objects */
|
/* Library objects */
|
||||||
|
|
||||||
@cdefstruct[ffi-lib
|
@cdefstruct[ffi-lib
|
||||||
[handle "NON_GCBALE_PTR(void)"]
|
[handle "NON_GCBALE_PTR(void)"]
|
||||||
[name "Scheme_Object*"]
|
[name "Scheme_Object*"]
|
||||||
[objects "Scheme_Hash_Table*"]]
|
[objects "Scheme_Hash_Table*"]
|
||||||
|
[is_global "int"]]
|
||||||
|
|
||||||
THREAD_LOCAL_DECL(static Scheme_Hash_Table *opened_libs);
|
THREAD_LOCAL_DECL(static Scheme_Hash_Table *opened_libs);
|
||||||
|
|
||||||
/* (ffi-lib filename no-error?) -> ffi-lib */
|
/* (ffi-lib filename no-error? global?) -> ffi-lib */
|
||||||
@cdefine[ffi-lib 1 2]{
|
@cdefine[ffi-lib 1 3]{
|
||||||
char *name;
|
char *name;
|
||||||
Scheme_Object *path, *hashname;
|
Scheme_Object *path, *hashname;
|
||||||
void *handle;
|
void *handle;
|
||||||
int null_ok = 0;
|
int null_ok = 0, as_global = 0;
|
||||||
ffi_lib_struct *lib;
|
ffi_lib_struct *lib;
|
||||||
if (!(SCHEME_PATH_STRINGP(argv[0]) || SCHEME_FALSEP(argv[0])))
|
if (!(SCHEME_PATH_STRINGP(argv[0]) || SCHEME_FALSEP(argv[0])))
|
||||||
scheme_wrong_type(MYNAME, "string-or-false", 0, argc, argv);
|
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 */
|
/* leave the filename as given, the system will look for it */
|
||||||
/* (`#f' means open the executable) */
|
/* (`#f' means open the executable) */
|
||||||
path = SCHEME_FALSEP(argv[0]) ? NULL : TO_PATH(argv[0]);
|
path = SCHEME_FALSEP(argv[0]) ? NULL : TO_PATH(argv[0]);
|
||||||
|
@ -196,7 +198,7 @@ THREAD_LOCAL_DECL(static Scheme_Hash_Table *opened_libs);
|
||||||
} else
|
} else
|
||||||
handle = LoadLibraryW(WIDE_PATH(name));
|
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 (handle == NULL && !null_ok) {
|
||||||
if (argc > 1 && SCHEME_TRUEP(argv[1])) return scheme_false;
|
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);
|
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);
|
scheme_hash_set(opened_libs, hashname, (Scheme_Object*)lib);
|
||||||
/* no dlclose finalizer - since the hash table always keeps a reference */
|
/* no dlclose finalizer - since the hash table always keeps a reference */
|
||||||
/* maybe add some explicit unload at some point */
|
/* 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]{
|
@cdefine[ffi-obj 2]{
|
||||||
ffi_obj_struct *obj;
|
ffi_obj_struct *obj;
|
||||||
void *dlobj;
|
void *dlobj;
|
||||||
ffi_lib_struct *lib = NULL;
|
ffi_lib_struct *lib = NULL, *lib2;
|
||||||
char *dlname;
|
char *dlname;
|
||||||
if (SCHEME_FFILIBP(argv[1]))
|
if (SCHEME_FFILIBP(argv[1]))
|
||||||
lib = (ffi_lib_struct*)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);
|
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) {
|
if (!dlobj) {
|
||||||
const char *err;
|
const char *err;
|
||||||
err = dlerror();
|
err = dlerror();
|
||||||
|
|
|
@ -13,12 +13,12 @@
|
||||||
consistently.)
|
consistently.)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define MZSCHEME_VERSION "5.2.1.3"
|
#define MZSCHEME_VERSION "5.2.1.4"
|
||||||
|
|
||||||
#define MZSCHEME_VERSION_X 5
|
#define MZSCHEME_VERSION_X 5
|
||||||
#define MZSCHEME_VERSION_Y 2
|
#define MZSCHEME_VERSION_Y 2
|
||||||
#define MZSCHEME_VERSION_Z 1
|
#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_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y)
|
||||||
#define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W)
|
#define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user