summaryrefslogtreecommitdiffstats
path: root/src/H5Lexternal.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2010-07-28 12:27:56 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2010-07-28 12:27:56 (GMT)
commit0b7306beed3616d5e259ce3efa1dd0105f436fdb (patch)
tree4d5d467a608e5fc9ada867f913136de744750860 /src/H5Lexternal.c
parentad2f3285b3a0e55aab2014c9e395009df758fef6 (diff)
downloadhdf5-0b7306beed3616d5e259ce3efa1dd0105f436fdb.zip
hdf5-0b7306beed3616d5e259ce3efa1dd0105f436fdb.tar.gz
hdf5-0b7306beed3616d5e259ce3efa1dd0105f436fdb.tar.bz2
[svn-r19133] Description:
Correct traversal of user-defined links (including external links) to retain path information of object, allowing H5Iget_name() queries to work quickly (without searching entire destination file). This required some refactoring and addition of a mechanism to detect if a "fast" query was performed (for the tests). Minor code cleanups, etc. Tested on: FreeBSD/32 6.3 (duty) in debug mode FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (jam) w/PGI compilers, w/default API=1.8.x, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (amani) w/Intel compilers, w/default API=1.6.x, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, w/threadsafe, in production mode Linux/PPC 2.6 (heiwa) w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in debug mode Mac OS X/32 10.6.4 (amazon) in debug mode Mac OS X/32 10.6.4 (amazon) w/C++ & FORTRAN, w/threadsafe, in production mode Mac OS X/32 10.6.4 (amazon) w/parallel, in debug mode
Diffstat (limited to 'src/H5Lexternal.c')
-rw-r--r--src/H5Lexternal.c52
1 files changed, 25 insertions, 27 deletions
diff --git a/src/H5Lexternal.c b/src/H5Lexternal.c
index c5ae92f..d98a843 100644
--- a/src/H5Lexternal.c
+++ b/src/H5Lexternal.c
@@ -53,6 +53,9 @@ const H5L_class_t H5L_EXTERN_LINK_CLASS[1] = {{
/* Valid flags for external links */
#define H5L_EXT_FLAGS_ALL 0
+/* Size of local link name buffer for traversing external links */
+#define H5L_EXT_TRAVERSE_BUF_SIZE 256
+
/*--------------------------------------------------------------------------
NAME
@@ -205,7 +208,8 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group,
H5L_elink_cb_t cb_info; /* Callback info struct */
hid_t fapl_id = -1; /* File access property list for external link's file */
hid_t ext_obj = -1; /* ID for external link's object */
- char *temp_group_name = NULL;/* Temporary pointer to group name */
+ char *parent_group_name = NULL;/* Temporary pointer to group name */
+ char local_group_name[H5L_EXT_TRAVERSE_BUF_SIZE]; /* Local buffer to hold group name */
char *temp_file_name = NULL; /* Temporary pointer to file name */
char *actual_file_name = NULL; /* Parent file's actual name */
H5P_genplist_t *fa_plist; /* File access property list pointer */
@@ -264,41 +268,34 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group,
/* Make callback if it exists */
if(cb_info.func) {
const char *parent_file_name; /* Parent file name */
- const char *parent_group_name; /* Parent group name */
+ ssize_t group_name_len; /* Length of parent group name */
/* Get parent file name */
parent_file_name = H5F_OPEN_NAME(loc.oloc->file);
+ /* Query length of parent group name */
+ if((group_name_len = H5G_get_name(&loc, NULL, (size_t) 0, NULL, lapl_id, H5AC_ind_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to retrieve length of group name")
+
+ /* Account for null terminator */
+ group_name_len++;
+
+ /* Check if we need to allocate larger buffer */
+ if((size_t)group_name_len > sizeof(local_group_name)) {
+ if(NULL == (parent_group_name = (char *)H5MM_malloc((size_t)group_name_len)))
+ HGOTO_ERROR(H5E_LINK, H5E_CANTALLOC, FAIL, "can't allocate buffer to hold group name, group_name_len = %Zu", group_name_len)
+ } /* end if */
+ else
+ parent_group_name = local_group_name;
+
/* Get parent group name */
- if(loc.path->user_path_r != NULL && loc.path->obj_hidden == 0)
- /* Use user_path_r if possible */
- parent_group_name = H5RS_get_str(loc.path->user_path_r);
- else {
- /* Otherwise use H5G_get_name */
- ssize_t group_name_len; /* Length of parent group name */
-
- /* Get length of parent group name */
- if((group_name_len = H5G_get_name(cur_group, NULL, (size_t) 0, lapl_id, H5AC_ind_dxpl_id)) < 0)
- HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to retrieve length of group name")
-
- /* account for null terminator */
- group_name_len++;
-
- /* Copy parent group name */
- if(NULL == (temp_group_name = (char *)H5MM_malloc((size_t)group_name_len)))
- HGOTO_ERROR(H5E_LINK, H5E_NOSPACE, FAIL, "memory allocation failed")
- if(H5G_get_name(cur_group, temp_group_name, (size_t) group_name_len, lapl_id, H5AC_ind_dxpl_id) < 0)
- HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to retrieve group name")
- parent_group_name = temp_group_name;
- } /* end else */
+ if(H5G_get_name(&loc, parent_group_name, (size_t) group_name_len, NULL, lapl_id, H5AC_ind_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to retrieve group name")
/* Make callback */
if((cb_info.func)(parent_file_name, parent_group_name, file_name, obj_name, &intent, fapl_id, cb_info.user_data) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "traversal operator failed")
- /* Free temp_group_name */
- temp_group_name = (char *)H5MM_xfree(temp_group_name);
-
/* Check access flags */
if((intent & H5F_ACC_TRUNC) || (intent & H5F_ACC_EXCL))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file open flags")
@@ -460,8 +457,9 @@ done:
HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom for file access property list")
if(ext_file && H5F_try_close(ext_file) < 0)
HDONE_ERROR(H5E_LINK, H5E_CANTCLOSEFILE, FAIL, "problem closing external file")
+ if(parent_group_name && parent_group_name != local_group_name)
+ parent_group_name = (char *)H5MM_xfree(parent_group_name);
full_name = (char *)H5MM_xfree(full_name);
- temp_group_name = (char *)H5MM_xfree(temp_group_name);
temp_file_name = (char *)H5MM_xfree(temp_file_name);
actual_file_name = (char *)H5MM_xfree(actual_file_name);