diff options
-rw-r--r-- | docs/libraries/README | 6 | ||||
-rw-r--r-- | include/wolf/library/loader.h | 7 | ||||
-rw-r--r-- | makefiles/gmake/compiler.mk | 4 | ||||
-rw-r--r-- | src/library/loader.c | 52 | ||||
-rw-r--r-- | tests/library/test_loader.c | 4 |
5 files changed, 65 insertions, 8 deletions
diff --git a/docs/libraries/README b/docs/libraries/README index c33ea38..3b49ed4 100644 --- a/docs/libraries/README +++ b/docs/libraries/README @@ -12,6 +12,12 @@ helpers: http://www.cse.iitb.ac.in/dbms/Data/Courses/CS631/PostgreSQL-Resources/postgresql-8.1.4/src/Makefile.shlib http://root.cern.ch/root/Makefile.html +Some more unsorted links: +- http://www.linuxjournal.com/article/3687: on C/C++ dlopen usage +- http://msdn.microsoft.com/en-us/library/ms684175(VS.85).aspx: LoadLibrary on Windows +- http://en.wikipedia.org/wiki/Dynamic_loading +- On MacX: http://developer.apple.com/mac/library/releasenotes/DeveloperTools/RN-dyld/index.html + Goal: - we want abstractions for varying versions of dlopen/LoadLibrary(Ex) etc. - only basic functionality, no module magic versions or other stuff, should diff --git a/include/wolf/library/loader.h b/include/wolf/library/loader.h index 233cd8c..85195a7 100644 --- a/include/wolf/library/loader.h +++ b/include/wolf/library/loader.h @@ -54,8 +54,13 @@ wolf_library_p wolf_library_load( const char *name, wolf_error_t *error ); * Free up resources used by the library object. * * @param demon the library object to free + * + * @return WOLF_OK if library has been unloaded, + * WOLF_ERR_INTERNAL_STATE if the library handle is in an illegal state + * (like double freeing the same library) */ -void wolf_library_unload( wolf_library_p library ); + +wolf_error_t wolf_library_unload( wolf_library_p library ); #if 0 diff --git a/makefiles/gmake/compiler.mk b/makefiles/gmake/compiler.mk index 222a453..0962f11 100644 --- a/makefiles/gmake/compiler.mk +++ b/makefiles/gmake/compiler.mk @@ -272,8 +272,8 @@ endif CFLAGS = $(COMPILE_FLAGS) $(PLATFORM_COMPILE_FLAGS) $(INCLUDE_DIRS) $(PTHREADS_CFLAGS) CCPPFLAGS = $(CCPP_COMPILE_FLAGS) $(PLATFORM_COMPILE_FLAGS) $(INCLUDE_DIRS) $(PTHREADS_CFLAGS) -LDFLAGS = $(INCLUDE_LDFLAGS) $(PTHREADS_LDFLAGS) $(LDFLAGS_NET) $(LDFLAGS_LT) -LIBS = $(INCLUDE_LIBS) $(PTHREADS_LIBS) $(LIBS_NET) $(LIBS_LT) +LDFLAGS = $(INCLUDE_LDFLAGS) $(PTHREADS_LDFLAGS) $(LDFLAGS_NET) $(LDFLAGS_LT) $(LDFLAGS_DL) +LIBS = $(INCLUDE_LIBS) $(PTHREADS_LIBS) $(LIBS_NET) $(LIBS_LT) $(LIBS_DL) LINK = $(CC) CCPP_LINK = $(CCPP) diff --git a/src/library/loader.c b/src/library/loader.c index e0bb055..1f8ce20 100644 --- a/src/library/loader.c +++ b/src/library/loader.c @@ -16,20 +16,62 @@ */ #include "library/loader.h" +#include "port/sys_internal.h" #include "port/unused.h" #include "port/stdlib.h" /* for malloc, free */ +#ifdef HAVE_DLFCN +#include <dlfcn.h> /* for dlopen. dlclose functions */ +#endif + struct wolf_library_t { - char dummy; /**< dummy */ + void *handle; /**< the OS handle for the library */ }; wolf_library_p wolf_library_load( const char *name, wolf_error_t *error ) { - WOLF_UNUSED( name ); + wolf_library_p l; + int flags = 0; + + l = (struct wolf_library_t *)malloc( sizeof ( struct wolf_library_t ) ); + if( l == NULL ) { + *error = WOLF_ERR_OUT_OF_MEMORY; + return NULL; + } + +#if defined HAVE_DLFCN + /* TODO: Apache has a flags variable and a direct parameter version, find out why.. + * also make up our bind how many flags we should "leak" to the application layer + */ + flags = RTLD_NOW | RTLD_LOCAL; + + l->handle = dlopen( name, flags ); + if( l->handle == NULL ) { + *error = WOLF_ERR_INTERNAL; + return NULL; + } +#else +#error Not using DLFCN as shared loader. Port first! +#endif + *error = WOLF_OK; - return NULL; + return l; } -void wolf_library_unload( wolf_library_p library ) { - WOLF_UNUSED( library ); +wolf_error_t wolf_library_unload( wolf_library_p l ) { + int res = 0; + + if( l == NULL || l->handle == NULL ) { + return WOLF_ERR_INVALID_STATE; + } + + res = dlclose( l->handle ); + if( res != 0 ) { + return WOLF_ERR_INVALID_STATE; + } + + free( l ); + l = NULL; + + return WOLF_OK; } diff --git a/tests/library/test_loader.c b/tests/library/test_loader.c index ac4f79c..d2b9329 100644 --- a/tests/library/test_loader.c +++ b/tests/library/test_loader.c @@ -25,6 +25,10 @@ int main( void ) { wolf_error_t error; library = wolf_library_load( "testlib.so", &error ); + if( library == NULL ) { + fprintf( stderr, "Error loading the library: %d\n", error ); + return EXIT_FAILURE; + } wolf_library_unload( library ); |