mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-03-19 16:50:46 +08:00
[svn-r346] Changes since 19980410
---------------------- ./html/H5.format.html ./src/H5E.c ./src/H5Epublic.h ./src/H5F.c ./src/H5G.c ./src/H5Gent.c ./src/H5Gnode.c ./src/H5Gprivate.h ./src/h5ls.c ./test/Makefile.in Symbolic links are now supported. The ./test/links program will create a `links.h5' file that demonstrates hard links, soft links, dangling links, and recursive links. A symbolic link is a symbol table entity and doesn't have an object header. It's format is described in H5.format.hml. ./src/H5G.c ./src/H5Gpublic.h ./src/h5ls.c Implemented H5Gstat() and H5Gget_linkval() as documented by Quincey. The `H5G_type_t type' field of `H5G_stat_t' was changed to `int type' because H5G_type_t was already used and the `type' data type should be open-ended. ./src/H5Ffamily.c Removed an incorrect diagnostic message. ./test/big.c Added read/write calls to test partial I/O to big contiguous datasets. With no arguments it writes to a dataset and prints the list of points written which should be redirected to a file. With an argument (the name of a file containing the stdout of a run with no arguments) values are read from the dataset. One would typically say `big >x && big x'.
This commit is contained in:
parent
3f571b6b44
commit
b6fc6ede10
1
MANIFEST
1
MANIFEST
@ -198,6 +198,7 @@
|
||||
./test/hyperslab.c
|
||||
./test/iopipe.c
|
||||
./test/istore.c
|
||||
./test/links.c
|
||||
./test/shtype.c
|
||||
./test/testhdf5.c
|
||||
./test/testhdf5.h
|
||||
|
@ -100,6 +100,7 @@ static const H5E_minor_mesg_t H5E_minor_mesg_g[] = {
|
||||
{H5E_COMPLEN, "Name component is too long"},
|
||||
{H5E_CWG, "Problem with current working group"},
|
||||
{H5E_LINK, "Link count failure"},
|
||||
{H5E_SLINK, "Symbolic link error"},
|
||||
};
|
||||
|
||||
/* Interface initialization? */
|
||||
|
@ -112,7 +112,8 @@ typedef enum H5E_minor_t {
|
||||
H5E_CANTOPENOBJ, /*Can't open object */
|
||||
H5E_COMPLEN, /*name component is too long */
|
||||
H5E_CWG, /*problem with current working group */
|
||||
H5E_LINK /*link count failure */
|
||||
H5E_LINK, /*link count failure */
|
||||
H5E_SLINK /*symbolic link error */
|
||||
} H5E_minor_t;
|
||||
|
||||
/* Information about an error */
|
||||
|
@ -1633,7 +1633,7 @@ H5F_debug(H5F_t *f, const haddr_t __unused__ *addr, FILE * stream,
|
||||
f->shared->root_grp ? "" : "(none)");
|
||||
if (f->shared->root_grp) {
|
||||
H5G_ent_debug(f, H5G_entof (f->shared->root_grp), stream,
|
||||
indent + 3, MAX(0, fwidth - 3));
|
||||
indent+3, MAX(0, fwidth-3), NULL);
|
||||
}
|
||||
FUNC_LEAVE(SUCCEED);
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ H5F_fam_open(const char *name, const H5F_access_t *access_parms,
|
||||
* descriptors (all family members are open at once).
|
||||
*/
|
||||
#ifdef H5F_DEBUG
|
||||
if (access_parms->u.fam.offset_bits+2>=8*sizeof(off_t)) {
|
||||
if (access_parms->u.fam.offset_bits+2>8*sizeof(off_t)) {
|
||||
fprintf (stderr, "H5F: family member size may be too large.\n");
|
||||
}
|
||||
#endif
|
||||
|
428
src/H5G.c
428
src/H5G.c
@ -75,11 +75,12 @@
|
||||
|
||||
/* Packages needed by this file... */
|
||||
#include <H5private.h>
|
||||
#include <H5Iprivate.h>
|
||||
#include <H5Bprivate.h>
|
||||
#include <H5Dprivate.h>
|
||||
#include <H5Eprivate.h>
|
||||
#include <H5Gpkg.h>
|
||||
#include <H5HLprivate.h>
|
||||
#include <H5Iprivate.h>
|
||||
#include <H5MMprivate.h>
|
||||
#include <H5Oprivate.h>
|
||||
|
||||
@ -561,6 +562,7 @@ H5Glink (hid_t loc_id, H5G_link_t type, const char *cur_name,
|
||||
|
||||
FUNC_ENTER (H5Glink, FAIL);
|
||||
|
||||
/* Check arguments */
|
||||
if (NULL==(loc=H5G_loc (loc_id))) {
|
||||
HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
|
||||
}
|
||||
@ -615,6 +617,93 @@ H5Gunlink (hid_t __unused__ loc_id, const char __unused__ *name)
|
||||
FUNC_LEAVE (SUCCEED);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5Gstat
|
||||
*
|
||||
* Purpose: Returns information about an object. If FOLLOW_LINK is
|
||||
* non-zero then all symbolic links are followed; otherwise all
|
||||
* links except the last component of the name are followed.
|
||||
*
|
||||
* Return: Success: SUCCEED with the fields of STATBUF (if
|
||||
* non-null) initialized.
|
||||
*
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Monday, April 13, 1998
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5Gstat (hid_t loc_id, const char *name, hbool_t follow_link,
|
||||
H5G_stat_t *statbuf/*out*/)
|
||||
{
|
||||
H5G_t *loc = NULL;
|
||||
|
||||
FUNC_ENTER (H5Gstat, FAIL);
|
||||
|
||||
/* Check arguments */
|
||||
if (NULL==(loc=H5G_loc (loc_id))) {
|
||||
HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
|
||||
}
|
||||
if (!name || !*name) {
|
||||
HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified");
|
||||
}
|
||||
|
||||
/* Get info */
|
||||
if (H5G_stat (loc, name, follow_link, statbuf)<0) {
|
||||
HRETURN_ERROR (H5E_ARGS, H5E_CANTINIT, FAIL, "cannot stat object");
|
||||
}
|
||||
|
||||
FUNC_LEAVE (SUCCEED);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5Gget_linkval
|
||||
*
|
||||
* Purpose: Returns the value of a symbolic link whose name is NAME. At
|
||||
* most SIZE characters (counting the null terminator) are
|
||||
* copied to the BUF result buffer.
|
||||
*
|
||||
* Return: Success: SUCCEED, the link value is in BUF.
|
||||
*
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Monday, April 13, 1998
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5Gget_linkval (hid_t loc_id, const char *name, size_t size, char *buf/*out*/)
|
||||
{
|
||||
H5G_t *loc = NULL;
|
||||
|
||||
FUNC_ENTER (H5Gget_linkval, FAIL);
|
||||
|
||||
/* Check arguments */
|
||||
if (NULL==(loc=H5G_loc (loc_id))) {
|
||||
HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
|
||||
}
|
||||
if (!name || !*name) {
|
||||
HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified");
|
||||
}
|
||||
|
||||
/* Get the link value */
|
||||
if (H5G_linkval (loc, name, size, buf)<0) {
|
||||
HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL,
|
||||
"unable to get link value");
|
||||
}
|
||||
|
||||
FUNC_LEAVE (SUCCEED);
|
||||
}
|
||||
|
||||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
*-------------------------------------------------------------------------
|
||||
@ -746,12 +835,18 @@ H5G_component(const char *name, size_t *size_p)
|
||||
* LOC_ENT. The component `.' is a no-op, but `..' is not
|
||||
* understood by this function (unless it appears as an entry in
|
||||
* the symbol table).
|
||||
*
|
||||
* Symbolic links are followed automatically, but if
|
||||
* FOLLOW_SLINK is false and the last component of the name is a
|
||||
* symbolic link then that link is not followed. At most NLINKS
|
||||
* are followed and the next link generates an error.
|
||||
*
|
||||
* Errors:
|
||||
*
|
||||
* Return: Success: SUCCEED if name can be fully resolved. See
|
||||
* above for values of REST, GRP_ENT, and
|
||||
* OBJ_ENT.
|
||||
* OBJ_ENT. NLINKS has been decremented for
|
||||
* each symbolic link that was followed.
|
||||
*
|
||||
* Failure: FAIL if the name could not be fully resolved.
|
||||
* See above for values of REST, GRP_ENT, and
|
||||
@ -767,22 +862,21 @@ H5G_component(const char *name, size_t *size_p)
|
||||
*/
|
||||
static herr_t
|
||||
H5G_namei(H5G_entry_t *loc_ent, const char *name, const char **rest/*out*/,
|
||||
H5G_entry_t *grp_ent/*out*/, H5G_entry_t *obj_ent/*out*/)
|
||||
H5G_entry_t *grp_ent/*out*/, H5G_entry_t *obj_ent/*out*/,
|
||||
hbool_t follow_slink, intn *nlinks)
|
||||
{
|
||||
H5G_entry_t _grp_ent; /*entry for current group */
|
||||
H5G_entry_t _obj_ent; /*entry found */
|
||||
size_t nchars; /*component name length */
|
||||
char comp[1024]; /*component name buffer */
|
||||
|
||||
/* clear output args before FUNC_ENTER() in case it fails */
|
||||
int _nlinks = H5G_NLINKS;
|
||||
const char *s = NULL;
|
||||
|
||||
if (rest) *rest = name;
|
||||
if (!grp_ent) grp_ent = &_grp_ent;
|
||||
if (!obj_ent) obj_ent = &_obj_ent;
|
||||
memset(grp_ent, 0, sizeof(H5G_entry_t));
|
||||
H5F_addr_undef(&(grp_ent->header));
|
||||
memset(obj_ent, 0, sizeof(H5G_entry_t));
|
||||
H5F_addr_undef(&(obj_ent->header));
|
||||
|
||||
if (!nlinks) nlinks = &_nlinks;
|
||||
|
||||
FUNC_ENTER(H5G_namei, FAIL);
|
||||
|
||||
/*
|
||||
@ -799,6 +893,9 @@ H5G_namei(H5G_entry_t *loc_ent, const char *name, const char **rest/*out*/,
|
||||
} else {
|
||||
*obj_ent = *loc_ent;
|
||||
}
|
||||
memset(grp_ent, 0, sizeof(H5G_entry_t));
|
||||
H5F_addr_undef(&(grp_ent->header));
|
||||
|
||||
|
||||
/* traverse the name */
|
||||
while ((name = H5G_component(name, &nchars)) && *name) {
|
||||
@ -837,6 +934,24 @@ H5G_namei(H5G_entry_t *loc_ent, const char *name, const char **rest/*out*/,
|
||||
*/
|
||||
HRETURN_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found");
|
||||
}
|
||||
|
||||
/*
|
||||
* If we found a symbolic link then we should follow it. But if this
|
||||
* is the last component of the name and FOLLOW_SLINK is zero then we
|
||||
* don't follow it.
|
||||
*/
|
||||
if (H5G_CACHED_SLINK==obj_ent->type &&
|
||||
(follow_slink || ((s=H5G_component(name+nchars, NULL)) && *s))) {
|
||||
if ((*nlinks)-- <= 0) {
|
||||
HRETURN_ERROR (H5E_SYM, H5E_SLINK, FAIL,
|
||||
"too many symbolic links");
|
||||
}
|
||||
if (H5G_traverse_slink (grp_ent, obj_ent, nlinks)<0) {
|
||||
HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL,
|
||||
"symbolic link traversal failed");
|
||||
}
|
||||
}
|
||||
|
||||
/* next component */
|
||||
name += nchars;
|
||||
}
|
||||
@ -845,6 +960,63 @@ H5G_namei(H5G_entry_t *loc_ent, const char *name, const char **rest/*out*/,
|
||||
FUNC_LEAVE(SUCCEED);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5G_traverse_slink
|
||||
*
|
||||
* Purpose: Traverses symbolic link. The link head appears in the group
|
||||
* whose entry is GRP_ENT and the link head entry is OBJ_ENT.
|
||||
*
|
||||
* Return: Success: SUCCEED, OBJ_ENT will contain information
|
||||
* about the object to which the link points and
|
||||
* GRP_ENT will contain the information about
|
||||
* the group in which the link tail appears.
|
||||
*
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Friday, April 10, 1998
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5G_traverse_slink (H5G_entry_t *grp_ent/*in,out*/,
|
||||
H5G_entry_t *obj_ent/*in,out*/,
|
||||
intn *nlinks/*in,out*/)
|
||||
{
|
||||
H5O_stab_t stab_mesg; /*info about local heap */
|
||||
const char *clv = NULL; /*cached link value */
|
||||
char *linkval = NULL; /*the copied link value */
|
||||
herr_t ret_value = FAIL; /*return value */
|
||||
|
||||
FUNC_ENTER (H5G_traverse_slink, FAIL);
|
||||
|
||||
/* Get the link value */
|
||||
if (NULL==H5O_read (grp_ent, H5O_STAB, 0, &stab_mesg)) {
|
||||
HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL,
|
||||
"unable to determine local heap address");
|
||||
}
|
||||
if (NULL==(clv=H5HL_peek (grp_ent->file, &(stab_mesg.heap_addr),
|
||||
obj_ent->cache.slink.lval_offset))) {
|
||||
HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL,
|
||||
"unable to read symbolic link value");
|
||||
}
|
||||
linkval = H5MM_xstrdup (clv);
|
||||
|
||||
/* Traverse the link */
|
||||
if (H5G_namei (grp_ent, linkval, NULL, grp_ent, obj_ent, TRUE, nlinks)) {
|
||||
HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL,
|
||||
"unable to follow symbolic link");
|
||||
}
|
||||
ret_value = SUCCEED;
|
||||
|
||||
done:
|
||||
H5MM_xfree (linkval);
|
||||
FUNC_LEAVE (ret_value);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5G_mkroot
|
||||
@ -963,7 +1135,8 @@ H5G_create(H5G_t *loc, const char *name, size_t size_hint)
|
||||
assert(name && *name);
|
||||
|
||||
/* lookup name */
|
||||
if (0 == H5G_namei(H5G_entof(loc), name, &rest, &grp_ent, NULL)) {
|
||||
if (0 == H5G_namei(H5G_entof(loc), name, &rest, &grp_ent, NULL,
|
||||
TRUE, NULL)) {
|
||||
HRETURN_ERROR(H5E_SYM, H5E_EXISTS, NULL, "already exists");
|
||||
}
|
||||
H5E_clear(); /*it's OK that we didn't find it */
|
||||
@ -1338,7 +1511,7 @@ H5G_insert(H5G_t *loc, const char *name, H5G_entry_t *ent)
|
||||
/*
|
||||
* Look up the name -- it shouldn't exist yet.
|
||||
*/
|
||||
if (H5G_namei(H5G_entof(loc), name, &rest, &grp, NULL) >= 0) {
|
||||
if (H5G_namei(H5G_entof(loc), name, &rest, &grp, NULL, TRUE, NULL) >= 0) {
|
||||
HRETURN_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "already exists");
|
||||
}
|
||||
H5E_clear(); /*it's OK that we didn't find it */
|
||||
@ -1411,7 +1584,8 @@ H5G_find(H5G_t *loc, const char *name,
|
||||
assert (loc);
|
||||
assert (name && *name);
|
||||
|
||||
if (H5G_namei(H5G_entof(loc), name, NULL, grp_ent, obj_ent) < 0) {
|
||||
if (H5G_namei(H5G_entof(loc), name, NULL, grp_ent, obj_ent,
|
||||
TRUE, NULL)<0) {
|
||||
HRETURN_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found");
|
||||
}
|
||||
FUNC_LEAVE(SUCCEED);
|
||||
@ -1531,7 +1705,13 @@ herr_t
|
||||
H5G_link (H5G_t *loc, H5G_type_t type, const char *cur_name,
|
||||
const char *new_name)
|
||||
{
|
||||
H5G_entry_t cur_obj;
|
||||
H5G_entry_t cur_obj; /*entry for the link tail */
|
||||
H5G_entry_t grp_ent; /*ent for grp containing link hd*/
|
||||
H5O_stab_t stab_mesg; /*symbol table message */
|
||||
const char *rest = NULL; /*last component of new name */
|
||||
char _comp[1024]; /*name component */
|
||||
size_t nchars; /*characters in component */
|
||||
size_t offset; /*offset to sym-link value */
|
||||
|
||||
FUNC_ENTER (H5G_link, FAIL);
|
||||
|
||||
@ -1542,8 +1722,74 @@ H5G_link (H5G_t *loc, H5G_type_t type, const char *cur_name,
|
||||
|
||||
switch (type) {
|
||||
case H5G_LINK_SOFT:
|
||||
HRETURN_ERROR (H5E_SYM, H5E_UNSUPPORTED, FAIL,
|
||||
"unable to create soft link (not implemented yet)");
|
||||
/*
|
||||
* Lookup the the new_name so we can get the group which will contain
|
||||
* the new entry. The entry shouldn't exist yet.
|
||||
*/
|
||||
if (H5G_namei (H5G_entof(loc), new_name, &rest, &grp_ent, NULL,
|
||||
TRUE, NULL)>=0) {
|
||||
HRETURN_ERROR (H5E_SYM, H5E_EXISTS, FAIL, "already exists");
|
||||
}
|
||||
H5E_clear (); /*it's okay that we didn't find it*/
|
||||
rest = H5G_component (rest, &nchars);
|
||||
|
||||
/*
|
||||
* There should be one component left. Make sure it's null
|
||||
* terminated and that `rest' points to it.
|
||||
*/
|
||||
if (rest[nchars]) {
|
||||
if (H5G_component (rest+nchars, NULL)) {
|
||||
HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL,
|
||||
"component not found");
|
||||
} else if (nchars+1 > sizeof _comp) {
|
||||
HRETURN_ERROR (H5E_SYM, H5E_COMPLEN, FAIL,
|
||||
"name component is too long");
|
||||
} else {
|
||||
HDmemcpy (_comp, rest, nchars);
|
||||
_comp[nchars] = '\0';
|
||||
rest = _comp;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the link-value to the local heap for the symbol table which
|
||||
* will contain the link.
|
||||
*/
|
||||
if (NULL==H5O_read (&grp_ent, H5O_STAB, 0, &stab_mesg)) {
|
||||
HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL,
|
||||
"unable to determine local heap address");
|
||||
}
|
||||
if ((size_t)(-1)==(offset=H5HL_insert (grp_ent.file,
|
||||
&(stab_mesg.heap_addr),
|
||||
strlen(cur_name)+1,
|
||||
cur_name))) {
|
||||
HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL,
|
||||
"unable to write link value to local heap");
|
||||
}
|
||||
H5O_reset (H5O_STAB, &stab_mesg);
|
||||
|
||||
/*
|
||||
* Create a symbol table entry for the link. The object header is
|
||||
* undefined and the cache contains the link-value offset.
|
||||
*/
|
||||
HDmemset (&cur_obj, 0, sizeof cur_obj);
|
||||
H5F_addr_undef (&(cur_obj.header));
|
||||
cur_obj.file = grp_ent.file;
|
||||
cur_obj.type = H5G_CACHED_SLINK;
|
||||
cur_obj.cache.slink.lval_offset = offset;
|
||||
|
||||
/*
|
||||
* Insert the link head in the symbol table. This shouldn't ever
|
||||
* fail because we've already checked that the link head doesn't
|
||||
* exist and the file is writable (because the local heap is
|
||||
* writable). But if it does, the only side effect is that the local
|
||||
* heap has some extra garbage in it.
|
||||
*/
|
||||
if (H5G_stab_insert (&grp_ent, rest, &cur_obj)<0) {
|
||||
HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL,
|
||||
"unable to create new name/link for object");
|
||||
}
|
||||
break;
|
||||
|
||||
case H5G_LINK_HARD:
|
||||
if (H5G_find (loc, cur_name, NULL, &cur_obj)<0) {
|
||||
@ -1563,3 +1809,153 @@ H5G_link (H5G_t *loc, H5G_type_t type, const char *cur_name,
|
||||
|
||||
FUNC_LEAVE (SUCCEED);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5G_stat
|
||||
*
|
||||
* Purpose: Returns information about an object.
|
||||
*
|
||||
* Return: Success: SUCCEED with info about the object returned
|
||||
* through STATBUF if it isn't the null pointer.
|
||||
*
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Monday, April 13, 1998
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5G_stat (H5G_t *loc, const char *name, hbool_t follow_link,
|
||||
H5G_stat_t *statbuf/*out*/)
|
||||
{
|
||||
H5O_stab_t stab_mesg;
|
||||
H5G_entry_t grp_ent, obj_ent;
|
||||
const char *s = NULL;
|
||||
H5D_t *temp_dset = NULL;
|
||||
H5G_t *temp_grp = NULL;
|
||||
|
||||
FUNC_ENTER (H5G_stat, FAIL);
|
||||
|
||||
assert (loc);
|
||||
assert (name && *name);
|
||||
if (statbuf) HDmemset (statbuf, 0, sizeof *statbuf);
|
||||
|
||||
/* Find the object's symbol table entry */
|
||||
if (H5G_namei (H5G_entof(loc), name, NULL, &grp_ent/*out*/,
|
||||
&obj_ent/*out*/, follow_link, NULL)<0) {
|
||||
HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to stat object");
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the stat buf. Symbolic links aren't normal objects and
|
||||
* therefor don't have much of the normal info. However, the link value
|
||||
* length is specific to symbolic links.
|
||||
*/
|
||||
if (statbuf) {
|
||||
if (H5G_CACHED_SLINK!=obj_ent.type) {
|
||||
statbuf->objno[0] = (unsigned long)(obj_ent.header.offset);
|
||||
statbuf->objno[1] = (unsigned long)(obj_ent.header.offset >>
|
||||
8*sizeof(long));
|
||||
statbuf->nlink = H5O_link (&obj_ent, 0);
|
||||
statbuf->type = H5G_LINK;
|
||||
} else {
|
||||
if (NULL==H5O_read (&grp_ent, H5O_STAB, 0, &stab_mesg) ||
|
||||
NULL==(s=H5HL_peek (grp_ent.file, &(stab_mesg.heap_addr),
|
||||
obj_ent.cache.slink.lval_offset))) {
|
||||
HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL,
|
||||
"unable to read symbolic link value");
|
||||
}
|
||||
statbuf->linklen = strlen(s)+1; /*count the null terminator*/
|
||||
|
||||
/*
|
||||
* Determining the type of an object is a rather expensive
|
||||
* operation compared to the other stuff here. It's also not
|
||||
* very flexible.
|
||||
*/
|
||||
if (NULL!=(temp_dset=H5D_open (loc, name))) {
|
||||
statbuf->type = H5G_DATASET;
|
||||
H5D_close (temp_dset);
|
||||
} else if (NULL!=(temp_grp=H5G_open (loc, name))) {
|
||||
statbuf->type = H5G_GROUP;
|
||||
H5G_close (temp_grp);
|
||||
} else {
|
||||
statbuf->type = H5G_UNKNOWN;
|
||||
}
|
||||
H5E_clear(); /*clear errors resulting from checking type*/
|
||||
}
|
||||
}
|
||||
|
||||
FUNC_LEAVE (SUCCEED);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5G_linkval
|
||||
*
|
||||
* Purpose: Returns the value of a symbolic link.
|
||||
*
|
||||
* Return: Success: SUCCEED, with at most SIZE bytes of the link
|
||||
* value copied into the BUF buffer. If the
|
||||
* link value is larger than SIZE characters
|
||||
* counting the null terminator then the BUF
|
||||
* result will not be null terminated.
|
||||
*
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Monday, April 13, 1998
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5G_linkval (H5G_t *loc, const char *name, size_t size, char *buf/*out*/)
|
||||
{
|
||||
const char *s = NULL;
|
||||
H5G_entry_t grp_ent, obj_ent;
|
||||
H5O_stab_t stab_mesg;
|
||||
|
||||
FUNC_ENTER (H5G_linkval, FAIL);
|
||||
|
||||
/*
|
||||
* Get the symbol table entry for the link head and the symbol table
|
||||
* entry for the group in which the link head appears.
|
||||
*/
|
||||
if (H5G_namei (H5G_entof(loc), name, NULL, &grp_ent/*out*/,
|
||||
&obj_ent/*out*/, FALSE, NULL)<0) {
|
||||
HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL,
|
||||
"symbolic link was not found");
|
||||
}
|
||||
if (H5G_CACHED_SLINK!=obj_ent.type) {
|
||||
HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL,
|
||||
"object is not a symbolic link");
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the address of the local heap for the link value and a pointer
|
||||
* into that local heap.
|
||||
*/
|
||||
if (NULL==H5O_read (&grp_ent, H5O_STAB, 0, &stab_mesg)) {
|
||||
HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL,
|
||||
"unable to determine local heap address");
|
||||
}
|
||||
if (NULL==(s=H5HL_peek (grp_ent.file, &(stab_mesg.heap_addr),
|
||||
obj_ent.cache.slink.lval_offset))) {
|
||||
HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL,
|
||||
"unable to read symbolic link value");
|
||||
}
|
||||
|
||||
/* Copy to output buffer */
|
||||
if (size>0 && buf) {
|
||||
strncpy (buf, s, size);
|
||||
}
|
||||
|
||||
FUNC_LEAVE (SUCCEED);
|
||||
}
|
||||
|
||||
|
||||
|
26
src/H5Gent.c
26
src/H5Gent.c
@ -10,6 +10,7 @@
|
||||
#include <H5private.h>
|
||||
#include <H5Eprivate.h>
|
||||
#include <H5Gpkg.h>
|
||||
#include <H5HLprivate.h>
|
||||
#include <H5MMprivate.h>
|
||||
|
||||
#define PABLO_MASK H5G_ent_mask
|
||||
@ -204,6 +205,10 @@ H5G_ent_decode(H5F_t *f, const uint8 **pp, H5G_entry_t *ent)
|
||||
H5F_addr_decode(f, pp, &(ent->cache.stab.heap_addr));
|
||||
break;
|
||||
|
||||
case H5G_CACHED_SLINK:
|
||||
UINT32DECODE (*pp, ent->cache.slink.lval_offset);
|
||||
break;
|
||||
|
||||
default:
|
||||
HDabort();
|
||||
}
|
||||
@ -310,6 +315,10 @@ H5G_ent_encode(H5F_t *f, uint8 **pp, H5G_entry_t *ent)
|
||||
H5F_addr_encode(f, pp, &(ent->cache.stab.heap_addr));
|
||||
break;
|
||||
|
||||
case H5G_CACHED_SLINK:
|
||||
UINT32ENCODE (*pp, ent->cache.slink.lval_offset);
|
||||
break;
|
||||
|
||||
default:
|
||||
HDabort();
|
||||
}
|
||||
@ -350,8 +359,10 @@ H5G_ent_encode(H5F_t *f, uint8 **pp, H5G_entry_t *ent)
|
||||
*/
|
||||
herr_t
|
||||
H5G_ent_debug(H5F_t __unused__ *f, H5G_entry_t *ent, FILE * stream,
|
||||
intn indent, intn fwidth)
|
||||
intn indent, intn fwidth, const haddr_t *heap)
|
||||
{
|
||||
const char *lval = NULL;
|
||||
|
||||
FUNC_ENTER(H5G_ent_debug, FAIL);
|
||||
|
||||
fprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth,
|
||||
@ -387,6 +398,19 @@ H5G_ent_debug(H5F_t __unused__ *f, H5G_entry_t *ent, FILE * stream,
|
||||
fprintf(stream, "\n");
|
||||
break;
|
||||
|
||||
case H5G_CACHED_SLINK:
|
||||
fprintf (stream, "Symbolic Link\n");
|
||||
fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
|
||||
"Link value offset:",
|
||||
(unsigned long)(ent->cache.slink.lval_offset));
|
||||
if (heap && H5F_addr_defined (heap)) {
|
||||
lval = H5HL_peek (ent->file, heap, ent->cache.slink.lval_offset);
|
||||
fprintf (stream, "%*s%-*s %s\n", indent, "", fwidth,
|
||||
"Link value:",
|
||||
lval);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stream, "*** Unknown symbol type %d\n", ent->type);
|
||||
break;
|
||||
|
@ -985,7 +985,7 @@ H5G_node_debug(H5F_t *f, const haddr_t *addr, FILE * stream, intn indent,
|
||||
"Name:",
|
||||
s);
|
||||
}
|
||||
H5G_ent_debug(f, sn->entry + i, stream, indent, fwidth);
|
||||
H5G_ent_debug(f, sn->entry + i, stream, indent, fwidth, heap);
|
||||
}
|
||||
|
||||
H5AC_unprotect(f, H5AC_SNODE, addr, sn);
|
||||
|
@ -33,6 +33,7 @@
|
||||
#define H5G_NODE_MAGIC "SNOD" /*symbol table node magic number */
|
||||
#define H5G_NODE_SIZEOF_MAGIC 4 /*sizeof symbol node magic number */
|
||||
#define H5G_NO_CHANGE (-1) /*see H5G_ent_modified() */
|
||||
#define H5G_NLINKS 16 /*max symlinks to follow per lookup */
|
||||
|
||||
/*
|
||||
* The disk size for a symbol table entry...
|
||||
@ -54,8 +55,9 @@ typedef enum H5G_type_t {
|
||||
H5G_CACHED_ERROR = -1, /*force enum to be signed */
|
||||
H5G_NOTHING_CACHED = 0, /*nothing is cached, must be 0 */
|
||||
H5G_CACHED_STAB = 1, /*symbol table, `stab' */
|
||||
H5G_CACHED_SLINK = 2, /*symbolic link */
|
||||
|
||||
H5G_NCACHED = 2 /*THIS MUST BE LAST */
|
||||
H5G_NCACHED = 3 /*THIS MUST BE LAST */
|
||||
} H5G_type_t;
|
||||
|
||||
/*
|
||||
@ -70,6 +72,10 @@ typedef union H5G_cache_t {
|
||||
haddr_t btree_addr; /*file address of symbol table B-tree*/
|
||||
haddr_t heap_addr; /*file address of stab name heap */
|
||||
} stab;
|
||||
|
||||
struct {
|
||||
size_t lval_offset; /*link value offset */
|
||||
} slink;
|
||||
} H5G_cache_t;
|
||||
|
||||
/*
|
||||
@ -106,9 +112,16 @@ herr_t H5G_pop (H5F_t *f);
|
||||
H5G_t *H5G_getcwg(H5F_t *f);
|
||||
herr_t H5G_link (H5G_t *loc, H5G_type_t type, const char *cur_name,
|
||||
const char *new_name);
|
||||
herr_t H5G_stat (H5G_t *loc, const char *name, hbool_t follow_link,
|
||||
H5G_stat_t *statbuf/*out*/);
|
||||
herr_t H5G_linkval (H5G_t *loc, const char *name, size_t size,
|
||||
char *buf/*out*/);
|
||||
herr_t H5G_insert (H5G_t *cwg, const char *name, H5G_entry_t *ent);
|
||||
herr_t H5G_find (H5G_t *cwg, const char *name, H5G_entry_t *grp_ent/*out*/,
|
||||
H5G_entry_t *ent/*out*/);
|
||||
herr_t H5G_traverse_slink (H5G_entry_t *grp_ent/*in,out*/,
|
||||
H5G_entry_t *obj_ent/*in,out*/,
|
||||
intn *nlinks/*in,out*/);
|
||||
herr_t H5G_ent_encode (H5F_t *f, uint8 **pp, H5G_entry_t *ent);
|
||||
herr_t H5G_ent_decode (H5F_t *f, const uint8 **pp, H5G_entry_t *ent/*out*/);
|
||||
|
||||
@ -127,6 +140,6 @@ H5G_entry_t *H5G_ent_calloc (H5G_entry_t *init);
|
||||
H5G_cache_t *H5G_ent_cache (H5G_entry_t *ent, H5G_type_t *cache_type);
|
||||
herr_t H5G_ent_modified (H5G_entry_t *ent, H5G_type_t cache_type);
|
||||
herr_t H5G_ent_debug (H5F_t *f, H5G_entry_t *ent, FILE * stream, intn indent,
|
||||
intn fwidth);
|
||||
intn fwidth, const haddr_t *heap);
|
||||
#endif
|
||||
|
||||
|
@ -27,12 +27,29 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Types of links */
|
||||
typedef enum H5G_link_t {
|
||||
H5G_LINK_ERROR = -1,
|
||||
H5G_LINK_HARD = 0,
|
||||
H5G_LINK_SOFT = 1
|
||||
} H5G_link_t;
|
||||
|
||||
/* An object has a certain type */
|
||||
#define H5G_UNKNOWN (-1) /* Unknown object type */
|
||||
#define H5G_LINK 0 /* Object is a symbolic link */
|
||||
#define H5G_GROUP 1 /* Object is a group */
|
||||
#define H5G_DATASET 2 /* Object is a dataset */
|
||||
|
||||
/* Information about an object */
|
||||
typedef struct H5G_stat_t {
|
||||
unsigned long fileno[2];
|
||||
unsigned long objno[2];
|
||||
unsigned nlink;
|
||||
int type;
|
||||
size_t linklen;
|
||||
} H5G_stat_t;
|
||||
|
||||
|
||||
typedef herr_t (*H5G_iterate_t)(hid_t group, const char *group_name,
|
||||
void *op_data);
|
||||
|
||||
@ -48,6 +65,10 @@ herr_t H5Gmove (hid_t loc_id, const char *src, const char *dst);
|
||||
herr_t H5Glink (hid_t loc_id, H5G_link_t type, const char *cur_name,
|
||||
const char *new_name);
|
||||
herr_t H5Gunlink (hid_t loc_id, const char *name);
|
||||
herr_t H5Gstat (hid_t loc_id, const char *name, hbool_t follow_link,
|
||||
H5G_stat_t *statbuf/*out*/);
|
||||
herr_t H5Gget_linkval (hid_t loc_id, const char *name, size_t size,
|
||||
char *buf/*out*/);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
117
src/H5Gstab.c
117
src/H5Gstab.c
@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Copyright (C) 1997 National Center for Supercomputing Applications
|
||||
* All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Programmer: Robb Matzke <matzke@llnl.gov>
|
||||
* Friday, September 19, 1997
|
||||
* Friday, September 19, 1997
|
||||
*
|
||||
*/
|
||||
#define H5G_PACKAGE
|
||||
@ -16,31 +16,31 @@
|
||||
#include <H5MMprivate.h>
|
||||
#include <H5Oprivate.h>
|
||||
|
||||
#define PABLO_MASK H5G_stab_mask
|
||||
static hbool_t interface_initialize_g = FALSE;
|
||||
#define INTERFACE_INIT NULL
|
||||
#define PABLO_MASK H5G_stab_mask
|
||||
static hbool_t interface_initialize_g = FALSE;
|
||||
#define INTERFACE_INIT NULL
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5G_stab_create
|
||||
* Function: H5G_stab_create
|
||||
*
|
||||
* Purpose: Creates a new empty symbol table (object header, name heap,
|
||||
* and B-tree). The caller can specify an initial size for the
|
||||
* name heap. The object header of the group is opened for
|
||||
* write access.
|
||||
* Purpose: Creates a new empty symbol table (object header, name heap,
|
||||
* and B-tree). The caller can specify an initial size for the
|
||||
* name heap. The object header of the group is opened for
|
||||
* write access.
|
||||
*
|
||||
* In order for the B-tree to operate correctly, the first
|
||||
* item in the heap is the empty string, and must appear at
|
||||
* heap offset zero.
|
||||
* In order for the B-tree to operate correctly, the first
|
||||
* item in the heap is the empty string, and must appear at
|
||||
* heap offset zero.
|
||||
*
|
||||
* Errors:
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
* Return: Success: SUCCEED
|
||||
*
|
||||
* Failure: FAIL
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* matzke@llnl.gov
|
||||
* Aug 1 1997
|
||||
* Programmer: Robb Matzke
|
||||
* matzke@llnl.gov
|
||||
* Aug 1 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
@ -49,8 +49,8 @@ static hbool_t interface_initialize_g = FALSE;
|
||||
herr_t
|
||||
H5G_stab_create(H5F_t *f, size_t init, H5G_entry_t *self/*out*/)
|
||||
{
|
||||
size_t name; /*offset of "" name */
|
||||
H5O_stab_t stab; /*symbol table message */
|
||||
size_t name; /*offset of "" name */
|
||||
H5O_stab_t stab; /*symbol table message */
|
||||
|
||||
FUNC_ENTER(H5G_stab_create, FAIL);
|
||||
|
||||
@ -63,11 +63,11 @@ H5G_stab_create(H5F_t *f, size_t init, H5G_entry_t *self/*out*/)
|
||||
|
||||
/* Create symbol table private heap */
|
||||
if (H5HL_create(f, init, &(stab.heap_addr)/*out*/)<0) {
|
||||
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create heap");
|
||||
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create heap");
|
||||
}
|
||||
name = H5HL_insert(f, &(stab.heap_addr), 1, "");
|
||||
if ((size_t)(-1)==name) {
|
||||
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't initialize heap");
|
||||
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't initialize heap");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -78,23 +78,25 @@ H5G_stab_create(H5F_t *f, size_t init, H5G_entry_t *self/*out*/)
|
||||
|
||||
/* Create the B-tree */
|
||||
if (H5B_create(f, H5B_SNODE, NULL, &(stab.btree_addr) /*out */ ) < 0) {
|
||||
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create B-tree");
|
||||
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create B-tree");
|
||||
}
|
||||
|
||||
/*
|
||||
* Create symbol table object header. It has a zero link count
|
||||
* since nothing refers to it yet. The link count will be
|
||||
* since nothing refers to it yet. The link count will be
|
||||
* incremented if the object is added to the group directed graph.
|
||||
*/
|
||||
if (H5O_create(f, 4 + 2 * H5F_SIZEOF_ADDR(f), self /*out */ ) < 0) {
|
||||
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create header");
|
||||
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create header");
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert the symbol table message into the object header and the symbol
|
||||
* table entry.
|
||||
*/
|
||||
if (H5O_modify(self, H5O_STAB, H5O_NEW_MESG, H5O_FLAG_CONSTANT, &stab) < 0) {
|
||||
H5O_close(self);
|
||||
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message");
|
||||
if (H5O_modify(self, H5O_STAB, H5O_NEW_MESG, H5O_FLAG_CONSTANT, &stab)<0) {
|
||||
H5O_close(self);
|
||||
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message");
|
||||
}
|
||||
self->cache.stab.btree_addr = stab.btree_addr;
|
||||
self->cache.stab.heap_addr = stab.heap_addr;
|
||||
@ -102,23 +104,24 @@ H5G_stab_create(H5F_t *f, size_t init, H5G_entry_t *self/*out*/)
|
||||
|
||||
FUNC_LEAVE(SUCCEED);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5G_stab_find
|
||||
* Function: H5G_stab_find
|
||||
*
|
||||
* Purpose: Finds a symbol named NAME in the symbol table whose
|
||||
* description is stored in GRP_ENT in file F and returns its
|
||||
* symbol table entry through OBJ_ENT (which is optional).
|
||||
* Purpose: Finds a symbol named NAME in the symbol table whose
|
||||
* description is stored in GRP_ENT in file F and returns its
|
||||
* symbol table entry through OBJ_ENT (which is optional).
|
||||
*
|
||||
* Errors:
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
* Return: Success: SUCCEED
|
||||
*
|
||||
* Failure: FAIL
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* matzke@llnl.gov
|
||||
* Aug 1 1997
|
||||
* Programmer: Robb Matzke
|
||||
* matzke@llnl.gov
|
||||
* Aug 1 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
@ -126,10 +129,10 @@ H5G_stab_create(H5F_t *f, size_t init, H5G_entry_t *self/*out*/)
|
||||
*/
|
||||
herr_t
|
||||
H5G_stab_find(H5G_entry_t *grp_ent, const char *name,
|
||||
H5G_entry_t *obj_ent /*out */ )
|
||||
H5G_entry_t *obj_ent/*out*/)
|
||||
{
|
||||
H5G_bt_ud1_t udata; /*data to pass through B-tree */
|
||||
H5O_stab_t stab; /*symbol table message */
|
||||
H5G_bt_ud1_t udata; /*data to pass through B-tree */
|
||||
H5O_stab_t stab; /*symbol table message */
|
||||
|
||||
FUNC_ENTER(H5G_stab_find, FAIL);
|
||||
|
||||
@ -140,7 +143,7 @@ H5G_stab_find(H5G_entry_t *grp_ent, const char *name,
|
||||
|
||||
/* set up the udata */
|
||||
if (NULL == H5O_read(grp_ent, H5O_STAB, 0, &stab)) {
|
||||
HRETURN_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't read message");
|
||||
HRETURN_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't read message");
|
||||
}
|
||||
udata.operation = H5G_OPER_FIND;
|
||||
udata.name = name;
|
||||
@ -148,29 +151,28 @@ H5G_stab_find(H5G_entry_t *grp_ent, const char *name,
|
||||
|
||||
/* search the B-tree */
|
||||
if (H5B_find(grp_ent->file, H5B_SNODE, &(stab.btree_addr), &udata) < 0) {
|
||||
HRETURN_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "not found");
|
||||
HRETURN_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "not found");
|
||||
}
|
||||
if (obj_ent)
|
||||
*obj_ent = udata.ent;
|
||||
if (obj_ent) *obj_ent = udata.ent;
|
||||
FUNC_LEAVE(SUCCEED);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5G_stab_insert
|
||||
* Function: H5G_stab_insert
|
||||
*
|
||||
* Purpose: Insert a new symbol into the table described by GRP_ENT in
|
||||
* file F. The name of the new symbol is NAME and its symbol
|
||||
* table entry is OBJ_ENT.
|
||||
* Purpose: Insert a new symbol into the table described by GRP_ENT in
|
||||
* file F. The name of the new symbol is NAME and its symbol
|
||||
* table entry is OBJ_ENT.
|
||||
*
|
||||
* Errors:
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
* Return: Success: SUCCEED
|
||||
*
|
||||
* Failure: FAIL
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* matzke@llnl.gov
|
||||
* Aug 1 1997
|
||||
* Programmer: Robb Matzke
|
||||
* matzke@llnl.gov
|
||||
* Aug 1 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
@ -179,8 +181,8 @@ H5G_stab_find(H5G_entry_t *grp_ent, const char *name,
|
||||
herr_t
|
||||
H5G_stab_insert(H5G_entry_t *grp_ent, const char *name, H5G_entry_t *obj_ent)
|
||||
{
|
||||
H5O_stab_t stab; /*symbol table message */
|
||||
H5G_bt_ud1_t udata; /*data to pass through B-tree */
|
||||
H5O_stab_t stab; /*symbol table message */
|
||||
H5G_bt_ud1_t udata; /*data to pass through B-tree */
|
||||
|
||||
FUNC_ENTER(H5G_stab_insert, FAIL);
|
||||
|
||||
@ -192,7 +194,7 @@ H5G_stab_insert(H5G_entry_t *grp_ent, const char *name, H5G_entry_t *obj_ent)
|
||||
|
||||
/* initialize data to pass through B-tree */
|
||||
if (NULL == H5O_read(grp_ent, H5O_STAB, 0, &stab)) {
|
||||
HRETURN_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "not a symbol table");
|
||||
HRETURN_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "not a symbol table");
|
||||
}
|
||||
udata.operation = H5G_OPER_INSERT;
|
||||
udata.name = name;
|
||||
@ -201,8 +203,9 @@ H5G_stab_insert(H5G_entry_t *grp_ent, const char *name, H5G_entry_t *obj_ent)
|
||||
|
||||
/* insert */
|
||||
if (H5B_insert(grp_ent->file, H5B_SNODE, &(stab.btree_addr), &udata) < 0) {
|
||||
HRETURN_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "can't insert entry");
|
||||
HRETURN_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "can't insert entry");
|
||||
}
|
||||
|
||||
/* update the name offset in the entry */
|
||||
obj_ent->name_off = udata.ent.name_off;
|
||||
FUNC_LEAVE(SUCCEED);
|
||||
|
16
src/h5ls.c
16
src/h5ls.c
@ -44,13 +44,22 @@ list (hid_t group, const char *name, void __unused__ *op_data)
|
||||
hid_t (*func)(void*);
|
||||
void *edata;
|
||||
int i;
|
||||
|
||||
char linkval[512];
|
||||
H5G_stat_t statbuf;
|
||||
|
||||
/* Disable error reporting */
|
||||
H5Eget_auto (&func, &edata);
|
||||
H5Eset_auto (NULL, NULL);
|
||||
|
||||
/* Print info about each name */
|
||||
printf ("%-30s", name);
|
||||
|
||||
if (H5Gstat (group, name, TRUE, &statbuf)>=0) {
|
||||
printf ("FILE={%lu,%lu}, OID={%lu,%lu} ",
|
||||
statbuf.fileno[0], statbuf.fileno[1],
|
||||
statbuf.objno[0], statbuf.objno[1]);
|
||||
}
|
||||
|
||||
if ((obj=H5Dopen (group, name))>=0) {
|
||||
hsize_t size[64];
|
||||
hid_t space = H5Dget_space (obj);
|
||||
@ -65,6 +74,11 @@ list (hid_t group, const char *name, void __unused__ *op_data)
|
||||
} else if ((obj=H5Gopen (group, name))>=0) {
|
||||
printf (" Group\n");
|
||||
H5Gclose (obj);
|
||||
} else if (H5Gget_linkval (group, name, sizeof(linkval), linkval)>=0) {
|
||||
if (NULL==HDmemchr (linkval, 0, sizeof(linkval))) {
|
||||
strcpy (linkval+sizeof(linkval)-4, "...");
|
||||
}
|
||||
printf (" -> %s\n", linkval);
|
||||
} else {
|
||||
printf (" Unknown Type\n");
|
||||
}
|
||||
|
@ -3,7 +3,9 @@ testhdf5.o: \
|
||||
testhdf5.h \
|
||||
../src/H5private.h \
|
||||
../src/H5public.h \
|
||||
../src/H5config.h
|
||||
../src/H5config.h \
|
||||
../src/H5Eprivate.h \
|
||||
../src/H5Epublic.h
|
||||
tfile.o: \
|
||||
tfile.c \
|
||||
testhdf5.h \
|
||||
@ -147,14 +149,13 @@ dtypes.o: \
|
||||
../src/H5Iprivate.h \
|
||||
../src/H5private.h \
|
||||
../src/H5Tprivate.h \
|
||||
../src/H5Gprivate.h
|
||||
../src/H5Gprivate.h \
|
||||
../src/H5Bprivate.h
|
||||
hyperslab.o: \
|
||||
hyperslab.c \
|
||||
../src/H5private.h \
|
||||
../src/H5public.h \
|
||||
../src/H5config.h \
|
||||
../src/H5MMprivate.h \
|
||||
../src/H5MMpublic.h
|
||||
../src/H5config.h
|
||||
istore.o: \
|
||||
istore.c \
|
||||
../src/H5private.h \
|
||||
@ -179,7 +180,8 @@ istore.o: \
|
||||
../src/H5HGpublic.h \
|
||||
../src/H5Tprivate.h \
|
||||
../src/H5Tpublic.h \
|
||||
../src/H5Sprivate.h
|
||||
../src/H5Sprivate.h \
|
||||
../src/H5Spublic.h
|
||||
dsets.o: \
|
||||
dsets.c \
|
||||
../src/hdf5.h \
|
||||
@ -218,8 +220,7 @@ cmpd_dset.o: \
|
||||
../src/H5MMpublic.h \
|
||||
../src/H5Opublic.h \
|
||||
../src/H5Ppublic.h \
|
||||
../src/H5Spublic.h \
|
||||
../src/H5Tpublic.h
|
||||
../src/H5Spublic.h
|
||||
extend.o: \
|
||||
extend.c \
|
||||
../src/hdf5.h \
|
||||
@ -332,4 +333,23 @@ big.o: \
|
||||
../src/H5MMpublic.h \
|
||||
../src/H5Opublic.h \
|
||||
../src/H5Ppublic.h \
|
||||
../src/H5Spublic.h
|
||||
../src/H5Spublic.h \
|
||||
../src/H5Tpublic.h
|
||||
links.o: \
|
||||
links.c \
|
||||
../src/hdf5.h \
|
||||
../src/H5public.h \
|
||||
../src/H5config.h \
|
||||
../src/H5ACpublic.h \
|
||||
../src/H5Bpublic.h \
|
||||
../src/H5Dpublic.h \
|
||||
../src/H5Ipublic.h \
|
||||
../src/H5Epublic.h \
|
||||
../src/H5Fpublic.h \
|
||||
../src/H5Gpublic.h \
|
||||
../src/H5HGpublic.h \
|
||||
../src/H5HLpublic.h \
|
||||
../src/H5MFpublic.h \
|
||||
../src/H5MMpublic.h \
|
||||
../src/H5Opublic.h \
|
||||
../src/H5Ppublic.h
|
||||
|
@ -12,9 +12,9 @@ CPPFLAGS=-I. -I../src @CPPFLAGS@
|
||||
# These are our main targets. They should be listed in the order to be
|
||||
# executed, generally most specific tests to least specific tests.
|
||||
PROGS=testhdf5 gheap hyperslab istore dtypes dsets cmpd_dset extend external \
|
||||
shtype iopipe big
|
||||
shtype iopipe big links
|
||||
TESTS=testhdf5 gheap hyperslab istore dtypes dsets cmpd_dset extend external \
|
||||
shtype
|
||||
shtype links
|
||||
TIMINGS=iopipe
|
||||
|
||||
# Temporary files
|
||||
@ -24,7 +24,7 @@ MOSTLYCLEAN=cmpd_dset.h5 dataset.h5 extend.h5 istore.h5 tfile1.h5 tfile2.h5 \
|
||||
extern_2.raw extern_2b.raw extern_3.raw extern_3b.raw \
|
||||
extern_4.raw extern_4b.raw iopipe.raw iopipe.h5 gheap0.h5 \
|
||||
gheap1.h5 gheap2.h5 gheap3.h5 gheap4.h5 shtype0.h5 shtype1.h5 \
|
||||
shtype2a.h5 shtype2b.h5 shtype3.h5
|
||||
shtype2a.h5 shtype2b.h5 shtype3.h5 links.h5
|
||||
|
||||
# Source and object files for programs... The PROG_SRC list contains all the
|
||||
# source files and is used for things like dependencies, archiving, etc. The
|
||||
@ -32,7 +32,7 @@ MOSTLYCLEAN=cmpd_dset.h5 dataset.h5 extend.h5 istore.h5 tfile1.h5 tfile2.h5 \
|
||||
# overlap with other tests.
|
||||
PROG_SRC=testhdf5.c tfile.c theap.c tmeta.c tohdr.c tstab.c th5s.c dtypes.c \
|
||||
hyperslab.c istore.c dsets.c cmpd_dset.c extend.c external.c \
|
||||
iopipe.c gheap.c shtype.c big.c
|
||||
iopipe.c gheap.c shtype.c big.c links.c
|
||||
PROG_OBJ=$(PROG_SRC:.c=.o)
|
||||
|
||||
TESTHDF5_SRC=testhdf5.c tfile.c theap.c tmeta.c tohdr.c tstab.c th5s.c
|
||||
@ -74,6 +74,9 @@ IOPIPE_OBJ=$(IOPIPE_SRC:.c=.o)
|
||||
BIG_SRC=big.c
|
||||
BIG_OBJ=$(BIG_SRC:.c=.o)
|
||||
|
||||
LINKS_SRC=links.c
|
||||
LINKS_OBJ=$(LINKS_SRC:.c=.o)
|
||||
|
||||
# Private header files (not to be installed)...
|
||||
PRIVATE_HDR=testhdf5.h
|
||||
|
||||
@ -127,4 +130,7 @@ grptime: $(GRPTIME_OBJ) ../src/libhdf5.a
|
||||
big: $(BIG_OBJ) ../src/libhdf5.a
|
||||
$(CC) $(CFLAGS) -o $@ $(BIG_OBJ) ../src/libhdf5.a $(LIBS)
|
||||
|
||||
links: $(LINKS_OBJ) ../src/libhdf5.a
|
||||
$(CC) $(CFLAGS) -o $@ $(LINKS_OBJ) ../src/libhdf5.a $(LIBS)
|
||||
|
||||
@CONCLUDE@
|
||||
|
160
test/big.c
160
test/big.c
@ -6,7 +6,26 @@
|
||||
* Wednesday, April 8, 1998
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <hdf5.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <H5private.h> /*needed for HDfprintf() */
|
||||
|
||||
#define FNAME "big%05d.h5"
|
||||
#define WRT_N 50
|
||||
#define WRT_SIZE 4*1024
|
||||
|
||||
static hsize_t
|
||||
randll (hsize_t limit)
|
||||
{
|
||||
hsize_t acc = rand ();
|
||||
acc *= rand ();
|
||||
|
||||
return acc % limit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -25,12 +44,16 @@
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
main (void)
|
||||
static void
|
||||
writer (int wrt_n)
|
||||
{
|
||||
hsize_t size1[4] = {8, 1024, 1024, 1024};
|
||||
hsize_t size2[1] = {8589934592LL};
|
||||
hid_t plist, file, space1, space2, dset;
|
||||
hssize_t hs_start[1];
|
||||
hsize_t hs_size[1];
|
||||
hid_t plist, file, space1, space2, mem_space, d1, d2;
|
||||
int *buf = malloc (sizeof(int) * WRT_SIZE);
|
||||
int i, j;
|
||||
|
||||
/*
|
||||
* Make sure that `hsize_t' is large enough to represent the entire data
|
||||
@ -44,20 +67,137 @@ main (void)
|
||||
*/
|
||||
plist = H5Pcreate (H5P_FILE_ACCESS);
|
||||
H5Pset_family (plist, 30, H5P_DEFAULT);
|
||||
file = H5Fcreate ("big%05d.h5", H5F_ACC_TRUNC, H5P_DEFAULT, plist);
|
||||
file = H5Fcreate (FNAME, H5F_ACC_TRUNC, H5P_DEFAULT, plist);
|
||||
|
||||
/* Create simple data spaces according to the size specified above. */
|
||||
space1 = H5Screate_simple (4, size1, size1);
|
||||
space2 = H5Screate_simple (1, size2, size2);
|
||||
|
||||
/* Create the datasets */
|
||||
dset = H5Dcreate (file, "d1", H5T_NATIVE_INT, space1, H5P_DEFAULT);
|
||||
H5Dclose (dset);
|
||||
dset = H5Dcreate (file, "d2", H5T_NATIVE_INT, space2, H5P_DEFAULT);
|
||||
H5Dclose (dset);
|
||||
|
||||
d1 = H5Dcreate (file, "d1", H5T_NATIVE_INT, space1, H5P_DEFAULT);
|
||||
d2 = H5Dcreate (file, "d2", H5T_NATIVE_INT, space2, H5P_DEFAULT);
|
||||
|
||||
/* Write some things to them randomly */
|
||||
hs_size[0] = WRT_SIZE;
|
||||
mem_space = H5Screate_simple (1, hs_size, hs_size);
|
||||
for (i=0; i<wrt_n; i++) {
|
||||
hs_start[0] = randll (size2[0]);
|
||||
HDfprintf (stdout, "#%03d 0x%016Hx\n", i, hs_start[0]);
|
||||
H5Sset_hyperslab (space2, hs_start, hs_size, NULL);
|
||||
for (j=0; j<WRT_SIZE; j++) {
|
||||
buf[j] = i+1;
|
||||
}
|
||||
H5Dwrite (d2, H5T_NATIVE_INT, mem_space, space2, H5P_DEFAULT, buf);
|
||||
}
|
||||
|
||||
H5Dclose (d1);
|
||||
H5Dclose (d2);
|
||||
H5Sclose (mem_space);
|
||||
H5Sclose (space1);
|
||||
H5Sclose (space2);
|
||||
H5Fclose (file);
|
||||
exit (0);
|
||||
free (buf);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: reader
|
||||
*
|
||||
* Purpose: Reads some data from random locations in the dataset.
|
||||
*
|
||||
* Return: void
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Friday, April 10, 1998
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
reader (const char *script_name)
|
||||
{
|
||||
FILE *script;
|
||||
hid_t plist, file, mspace, fspace, d2;
|
||||
char ln[64], *s;
|
||||
hssize_t hs_offset[1];
|
||||
hsize_t hs_size[1] = {WRT_SIZE};
|
||||
int *buf = malloc (sizeof(int) * WRT_SIZE);
|
||||
int i, j, zero, wrong;
|
||||
|
||||
/* Open script file */
|
||||
script = fopen (script_name, "r");
|
||||
|
||||
/* Open HDF5 file */
|
||||
plist = H5Pcreate (H5P_FILE_ACCESS);
|
||||
H5Pset_family (plist, 30, H5P_DEFAULT);
|
||||
file = H5Fopen (FNAME, H5F_ACC_RDONLY, plist);
|
||||
|
||||
/* Open the dataset */
|
||||
d2 = H5Dopen (file, "d2");
|
||||
fspace = H5Dget_space (d2);
|
||||
|
||||
/* Describe `buf' */
|
||||
mspace = H5Screate_simple (1, hs_size, hs_size);
|
||||
|
||||
/* Read each region */
|
||||
while (fgets (ln, sizeof(ln), script)) {
|
||||
if ('#'!=ln[0]) break;
|
||||
i = strtol (ln+1, &s, 10);
|
||||
hs_offset[0] = HDstrtoll (s, NULL, 0);
|
||||
HDfprintf (stdout, "#%03d 0x%016Hx", i, hs_offset[0]);
|
||||
fflush (stdout);
|
||||
|
||||
H5Sset_hyperslab (fspace, hs_offset, hs_size, NULL);
|
||||
H5Dread (d2, H5T_NATIVE_INT, mspace, fspace, H5P_DEFAULT, buf);
|
||||
|
||||
/* Check */
|
||||
for (j=zero=wrong=0; j<WRT_SIZE; j++) {
|
||||
if (0==buf[j]) zero++;
|
||||
else if (buf[j]!=i+1) wrong++;
|
||||
}
|
||||
if (zero) {
|
||||
printf (" *FAILED* (%d zeros)\n", zero);
|
||||
} else if (wrong) {
|
||||
printf (" *SKIPPED* (possible overlap with another region)\n");
|
||||
} else {
|
||||
printf (" PASSED\n");
|
||||
}
|
||||
}
|
||||
|
||||
H5Dclose (d2);
|
||||
H5Sclose (mspace);
|
||||
H5Sclose (fspace);
|
||||
H5Fclose (file);
|
||||
fclose (script);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: main
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Return: Success:
|
||||
*
|
||||
* Failure:
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Friday, April 10, 1998
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
if (1==argc) {
|
||||
writer (WRT_N);
|
||||
} else if (isdigit (argv[1][0])) {
|
||||
writer (strtol (argv[1], NULL, 0));
|
||||
} else {
|
||||
reader (argv[1]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
63
test/links.c
Normal file
63
test/links.c
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 1998 NCSA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Programmer: Robb Matzke <matzke@llnl.gov>
|
||||
* Friday, April 10, 1998
|
||||
*
|
||||
* Purpose: Tests hard and soft (symbolic) links.
|
||||
*/
|
||||
#include <hdf5.h>
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: main
|
||||
*
|
||||
* Purpose: Tests links.
|
||||
*
|
||||
* Return: Success: 0
|
||||
*
|
||||
* Failure: non-zero
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Friday, April 10, 1998
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
hid_t file, scalar, grp, d1;
|
||||
hsize_t size[1] = {1};
|
||||
|
||||
/* Create a file */
|
||||
file = H5Fcreate ("links.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
|
||||
scalar = H5Screate_simple (1, size, size);
|
||||
|
||||
/* Create a group */
|
||||
grp = H5Gcreate (file, "grp1", 0);
|
||||
H5Gclose (grp);
|
||||
|
||||
/* Create a dataset */
|
||||
d1 = H5Dcreate (file, "d1", H5T_NATIVE_INT, scalar, H5P_DEFAULT);
|
||||
H5Dclose (d1);
|
||||
|
||||
/* Create a hard link */
|
||||
H5Glink (file, H5G_LINK_HARD, "d1", "grp1/hard");
|
||||
|
||||
/* Create a symbolic link */
|
||||
H5Glink (file, H5G_LINK_SOFT, "/d1", "grp1/soft");
|
||||
|
||||
/* Create a symbolic link to something that doesn't exist */
|
||||
H5Glink (file, H5G_LINK_SOFT, "foobar", "grp1/dangle");
|
||||
|
||||
/* Create a recursive symbolic link */
|
||||
H5Glink (file, H5G_LINK_SOFT, "/grp1/recursive", "/grp1/recursive");
|
||||
|
||||
/* Close */
|
||||
H5Sclose (scalar);
|
||||
H5Fclose (file);
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user