summaryrefslogtreecommitdiffstats
path: root/src/H5system.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5system.c')
-rw-r--r--src/H5system.c1107
1 files changed, 426 insertions, 681 deletions
diff --git a/src/H5system.c b/src/H5system.c
index e2747f4..56110ea 100644
--- a/src/H5system.c
+++ b/src/H5system.c
@@ -6,7 +6,7 @@
* This file is part of HDF5. The full HDF5 copyright notice, including *
* terms governing use, modification, and redistribution, is contained in *
* the COPYING file, which can be found at the root of the source code *
- * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
+ * distribution tree, or in https://www.hdfgroup.org/licenses. *
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@@ -25,47 +25,40 @@
/****************/
/* Module Setup */
/****************/
-
+#include "H5module.h" /* This source code file is part of the H5 module */
/***********/
/* Headers */
/***********/
-#include "H5private.h" /* Generic Functions */
-#include "H5Eprivate.h" /* Error handling */
-#include "H5Fprivate.h" /* File access */
-#include "H5MMprivate.h" /* Memory management */
-
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fprivate.h" /* File access */
+#include "H5MMprivate.h" /* Memory management */
/****************/
/* Local Macros */
/****************/
-
/******************/
/* Local Typedefs */
/******************/
-
/********************/
/* Package Typedefs */
/********************/
-
/********************/
/* Local Prototypes */
/********************/
-
/*********************/
/* Package Variables */
/*********************/
-
/*****************************/
/* Library Private Variables */
/*****************************/
-
/*******************/
/* Local Variables */
/*******************/
@@ -73,381 +66,36 @@
/* Track whether tzset routine was called */
static hbool_t H5_ntzset = FALSE;
-
-/*-------------------------------------------------------------------------
- * Function: HDfprintf
- *
- * Purpose: Prints the optional arguments under the control of the format
- * string FMT to the stream STREAM. This function takes the
- * same format as fprintf(3c) with a few added features:
- *
- * The conversion modifier `H' refers to the size of an
- * `hsize_t' or `hssize_t' type. For instance, "0x%018Hx"
- * prints an `hsize_t' value as a hex number right justified and
- * zero filled in an 18-character field.
- *
- * The conversion 'a' refers to an haddr_t type.
- *
- * The conversion 't' refers to an htri_t type.
- *
- * Return: Success: Number of characters printed
- *
- * Failure: -1
- *
- * Programmer: Robb Matzke
- * Thursday, April 9, 1998
- *
- *-------------------------------------------------------------------------
- */
-/* Disable warning for "format not a string literal" here -QAK */
-/*
- * This pragma only needs to surround the fprintf() calls with
- * format_templ in the code below, but early (4.4.7, at least) gcc only
- * allows diagnostic pragmas to be toggled outside of functions.
+#ifndef H5_HAVE_VASPRINTF
+/* HDvasprintf provides vasprintf-like function on targets where it is
+ * unavailable.
*/
-H5_GCC_DIAG_OFF(format-nonliteral)
int
-HDfprintf(FILE *stream, const char *fmt, ...)
+HDvasprintf(char **bufp, const char *fmt, va_list _ap)
{
- int n=0, nout = 0;
- int fwidth, prec;
- int zerofill;
- int leftjust;
- int plussign;
- int ldspace;
- int prefix;
- char modifier[8];
- int conv;
- char *rest, format_templ[128];
- int len;
- const char *s;
- va_list ap;
-
- HDassert(stream);
- HDassert(fmt);
-
- HDva_start (ap, fmt);
- while (*fmt) {
- fwidth = prec = 0;
- zerofill = 0;
- leftjust = 0;
- plussign = 0;
- prefix = 0;
- ldspace = 0;
- modifier[0] = '\0';
-
- if ('%'==fmt[0] && '%'==fmt[1]) {
- HDputc ('%', stream);
- fmt += 2;
- nout++;
- } else if ('%'==fmt[0]) {
- s = fmt + 1;
-
- /* Flags */
- while(HDstrchr("-+ #", *s)) {
- switch(*s) {
- case '-':
- leftjust = 1;
- break;
-
- case '+':
- plussign = 1;
- break;
-
- case ' ':
- ldspace = 1;
- break;
-
- case '#':
- prefix = 1;
- break;
-
- default:
- HDassert(0 && "Unknown format flag");
- } /* end switch */ /*lint !e744 Switch statement doesn't _need_ default */
- s++;
- } /* end while */
-
- /* Field width */
- if(HDisdigit(*s)) {
- zerofill = ('0' == *s);
- fwidth = (int)HDstrtol (s, &rest, 10);
- s = rest;
- } /* end if */
- else if ('*'==*s) {
- fwidth = HDva_arg(ap, int);
- if(fwidth < 0) {
- leftjust = 1;
- fwidth = -fwidth;
- }
- s++;
- }
-
- /* Precision */
- if('.'==*s) {
- s++;
- if(HDisdigit(*s)) {
- prec = (int)HDstrtol(s, &rest, 10);
- s = rest;
- } else if('*'==*s) {
- prec = HDva_arg(ap, int);
- s++;
- }
- if(prec < 1)
- prec = 1;
- }
-
- /* Extra type modifiers */
- if(HDstrchr("zZHhlqLI", *s)) {
- switch(*s) {
- /*lint --e{506} Don't issue warnings about constant value booleans */
- /*lint --e{774} Don't issue warnings boolean within 'if' always evaluates false/true */
- case 'H':
- if(sizeof(hsize_t) < sizeof(long))
- modifier[0] = '\0';
- else if(sizeof(hsize_t) == sizeof(long)) {
- HDstrncpy(modifier, "l", sizeof(modifier));
- modifier[sizeof(modifier) - 1] = '\0';
- } /* end if */
- else {
- HDstrncpy(modifier, H5_PRINTF_LL_WIDTH, sizeof(modifier));
- modifier[sizeof(modifier) - 1] = '\0';
- } /* end else */
- break;
-
- case 'Z':
- case 'z':
- if(sizeof(size_t) < sizeof(long))
- modifier[0] = '\0';
- else if(sizeof(size_t) == sizeof(long)) {
- HDstrncpy(modifier, "l", sizeof(modifier));
- modifier[sizeof(modifier) - 1] = '\0';
- } /* end if */
- else {
- HDstrncpy(modifier, H5_PRINTF_LL_WIDTH, sizeof(modifier));
- modifier[sizeof(modifier) - 1] = '\0';
- } /* end else */
- break;
-
- default:
- /* Handle 'I64' modifier for Microsoft's "__int64" type */
- if(*s=='I' && *(s+1)=='6' && *(s+2)=='4') {
- modifier[0] = *s;
- modifier[1] = *(s+1);
- modifier[2] = *(s+2);
- modifier[3] = '\0';
- s += 2; /* Increment over 'I6', the '4' is taken care of below */
- } /* end if */
- else {
- /* Handle 'll' for long long types */
- if(*s=='l' && *(s+1)=='l') {
- modifier[0] = *s;
- modifier[1] = *s;
- modifier[2] = '\0';
- s++; /* Increment over first 'l', second is taken care of below */
- } /* end if */
- else {
- modifier[0] = *s;
- modifier[1] = '\0';
- } /* end else */
- } /* end else */
- break;
- }
- s++;
- }
-
- /* Conversion */
- conv = *s++;
-
- /* Create the format template */
- len = 0;
- len += HDsnprintf(format_templ, (sizeof(format_templ) - (size_t)(len + 1)), "%%%s%s%s%s%s", (leftjust ? "-" : ""),
- (plussign ? "+" : ""), (ldspace ? " " : ""),
- (prefix ? "#" : ""), (zerofill ? "0" : ""));
- if(fwidth > 0)
- len += HDsnprintf(format_templ + len, (sizeof(format_templ) - (size_t)(len + 1)), "%d", fwidth);
- if(prec > 0)
- len += HDsnprintf(format_templ + len, (sizeof(format_templ) - (size_t)(len + 1)), ".%d", prec);
- if(*modifier)
- len += HDsnprintf(format_templ + len, (sizeof(format_templ) - (size_t)(len + 1)), "%s", modifier);
- HDsnprintf(format_templ + len, (sizeof(format_templ) - (size_t)(len + 1)), "%c", conv);
-
- /* Conversion */
- switch (conv) {
- case 'd':
- case 'i':
- if(!HDstrcmp(modifier, "h")) {
- short x = (short)HDva_arg(ap, int);
- n = fprintf(stream, format_templ, x);
- } else if(!*modifier) {
- int x = HDva_arg(ap, int);
- n = fprintf(stream, format_templ, x);
- } else if(!HDstrcmp(modifier, "l")) {
- long x = HDva_arg(ap, long);
- n = fprintf(stream, format_templ, x);
- } else {
- int64_t x = HDva_arg(ap, int64_t);
- n = fprintf(stream, format_templ, x);
- }
- break;
-
- case 'o':
- case 'u':
- case 'x':
- case 'X':
- if(!HDstrcmp(modifier, "h")) {
- unsigned short x = (unsigned short)HDva_arg(ap, unsigned int);
- n = fprintf(stream, format_templ, x);
- } else if(!*modifier) {
- unsigned int x = HDva_arg(ap, unsigned int);
- n = fprintf(stream, format_templ, x);
- } else if(!HDstrcmp(modifier, "l")) {
- unsigned long x = HDva_arg(ap, unsigned long);
- n = fprintf(stream, format_templ, x);
- } else {
- uint64_t x = HDva_arg(ap, uint64_t);
- n = fprintf(stream, format_templ, x);
- }
- break;
-
- case 'f':
- case 'e':
- case 'E':
- case 'g':
- case 'G':
- if(!HDstrcmp(modifier, "h")) {
- float x = (float)HDva_arg(ap, double);
- n = fprintf(stream, format_templ, (double)x);
- } else if(!*modifier || !HDstrcmp(modifier, "l")) {
- double x = HDva_arg(ap, double);
- n = fprintf(stream, format_templ, x);
- } else {
- /*
- * Some compilers complain when `long double' and
- * `double' are the same thing.
- */
-#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE
- long double x = HDva_arg(ap, long double);
- n = fprintf(stream, format_templ, x);
-#else
- double x = HDva_arg(ap, double);
- n = fprintf(stream, format_templ, x);
-#endif
- }
- break;
-
- case 'a':
- {
- haddr_t x = HDva_arg(ap, haddr_t);
-
- if(H5F_addr_defined(x)) {
- len = 0;
- len += HDsnprintf(format_templ, (sizeof(format_templ) - (size_t)(len + 1)), "%%%s%s%s%s%s",
- (leftjust ? "-" : ""), (plussign ? "+" : ""),
- (ldspace ? " " : ""), (prefix ? "#" : ""),
- (zerofill ? "0" : ""));
- if(fwidth > 0)
- len += HDsnprintf(format_templ + len, (sizeof(format_templ) - (size_t)(len + 1)), "%d", fwidth);
-
- /*lint --e{506} Don't issue warnings about constant value booleans */
- /*lint --e{774} Don't issue warnings boolean within 'if' always evaluates false/true */
- if(sizeof(x) == H5_SIZEOF_INT) {
- HDstrncat(format_templ, "u", (sizeof(format_templ) - (size_t)(len + 1)));
- len++;
- } /* end if */
- else if(sizeof(x) == H5_SIZEOF_LONG) {
- HDstrncat(format_templ, "lu", (sizeof(format_templ) - (size_t)(len + 1)));
- len++;
- } /* end if */
- else if(sizeof(x) == H5_SIZEOF_LONG_LONG) {
- HDstrncat(format_templ, H5_PRINTF_LL_WIDTH, (sizeof(format_templ) - (size_t)(len + 1)));
- len += (int)sizeof(H5_PRINTF_LL_WIDTH);
- HDstrncat(format_templ, "u", (sizeof(format_templ) - (size_t)(len + 1)));
- len++;
- }
- n = fprintf(stream, format_templ, x);
- } else {
- len = 0;
- HDstrncpy(format_templ, "%", (sizeof(format_templ) - (size_t)(len + 1)));
- len++;
- if(leftjust) {
- HDstrncat(format_templ, "-", (sizeof(format_templ) - (size_t)(len + 1)));
- len++;
- } /* end if */
- if(fwidth)
- len += HDsnprintf(format_templ + len, (sizeof(format_templ) - (size_t)(len + 1)), "%d", fwidth);
- HDstrncat(format_templ, "s", (sizeof(format_templ) - (size_t)(len + 1)));
- n = fprintf(stream, format_templ, "UNDEF");
- }
- }
- break;
-
- case 'c':
- {
- char x = (char)HDva_arg(ap, int);
- n = fprintf(stream, format_templ, x);
- }
- break;
-
- case 's':
- case 'p':
- {
- char *x = HDva_arg(ap, char*);
- n = fprintf(stream, format_templ, x);
- }
- break;
-
- case 'n':
- format_templ[HDstrlen(format_templ) - 1] = 'u';
- n = fprintf(stream, format_templ, nout);
- break;
-
- case 't':
- {
- htri_t tri_var = HDva_arg(ap, htri_t);
-
- if(tri_var > 0)
- n = fprintf(stream, "TRUE");
- else if(!tri_var)
- n = fprintf(stream, "FALSE");
- else
- n = fprintf(stream, "FAIL(%d)", (int)tri_var);
- }
- break;
-
- case 'T': /* Elapsed time, in seconds */
- {
- double seconds = HDva_arg(ap, double);
- char *time_string = H5_timer_get_time_string(seconds);
-
- if(time_string) {
- n = fprintf(stream, format_templ, time_string);
- HDfree(time_string);
- } /* end if */
- else
- n = fprintf(stream, format_templ, "(error)");
- }
- break;
-
- default:
- HDfputs(format_templ, stream);
- n = (int)HDstrlen(format_templ);
- break;
- }
- nout += n;
- fmt = s;
- } else {
- HDputc(*fmt, stream);
- fmt++;
- nout++;
+ char * buf; /* buffer to receive formatted string */
+ size_t bufsz; /* size of buffer to allocate */
+
+ for (bufsz = 32; (buf = HDmalloc(bufsz)) != NULL;) {
+ int ret;
+ va_list ap;
+
+ HDva_copy(ap, _ap);
+ ret = HDvsnprintf(buf, bufsz, fmt, ap);
+ va_end(ap);
+ if (ret >= 0 && (size_t)ret < bufsz) {
+ *bufp = buf;
+ return ret;
}
+ HDfree(buf);
+ if (ret < 0)
+ return ret;
+ bufsz = (size_t)ret + 1;
}
- HDva_end(ap);
- return nout;
-} /* end HDfprintf() */
-H5_GCC_DIAG_ON(format-nonliteral)
+ return -1;
+}
+#endif /* H5_HAVE_VASPRINTF */
-
/*-------------------------------------------------------------------------
* Function: HDstrtoll
*
@@ -494,61 +142,61 @@ H5_GCC_DIAG_ON(format-nonliteral)
int64_t
HDstrtoll(const char *s, const char **rest, int base)
{
- int64_t sign=1, acc=0;
- hbool_t overflow = FALSE;
+ int64_t sign = 1, acc = 0;
+ hbool_t overflow = FALSE;
errno = 0;
- if (!s || (base && (base<2 || base>36))) {
+ if (!s || (base && (base < 2 || base > 36))) {
if (rest)
*rest = s;
return 0;
}
/* Skip white space */
- while (HDisspace (*s)) s++;
+ while (HDisspace(*s))
+ s++;
/* Optional minus or plus sign */
- if ('+'==*s) {
+ if ('+' == *s) {
s++;
}
- else if ('-'==*s) {
+ else if ('-' == *s) {
sign = -1;
s++;
}
/* Zero base prefix */
- if (0==base && '0'==*s && ('x'==s[1] || 'X'==s[1])) {
+ if (0 == base && '0' == *s && ('x' == s[1] || 'X' == s[1])) {
base = 16;
s += 2;
}
- else if (0==base && '0'==*s) {
+ else if (0 == base && '0' == *s) {
base = 8;
s++;
}
- else if (0==base) {
+ else if (0 == base) {
base = 10;
}
/* Digits */
- while ((base<=10 && *s>='0' && *s<'0'+base) ||
- (base>10 && ((*s>='0' && *s<='9') ||
- (*s>='a' && *s<'a'+base-10) ||
- (*s>='A' && *s<'A'+base-10)))) {
+ while ((base <= 10 && *s >= '0' && *s < '0' + base) ||
+ (base > 10 && ((*s >= '0' && *s <= '9') || (*s >= 'a' && *s < 'a' + base - 10) ||
+ (*s >= 'A' && *s < 'A' + base - 10)))) {
if (!overflow) {
int64_t digit = 0;
- if (*s>='0' && *s<='9')
+ if (*s >= '0' && *s <= '9')
digit = *s - '0';
- else if (*s>='a' && *s<='z')
- digit = (*s-'a')+10;
+ else if (*s >= 'a' && *s <= 'z')
+ digit = (*s - 'a') + 10;
else
- digit = (*s-'A')+10;
+ digit = (*s - 'A') + 10;
- if (acc*base+digit < acc) {
+ if (acc * base + digit < acc) {
overflow = TRUE;
}
else {
- acc = acc*base + digit;
+ acc = acc * base + digit;
}
}
s++;
@@ -556,11 +204,11 @@ HDstrtoll(const char *s, const char **rest, int base)
/* Overflow */
if (overflow) {
- if (sign>0) {
- acc = ((uint64_t)1<<(8*sizeof(int64_t)-1))-1;
+ if (sign > 0) {
+ acc = ((uint64_t)1 << (8 * sizeof(int64_t) - 1)) - 1;
}
else {
- acc = (int64_t)((uint64_t)1<<(8*sizeof(int64_t)-1));
+ acc = (int64_t)((uint64_t)1 << (8 * sizeof(int64_t) - 1));
}
errno = ERANGE;
}
@@ -572,7 +220,7 @@ HDstrtoll(const char *s, const char **rest, int base)
return acc;
} /* end HDstrtoll() */
#endif
-
+
/*-------------------------------------------------------------------------
* Function: HDrand/HDsrand
*
@@ -596,19 +244,19 @@ HDstrtoll(const char *s, const char **rest, int base)
static unsigned int g_seed = 42;
-int HDrand(void)
+int
+HDrand(void)
{
return rand_r(&g_seed);
}
-void HDsrand(unsigned int seed)
+void
+HDsrand(unsigned int seed)
{
g_seed = seed;
}
#endif /* H5_HAVE_RAND_R */
-
-
/*-------------------------------------------------------------------------
* Function: Pflock
*
@@ -625,26 +273,27 @@ void HDsrand(unsigned int seed)
*/
#ifdef H5_HAVE_FCNTL
int
-Pflock(int fd, int operation) {
+Pflock(int fd, int operation)
+{
- struct flock flk;
+ struct flock flk;
/* Set the lock type */
- if(operation & LOCK_UN)
+ if (operation & LOCK_UN)
flk.l_type = F_UNLCK;
- else if(operation & LOCK_SH)
+ else if (operation & LOCK_SH)
flk.l_type = F_RDLCK;
else
flk.l_type = F_WRLCK;
/* Set the other flock struct values */
flk.l_whence = SEEK_SET;
- flk.l_start = 0;
- flk.l_len = 0; /* to EOF */
- flk.l_pid = 0; /* not used with set */
+ flk.l_start = 0;
+ flk.l_len = 0; /* to EOF */
+ flk.l_pid = 0; /* not used with set */
/* Lock or unlock */
- if(HDfcntl(fd, F_SETLK, &flk) < 0)
+ if (HDfcntl(fd, F_SETLK, &flk) < 0)
return -1;
return 0;
@@ -652,7 +301,6 @@ Pflock(int fd, int operation) {
} /* end Pflock() */
#endif /* H5_HAVE_FCNTL */
-
/*-------------------------------------------------------------------------
* Function: Nflock
*
@@ -664,12 +312,12 @@ Pflock(int fd, int operation) {
*-------------------------------------------------------------------------
*/
int H5_ATTR_CONST
-Nflock(int H5_ATTR_UNUSED fd, int H5_ATTR_UNUSED operation) {
+Nflock(int H5_ATTR_UNUSED fd, int H5_ATTR_UNUSED operation)
+{
/* just succeed */
return 0;
} /* end Nflock() */
-
/*-------------------------------------------------------------------------
* Function: H5_make_time
*
@@ -692,15 +340,15 @@ Nflock(int H5_ATTR_UNUSED fd, int H5_ATTR_UNUSED operation) {
time_t
H5_make_time(struct tm *tm)
{
- time_t the_time; /* The converted time */
-#if defined(H5_HAVE_VISUAL_STUDIO) && (_MSC_VER >= 1900) /* VS 2015 */
+ time_t the_time; /* The converted time */
+#if defined(H5_HAVE_VISUAL_STUDIO) && (_MSC_VER >= 1900) /* VS 2015 */
/* In gcc and in Visual Studio prior to VS 2015 'timezone' is a global
* variable declared in time.h. That variable was deprecated and in
* VS 2015 is removed, with _get_timezone replacing it.
*/
long timezone = 0;
-#endif /* defined(H5_HAVE_VISUAL_STUDIO) && (_MSC_VER >= 1900) */
- time_t ret_value; /* Return value */
+#endif /* defined(H5_HAVE_VISUAL_STUDIO) && (_MSC_VER >= 1900) */
+ time_t ret_value = 0; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@@ -708,21 +356,21 @@ H5_make_time(struct tm *tm)
HDassert(tm);
/* Initialize timezone information */
- if(!H5_ntzset) {
+ if (!H5_ntzset) {
HDtzset();
H5_ntzset = TRUE;
} /* end if */
/* Perform base conversion */
- if((time_t)-1 == (the_time = HDmktime(tm)))
+ if ((time_t)-1 == (the_time = HDmktime(tm)))
HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCONVERT, FAIL, "badly formatted modification time message")
- /* Adjust for timezones */
+ /* Adjust for timezones */
#if defined(H5_HAVE_TM_GMTOFF)
/* BSD-like systems */
the_time += tm->tm_gmtoff;
#elif defined(H5_HAVE_TIMEZONE)
-#if defined(H5_HAVE_VISUAL_STUDIO) && (_MSC_VER >= 1900) /* VS 2015 */
+#if defined(H5_HAVE_VISUAL_STUDIO) && (_MSC_VER >= 1900) /* VS 2015 */
/* In gcc and in Visual Studio prior to VS 2015 'timezone' is a global
* variable declared in time.h. That variable was deprecated and in
* VS 2015 is removed, with _get_timezone replacing it.
@@ -754,7 +402,6 @@ done:
/* Offset between 1/1/1601 and 1/1/1970 in 100 nanosecond units */
#define _W32_FT_OFFSET (116444736000000000ULL)
-
/*-------------------------------------------------------------------------
* Function: Wgettimeofday
*
@@ -779,34 +426,33 @@ done:
int
Wgettimeofday(struct timeval *tv, struct timezone *tz)
{
- union {
- unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */
- FILETIME ft;
- } _now;
+ union {
+ unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */
+ FILETIME ft;
+ } _now;
static int tzsetflag;
- if(tv) {
- GetSystemTimeAsFileTime (&_now.ft);
- tv->tv_usec=(long)((_now.ns100 / 10ULL) % 1000000ULL );
- tv->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL);
+ if (tv) {
+ GetSystemTimeAsFileTime(&_now.ft);
+ tv->tv_usec = (long)((_now.ns100 / 10ULL) % 1000000ULL);
+ tv->tv_sec = (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL);
}
- if(tz) {
- if(!tzsetflag) {
+ if (tz) {
+ if (!tzsetflag) {
_tzset();
tzsetflag = 1;
}
tz->tz_minuteswest = _timezone / 60;
- tz->tz_dsttime = _daylight;
+ tz->tz_dsttime = _daylight;
}
- /* Always return 0 as per Open Group Base Specifications Issue 6.
- Do not set errno on error. */
- return 0;
+ /* Always return 0 as per Open Group Base Specifications Issue 6.
+ Do not set errno on error. */
+ return 0;
} /* end Wgettimeofday() */
-
/*-------------------------------------------------------------------------
* Function: Wsetenv
*
@@ -825,14 +471,14 @@ Wgettimeofday(struct timeval *tv, struct timezone *tz)
int
Wsetenv(const char *name, const char *value, int overwrite)
{
- size_t bufsize;
+ size_t bufsize;
errno_t err;
/* If we're not overwriting, check if the environment variable exists.
* If it does (i.e.: the required buffer size to store the variable's
* value is non-zero), then return an error code.
*/
- if(!overwrite) {
+ if (!overwrite) {
err = getenv_s(&bufsize, NULL, 0, name);
if (err || bufsize)
return (int)err;
@@ -841,11 +487,10 @@ Wsetenv(const char *name, const char *value, int overwrite)
return (int)_putenv_s(name, value);
} /* end Wsetenv() */
-#ifdef H5_HAVE_WINSOCK2_H
+#ifdef H5_HAVE_WIN32_API
#pragma comment(lib, "advapi32.lib")
#endif
-
/*-------------------------------------------------------------------------
* Function: H5_get_win32_times
*
@@ -864,25 +509,25 @@ Wsetenv(const char *name, const char *value, int overwrite)
int
H5_get_win32_times(H5_timevals_t *tvs /*in,out*/)
{
- static HANDLE process_handle;
- ULARGE_INTEGER kernel_start;
- ULARGE_INTEGER user_start;
- FILETIME KernelTime;
- FILETIME UserTime;
- FILETIME CreationTime;
- FILETIME ExitTime;
- LARGE_INTEGER counts_start;
+ static HANDLE process_handle;
+ ULARGE_INTEGER kernel_start;
+ ULARGE_INTEGER user_start;
+ FILETIME KernelTime;
+ FILETIME UserTime;
+ FILETIME CreationTime;
+ FILETIME ExitTime;
+ LARGE_INTEGER counts_start;
static LARGE_INTEGER counts_freq;
- static hbool_t is_initialized = FALSE;
- BOOL err;
+ static hbool_t is_initialized = FALSE;
+ BOOL err;
HDassert(tvs);
- if(!is_initialized) {
+ if (!is_initialized) {
/* NOTE: This is just a pseudo handle and does not need to be closed. */
process_handle = GetCurrentProcess();
- err = QueryPerformanceFrequency(&counts_freq);
- if(0 == err)
+ err = QueryPerformanceFrequency(&counts_freq);
+ if (0 == err)
return -1;
is_initialized = TRUE;
} /* end if */
@@ -891,28 +536,27 @@ H5_get_win32_times(H5_timevals_t *tvs /*in,out*/)
* System and user times *
*************************/
- err = GetProcessTimes(process_handle, &CreationTime, &ExitTime, &KernelTime,
- &UserTime);
- if(0 == err)
+ err = GetProcessTimes(process_handle, &CreationTime, &ExitTime, &KernelTime, &UserTime);
+ if (0 == err)
return -1;
/* The 1.0E7 factor seems strange but it's due to the clock
* ticking in 100 ns increments.
*/
kernel_start.HighPart = KernelTime.dwHighDateTime;
- kernel_start.LowPart = KernelTime.dwLowDateTime;
- tvs->system = (double)(kernel_start.QuadPart / 1.0E7F);
+ kernel_start.LowPart = KernelTime.dwLowDateTime;
+ tvs->system = (double)(kernel_start.QuadPart / 1.0E7F);
user_start.HighPart = UserTime.dwHighDateTime;
- user_start.LowPart = UserTime.dwLowDateTime;
- tvs->user = (double)(user_start.QuadPart / 1.0E7F);
+ user_start.LowPart = UserTime.dwLowDateTime;
+ tvs->user = (double)(user_start.QuadPart / 1.0E7F);
/****************
* Elapsed time *
****************/
err = QueryPerformanceCounter(&counts_start);
- if(0 == err)
+ if (0 == err)
return -1;
tvs->elapsed = (double)(counts_start.QuadPart) / (double)counts_freq.QuadPart;
@@ -924,45 +568,19 @@ H5_get_win32_times(H5_timevals_t *tvs /*in,out*/)
#define WloginBuffer_count 256
static char Wlogin_buffer[WloginBuffer_count];
-
-char*
+char *
Wgetlogin(void)
{
-#ifdef H5_HAVE_WINSOCK2_H
- long bufferCount = WloginBuffer_count;
- if (GetUserName(Wlogin_buffer, &bufferCount) == 0)
+#ifdef H5_HAVE_WIN32_API
+ DWORD bufferCount = WloginBuffer_count;
+ if (GetUserName(Wlogin_buffer, &bufferCount) != 0)
return (Wlogin_buffer);
else
-#endif /* H5_HAVE_WINSOCK2_H */
+#endif
return NULL;
}
-int c99_snprintf(char* str, size_t size, const char* format, ...)
-{
- int count;
- va_list ap;
-
- HDva_start(ap, format);
- count = c99_vsnprintf(str, size, format, ap);
- HDva_end(ap);
-
- return count;
-}
-
-int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap)
-{
- int count = -1;
-
- if (size != 0)
- count = _vsnprintf_s(str, size, _TRUNCATE, format, ap);
- if (count == -1)
- count = _vscprintf(format, ap);
-
- return count;
-}
-
-
/*-------------------------------------------------------------------------
* Function: Wflock
*
@@ -974,151 +592,85 @@ int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap)
*-------------------------------------------------------------------------
*/
int
-Wflock(int H5_ATTR_UNUSED fd, int H5_ATTR_UNUSED operation) {
-
-/* This is a no-op while we implement a Win32 VFD */
-#if 0
-int
-Wflock(int fd, int operation) {
+Wflock(int fd, int operation)
+{
- HANDLE hFile;
- DWORD dwFlags = LOCKFILE_FAIL_IMMEDIATELY;
- DWORD dwReserved = 0;
- /* MAXDWORD for entire file */
- DWORD nNumberOfBytesToLockLow = MAXDWORD;
- DWORD nNumberOfBytesToLockHigh = MAXDWORD;
- /* Must initialize OVERLAPPED struct */
- OVERLAPPED overlapped = {0};
+ HANDLE hFile;
+ DWORD dwFlags = LOCKFILE_FAIL_IMMEDIATELY;
+ DWORD dwReserved = 0;
+ /* MAXDWORD locks the entire file */
+ DWORD nNumberOfBytesToLockLow = MAXDWORD;
+ DWORD nNumberOfBytesToLockHigh = MAXDWORD;
+ /* Must initialize OVERLAPPED struct */
+ OVERLAPPED overlapped = {0};
/* Get Windows HANDLE */
- hFile = _get_osfhandle(fd);
+ if (INVALID_HANDLE_VALUE == (hFile = (HANDLE)_get_osfhandle(fd)))
+ return -1;
/* Convert to Windows flags */
- if(operation & LOCK_EX)
+ if (operation & LOCK_EX)
dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
/* Lock or unlock */
- if(operation & LOCK_UN)
- if(0 == UnlockFileEx(hFile, dwReserved, nNumberOfBytesToLockLow,
- nNumberOfBytesToLockHigh, &overlapped))
- return -1;
- else
- if(0 == LockFileEx(hFile, dwFlags, dwReserved, nNumberOfBytesToLockLow,
- nNumberOfBytesToLockHigh, &overlapped))
+ if (operation & LOCK_UN) {
+ if (0 ==
+ UnlockFileEx(hFile, dwReserved, nNumberOfBytesToLockLow, nNumberOfBytesToLockHigh, &overlapped)) {
+ /* Attempting to unlock an already unlocked file will fail and this can happen
+ * in H5Fstart_swmr_write(). For now, just ignore the "error" (error code: 0x9e / 158).
+ */
+ if (GetLastError() != 158)
+ return -1;
+ }
+ }
+ else {
+ if (0 == LockFileEx(hFile, dwFlags, dwReserved, nNumberOfBytesToLockLow, nNumberOfBytesToLockHigh,
+ &overlapped))
return -1;
-#endif /* 0 */
- return 0;
-} /* end Wflock() */
-
+ }
- /*--------------------------------------------------------------------------
- * Function: Wnanosleep
- *
- * Purpose: Sleep for a given # of nanoseconds (Windows version)
- *
- * Return: SUCCEED/FAIL
- *
- * Programmer: Dana Robinson
- * Fall 2016
- *--------------------------------------------------------------------------
- */
-int
-Wnanosleep(const struct timespec *req, struct timespec *rem)
-{
- /* XXX: Currently just a placeholder */
return 0;
+} /* end Wflock() */
-} /* end Wnanosleep() */
-
-
/*-------------------------------------------------------------------------
- * Function: Wllround, Wllroundf, Wlround, Wlroundf, Wround, Wroundf
+ * Function: H5_get_utf16_str
*
- * Purpose: Wrapper function for round functions for use with VS2012
- * and earlier.
+ * Purpose: Gets a UTF-16 string from an UTF-8 (or ASCII) string.
*
- * Return: The rounded value that was passed in.
+ * Return: Success: A pointer to a UTF-16 string
+ * This must be freed by the caller using H5MM_xfree()
+ * Failure: NULL
*
* Programmer: Dana Robinson
- * December 2016
+ * Spring 2019
*
*-------------------------------------------------------------------------
*/
-long long
-Wllround(double arg)
-{
- return (long long)(arg < 0.0 ? HDceil(arg - 0.5) : HDfloor(arg + 0.5));
-}
-
-long long
-Wllroundf(float arg)
-{
- return (long long)(arg < 0.0F ? HDceil(arg - 0.5F) : HDfloor(arg + 0.5F));
-}
-
-long
-Wlround(double arg)
-{
- return (long)(arg < 0.0 ? HDceil(arg - 0.5) : HDfloor(arg + 0.5));
-}
-
-long
-Wlroundf(float arg)
-{
- return (long)(arg < 0.0F ? HDceil(arg - 0.5F) : HDfloor(arg + 0.5F));
-}
-
-double
-Wround(double arg)
-{
- return arg < 0.0 ? HDceil(arg - 0.5) : HDfloor(arg + 0.5);
-}
-
-float
-Wroundf(float arg)
-{
- return (float)(arg < 0.0F ? HDceil(arg - 0.5F) : HDfloor(arg + 0.5F));
-}
-
-/*-------------------------------------------------------------------------
-* Function: H5_get_utf16_str
-*
-* Purpose: Gets a UTF-16 string from an UTF-8 (or ASCII) string.
-*
-* Return: Success: A pointer to a UTF-16 string
-* This must be freed by the caller using H5MM_xfree()
-* Failure: NULL
-*
-* Programmer: Dana Robinson
-* Spring 2019
-*
-*-------------------------------------------------------------------------
-*/
-const wchar_t *
+wchar_t *
H5_get_utf16_str(const char *s)
{
- int nwchars = -1; /* Length of the UTF-16 buffer */
- wchar_t *ret_s = NULL; /* UTF-16 version of the string */
+ int nwchars = -1; /* Length of the UTF-16 buffer */
+ wchar_t *ret_s = NULL; /* UTF-16 version of the string */
/* Get the number of UTF-16 characters needed */
- if(0 == (nwchars = MultiByteToWideChar(CP_UTF8, 0, s, -1, NULL, 0)))
+ if (0 == (nwchars = MultiByteToWideChar(CP_UTF8, 0, s, -1, NULL, 0)))
goto error;
/* Allocate a buffer for the UTF-16 string */
- if(NULL == (ret_s = (wchar_t *)H5MM_calloc(sizeof(wchar_t) * (size_t)nwchars)))
+ if (NULL == (ret_s = (wchar_t *)H5MM_calloc(sizeof(wchar_t) * (size_t)nwchars)))
goto error;
/* Convert the input UTF-8 string to UTF-16 */
- if(0 == MultiByteToWideChar(CP_UTF8, 0, s, -1, ret_s, nwchars))
+ if (0 == MultiByteToWideChar(CP_UTF8, 0, s, -1, ret_s, nwchars))
goto error;
return ret_s;
error:
- if(ret_s)
+ if (ret_s)
H5MM_xfree((void *)ret_s);
return NULL;
-} /* end H5_get_utf16_str() */
+} /* end H5_get_utf16_str() */
/*-------------------------------------------------------------------------
* Function: Wopen_utf8
@@ -1138,22 +690,22 @@ error:
int
Wopen_utf8(const char *path, int oflag, ...)
{
- int fd = -1; /* POSIX file descriptor to be returned */
- wchar_t *wpath = NULL; /* UTF-16 version of the path */
- int pmode = 0; /* mode (optionally set via variable args) */
+ int fd = -1; /* POSIX file descriptor to be returned */
+ wchar_t *wpath = NULL; /* UTF-16 version of the path */
+ int pmode = 0; /* mode (optionally set via variable args) */
/* Convert the input UTF-8 path to UTF-16 */
- if(NULL == (wpath = H5_get_utf16_str(path)))
+ if (NULL == (wpath = H5_get_utf16_str(path)))
goto done;
/* _O_BINARY must be set in Windows to avoid CR-LF <-> LF EOL
- * transformations when performing I/O. Note that this will
- * produce Unix-style text files, though.
- */
+ * transformations when performing I/O. Note that this will
+ * produce Unix-style text files, though.
+ */
oflag |= _O_BINARY;
/* Get the mode, if O_CREAT was specified */
- if(oflag & O_CREAT) {
+ if (oflag & O_CREAT) {
va_list vl;
HDva_start(vl, oflag);
@@ -1165,11 +717,11 @@ Wopen_utf8(const char *path, int oflag, ...)
fd = _wopen(wpath, oflag, pmode);
done:
- if(wpath)
+ if (wpath)
H5MM_xfree((void *)wpath);
return fd;
-} /* end Wopen_utf8() */
+} /* end Wopen_utf8() */
/*-------------------------------------------------------------------------
* Function: Wremove_utf8
@@ -1189,26 +741,25 @@ done:
int
Wremove_utf8(const char *path)
{
- wchar_t *wpath = NULL; /* UTF-16 version of the path */
- int ret;
+ wchar_t *wpath = NULL; /* UTF-16 version of the path */
+ int ret = -1;
/* Convert the input UTF-8 path to UTF-16 */
- if(NULL == (wpath = H5_get_utf16_str(path)))
+ if (NULL == (wpath = H5_get_utf16_str(path)))
goto done;
/* Open the file */
ret = _wremove(wpath);
done:
- if(wpath)
+ if (wpath)
H5MM_xfree((void *)wpath);
return ret;
-} /* end Wremove_utf8() */
+} /* end Wremove_utf8() */
#endif /* H5_HAVE_WIN32_API */
-
/*-------------------------------------------------------------------------
* Function: H5_build_extpath
*
@@ -1225,15 +776,15 @@ done:
*
*-------------------------------------------------------------------------
*/
-#define MAX_PATH_LEN 1024
+#define MAX_PATH_LEN 1024
herr_t
H5_build_extpath(const char *name, char **extpath /*out*/)
{
- char *full_path = NULL; /* Pointer to the full path, as built or passed in */
- char *cwdpath = NULL; /* Pointer to the current working directory path */
- char *new_name = NULL; /* Pointer to the name of the file */
- herr_t ret_value = SUCCEED; /* Return value */
+ char * full_path = NULL; /* Pointer to the full path, as built or passed in */
+ char * cwdpath = NULL; /* Pointer to the current working directory path */
+ char * new_name = NULL; /* Pointer to the name of the file */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@@ -1248,19 +799,19 @@ H5_build_extpath(const char *name, char **extpath /*out*/)
* Unix: name[0] is a "/"
* Windows: name[0-2] is "<drive letter>:\" or "<drive-letter>:/"
*/
- if(H5_CHECK_ABSOLUTE(name)) {
- if(NULL == (full_path = (char *)H5MM_strdup(name)))
+ if (H5_CHECK_ABSOLUTE(name)) {
+ if (NULL == (full_path = (char *)H5MM_strdup(name)))
HGOTO_ERROR(H5E_INTERNAL, H5E_NOSPACE, FAIL, "memory allocation failed")
- } /* end if */
+ } /* end if */
else { /* relative pathname */
- char *retcwd;
+ char * retcwd;
size_t name_len;
- int drive;
+ int drive;
- if(NULL == (cwdpath = (char *)H5MM_malloc(MAX_PATH_LEN)))
+ if (NULL == (cwdpath = (char *)H5MM_malloc(MAX_PATH_LEN)))
HGOTO_ERROR(H5E_INTERNAL, H5E_NOSPACE, FAIL, "memory allocation failed")
name_len = HDstrlen(name) + 1;
- if(NULL == (new_name = (char *)H5MM_malloc(name_len)))
+ if (NULL == (new_name = (char *)H5MM_malloc(name_len)))
HGOTO_ERROR(H5E_INTERNAL, H5E_NOSPACE, FAIL, "memory allocation failed")
/*
@@ -1268,17 +819,17 @@ H5_build_extpath(const char *name, char **extpath /*out*/)
* Get current working directory on the drive specified in NAME
* Unix: does not apply
*/
- if(H5_CHECK_ABS_DRIVE(name)) {
- drive = HDtoupper(name[0]) - 'A' + 1;
+ if (H5_CHECK_ABS_DRIVE(name)) {
+ drive = HDtoupper(name[0]) - 'A' + 1;
retcwd = HDgetdcwd(drive, cwdpath, MAX_PATH_LEN);
HDstrncpy(new_name, &name[2], name_len);
} /* end if */
- /*
- * Windows: name[0] is a '/' or '\'
- * Get current drive
- * Unix: does not apply
- */
- else if(H5_CHECK_ABS_PATH(name) && (0 != (drive = HDgetdrive()))) {
+ /*
+ * Windows: name[0] is a '/' or '\'
+ * Get current drive
+ * Unix: does not apply
+ */
+ else if (H5_CHECK_ABS_PATH(name) && (0 != (drive = HDgetdrive()))) {
HDsnprintf(cwdpath, MAX_PATH_LEN, "%c:%c", (drive + 'A' - 1), name[0]);
retcwd = cwdpath;
HDstrncpy(new_name, &name[1], name_len);
@@ -1289,7 +840,7 @@ H5_build_extpath(const char *name, char **extpath /*out*/)
HDstrncpy(new_name, name, name_len);
} /* end if */
- if(retcwd != NULL) {
+ if (retcwd != NULL) {
size_t cwdlen;
size_t path_len;
@@ -1298,37 +849,36 @@ H5_build_extpath(const char *name, char **extpath /*out*/)
HDassert(cwdlen);
HDassert(new_name);
path_len = cwdlen + HDstrlen(new_name) + 2;
- if(NULL == (full_path = (char *)H5MM_malloc(path_len)))
+ if (NULL == (full_path = (char *)H5MM_malloc(path_len)))
HGOTO_ERROR(H5E_INTERNAL, H5E_NOSPACE, FAIL, "memory allocation failed")
HDstrncpy(full_path, cwdpath, cwdlen + 1);
- if(!H5_CHECK_DELIMITER(cwdpath[cwdlen - 1]))
+ if (!H5_CHECK_DELIMITER(cwdpath[cwdlen - 1]))
HDstrncat(full_path, H5_DIR_SEPS, HDstrlen(H5_DIR_SEPS));
HDstrncat(full_path, new_name, HDstrlen(new_name));
} /* end if */
- } /* end else */
+ } /* end else */
/* strip out the last component (the file name itself) from the path */
- if(full_path) {
+ if (full_path) {
char *ptr = NULL;
H5_GET_LAST_DELIMITER(full_path, ptr)
HDassert(ptr);
- *++ptr = '\0';
+ *++ptr = '\0';
*extpath = full_path;
} /* end if */
done:
/* Release resources */
- if(cwdpath)
+ if (cwdpath)
H5MM_xfree(cwdpath);
- if(new_name)
+ if (new_name)
H5MM_xfree(new_name);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5_build_extpath() */
-
/*--------------------------------------------------------------------------
* Function: H5_combine_path
*
@@ -1343,35 +893,35 @@ done:
*--------------------------------------------------------------------------
*/
herr_t
-H5_combine_path(const char* path1, const char* path2, char **full_name /*out*/)
+H5_combine_path(const char *path1, const char *path2, char **full_name /*out*/)
{
- size_t path1_len; /* length of path1 */
- size_t path2_len; /* length of path2 */
- herr_t ret_value = SUCCEED; /* Return value */
+ size_t path1_len = 0; /* length of path1 */
+ size_t path2_len; /* length of path2 */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
HDassert(path2);
- if(path1)
+ if (path1)
path1_len = HDstrlen(path1);
path2_len = HDstrlen(path2);
- if(path1 == NULL || *path1 == '\0' || H5_CHECK_ABSOLUTE(path2)) {
+ if (path1 == NULL || *path1 == '\0' || H5_CHECK_ABSOLUTE(path2)) {
/* If path1 is empty or path2 is absolute, simply use path2 */
- if(NULL == (*full_name = (char *)H5MM_strdup(path2)))
+ if (NULL == (*full_name = (char *)H5MM_strdup(path2)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
} /* end if */
- else if(H5_CHECK_ABS_PATH(path2)) {
+ else if (H5_CHECK_ABS_PATH(path2)) {
/* On windows path2 is a path absolute name */
if (H5_CHECK_ABSOLUTE(path1) || H5_CHECK_ABS_DRIVE(path1)) {
/* path1 is absolute or drive absolute and path2 is path absolute.
* Use the drive letter of path1 + path2
*/
- if(NULL == (*full_name = (char *)H5MM_malloc(path2_len + 3)))
+ if (NULL == (*full_name = (char *)H5MM_malloc(path2_len + 3)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate path2 buffer")
HDsnprintf(*full_name, (path2_len + 3), "%c:%s", path1[0], path2);
} /* end if */
@@ -1380,7 +930,7 @@ H5_combine_path(const char* path1, const char* path2, char **full_name /*out*/)
* path1 does not have a drive letter (i.e. is "a\b" or "\a\b").
* Use path2.
*/
- if(NULL == (*full_name = (char *)H5MM_strdup(path2)))
+ if (NULL == (*full_name = (char *)H5MM_strdup(path2)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
} /* end else */
@@ -1391,11 +941,14 @@ H5_combine_path(const char* path1, const char* path2, char **full_name /*out*/)
* Allocate a buffer to hold path1 + path2 + possibly the delimiter
* + terminating null byte
*/
- if(NULL == (*full_name = (char *)H5MM_malloc(path1_len + path2_len + 2 + 2))) /* Extra "+2" to quiet GCC warning - 2019/07/05, QAK */
+ if (NULL ==
+ (*full_name = (char *)H5MM_malloc(path1_len + path2_len + 2 +
+ 2))) /* Extra "+2" to quiet GCC warning - 2019/07/05, QAK */
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate filename buffer")
/* Compose the full file name */
- HDsnprintf(*full_name, (path1_len + path2_len + 2 + 2), "%s%s%s", path1, /* Extra "+2" to quiet GCC warning - 2019/07/05, QAK */
+ HDsnprintf(*full_name, (path1_len + path2_len + 2 + 2), "%s%s%s",
+ path1, /* Extra "+2" to quiet GCC warning - 2019/07/05, QAK */
(H5_CHECK_DELIMITER(path1[path1_len - 1]) ? "" : H5_DIR_SEPS), path2);
} /* end else */
@@ -1403,39 +956,67 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5_combine_path() */
-
/*--------------------------------------------------------------------------
* Function: H5_nanosleep
*
* Purpose: Sleep for a given # of nanoseconds
*
- * Return: SUCCEED/FAIL
+ * Note that commodity hardware is probably going to have a
+ * resolution of milliseconds, not nanoseconds.
*
- * Programmer: Quincey Koziol
- * October 01, 2016
+ * Return: void
*--------------------------------------------------------------------------
*/
void
H5_nanosleep(uint64_t nanosec)
{
- struct timespec sleeptime; /* Struct to hold time to sleep */
-
FUNC_ENTER_NOAPI_NOINIT_NOERR
- /* Set up time to sleep */
- sleeptime.tv_sec = 0;
- sleeptime.tv_nsec = (long)nanosec;
+#ifdef H5_HAVE_WIN32_API
+ DWORD dwMilliseconds = (DWORD)HDceil(nanosec / 1.0e6);
+ DWORD ignore;
- HDnanosleep(&sleeptime, NULL);
+ /* Windows can't sleep at a ns resolution. Best we can do is ~1 ms. We
+ * don't care about the return value since the second parameter
+ * (bAlertable) is FALSE, so it will always be zero.
+ */
+ ignore = SleepEx(dwMilliseconds, FALSE);
+
+#else
+
+ const uint64_t nanosec_per_sec = 1000 * 1000 * 1000;
+ struct timespec sleeptime; /* Struct to hold time to sleep */
+
+ /* Set up time to sleep
+ *
+ * Assuming ILP32 or LP64 or wider architecture, (long)operand
+ * satisfies 0 <= operand < nanosec_per_sec < LONG_MAX.
+ *
+ * It's harder to be sure that we don't overflow time_t.
+ */
+ sleeptime.tv_sec = (time_t)(nanosec / nanosec_per_sec);
+ sleeptime.tv_nsec = (long)(nanosec % nanosec_per_sec);
+
+ /* Sleep for up to `sleeptime` and, in the event of an interruption,
+ * save the unslept time back to `sleeptime`.
+ */
+ while (HDnanosleep(&sleeptime, &sleeptime) == -1) {
+ /* If we were just interrupted, sleep for the remaining time.
+ * Otherwise, the error was essentially impossible, so just stop
+ * sleeping.
+ */
+ if (errno != EINTR)
+ break;
+ }
+#endif
FUNC_LEAVE_NOAPI_VOID
} /* end H5_nanosleep() */
#ifdef H5_HAVE_WIN32_API
-#define H5_WIN32_ENV_VAR_BUFFER_SIZE 32767
+#define H5_WIN32_ENV_VAR_BUFFER_SIZE 32767
-
/*-------------------------------------------------------------------------
* Function: H5_expand_windows_env_vars()
*
@@ -1449,9 +1030,9 @@ H5_nanosleep(uint64_t nanosec)
herr_t
H5_expand_windows_env_vars(char **env_var)
{
- long n_chars = 0;
- char *temp_buf = NULL;
- herr_t ret_value = SUCCEED; /* Return value */
+ long n_chars = 0;
+ char * temp_buf = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@@ -1460,7 +1041,8 @@ H5_expand_windows_env_vars(char **env_var)
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for expanded path")
/* Expand the environment variable string */
- if ((n_chars = ExpandEnvironmentStringsA(*env_var, temp_buf, H5_WIN32_ENV_VAR_BUFFER_SIZE)) > H5_WIN32_ENV_VAR_BUFFER_SIZE)
+ if ((n_chars = ExpandEnvironmentStringsA(*env_var, temp_buf, H5_WIN32_ENV_VAR_BUFFER_SIZE)) >
+ H5_WIN32_ENV_VAR_BUFFER_SIZE)
HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "expanded path is too long")
if (0 == n_chars)
@@ -1477,3 +1059,166 @@ done:
} /* end H5_expand_windows_env_vars() */
#endif /* H5_HAVE_WIN32_API */
+/* Global variables */
+int H5_opterr = 1; /* Get_option prints errors if this is on */
+int H5_optind = 1; /* Token pointer */
+const char *H5_optarg; /* Flag argument (or value) */
+
+/*-------------------------------------------------------------------------
+ * Function: H5_get_option
+ *
+ * Purpose: Determine the command-line options a user specified. We can
+ * accept both short and long type command-lines.
+ *
+ * Return: Success: The short valued "name" of the command line
+ * parameter or EOF if there are no more
+ * parameters to process.
+ *
+ * Failure: A question mark.
+ *-------------------------------------------------------------------------
+ */
+int
+H5_get_option(int argc, const char **argv, const char *opts, const struct h5_long_options *l_opts)
+{
+ static int sp = 1; /* character index in current token */
+ int optopt = '?'; /* option character passed back to user */
+
+ if (sp == 1) {
+ /* check for more flag-like tokens */
+ if (H5_optind >= argc || argv[H5_optind][0] != '-' || argv[H5_optind][1] == '\0') {
+ return EOF;
+ }
+ else if (HDstrcmp(argv[H5_optind], "--") == 0) {
+ H5_optind++;
+ return EOF;
+ }
+ }
+
+ if (sp == 1 && argv[H5_optind][0] == '-' && argv[H5_optind][1] == '-') {
+ /* long command line option */
+ int i;
+ const char ch = '=';
+ char * arg = HDstrdup(&argv[H5_optind][2]);
+ size_t arg_len = 0;
+
+ H5_optarg = strchr(&argv[H5_optind][2], ch);
+ arg_len = HDstrlen(&argv[H5_optind][2]);
+ if (H5_optarg) {
+ arg_len -= HDstrlen(H5_optarg);
+ H5_optarg++; /* skip the equal sign */
+ }
+ arg[arg_len] = 0;
+
+ for (i = 0; l_opts && l_opts[i].name; i++) {
+ if (HDstrcmp(arg, l_opts[i].name) == 0) {
+ /* we've found a matching long command line flag */
+ optopt = l_opts[i].shortval;
+
+ if (l_opts[i].has_arg != no_arg) {
+ if (H5_optarg == NULL) {
+ if (l_opts[i].has_arg != optional_arg) {
+ if (H5_optind < (argc - 1))
+ if (argv[H5_optind + 1][0] != '-')
+ H5_optarg = argv[++H5_optind];
+ }
+ else if (l_opts[i].has_arg == require_arg) {
+ if (H5_opterr)
+ HDfprintf(stderr, "%s: option required for \"--%s\" flag\n", argv[0], arg);
+
+ optopt = '?';
+ }
+ }
+ }
+ else {
+ if (H5_optarg) {
+ if (H5_opterr)
+ HDfprintf(stderr, "%s: no option required for \"%s\" flag\n", argv[0], arg);
+
+ optopt = '?';
+ }
+ }
+ break;
+ }
+ }
+
+ if (l_opts[i].name == NULL) {
+ /* exhausted all of the l_opts we have and still didn't match */
+ if (H5_opterr)
+ HDfprintf(stderr, "%s: unknown option \"%s\"\n", argv[0], arg);
+
+ optopt = '?';
+ }
+
+ H5_optind++;
+ sp = 1;
+
+ HDfree(arg);
+ }
+ else {
+ register char *cp; /* pointer into current token */
+
+ /* short command line option */
+ optopt = argv[H5_optind][sp];
+
+ if (optopt == ':' || (cp = HDstrchr(opts, optopt)) == 0) {
+ if (H5_opterr)
+ HDfprintf(stderr, "%s: unknown option \"%c\"\n", argv[0], optopt);
+
+ /* if no chars left in this token, move to next token */
+ if (argv[H5_optind][++sp] == '\0') {
+ H5_optind++;
+ sp = 1;
+ }
+ return '?';
+ }
+
+ if (*++cp == ':') {
+ /* if a value is expected, get it */
+ if (argv[H5_optind][sp + 1] != '\0') {
+ /* flag value is rest of current token */
+ H5_optarg = &argv[H5_optind++][sp + 1];
+ }
+ else if (++H5_optind >= argc) {
+ if (H5_opterr)
+ HDfprintf(stderr, "%s: value expected for option \"%c\"\n", argv[0], optopt);
+
+ optopt = '?';
+ }
+ else {
+ /* flag value is next token */
+ H5_optarg = argv[H5_optind++];
+ }
+
+ sp = 1;
+ }
+ /* wildcard argument */
+ else if (*cp == '*') {
+ /* check the next argument */
+ H5_optind++;
+ /* we do have an extra argument, check if not last */
+ if ((H5_optind + 1) < argc) {
+ if (argv[H5_optind][0] != '-') {
+ H5_optarg = argv[H5_optind++];
+ }
+ else {
+ H5_optarg = NULL;
+ }
+ }
+ else {
+ H5_optarg = NULL;
+ }
+ }
+ else {
+ /* set up to look at next char in token, next time */
+ if (argv[H5_optind][++sp] == '\0') {
+ /* no more in current token, so setup next token */
+ H5_optind++;
+ sp = 1;
+ }
+ H5_optarg = NULL;
+ }
+ }
+
+ /* return the current flag character found */
+ return optopt;
+}