diff options
-rw-r--r-- | src/H5private.h | 15 | ||||
-rw-r--r-- | src/H5system.c | 140 | ||||
-rw-r--r-- | test/page_buffer.c | 20 | ||||
-rw-r--r-- | test/vfd_swmr_bigset_writer.c | 3 | ||||
-rw-r--r-- | test/vfd_swmr_group_writer.c | 3 | ||||
-rw-r--r-- | test/vfd_swmr_zoo_writer.c | 3 | ||||
-rw-r--r-- | tools/lib/h5tools.c | 12 |
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) { |