summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRobb Matzke <matzke@llnl.gov>1999-04-27 14:47:54 (GMT)
committerRobb Matzke <matzke@llnl.gov>1999-04-27 14:47:54 (GMT)
commit2dc738a321e45ce1e0c5edcc2bf7f3623e823c9e (patch)
treebd07d5bdb789fed39d8a77122ed0d5613c1cb0b9 /src
parenta66c628b3c5e06e5ab188400d18c7565e5a0d738 (diff)
downloadhdf5-2dc738a321e45ce1e0c5edcc2bf7f3623e823c9e.zip
hdf5-2dc738a321e45ce1e0c5edcc2bf7f3623e823c9e.tar.gz
hdf5-2dc738a321e45ce1e0c5edcc2bf7f3623e823c9e.tar.bz2
[svn-r1224] Changes since 19990426
---------------------- ./tools/h5tools.c ./tools/h5tools.h Finally fixed a long-standing bug that caused core dumps if a compound datum rendered to more than some number of characters (we kept bumping up the limit at the risk of violating stack size limits on some machines). The fix works only on systems that have the vsnprintf() function (otherwise a 4kB limit is imposed, which if violated probably dumps core). If vsnprintf() is present then the library dynamically allocates space for the output string. Also made it possible to control how compound data is rendered across multiple lines of output by allowing the caller to specify where optional line-breaks get inserted. The output functions split up the value at one or more optional line-breaks to prevent it from wrapping around the screen. If a datum doesn't fit on the current line but would fit on the next line then it is printed on the next line regardless of whether optional line-breaks would have prevent wrapping around the screen. This makes it easier to find the beginnings of compound data values. This feature is disabled by default but can be enabled by the application. If a datum doesn't fit on the current line and the previous datum also occupied more than one line then we move to the next line before printing. This makes it easier to find the beginnings of compound data values but prevents the output from looking fragmented if there are only a few long values among mostly short values. This feature is disabled by default but can be enabled by the application. The application can control the printf() formats used for all the native data types. The defaults are what the library used to use: %g, %ld, %lu, %d, and %u ./tools/h5ls.c Compound datatype values can now be split across multiple lines of output instead of just wrapping. Also, when lots of compound values are too long they all start at the beginning of a line. This only required about 10 lines of changes in the setup for tools library calls (I didn't modify the h5dump program because it uses its own version of the tools library that forked off long ago). Added code for Win32 which is unable to cast `unsigned long long' to `double'. If the dataset size exceeds (2^63)-1 then the percent utilization is not displayed (this is easily possible with chunked datasets). This is untested yet. ./configure.in ./src/H5config.h.in ./src/H5.c ./src/H5private.h Check for vsnprintf() and provide a simple, stupid definition if it isn't available. The stupid definition just calls vsprintf() and ignores the second argument. This can result in buffer overflows in h5ls and h5dump since vsprintf() is an unsafe function (and anyone can create an hdf5 file that runs an arbitrary command from h5ls and h5dump in that case)! ./config/conclude.in Remove more *.o files for `make clean' ./src/H5A.c ./src/H5D.c ./src/H5F.c ./src/H5I.c ./src/H5Iprivate.h ./src/H5P.c ./src/H5R.c ./src/H5RA.c ./src/H5S.c ./src/H5T.c ./src/H5TB.c Cleaned up a memory leak during H5_term_library() by allowing H5I_clear_group() to skip items that couldn't be freed. This allows the item to remain in the group until we can free it later. ./src/H5F.c The H5F_close_all() function fails if a file cannot be closed.
Diffstat (limited to 'src')
-rw-r--r--src/H5.c35
-rw-r--r--src/H5A.c2
-rw-r--r--src/H5D.c2
-rw-r--r--src/H5F.c5
-rw-r--r--src/H5G.c2
-rw-r--r--src/H5I.c42
-rw-r--r--src/H5Iprivate.h2
-rw-r--r--src/H5P.c2
-rw-r--r--src/H5R.c2
-rw-r--r--src/H5RA.c2
-rw-r--r--src/H5S.c2
-rw-r--r--src/H5T.c133
-rw-r--r--src/H5TB.c2
-rw-r--r--src/H5config.h.in3
-rw-r--r--src/H5private.h6
15 files changed, 152 insertions, 90 deletions
diff --git a/src/H5.c b/src/H5.c
index c2ce573..d096a16 100644
--- a/src/H5.c
+++ b/src/H5.c
@@ -471,6 +471,41 @@ HDsnprintf(char *buf, size_t UNUSED size, const char *fmt, ...)
}
#endif /* HAVE_SNPRINTF */
+#ifndef HAVE_VSNPRINTF
+
+
+/*-------------------------------------------------------------------------
+ * Function: HDvsnprintf
+ *
+ * Purpose: The same as HDsnprintf() except the variable arguments are
+ * passed as a va_list.
+ *
+ * Note: This function is for compatibility on systems that don't have
+ * vsnprintf(3). It doesn't actually check for overflow like the
+ * real vsnprintf() would.
+ *
+ * Return: Success: Number of characters stored, not including
+ * the terminating null. If this value equals
+ * SIZE then there was not enough space in BUF
+ * for all the output.
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Monday, April 26, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+HDvsnprintf(char *buf, size_t size, const char *fmt, va_list ap)
+{
+ return vsprintf(buf, fmt, ap);
+}
+#endif /* HAVE_VSNPRINTF */
+
+
/*-------------------------------------------------------------------------
* Function: HDfprintf
diff --git a/src/H5A.c b/src/H5A.c
index 624a9fd..b7bb4c3 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -100,7 +100,7 @@ H5A_term_interface(void)
if (interface_initialize_g) {
if ((n=H5I_nmembers(H5I_ATTR))) {
- H5I_clear_group(H5I_ATTR);
+ H5I_clear_group(H5I_ATTR, FALSE);
} else {
H5I_destroy_group(H5I_ATTR);
interface_initialize_g = 0;
diff --git a/src/H5D.c b/src/H5D.c
index 9f6c253..7a4a148 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -126,7 +126,7 @@ H5D_term_interface(void)
if (interface_initialize_g) {
if ((n=H5I_nmembers(H5I_DATASET))) {
- H5I_clear_group(H5I_DATASET);
+ H5I_clear_group(H5I_DATASET, FALSE);
} else {
H5I_destroy_group(H5I_DATASET);
interface_initialize_g = 0;
diff --git a/src/H5F.c b/src/H5F.c
index 0b30f27..6fa808a 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -338,7 +338,10 @@ herr_t
H5F_close_all(void)
{
FUNC_ENTER(H5F_close_all, FAIL);
- H5I_clear_group(H5I_FILE);
+ if (H5I_clear_group(H5I_FILE, FALSE)<0) {
+ HRETURN_ERROR(H5E_FILE, H5E_CLOSEERROR, FAIL,
+ "unable to close one or more files");
+ }
FUNC_LEAVE(SUCCEED);
}
diff --git a/src/H5G.c b/src/H5G.c
index 003bcc5..8e488d9 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -726,7 +726,7 @@ H5G_term_interface(void)
if (interface_initialize_g) {
if ((n=H5I_nmembers(H5I_GROUP))) {
- H5I_clear_group(H5I_GROUP);
+ H5I_clear_group(H5I_GROUP, FALSE);
} else {
/* Empty the object type table */
for (i=0; i<H5G_ntypes_g; i++) {
diff --git a/src/H5I.c b/src/H5I.c
index b7e73b5..46bd3e4 100644
--- a/src/H5I.c
+++ b/src/H5I.c
@@ -364,14 +364,18 @@ H5I_nmembers(H5I_type_t grp)
* Wednesday, March 24, 1999
*
* Modifications:
+ * Robb Matzke, 1999-04-27
+ * If FORCE is zero then any item for which the free callback
+ * failed is not removed. This function returns failure if
+ * items could not be removed.
*
*-------------------------------------------------------------------------
*/
herr_t
-H5I_clear_group(H5I_type_t grp)
+H5I_clear_group(H5I_type_t grp, hbool_t force)
{
H5I_id_group_t *grp_ptr = NULL; /* ptr to the atomic group */
- H5I_id_info_t *cur=NULL, *next=NULL;
+ H5I_id_info_t *cur=NULL, *next=NULL, *prev=NULL;
intn ret_value = SUCCEED;
uintn i;
@@ -401,26 +405,35 @@ H5I_clear_group(H5I_type_t grp)
/*
* Call free method for all objects in group regardless of their reference
* counts. Ignore the return value from from the free method and remove
- * object from group regardless.
+ * object from group regardless if FORCE is non-zero.
*/
for (i=0; i<grp_ptr->hash_size; i++) {
for (cur=grp_ptr->id_list[i]; cur; cur=next) {
/* Free the object regardless of reference count */
if (grp_ptr->free_func && (grp_ptr->free_func)(cur->obj_ptr)<0) {
+ if (force) {
#if H5I_DEBUG
- if (H5DEBUG(I)) {
- fprintf(H5DEBUG(I), "H5I: free grp=%d obj=0x%08lx "
- "failure ignored\n", (int)grp,
- (unsigned long)(cur->obj_ptr));
- }
+ if (H5DEBUG(I)) {
+ fprintf(H5DEBUG(I), "H5I: free grp=%d obj=0x%08lx "
+ "failure ignored\n", (int)grp,
+ (unsigned long)(cur->obj_ptr));
+ }
#endif /*H5I_DEBUG*/
+ /* Add ID struct to free list */
+ next = cur->next;
+ H5I_release_id_node(cur);
+ } else {
+ if (prev) prev->next = cur;
+ else grp_ptr->id_list[i] = cur;
+ prev = cur;
+ }
+ } else {
+ /* Add ID struct to free list */
+ next = cur->next;
+ H5I_release_id_node(cur);
}
-
- /* Add ID struct to free list */
- next = cur->next;
- H5I_release_id_node(cur);
}
- grp_ptr->id_list[i]=NULL;
+ if (!prev) grp_ptr->id_list[i]=NULL;
}
done:
@@ -472,7 +485,8 @@ H5I_destroy_group(H5I_type_t grp)
* free function is invoked for each atom being freed.
*/
if (1==grp_ptr->count) {
- H5I_clear_group(grp);
+ H5I_clear_group(grp, TRUE);
+ H5E_clear(); /*don't care about errors*/
H5MM_xfree(grp_ptr->id_list);
HDmemset (grp_ptr, 0, sizeof(*grp_ptr));
} else {
diff --git a/src/H5Iprivate.h b/src/H5Iprivate.h
index 99b6628..dbe5078 100644
--- a/src/H5Iprivate.h
+++ b/src/H5Iprivate.h
@@ -74,7 +74,7 @@ typedef struct {
__DLL__ intn H5I_init_group(H5I_type_t grp, size_t hash_size, uintn reserved,
H5I_free_t func);
__DLL__ intn H5I_nmembers(H5I_type_t grp);
-__DLL__ herr_t H5I_clear_group(H5I_type_t grp);
+__DLL__ herr_t H5I_clear_group(H5I_type_t grp, hbool_t force);
__DLL__ herr_t H5I_destroy_group(H5I_type_t grp);
__DLL__ hid_t H5I_register(H5I_type_t grp, void *object);
__DLL__ void *H5I_object(hid_t id);
diff --git a/src/H5P.c b/src/H5P.c
index 3a7f221..0f33e95 100644
--- a/src/H5P.c
+++ b/src/H5P.c
@@ -111,7 +111,7 @@ H5P_term_interface(void)
}
if (n) {
for (i=0; i<H5P_NCLASSES; i++) {
- H5I_clear_group((H5I_type_t)(H5I_TEMPLATE_0+i));
+ H5I_clear_group((H5I_type_t)(H5I_TEMPLATE_0+i), FALSE);
}
} else {
for (i=0; i<H5P_NCLASSES; i++) {
diff --git a/src/H5R.c b/src/H5R.c
index 1ed1632..274b69f 100644
--- a/src/H5R.c
+++ b/src/H5R.c
@@ -94,7 +94,7 @@ H5R_term_interface(void)
if (interface_initialize_g) {
if ((n=H5I_nmembers(H5I_REFERENCE))) {
- H5I_clear_group(H5I_REFERENCE);
+ H5I_clear_group(H5I_REFERENCE, FALSE);
} else {
H5I_destroy_group(H5I_REFERENCE);
interface_initialize_g = 0;
diff --git a/src/H5RA.c b/src/H5RA.c
index 389e8dc..3690a50 100644
--- a/src/H5RA.c
+++ b/src/H5RA.c
@@ -125,7 +125,7 @@ H5RA_term_interface(void)
if (interface_initialize_g) {
if ((n=H5I_nmembers(H5I_RAGGED))) {
- H5I_clear_group(H5I_RAGGED);
+ H5I_clear_group(H5I_RAGGED, FALSE);
} else {
H5T_close(H5RA_meta_type_g);
H5RA_meta_type_g = NULL;
diff --git a/src/H5S.c b/src/H5S.c
index d9e5c49..b2874ce06 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -122,7 +122,7 @@ H5S_term_interface(void)
if (interface_initialize_g) {
if ((n=H5I_nmembers(H5I_DATASPACE))) {
- H5I_clear_group(H5I_DATASPACE);
+ H5I_clear_group(H5I_DATASPACE, FALSE);
} else {
#ifdef H5S_DEBUG
/*
diff --git a/src/H5T.c b/src/H5T.c
index 4919617..2ccdcb1 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -1113,50 +1113,46 @@ H5T_term_interface(void)
H5T_path_t *path = NULL;
if (interface_initialize_g) {
- if ((n=H5I_nmembers(H5I_DATATYPE))) {
- H5I_clear_group(H5I_DATATYPE);
- } else {
- /* Unregister all conversion functions */
- for (i=0; i<H5T_g.npaths; i++) {
- path = H5T_g.path[i];
- assert (path);
-
- if (path->func) {
- H5T_print_stats(path, &nprint/*in,out*/);
- path->cdata.command = H5T_CONV_FREE;
- if ((path->func)(FAIL, FAIL, &(path->cdata),
- 0, NULL, NULL)<0) {
+ /* Unregister all conversion functions */
+ for (i=0; i<H5T_g.npaths; i++) {
+ path = H5T_g.path[i];
+ assert (path);
+
+ if (path->func) {
+ H5T_print_stats(path, &nprint/*in,out*/);
+ path->cdata.command = H5T_CONV_FREE;
+ if ((path->func)(FAIL, FAIL, &(path->cdata),
+ 0, NULL, NULL)<0) {
#ifdef H5T_DEBUG
- if (H5DEBUG(T)) {
- fprintf (H5DEBUG(T), "H5T: conversion function "
- "0x%08lx failed to free private data for "
- "%s (ignored)\n",
- (unsigned long)(path->func), path->name);
- }
-#endif
- H5E_clear(); /*ignore the error*/
+ if (H5DEBUG(T)) {
+ fprintf (H5DEBUG(T), "H5T: conversion function "
+ "0x%08lx failed to free private data for "
+ "%s (ignored)\n",
+ (unsigned long)(path->func), path->name);
}
+#endif
+ H5E_clear(); /*ignore the error*/
}
- H5T_close (path->src);
- H5T_close (path->dst);
- H5MM_xfree (path);
- H5T_g.path[i] = NULL;
}
+ H5T_close (path->src);
+ H5T_close (path->dst);
+ H5MM_xfree (path);
+ H5T_g.path[i] = NULL;
+ }
- /* Clear conversion tables */
- H5T_g.path = H5MM_xfree(H5T_g.path);
- H5T_g.npaths = H5T_g.apaths = 0;
- H5T_g.soft = H5MM_xfree(H5T_g.soft);
- H5T_g.nsoft = H5T_g.asoft = 0;
+ /* Clear conversion tables */
+ H5T_g.path = H5MM_xfree(H5T_g.path);
+ H5T_g.npaths = H5T_g.apaths = 0;
+ H5T_g.soft = H5MM_xfree(H5T_g.soft);
+ H5T_g.nsoft = H5T_g.asoft = 0;
- /* Unlock all datatypes, then free them */
- H5I_search (H5I_DATATYPE, H5T_unlock_cb, NULL);
- H5I_destroy_group(H5I_DATATYPE);
+ /* Unlock all datatypes, then free them */
+ H5I_search (H5I_DATATYPE, H5T_unlock_cb, NULL);
+ H5I_destroy_group(H5I_DATATYPE);
- /* Mark interface as closed */
- interface_initialize_g = 0;
- n = 1; /*H5I*/
- }
+ /* Mark interface as closed */
+ interface_initialize_g = 0;
+ n = 1; /*H5I*/
}
return n;
}
@@ -4551,6 +4547,8 @@ H5T_lock (H5T_t *dt, hbool_t immutable)
* Monday, December 8, 1997
*
* Modifications:
+ * Robb Matzke, 1999-04-27
+ * This function fails if the datatype state is IMMUTABLE.
*
*-------------------------------------------------------------------------
*/
@@ -4558,9 +4556,9 @@ herr_t
H5T_close(H5T_t *dt)
{
intn i;
+ H5T_t *parent = dt->parent;
FUNC_ENTER(H5T_close, FAIL);
-
assert(dt);
/*
@@ -4575,41 +4573,44 @@ H5T_close(H5T_t *dt)
dt->state = H5T_STATE_NAMED;
}
- /* Close the parent */
- if (dt->parent && H5T_close(dt->parent)<0) {
- HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
- "unable to close parent data type");
- }
-
/*
- * Don't free locked datatypes unless we are shutting down the
- * interface.
+ * Don't free locked datatypes.
*/
- if (H5T_STATE_IMMUTABLE!=dt->state) {
- switch (dt->type) {
- case H5T_COMPOUND:
- for (i=0; i<dt->u.compnd.nmembs; i++) {
- H5MM_xfree(dt->u.compnd.memb[i].name);
- H5T_close(dt->u.compnd.memb[i].type);
- }
- H5MM_xfree(dt->u.compnd.memb);
- H5MM_xfree(dt);
- break;
+ if (H5T_STATE_IMMUTABLE==dt->state) {
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, FAIL,
+ "unable to close immutable datatype");
+ }
- case H5T_ENUM:
- for (i=0; i<dt->u.enumer.nmembs; i++) {
- H5MM_xfree(dt->u.enumer.name[i]);
- }
- H5MM_xfree(dt->u.enumer.name);
- H5MM_xfree(dt->u.enumer.value);
- H5MM_xfree(dt);
- break;
+ /* Close the datatype */
+ switch (dt->type) {
+ case H5T_COMPOUND:
+ for (i=0; i<dt->u.compnd.nmembs; i++) {
+ H5MM_xfree(dt->u.compnd.memb[i].name);
+ H5T_close(dt->u.compnd.memb[i].type);
+ }
+ H5MM_xfree(dt->u.compnd.memb);
+ H5MM_xfree(dt);
+ break;
- default:
- H5MM_xfree(dt);
+ case H5T_ENUM:
+ for (i=0; i<dt->u.enumer.nmembs; i++) {
+ H5MM_xfree(dt->u.enumer.name[i]);
}
+ H5MM_xfree(dt->u.enumer.name);
+ H5MM_xfree(dt->u.enumer.value);
+ H5MM_xfree(dt);
+ break;
+
+ default:
+ H5MM_xfree(dt);
}
+ /* Close the parent */
+ if (parent && H5T_close(parent)<0) {
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
+ "unable to close parent data type");
+ }
+
FUNC_LEAVE(SUCCEED);
}
diff --git a/src/H5TB.c b/src/H5TB.c
index 19d400e..4b6bf25 100644
--- a/src/H5TB.c
+++ b/src/H5TB.c
@@ -117,7 +117,7 @@ H5TB_term_interface(void)
if (interface_initialize_g) {
if ((n=H5I_nmembers(H5I_TEMPBUF))) {
- H5I_clear_group(H5I_TEMPBUF);
+ H5I_clear_group(H5I_TEMPBUF, FALSE);
} else {
/* Free group and buffers */
H5I_destroy_group(H5I_TEMPBUF);
diff --git a/src/H5config.h.in b/src/H5config.h.in
index 0b8340e..cdb3fb2 100644
--- a/src/H5config.h.in
+++ b/src/H5config.h.in
@@ -194,6 +194,9 @@
/* Define if you have the system function. */
#undef HAVE_SYSTEM
+/* Define if you have the vsnprintf function. */
+#undef HAVE_VSNPRINTF
+
/* Define if you have the waitpid function. */
#undef HAVE_WAITPID
diff --git a/src/H5private.h b/src/H5private.h
index 539e93c..6c80e2b 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -689,6 +689,9 @@ __DLL__ int64_t HDstrtoll (const char *s, const char **rest, int base);
#define HDvfprintf(F,FMT,A) vfprintf(F,FMT,A)
#define HDvprintf(FMT,A) vprintf(FMT,A)
#define HDvsprintf(S,FMT,A) vsprintf(S,FMT,A)
+#ifdef HAVE_VSNPRINTF
+# define HDvsnprintf(S,N,FMT,A) vsnprintf(S,N,FMT,A)
+#endif
#define HDwait(W) wait(W)
#define HDwaitpid(P,W,O) waitpid(P,W,O)
#define HDwcstombs(S,P,Z) wcstombs(S,P,Z)
@@ -704,6 +707,9 @@ char *strdup(const char *s);
#ifndef HAVE_SNPRINTF
__DLL__ int HDsnprintf(char *buf, size_t size, const char *fmt, ...);
#endif
+#ifndef HAVE_VSNPRINTF
+__DLL__ int HDvsnprintf(char *buf, size_t size, const char *fmt, va_list ap);
+#endif
/*
* These macros check whether debugging has been requested for a certain