summaryrefslogtreecommitdiffstats
path: root/src/H5Gtraverse.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2010-02-03 15:05:41 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2010-02-03 15:05:41 (GMT)
commitc8d05fbe4d4d135ee2ec352f6437e43bdbe423b7 (patch)
tree1257e54854f3b85d498ad078aaa562cc9cd2680d /src/H5Gtraverse.c
parent1c05d48b9329e05f874e494c45c429f6cadc1ee5 (diff)
downloadhdf5-c8d05fbe4d4d135ee2ec352f6437e43bdbe423b7.zip
hdf5-c8d05fbe4d4d135ee2ec352f6437e43bdbe423b7.tar.gz
hdf5-c8d05fbe4d4d135ee2ec352f6437e43bdbe423b7.tar.bz2
[svn-r18205] Description:
Add prototype of new H5Oexists() API routine. Tested on: Mac OS X/32 10.6.2 (amazon) (further tests pending shortly)
Diffstat (limited to 'src/H5Gtraverse.c')
-rw-r--r--src/H5Gtraverse.c104
1 files changed, 74 insertions, 30 deletions
diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c
index 4c287d5..e9f3010 100644
--- a/src/H5Gtraverse.c
+++ b/src/H5Gtraverse.c
@@ -43,8 +43,13 @@
/* User data for path traversal routine */
typedef struct {
+ /* down */
+ hbool_t chk_exists; /* Flag to indicate we are checking if object exists */
+
+ /* up */
H5G_loc_t *obj_loc; /* Object location */
-} H5G_trav_ud1_t;
+ hbool_t exists; /* Indicate if object exists */
+} H5G_trav_slink_t;
/* Private macros */
@@ -53,15 +58,15 @@ static char *H5G_comp_g = NULL; /*component buffer */
static size_t H5G_comp_alloc_g = 0; /*sizeof component buffer */
/* PRIVATE PROTOTYPES */
-static herr_t H5G_traverse_link_cb(H5G_loc_t *grp_loc, const char *name,
+static herr_t H5G_traverse_slink_cb(H5G_loc_t *grp_loc, const char *name,
const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/,
H5G_own_loc_t *own_loc/*out*/);
static herr_t H5G_traverse_ud(const H5G_loc_t *grp_loc, const H5O_link_t *lnk,
- H5G_loc_t *obj_loc/*in,out*/, size_t *nlinks/*in,out*/, hid_t lapl_id,
- hid_t dxpl_id);
+ H5G_loc_t *obj_loc/*in,out*/, unsigned target, size_t *nlinks/*in,out*/,
+ hbool_t *obj_exists, hid_t lapl_id, hid_t dxpl_id);
static herr_t H5G_traverse_slink(const H5G_loc_t *grp_loc, const H5O_link_t *lnk,
- H5G_loc_t *obj_loc/*in,out*/, size_t *nlinks/*in,out*/, hid_t lapl_id,
- hid_t dxpl_id);
+ H5G_loc_t *obj_loc/*in,out*/, unsigned target, size_t *nlinks/*in,out*/,
+ hbool_t *obj_exists, hid_t lapl_id, hid_t dxpl_id);
static herr_t H5G_traverse_mount(H5G_loc_t *loc/*in,out*/);
static herr_t H5G_traverse_real(const H5G_loc_t *loc, const char *name,
unsigned target, size_t *nlinks, H5G_traverse_t op, void *op_data,
@@ -97,9 +102,9 @@ H5G_traverse_term_interface(void)
/*-------------------------------------------------------------------------
- * Function: H5G_traverse_link_cb
+ * Function: H5G_traverse_slink_cb
*
- * Purpose: Callback for link traversal. This routine sets the
+ * Purpose: Callback for soft link traversal. This routine sets the
* correct information for the object location.
*
* Return: Non-negative on success/Negative on failure
@@ -110,20 +115,29 @@ H5G_traverse_term_interface(void)
*-------------------------------------------------------------------------
*/
static herr_t
-H5G_traverse_link_cb(H5G_loc_t UNUSED *grp_loc, const char UNUSED *name, const H5O_link_t UNUSED *lnk,
- H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/)
+H5G_traverse_slink_cb(H5G_loc_t UNUSED *grp_loc, const char UNUSED *name,
+ const H5O_link_t UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/,
+ H5G_own_loc_t *own_loc/*out*/)
{
- H5G_trav_ud1_t *udata = (H5G_trav_ud1_t *)_udata; /* User data passed in */
+ H5G_trav_slink_t *udata = (H5G_trav_slink_t *)_udata; /* User data passed in */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5G_traverse_link_cb)
+ FUNC_ENTER_NOAPI_NOINIT(H5G_traverse_slink_cb)
/* Check for dangling soft link */
- if(obj_loc == NULL)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found")
+ if(obj_loc == NULL) {
+ if(udata->chk_exists)
+ udata->exists = FALSE;
+ else
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found")
+ } /* end if */
+ else {
+ /* Copy new location information for resolved object */
+ H5O_loc_copy(udata->obj_loc->oloc, obj_loc->oloc, H5_COPY_DEEP);
- /* Copy new location information for resolved object */
- H5O_loc_copy(udata->obj_loc->oloc, obj_loc->oloc, H5_COPY_DEEP);
+ /* Indicate that the object exists */
+ udata->exists = TRUE;
+ } /* end else */
done:
/* Indicate that this callback didn't take ownership of the group *
@@ -131,7 +145,7 @@ done:
*own_loc = H5G_OWN_NONE;
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5G_traverse_link_cb() */
+} /* end H5G_traverse_slink_cb() */
/*-------------------------------------------------------------------------
@@ -149,8 +163,8 @@ done:
*/
static herr_t
H5G_traverse_ud(const H5G_loc_t *grp_loc/*in,out*/, const H5O_link_t *lnk,
- H5G_loc_t *obj_loc/*in,out*/, size_t *nlinks/*in,out*/, hid_t _lapl_id,
- hid_t dxpl_id)
+ H5G_loc_t *obj_loc/*in,out*/, unsigned target, size_t *nlinks/*in,out*/,
+ hbool_t *obj_exists, hid_t _lapl_id, hid_t dxpl_id)
{
const H5L_class_t *link_class; /* User-defined link class */
hid_t cb_return = -1; /* The ID the user-defined callback returned */
@@ -222,8 +236,25 @@ H5G_traverse_ud(const H5G_loc_t *grp_loc/*in,out*/, const H5O_link_t *lnk,
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set nlink info")
/* User-defined callback function */
- if((cb_return = (link_class->trav_func)(lnk->name, cur_grp, lnk->u.ud.udata, lnk->u.ud.size, lapl_id)) < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADATOM, FAIL, "traversal callback returned invalid ID")
+ cb_return = (link_class->trav_func)(lnk->name, cur_grp, lnk->u.ud.udata, lnk->u.ud.size, lapl_id);
+
+ /* Check for failing to locate the object */
+ if(cb_return < 0) {
+ /* Check if we just needed to know if the object exists */
+ if(target & H5G_TARGET_EXISTS) {
+ /* Clear any errors from the stack */
+ H5E_clear_stack(NULL);
+
+ /* Indicate that the object doesn't exist */
+ *obj_exists = FALSE;
+
+ /* Get out now */
+ HGOTO_DONE(SUCCEED);
+ } /* end if */
+ /* else, we really needed to open the object */
+ else
+ HGOTO_ERROR(H5E_ARGS, H5E_BADATOM, FAIL, "traversal callback returned invalid ID")
+ } /* end if */
/* Get the oloc from the ID the user callback returned */
switch(H5I_get_type(cb_return)) {
@@ -306,10 +337,10 @@ done:
*/
static herr_t
H5G_traverse_slink(const H5G_loc_t *grp_loc, const H5O_link_t *lnk,
- H5G_loc_t *obj_loc/*in,out*/, size_t *nlinks/*in,out*/, hid_t lapl_id,
- hid_t dxpl_id)
+ H5G_loc_t *obj_loc/*in,out*/, unsigned target, size_t *nlinks/*in,out*/,
+ hbool_t *obj_exists, hid_t lapl_id, hid_t dxpl_id)
{
- H5G_trav_ud1_t udata; /* User data to pass to link traversal callback */
+ H5G_trav_slink_t udata; /* User data to pass to link traversal callback */
H5G_name_t tmp_obj_path; /* Temporary copy of object's path */
hbool_t tmp_obj_path_set = FALSE; /* Flag to indicate that tmp object path is initialized */
H5O_loc_t tmp_grp_oloc; /* Temporary copy of group entry */
@@ -347,12 +378,17 @@ H5G_traverse_slink(const H5G_loc_t *grp_loc, const H5O_link_t *lnk,
tmp_obj_path_set = TRUE;
/* Set up user data for traversal callback */
+ udata.chk_exists = (target & H5G_TARGET_EXISTS) ? TRUE : FALSE;
+ udata.exists = FALSE;
udata.obj_loc = obj_loc;
/* Traverse the link */
- if(H5G_traverse_real(&tmp_grp_loc, lnk->u.soft.name, H5G_TARGET_NORMAL, nlinks, H5G_traverse_link_cb, &udata, lapl_id, dxpl_id) < 0)
+ if(H5G_traverse_real(&tmp_grp_loc, lnk->u.soft.name, target, nlinks, H5G_traverse_slink_cb, &udata, lapl_id, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to follow symbolic link")
+ /* Pass back information about whether the object exists */
+ *obj_exists = udata.exists;
+
done:
/* Restore object's group hier. path */
if(tmp_obj_path_set) {
@@ -464,7 +500,7 @@ done:
herr_t
H5G_traverse_special(const H5G_loc_t *grp_loc, const H5O_link_t *lnk,
unsigned target, size_t *nlinks, hbool_t last_comp,
- H5G_loc_t *obj_loc, hid_t lapl_id, hid_t dxpl_id)
+ H5G_loc_t *obj_loc, hbool_t *obj_exists, hid_t lapl_id, hid_t dxpl_id)
{
herr_t ret_value = SUCCEED; /* Return value */
@@ -485,7 +521,7 @@ H5G_traverse_special(const H5G_loc_t *grp_loc, const H5O_link_t *lnk,
(0 == (target & H5G_TARGET_SLINK) || !last_comp)) {
if((*nlinks)-- <= 0)
HGOTO_ERROR(H5E_LINK, H5E_NLINKS, FAIL, "too many links")
- if(H5G_traverse_slink(grp_loc, lnk, obj_loc, nlinks, lapl_id, dxpl_id) < 0)
+ if(H5G_traverse_slink(grp_loc, lnk, obj_loc, (target & H5G_TARGET_EXISTS), nlinks, obj_exists, lapl_id, dxpl_id) < 0)
HGOTO_ERROR(H5E_LINK, H5E_TRAVERSE, FAIL, "symbolic link traversal failed")
} /* end if */
@@ -498,7 +534,7 @@ H5G_traverse_special(const H5G_loc_t *grp_loc, const H5O_link_t *lnk,
(0 == (target & H5G_TARGET_UDLINK) || !last_comp) ) {
if((*nlinks)-- <= 0)
HGOTO_ERROR(H5E_LINK, H5E_NLINKS, FAIL, "too many links")
- if(H5G_traverse_ud(grp_loc, lnk, obj_loc, nlinks, lapl_id, dxpl_id) < 0)
+ if(H5G_traverse_ud(grp_loc, lnk, obj_loc, (target & H5G_TARGET_EXISTS), nlinks, obj_exists, lapl_id, dxpl_id) < 0)
HGOTO_ERROR(H5E_LINK, H5E_TRAVERSE, FAIL, "user-defined link traversal failed")
} /* end if */
@@ -634,6 +670,7 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target,
while((name = H5G_component(name, &nchars)) && *name) {
const char *s; /* Temporary string pointer */
htri_t lookup_status; /* Status from object lookup */
+ hbool_t obj_exists; /* Whether the object exists */
/*
* Copy the component name into a null-terminated buffer so
@@ -663,6 +700,7 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target,
/* Get information for object in current group */
if((lookup_status = H5G_obj_lookup(grp_loc.oloc, H5G_comp_g, &lnk/*out*/, dxpl_id)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't look up component")
+ obj_exists = FALSE;
/* If the lookup was OK, build object location and traverse special links, etc. */
if(lookup_status) {
@@ -676,9 +714,12 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target,
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "cannot initialize object location")
obj_loc_valid = TRUE;
+ /* Assume object exists */
+ obj_exists = TRUE;
+
/* Perform any special traversals that the link needs */
/* (soft links, user-defined links, file mounting, etc.) */
- if(H5G_traverse_special(&grp_loc, &lnk, target, nlinks, last_comp, &obj_loc, lapl_id, dxpl_id) < 0)
+ if(H5G_traverse_special(&grp_loc, &lnk, target, nlinks, last_comp, &obj_loc, &obj_exists, lapl_id, dxpl_id) < 0)
HGOTO_ERROR(H5E_LINK, H5E_TRAVERSE, FAIL, "special link traversal failed")
} /* end if */
@@ -690,7 +731,10 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target,
/* Set callback parameters appropriately, based on link being found */
if(lookup_status) {
cb_lnk = &lnk;
- cb_loc = &obj_loc;
+ if(obj_exists)
+ cb_loc = &obj_loc;
+ else
+ cb_loc = NULL;
} /* end if */
else {
HDassert(!obj_loc_valid);