From f6f202dc71e0837c2bb721cb8fc8c6dd6ddded3a Mon Sep 17 00:00:00 2001 From: Raymond Lu Date: Fri, 15 Mar 2013 16:25:30 -0500 Subject: [svn-r23359] I added some macros and refactoring the code to prepare for Windows support. Tested on koala. --- src/H5Edefin.h | 1 + src/H5Einit.h | 5 ++ src/H5Epubgen.h | 2 + src/H5Eterm.h | 3 +- src/H5PL.c | 215 ++++++++++++++++++++++++++-------------------- src/H5PLpkg.h | 71 ++++++++++++++- src/H5PLprivate.h | 1 - src/H5err.txt | 3 + test/plugin_lib/dynlib1.c | 2 - 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= diff --git a/src/H5PL.c b/src/H5PL.c index afa1785..0a40d0c 100644 --- a/src/H5PL.c +++ b/src/H5PL.c @@ -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; id_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