diff options
author | Raymond Lu <songyulu@hdfgroup.org> | 2013-03-15 21:25:30 (GMT) |
---|---|---|
committer | Raymond Lu <songyulu@hdfgroup.org> | 2013-03-15 21:25:30 (GMT) |
commit | f6f202dc71e0837c2bb721cb8fc8c6dd6ddded3a (patch) | |
tree | 612841344942f5f35baef5964c9405be6b7e94aa | |
parent | 7f44286aa57f7b67c47608022c1a48dfd71c98ad (diff) | |
download | hdf5-f6f202dc71e0837c2bb721cb8fc8c6dd6ddded3a.zip hdf5-f6f202dc71e0837c2bb721cb8fc8c6dd6ddded3a.tar.gz hdf5-f6f202dc71e0837c2bb721cb8fc8c6dd6ddded3a.tar.bz2 |
[svn-r23359] I added some macros and refactoring the code to prepare for Windows support.
Tested on koala.
-rw-r--r-- | src/H5Edefin.h | 1 | ||||
-rw-r--r-- | src/H5Einit.h | 5 | ||||
-rw-r--r-- | src/H5Epubgen.h | 2 | ||||
-rw-r--r-- | src/H5Eterm.h | 3 | ||||
-rw-r--r-- | src/H5PL.c | 215 | ||||
-rw-r--r-- | src/H5PLpkg.h | 71 | ||||
-rw-r--r-- | src/H5PLprivate.h | 1 | ||||
-rw-r--r-- | src/H5err.txt | 3 | ||||
-rw-r--r-- | test/plugin_lib/dynlib1.c | 2 | ||||
-rw-r--r-- | test/plugin_lib/dynlib1.h | 2 |
10 files changed, 203 insertions, 102 deletions
diff --git a/src/H5Edefin.h b/src/H5Edefin.h index 8557f13..183f72c 100644 --- a/src/H5Edefin.h +++ b/src/H5Edefin.h @@ -133,6 +133,7 @@ hid_t H5E_PATH_g = FAIL; /* Problem with path to object */ hid_t H5E_NONE_MINOR_g = FAIL; /* No error */ /* Plugin errors */ +hid_t H5E_OPENERROR_g = FAIL; /* Can't open directory or file */ /* File accessibilty errors */ hid_t H5E_FILEEXISTS_g = FAIL; /* File already exists */ diff --git a/src/H5Einit.h b/src/H5Einit.h index edd9bf5..9724748 100644 --- a/src/H5Einit.h +++ b/src/H5Einit.h @@ -483,6 +483,11 @@ if((H5E_NONE_MINOR_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") /* Plugin errors */ +assert(H5E_OPENERROR_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't open directory or file"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_OPENERROR_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") /* File accessibilty errors */ assert(H5E_FILEEXISTS_g==(-1)); diff --git a/src/H5Epubgen.h b/src/H5Epubgen.h index 3df7d7e..e79106f 100644 --- a/src/H5Epubgen.h +++ b/src/H5Epubgen.h @@ -224,6 +224,8 @@ H5_DLLVAR hid_t H5E_PATH_g; /* Problem with path to object */ H5_DLLVAR hid_t H5E_NONE_MINOR_g; /* No error */ /* Plugin errors */ +#define H5E_OPENERROR (H5OPEN H5E_OPENERROR_g) +H5_DLLVAR hid_t H5E_OPENERROR_g; /* Can't open directory or file */ /* File accessibilty errors */ #define H5E_FILEEXISTS (H5OPEN H5E_FILEEXISTS_g) diff --git a/src/H5Eterm.h b/src/H5Eterm.h index f782db5..5db503c 100644 --- a/src/H5Eterm.h +++ b/src/H5Eterm.h @@ -134,7 +134,8 @@ H5E_PATH_g= /* No error */ H5E_NONE_MINOR_g= -/* Plugin errors */ +/* Plugin errors */ +H5E_OPENERROR_g= /* File accessibilty errors */ H5E_FILEEXISTS_g= @@ -95,7 +95,7 @@ H5PL_term_interface(void) /* Free the table of search paths */ for(i = 0; i < num_paths; i++) { if(path_table[i]) - path_table[i] = H5MM_xfree(path_table[i]); + path_table[i] = (char *)H5MM_xfree(path_table[i]); } num_paths = 0; path_found = FALSE; @@ -130,22 +130,18 @@ H5PL_load(H5PL_type_t type, int id) { char *dl_path = NULL; char *origin_dl_path = NULL; - char *pathname = NULL; size_t len = 0; char *dir = NULL; - DIR *dirp = NULL; - int i; - void *handle = NULL; + size_t i; htri_t found_in_table = FALSE; htri_t found_in_path = FALSE; - H5Z_class2_t* (*PL_get_plugin_info)(void) = NULL; H5Z_class2_t *plugin_info = NULL; void *ret_value = NULL; FUNC_ENTER_NOAPI(NULL) /* Search in the table of already loaded plugin libraries */ - if((found_in_table = H5PL_search_table(type, id, &plugin_info)) < 0) + if((found_in_table = H5PL_search_table(type, id, (void **)&plugin_info)) < 0) HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, NULL, "search in table failed") /* Finish the function if found */ @@ -185,7 +181,7 @@ H5PL_load(H5PL_type_t type, int id) /* Iterate through the path table to find the right dynamic libraries */ for(i=0; i<num_paths; i++) { - if((found_in_path = H5PL_find(type, id, path_table[i], &plugin_info)) < 0) + if((found_in_path = H5PL_find(type, id, path_table[i], (void **)&plugin_info)) < 0) HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, NULL, "search in paths failed") /* Finish the function if found */ @@ -206,10 +202,9 @@ done: /*------------------------------------------------------------------------- * Function: H5PL_find * - * Purpose: Given a path, this function opens the directory and iterates - * through all files to find the right plugin library. It - * loads the dynamic plugin library and keeps it on the list - * of loaded libraries. + * Purpose: Given a path, this function opens the directory and envokes + * another function to go through all files to find the right + * plugin library. * * Return: TRUE on success, * FALSE on not found, @@ -225,90 +220,53 @@ done: htri_t H5PL_find(H5PL_type_t plugin_type, int type_id, char *dir, void **info) { - char *dl_path = NULL; char *pathname = NULL; DIR *dirp = NULL; - int i; - void *handle = NULL; - htri_t found_in_table = FALSE; - hbool_t free_path = FALSE; - H5Z_class2_t* (*H5PL_get_plugin_info)(void) = NULL; - H5Z_class2_t *plugin_info = NULL; + struct dirent *dp = NULL; + struct stat my_stat; + htri_t found_in_dir = FALSE; htri_t ret_value = FALSE; FUNC_ENTER_NOAPI(FAIL) /* Open the directory */ - if(dirp = HDopendir(dir)) { - struct dirent *dp = NULL; - struct stat my_stat; - /* Iterates through all entries in the directory to find the right plugin library */ - while ((dp = HDreaddir(dirp)) != NULL) { - /* The library we are looking for should be called libxxx.so... */ - if(!HDstrncmp(dp->d_name, "lib", 3) && HDstrstr(dp->d_name, ".so")) { - pathname = (char *)H5MM_malloc(strlen(dir) + strlen(dp->d_name) + 2); - HDstrncpy(pathname, dir, strlen(dir)+1); - HDstrcat(pathname, "/"); - HDstrcat(pathname, dp->d_name); - - /*fprintf(stderr, "dp->d_name=%s, pathname=%s. ", dp->d_name, pathname); - fprintf(stderr, "\n");*/ - - if(HDstat(pathname, &my_stat) == -1) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't stat file: %s", strerror(errno)) - - if(!S_ISDIR(my_stat.st_mode)) { /* if it is a directory, skip it */ - if(NULL == (handle = dlopen(pathname, RTLD_NOW|RTLD_LAZY))) { - /*fprintf(stderr, "not open dl library: %s", dlerror());*/ - /* There are different reasons why a library can't be open, e.g. wrong architecture. - * simply continue if we can't open it */ - continue; - } - - dlerror(); /*clear error*/ - - /* Return a handle for the function H5PL_get_plugin_info in the dynamic library. - * The plugin library is suppose to define this function. */ - if(NULL == (H5PL_get_plugin_info = dlsym(handle, "H5PL_get_plugin_info"))) { - if(H5PL_close(handle) < 0) - HGOTO_ERROR(H5E_PLUGIN, H5E_CLOSEERROR, FAIL, "can't close dynamic library") - } - - /* Envoke H5PL_get_plugin_info to verify this is the right library we are looking for. - * Move on if it isn't. */ - if(H5PL_get_plugin_info) { - if(NULL == (plugin_info = (*H5PL_get_plugin_info)())) { - if(H5PL_close(handle) < 0) - HGOTO_ERROR(H5E_PLUGIN, H5E_CLOSEERROR, FAIL, "can't close dynamic library") - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get plugin info") - } - - if(plugin_info->id == type_id) { - (H5PL_table_g[H5PL_table_used_g]).handle = handle; - (H5PL_table_g[H5PL_table_used_g]).pl_type = plugin_type; - (H5PL_table_g[H5PL_table_used_g]).pl_id = plugin_info->id; -/*fprintf(stderr, "%s: H5PL_table_used_g=%d, id=%d, id 2=%d\n", FUNC, H5PL_table_used_g, (H5PL_table_g[H5PL_table_used_g]).pl_id, plugin_info->id);*/ - H5PL_table_used_g++; - - *info = (void *)plugin_info; - ret_value = TRUE; - - HGOTO_DONE(ret_value) - } else if(H5PL_close(handle) < 0) - HGOTO_ERROR(H5E_PLUGIN, H5E_CLOSEERROR, FAIL, "can't close dynamic library") - } - } - - if(pathname) - pathname = (char *)H5MM_xfree(pathname); - } - } - - if(HDclosedir(dirp) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CLOSEERROR, FAIL, "can't close directory: %s", strerror(errno)) - dirp = NULL; + if(!(dirp = HDopendir(dir))) + HGOTO_ERROR(H5E_PLUGIN, H5E_OPENERROR, FAIL, "can't open directory") + + /* Iterates through all entries in the directory to find the right plugin library */ + while ((dp = HDreaddir(dirp)) != NULL) { + /* The library we are looking for should be called libxxx.so... */ + if(!HDstrncmp(dp->d_name, "lib", (size_t)3) && HDstrstr(dp->d_name, ".so")) { + pathname = (char *)H5MM_malloc(strlen(dir) + strlen(dp->d_name) + 2); + HDstrncpy(pathname, dir, strlen(dir)+1); + HDstrcat(pathname, "/"); + HDstrcat(pathname, dp->d_name); + + /*fprintf(stderr, "dp->d_name=%s, pathname=%s. ", dp->d_name, pathname); + fprintf(stderr, "\n");*/ + + if(HDstat(pathname, &my_stat) == -1) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't stat file: %s", strerror(errno)) + + /* If it is a directory, skip it */ + if(S_ISDIR(my_stat.st_mode)) + continue; + + if((found_in_dir = H5PL_open(plugin_type, pathname, type_id, info)) < 0) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "search in directory failed") + + if(found_in_dir) { + ret_value = TRUE; + HGOTO_DONE(ret_value) + } else + if(pathname) + pathname = (char *)H5MM_xfree(pathname); + } } + if(HDclosedir(dirp) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CLOSEERROR, FAIL, "can't close directory: %s", strerror(errno)) + dirp = NULL; done: if(pathname) @@ -321,6 +279,78 @@ done: /*------------------------------------------------------------------------- + * Function: H5PL_open + * + * Purpose: Iterates through all files to find the right plugin library. + * It loads the dynamic plugin library and keeps it on the list + * of loaded libraries. + * + * Return: TRUE on success, + * FALSE on not found, + * negative on failure + * + * Programmer: Raymond Lu + * 13 February 2013 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +htri_t +H5PL_open(H5PL_type_t pl_type, char *libname, int pl_id, void **pl_info) +{ + H5PL_HANDLE handle = NULL; + H5Z_class2_t* (*H5PL_get_plugin_info)(void) = NULL; + H5Z_class2_t *plugin_info = NULL; + htri_t ret_value = FALSE; + + FUNC_ENTER_NOAPI(FAIL) + + /* There are different reasons why a library can't be open, e.g. wrong architecture. + * simply continue if we can't open it */ + if(NULL == (handle = H5PL_OPEN_DLIB(libname))) + /*fprintf(stderr, "not open dl library: %s", H5PL_CLR_ERR);*/ + HGOTO_DONE(ret_value) + + H5PL_CLR_ERR; /*clear error*/ + + /* Return a handle for the function H5PL_get_plugin_info in the dynamic library. + * The plugin library is suppose to define this function. */ + if(NULL == (H5PL_get_plugin_info = H5PL_GET_LIB_FUNC(handle, "H5PL_get_plugin_info"))) { + if(H5PL_close(handle) < 0) + HGOTO_ERROR(H5E_PLUGIN, H5E_CLOSEERROR, FAIL, "can't close dynamic library") + } + + /* Envoke H5PL_get_plugin_info to verify this is the right library we are looking for. + * Move on if it isn't. */ + if(H5PL_get_plugin_info) { + if(NULL == (plugin_info = (*H5PL_get_plugin_info)())) { + if(H5PL_close(handle) < 0) + HGOTO_ERROR(H5E_PLUGIN, H5E_CLOSEERROR, FAIL, "can't close dynamic library") + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get plugin info") + } + + if(plugin_info->id == pl_id) { + (H5PL_table_g[H5PL_table_used_g]).handle = handle; + (H5PL_table_g[H5PL_table_used_g]).pl_type = pl_type; + (H5PL_table_g[H5PL_table_used_g]).pl_id = plugin_info->id; +/*fprintf(stderr, "%s: H5PL_table_used_g=%d, id=%d, id 2=%d\n", FUNC, H5PL_table_used_g, (H5PL_table_g[H5PL_table_used_g]).pl_id, plugin_info->id);*/ + H5PL_table_used_g++; + + *pl_info = (void *)plugin_info; + ret_value = TRUE; + + HGOTO_DONE(ret_value) + } else if(H5PL_close(handle) < 0) + HGOTO_ERROR(H5E_PLUGIN, H5E_CLOSEERROR, FAIL, "can't close dynamic library") + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} + + +/*------------------------------------------------------------------------- * Function: H5PL_search_table * * Purpose: Search in the list of already opened dynamic libraries @@ -340,10 +370,9 @@ done: htri_t H5PL_search_table(H5PL_type_t plugin_type, int type_id, void **info) { - htri_t found = FALSE; H5Z_class2_t* (*H5PL_get_plugin_info)(void) = NULL; H5Z_class2_t *plugin_info = NULL; - int i; + size_t i; htri_t ret_value = FALSE; FUNC_ENTER_NOAPI(FAIL) @@ -355,8 +384,8 @@ fprintf(stderr, "%s: H5PL_table_used_g=%d, id=%d\n", FUNC, H5PL_table_used_g, (H if(0 < H5PL_table_used_g) { for(i=0; i<H5PL_table_used_g; i++) { if((plugin_type == (H5PL_table_g[i]).pl_type) && (type_id == (H5PL_table_g[i]).pl_id)) { - if(NULL == (H5PL_get_plugin_info = dlsym((H5PL_table_g[i]).handle, "H5PL_get_plugin_info"))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get function: %s", dlerror()) + if(NULL == (H5PL_get_plugin_info = H5PL_GET_LIB_FUNC((H5PL_table_g[i]).handle, "H5PL_get_plugin_info"))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get function: %s", H5PL_CLR_ERR) if(NULL == (plugin_info = (*H5PL_get_plugin_info)())) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get plugin info") @@ -401,13 +430,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5PL_close(void *handle) +H5PL_close(H5PL_HANDLE handle) { herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI(FAIL) /*fprintf(stderr, "%s: closing. handle=%p\n", FUNC, handle);*/ - dlclose(handle); + H5PL_CLOSE_LIB(handle); done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5PLpkg.h b/src/H5PLpkg.h index dae4c59..6ab0aa9 100644 --- a/src/H5PLpkg.h +++ b/src/H5PLpkg.h @@ -26,6 +26,69 @@ #define MAX_PATH_NUM 16 /****************************/ +/* Macros for supporting + * both Windows and Unix */ +/****************************/ + +/* Handle for dynamic library */ +#ifdef H5_HAVE_WIN32_API +/* Handle for dynamic library */ +#define H5PL_HANDLE HINSTANCE + +/* Get a handle to a plugin library. Windows: TEXT macro handles Unicode strings */ +#define H5PL_OPEN_DLIB(S) LoadLibraryEx(TEXT(S), NULL, LOAD_WITH_ALTERED_SEARCH_PATH) + +/* Get the address of a symbol in dynamic library */ +#define H5PL_GET_LIB_FUNC(H,N) GetProcAddress(H,N) + +/* Close dynamic library */ +#define H5PL_CLOSE_LIB(H) FreeLibrary(H) + +/* Declare error string */ +#define H5PL_ERROR DWORD dw; char *error + +/* Clear error - nothing to do */ +#define H5PLG_CLR_ERROR + +/* Print error message */ +#define H5PL_CHECK_ERR(R) { \ + if(R==NULL) { \ + dw = GetLastError(); \ + sprintf(error, "%ld", dw); \ + } \ + else error = NULL; \ +} + +#else +/* Handle for dynamic library */ +#define H5PL_HANDLE void * + +/* Get a handle to a plugin library. Windows: TEXT macro handles Unicode strings */ +#define H5PL_OPEN_DLIB(S) dlopen(S, RTLD_NOW|RTLD_LAZY) + +/* Get the address of a symbol in dynamic library */ +#define H5PL_GET_LIB_FUNC(H,N) dlsym(H,N) + +/* Close dynamic library */ +#define H5PL_CLOSE_LIB(H) dlclose(H) + +/* Declare error string */ +#define H5PL_ERROR char *error + +/* Clear error */ +#define H5PL_CLR_ERR dlerror() + +/* Print error message */ +#define H5PL_CHECK_ERR(R) { \ + if(R==NULL) { \ + error = dlerror(); \ + } \ + else error = NULL; \ +} + +#endif + +/****************************/ /* Local typedefs */ /****************************/ @@ -33,7 +96,7 @@ typedef struct H5PL_table_t { H5PL_type_t pl_type; /* plugin type */ int pl_id; /* ID for the plugin */ - void *handle; /* plugin handle */ + H5PL_HANDLE handle; /* plugin handle */ } H5PL_table_t; /****************************/ @@ -55,8 +118,10 @@ static htri_t path_found = FALSE; /******************************/ /* Function prototypes for H5PL package scope */ -htri_t H5PL_find(H5PL_type_t plugin_type, int type_id, char *dir, void **info); -htri_t H5PL_search_table(H5PL_type_t plugin_type, int type_id, void **info); +H5_DLL htri_t H5PL_find(H5PL_type_t plugin_type, int type_id, char *dir, void **info); +H5_DLL htri_t H5PL_open(H5PL_type_t pl_type, char *libname, int plugin_id, void **pl_info); +H5_DLL htri_t H5PL_search_table(H5PL_type_t plugin_type, int type_id, void **info); +H5_DLL herr_t H5PL_close(H5PL_HANDLE handle); #endif /* _H5PLpkg_H */ diff --git a/src/H5PLprivate.h b/src/H5PLprivate.h index 0a79249..f0aa348 100644 --- a/src/H5PLprivate.h +++ b/src/H5PLprivate.h @@ -54,6 +54,5 @@ /* Internal API routines */ H5_DLL void* H5PL_load(H5PL_type_t plugin_type, int type_id); -H5_DLL herr_t H5PL_close(void *handle); #endif diff --git a/src/H5err.txt b/src/H5err.txt index 282afd8..5a38cdf 100644 --- a/src/H5err.txt +++ b/src/H5err.txt @@ -260,5 +260,8 @@ MINOR, PIPELINE, H5E_CANTFILTER, Filter operation failed # System level errors MINOR, SYSTEM, H5E_SYSERRSTR, System error message +# Plugin errors +MINOR, PLUGIN, H5E_OPENERROR, Can't open directory or file + # No error, for backward compatibility */ MINOR, NONE, H5E_NONE_MINOR, No error diff --git a/test/plugin_lib/dynlib1.c b/test/plugin_lib/dynlib1.c index 4b57ddb..1f4fff8 100644 --- a/test/plugin_lib/dynlib1.c +++ b/test/plugin_lib/dynlib1.c @@ -33,8 +33,6 @@ const H5Z_class2_t H5Z_DYNLIB1[1] = {{ }}; const H5PL_type_t H5PL_get_plugin_type(void) {return H5PL_TYPE_FILTER;} -const int H5PL_get_plugin_version(void) {return (int)FILTER_DYNLIB1_VERS;} -const char* H5PL_get_plugin_name(void) {return "dynlib1";} const H5Z_class2_t* H5PL_get_plugin_info(void) {return H5Z_DYNLIB1;} /*------------------------------------------------------------------------- diff --git a/test/plugin_lib/dynlib1.h b/test/plugin_lib/dynlib1.h index 5d68780..f3bb8c3 100644 --- a/test/plugin_lib/dynlib1.h +++ b/test/plugin_lib/dynlib1.h @@ -26,8 +26,6 @@ #define FILTER_DYNLIB1_VERS 1 const H5PL_type_t H5PL_get_plugin_type(void); -const int H5PL_get_plugin_version(void); -const char* H5PL_get_plugin_name(void); const H5Z_class2_t* H5PL_get_plugin_info(void); /* Local prototypes for filter functions */ |