summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDana Robinson <derobins@hdfgroup.org>2021-03-09 14:50:13 (GMT)
committerDana Robinson <derobins@hdfgroup.org>2021-03-09 14:50:13 (GMT)
commit22723e87d8de3b768f5a70e1658f17eb4ad85000 (patch)
treeeae5407f9044cfd585770195658ba08524adfdf9
parentd72405e43d44a3ac9ec27bb9d7a84e638a7aea10 (diff)
downloadhdf5-22723e87d8de3b768f5a70e1658f17eb4ad85000.zip
hdf5-22723e87d8de3b768f5a70e1658f17eb4ad85000.tar.gz
hdf5-22723e87d8de3b768f5a70e1658f17eb4ad85000.tar.bz2
Replaces basename and dirname with code that will work everywhere
-rw-r--r--src/H5private.h15
-rw-r--r--src/H5system.c140
-rw-r--r--test/page_buffer.c20
-rw-r--r--test/vfd_swmr_bigset_writer.c3
-rw-r--r--test/vfd_swmr_group_writer.c3
-rw-r--r--test/vfd_swmr_zoo_writer.c3
-rw-r--r--tools/lib/h5tools.c12
7 files changed, 162 insertions, 34 deletions
diff --git a/src/H5private.h b/src/H5private.h
index 66763b2..4e190a6 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -154,13 +154,6 @@
#endif
/*
- * Needed for dirname and basename on POSIX systems
- */
-#ifdef H5_HAVE_LIBGEN_H
-#include <libgen.h>
-#endif
-
-/*
* Dynamic library handling. These are needed for dynamically loading I/O
* filters and VFDs.
*/
@@ -741,9 +734,6 @@ typedef struct {
#ifndef HDatoll
#define HDatoll(S) atoll(S)
#endif /* HDatol */
-#ifndef HDbasename
- #define HDbasename(P) basename(P)
-#endif /* HDbasename */
#ifndef HDbind
#define HDbind(A,B,C) bind((A),(B),(C)) /* mirror VFD */
#endif /* HDbind */
@@ -820,9 +810,6 @@ typedef struct {
#define HDdifftime(X,Y) ((double)(X)-(double)(Y))
#endif /* H5_HAVE_DIFFTIME */
#endif /* HDdifftime */
-#ifndef HDdirname
- #define HDdirname(P) dirname(P)
-#endif /* HDdirname */
#ifndef HDdiv
#define HDdiv(X,Y) div(X,Y)
#endif /* HDdiv */
@@ -2863,6 +2850,8 @@ H5_DLL double H5_get_time(void);
/* Functions for building paths, etc. */
H5_DLL herr_t H5_build_extpath(const char *name, char **extpath /*out*/);
H5_DLL herr_t H5_combine_path(const char *path1, const char *path2, char **full_name /*out*/);
+H5_DLL herr_t H5_dirname(const char *path, char **dirname/*out*/);
+H5_DLL herr_t H5_basename(const char *path, char **basename/*out*/);
#ifdef H5_HAVE_PARALLEL
/* Generic MPI functions */
diff --git a/src/H5system.c b/src/H5system.c
index c645105..784719e 100644
--- a/src/H5system.c
+++ b/src/H5system.c
@@ -1516,3 +1516,143 @@ done:
} /* end H5_expand_windows_env_vars() */
#endif /* H5_HAVE_WIN32_API */
+
+/* dirname() and basename() are not easily ported to Windows and basename
+ * behavior varies depending on if you get POSIX vs. GNU. As a more
+ * platform-indpendent work-around, we've implemented H5_ versions of
+ * dirname() and basename().
+ *
+ * - The input string is never modified.
+ *
+ * - The out parameter is a new string that was allocated with HDcalloc()
+ * and must be freed by the caller via HDfree().
+ *
+ * - NULL pointers are errors.
+ *
+ * - On errors, FAIL will be returned and the output parameter will be
+ * undefined.
+ *
+ * - The trailing file separator is not returned in H5_dirname().
+ *
+ * - Passing a path that ends in a file separator to H5_basename() will
+ * return the empty string.
+ *
+ * - If the path doesn't contain a file separator, we assume you passed
+ * in a raw filename and H5_basename() will return the input string
+ * while H5_dirname will return ".".
+ *
+ * - Assumes the file separator is \ on Win32 and / everywhere else,
+ * including Cygwin.
+ */
+
+#ifdef H5_HAVE_WIN32_API
+#define H5_FILE_SEPARATOR '\\'
+#else
+#define H5_FILE_SEPARATOR '/'
+#endif
+
+static size_t
+H5__find_last_file_separator(const char *path, size_t len, hbool_t *no_separator)
+{
+ size_t i;
+
+ FUNC_ENTER_STATIC_NOERR
+
+ *no_separator = TRUE;
+
+ for (i = len; i > 0; i--) {
+ if (H5_FILE_SEPARATOR == path[i - 1]) {
+ break;
+ no_separator = FALSE;
+ }
+ }
+
+ FUNC_LEAVE_NOAPI(i - 1)
+}
+
+herr_t
+H5_dirname(const char *path, char **dirname)
+{
+ size_t path_len;
+ size_t pos;
+ size_t out_len;
+ char *out = NULL;
+ hbool_t no_separator = FALSE;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if (!path)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "path can't be NULL")
+ if (!dirname)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dirname can't be NULL")
+
+ path_len = HDstrlen(path);
+
+ pos = H5__find_last_file_separator(path, path_len, &no_separator);
+
+ /* Special case of no path separator */
+ if (no_separator)
+ out_len = 2;
+ else
+ out_len = pos + 1; /* Include room for terminator */
+
+ if (NULL == (out = HDmalloc(out_len * sizeof(char))))
+ HGOTO_ERROR(H5E_SYSTEM, H5E_NOSPACE, FAIL, "unable to allocate memory for output string")
+
+ /* Copy bytes and terminate */
+ if (no_separator)
+ HDstrncpy(out, ".", 2);
+ else {
+ HDstrncpy(out, path, out_len - 1);
+ out[out_len - 1] = '\0';
+ }
+
+ *dirname = out;
+done:
+ if (FAIL == ret_value)
+ HDfree(out);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5_dirname() */
+
+herr_t
+H5_basename(const char *path, char **basename)
+{
+ size_t path_len;
+ size_t pos;
+ size_t out_len;
+ char *out = NULL;
+ hbool_t no_separator = FALSE;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if (!path)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "path can't be NULL")
+ if (!basename)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dirname can't be NULL")
+
+ path_len = HDstrlen(path);
+ pos = H5__find_last_file_separator(path, path_len, &no_separator);
+
+ if (no_separator)
+ out_len = path_len;
+ else
+ out_len = path_len - pos; /* Include room for terminator */
+
+ if (NULL == (out = HDmalloc(out_len * sizeof(char))))
+ HGOTO_ERROR(H5E_SYSTEM, H5E_NOSPACE, FAIL, "unable to allocate memory for output string")
+
+ /* Copy bytes and terminate */
+ HDstrncpy(out, path + pos + 1, out_len - 1);
+ out[out_len - 1] = '\0';
+
+ /* Copy bytes and terminate */
+ *basename = out;
+done:
+ if (FAIL == ret_value)
+ HDfree(out);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5_basename() */
diff --git a/test/page_buffer.c b/test/page_buffer.c
index 112ea77..db1688d 100644
--- a/test/page_buffer.c
+++ b/test/page_buffer.c
@@ -139,23 +139,21 @@ swmr_fapl_augment(hid_t fapl, const char *filename, uint32_t max_lag)
, .writer = true
, .md_pages_reserved = 128
};
- const char *bname, *dname;
- char *tname[2];
+ char *bname = NULL;
+ char *dname = NULL;
- if ((tname[0] = strdup(filename)) == NULL) {
- HDfprintf(stderr, "temporary string allocation failed\n");
+ if (H5_dirname(filename, &dname) < 0) {
+ HDfprintf(stderr, "H5_dirname() failed\n");
return -1;
}
- if ((tname[1] = strdup(filename)) == NULL) {
- HDfprintf(stderr, "temporary string allocation failed\n");
+ if (H5_basename(filename, &bname) < 0) {
+ HDfprintf(stderr, "H5_basename() failed\n");
return -1;
}
- dname = HDdirname(tname[0]);
- bname = HDbasename(tname[1]);
- snprintf(config.md_file_path, sizeof(config.md_file_path),
+ HDsnprintf(config.md_file_path, sizeof(config.md_file_path),
"%s/%s.shadow", dname, bname);
- free(tname[0]);
- free(tname[1]);
+ HDfree(dname);
+ HDfree(bname);
/* Enable VFD SWMR configuration */
if(H5Pset_vfd_swmr_config(fapl, &config) < 0) {
diff --git a/test/vfd_swmr_bigset_writer.c b/test/vfd_swmr_bigset_writer.c
index 7b0f451..4bf08fd 100644
--- a/test/vfd_swmr_bigset_writer.c
+++ b/test/vfd_swmr_bigset_writer.c
@@ -67,6 +67,7 @@
*/
#include <err.h>
+#include <libgen.h>
#define H5C_FRIEND /*suppress error about including H5Cpkg */
#define H5F_FRIEND /*suppress error about including H5Fpkg */
@@ -270,7 +271,7 @@ state_init(state_t *s, int argc, char **argv)
*s = state_initializer();
esnprintf(tfile, sizeof(tfile), "%s", argv[0]);
- esnprintf(s->progname, sizeof(s->progname), "%s", HDbasename(tfile));
+ esnprintf(s->progname, sizeof(s->progname), "%s", basename(tfile));
while ((ch = getopt(argc, argv, "FMSVWa:bc:d:n:qr:s:u:")) != -1) {
switch (ch) {
diff --git a/test/vfd_swmr_group_writer.c b/test/vfd_swmr_group_writer.c
index 2f355c2..155e9b1 100644
--- a/test/vfd_swmr_group_writer.c
+++ b/test/vfd_swmr_group_writer.c
@@ -12,6 +12,7 @@
*/
#include <err.h>
+#include <libgen.h>
#define H5F_FRIEND /*suppress error about including H5Fpkg */
@@ -84,7 +85,7 @@ state_init(state_t *s, int argc, char **argv)
*s = ALL_HID_INITIALIZER;
esnprintf(tfile, sizeof(tfile), "%s", argv[0]);
- esnprintf(s->progname, sizeof(s->progname), "%s", HDbasename(tfile));
+ esnprintf(s->progname, sizeof(s->progname), "%s", basename(tfile));
while ((ch = getopt(argc, argv, "SWa:bn:qu:")) != -1) {
switch (ch) {
diff --git a/test/vfd_swmr_zoo_writer.c b/test/vfd_swmr_zoo_writer.c
index 1792a93..9ede006 100644
--- a/test/vfd_swmr_zoo_writer.c
+++ b/test/vfd_swmr_zoo_writer.c
@@ -12,6 +12,7 @@
*/
#include <err.h>
+#include <libgen.h>
#define H5C_FRIEND /* suppress error about including H5Cpkg */
#define H5F_FRIEND /* suppress error about including H5Fpkg */
@@ -223,7 +224,7 @@ main(int argc, char **argv)
const char *seedvar = "H5_ZOO_STEP_SEED";
bool use_vfd_swmr = true;
bool print_estack = false;
- const char *progname = HDbasename(argv[0]);
+ const char *progname = basename(argv[0]);
const char *personality = strstr(progname, "vfd_swmr_zoo_");
estack_state_t es;
char step = 'b';
diff --git a/tools/lib/h5tools.c b/tools/lib/h5tools.c
index f68eb3b..2efca76 100644
--- a/tools/lib/h5tools.c
+++ b/tools/lib/h5tools.c
@@ -473,8 +473,7 @@ static hid_t
swmr_fapl_augment(hid_t fapl, const char *fname)
{
H5F_vfd_swmr_config_t *config = NULL; /* Configuration for VFD SWMR */
- const char *dname;
- char *tname;
+ char *dname = NULL;
/*
* Set up to open the file with VFD SWMR configured.
@@ -498,14 +497,13 @@ swmr_fapl_augment(hid_t fapl, const char *fname)
config->writer = FALSE;
config->md_pages_reserved = 128;
- if ((tname = strdup(fname)) == NULL) {
- HDfprintf(rawerrorstream, "temporary string allocation failed\n");
+ if (H5_dirname(fname, &dname) < 0) {
+ HDfprintf(rawerrorstream, "H5_dirname() failed\n");
return H5I_INVALID_HID;
}
- dname = dirname(tname);
- snprintf(config->md_file_path, sizeof(config->md_file_path),
+ HDsnprintf(config->md_file_path, sizeof(config->md_file_path),
"%s/my_md_file", dname);
- free(tname);
+ HDfree(dname);
/* Enable VFD SWMR configuration */
if(H5Pset_vfd_swmr_config(fapl, config) < 0) {