summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config/cmake/H5pubconf.h.in6
-rw-r--r--config/cmake_ext_mod/ConfigureChecks.cmake2
-rw-r--r--configure.ac6
-rw-r--r--src/H5private.h74
-rw-r--r--src/H5system.c112
-rw-r--r--src/H5win32defs.h2
6 files changed, 197 insertions, 5 deletions
diff --git a/config/cmake/H5pubconf.h.in b/config/cmake/H5pubconf.h.in
index 5011b03..ce8219f 100644
--- a/config/cmake/H5pubconf.h.in
+++ b/config/cmake/H5pubconf.h.in
@@ -100,6 +100,9 @@
/* Define if library information should be embedded in the executables */
#cmakedefine H5_HAVE_EMBEDDED_LIBINFO @H5_HAVE_EMBEDDED_LIBINFO@
+/* Define to 1 if you have the `fcntl' function. */
+#cmakedefine H5_HAVE_FCNTL @H5_HAVE_FCNTL@
+
/* Define to 1 if you have the <features.h> header file. */
#cmakedefine H5_HAVE_FEATURES_H @H5_HAVE_FEATURES_H@
@@ -109,6 +112,9 @@
/* Define if support for szip filter is enabled */
#cmakedefine H5_HAVE_FILTER_SZIP @H5_HAVE_FILTER_SZIP@
+/* Define to 1 if you have the `flock' function. */
+#cmakedefine H5_HAVE_FLOCK @H5_HAVE_FLOCK@
+
/* Define to 1 if you have the `fork' function. */
#cmakedefine H5_HAVE_FORK @H5_HAVE_FORK@
diff --git a/config/cmake_ext_mod/ConfigureChecks.cmake b/config/cmake_ext_mod/ConfigureChecks.cmake
index c4fabf1..cfda66b 100644
--- a/config/cmake_ext_mod/ConfigureChecks.cmake
+++ b/config/cmake_ext_mod/ConfigureChecks.cmake
@@ -490,6 +490,8 @@ endif (NOT WINDOWS)
# Check for some functions that are used
#
CHECK_FUNCTION_EXISTS (alarm ${HDF_PREFIX}_HAVE_ALARM)
+CHECK_FUNCTION_EXISTS (fcntl ${HDF_PREFIX}_HAVE_FCNTL)
+CHECK_FUNCTION_EXISTS (flock ${HDF_PREFIX}_HAVE_FLOCK)
CHECK_FUNCTION_EXISTS (fork ${HDF_PREFIX}_HAVE_FORK)
CHECK_FUNCTION_EXISTS (frexpf ${HDF_PREFIX}_HAVE_FREXPF)
CHECK_FUNCTION_EXISTS (frexpl ${HDF_PREFIX}_HAVE_FREXPL)
diff --git a/configure.ac b/configure.ac
index b9606f4..0c3514c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -947,7 +947,7 @@ AC_HEADER_TIME
## Unix
AC_CHECK_HEADERS([sys/resource.h sys/time.h unistd.h sys/ioctl.h sys/stat.h])
-AC_CHECK_HEADERS([sys/socket.h sys/types.h])
+AC_CHECK_HEADERS([sys/socket.h sys/types.h sys/file.h])
AC_CHECK_HEADERS([stddef.h setjmp.h features.h])
AC_CHECK_HEADERS([dirent.h])
AC_CHECK_HEADERS([stdint.h], [C9x=yes])
@@ -1743,8 +1743,8 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
## NOTE: clock_gettime may require linking to the rt or posix4 library
## so we'll search for it before calling AC_CHECK_FUNCS.
AC_SEARCH_LIBS([clock_gettime], [rt posix4])
-AC_CHECK_FUNCS([alarm clock_gettime difftime fork frexpf frexpl])
-AC_CHECK_FUNCS([gethostname getpwuid getrusage gettimeofday])
+AC_CHECK_FUNCS([alarm clock_gettime difftime fcntl flock fork frexpf])
+AC_CHECK_FUNCS([frexpl gethostname getpwuid getrusage gettimeofday])
AC_CHECK_FUNCS([lstat rand_r random setsysinfo])
AC_CHECK_FUNCS([signal longjmp setjmp siglongjmp sigsetjmp sigprocmask])
AC_CHECK_FUNCS([snprintf srandom strdup symlink system])
diff --git a/src/H5private.h b/src/H5private.h
index daf6998..c536566 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -119,6 +119,13 @@
#endif
/*
+ * flock() in sys/file.h is used for the implemention of file locking.
+ */
+#if defined(H5_HAVE_FLOCK) && defined(H5_HAVE_SYS_FILE_H)
+# include <sys/file.h>
+#endif
+
+/*
* Resource usage is not Posix.1 but HDF5 uses it anyway for some performance
* and debugging code if available.
*/
@@ -291,6 +298,10 @@
*
* Note that Solaris Studio supports attribute, but does not support the
* attributes we use.
+ *
+ * H5_ATTR_CONST is redefined in tools/h5repack/dynlib_rpk.c to quiet
+ * gcc warnings (it has to use the public API and can't include this
+ * file). Be sure to update that file if the #ifdefs change here.
*/
#ifdef __cplusplus
# define H5_ATTR_FORMAT(X,Y,Z) /*void*/
@@ -542,6 +553,18 @@
#define H5_TB (1024.0F * 1024.0F * 1024.0F * 1024.0F)
#define H5_EB (1024.0F * 1024.0F * 1024.0F * 1024.0F * 1024.0F)
+#ifndef H5_HAVE_FLOCK
+/* flock() operations. Used in the source so we have to define them when
+ * the call is not available (e.g.: Windows). These should NOT be used
+ * with system-provided flock() calls since the values will come from the
+ * header file.
+ */
+#define LOCK_SH 0x01
+#define LOCK_EX 0x02
+#define LOCK_NB 0x04
+#define LOCK_UN 0x08
+#endif /* H5_HAVE_FLOCK */
+
/*
* Data types and functions for timing certain parts of the library.
*/
@@ -746,7 +769,11 @@ typedef struct {
#ifndef HDfclose
#define HDfclose(F) fclose(F)
#endif /* HDfclose */
-/* fcntl() variable arguments */
+#ifdef H5_HAVE_FCNTL
+ #ifndef HDfcntl
+ #define HDfcntl(F,C,...) fcntl(F,C,__VA_ARGS__)
+ #endif /* HDfcntl */
+#endif /* H5_HAVE_FCNTL */
#ifndef HDfdopen
#define HDfdopen(N,S) fdopen(N,S)
#endif /* HDfdopen */
@@ -771,6 +798,27 @@ typedef struct {
#ifndef HDfileno
#define HDfileno(F) fileno(F)
#endif /* HDfileno */
+/* Since flock is so prevalent, always build these functions
+ * when possible to avoid them becoming dead code.
+ */
+#ifdef H5_HAVE_FCNTL
+H5_DLL int Pflock(int fd, int operation);
+#endif /* H5_HAVE_FCNTL */
+H5_DLL H5_ATTR_CONST int Nflock(int fd, int operation);
+#ifndef HDflock
+ /* NOTE: flock(2) is not present on all POSIX systems.
+ * If it is not present, we try a flock() equivalent based on
+ * fcntl(2), then fall back to a function that always fails if
+ * it is not present at all.
+ */
+ #if defined(H5_HAVE_FLOCK)
+ #define HDflock(F,L) flock(F,L)
+ #elif defined(H5_HAVE_FCNTL)
+ #define HDflock(F,L) Pflock(F,L)
+ #else
+ #define HDflock(F,L) Nflock(F,L)
+ #endif /* H5_HAVE_FLOCK */
+#endif /* HDflock */
#ifndef HDfloor
#define HDfloor(X) floor(X)
#endif /* HDfloor */
@@ -1163,6 +1211,9 @@ H5_DLL int HDfprintf (FILE *stream, const char *fmt, ...);
#define HDrmdir(S) rmdir(S)
#endif /* HDrmdir */
/* scanf() variable arguments */
+#ifndef HDselect
+ #define HDselect(N,RD,WR,ER,T) select(N,RD,WR,ER,T)
+#endif /* HDsetbuf */
#ifndef HDsetbuf
#define HDsetbuf(F,S) setbuf(F,S)
#endif /* HDsetbuf */
@@ -2374,6 +2425,16 @@ func \
H5_GLUE(FUNC_ERR_VAR_, use_err)(ret_typ, err) \
H5_GLUE(FUNC_ENT_, scope)(H5_MY_PKG, H5_MY_PKG_INIT)
+/* Use this macro when entering functions that have no return value */
+#define BEGIN_FUNC_VOID(scope, use_err, func) \
+H5_GLUE(FUNC_PREFIX_, scope) \
+void \
+func \
+/* Open function */ \
+{ \
+ H5_GLUE(FUNC_ERR_VAR_, use_err)(void, -, -) \
+ H5_GLUE(FUNC_ENT_, scope)
+
/* Macros for label when a function initialization can fail */
#define H5_PRIV_YES_FUNC_INIT_FAILED func_init_failed:
#define H5_PRIV_NO_FUNC_INIT_FAILED
@@ -2449,6 +2510,17 @@ func_init_failed: \
/* Close Function */ \
}
+/* Use this macro when leaving void functions */
+#define END_FUNC_VOID(scope) \
+ /* Scope-specific function conclusion */ \
+ H5_GLUE(FUNC_LEAVE_, scope) \
+ \
+ /* Leave routine */ \
+ return; \
+ \
+ /* Close Function */ \
+}
+
/* Macro to begin/end tagging (when FUNC_ENTER_*TAG macros are insufficient).
* Make sure to use HGOTO_ERROR_TAG and HGOTO_DONE_TAG between these macros! */
#define H5_BEGIN_TAG(dxpl, tag, err) { \
diff --git a/src/H5system.c b/src/H5system.c
index f91fb27..4baebc5 100644
--- a/src/H5system.c
+++ b/src/H5system.c
@@ -587,6 +587,68 @@ void HDsrand(unsigned int seed)
#endif /* H5_HAVE_RAND_R */
+
+/*-------------------------------------------------------------------------
+ * Function: Pflock
+ *
+ * Purpose: Wrapper function for POSIX systems where flock(2) is not
+ * available.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+/* NOTE: Compile this all the time on POSIX systems, even when flock(2) is
+ * present so that it's less likely to become dead code.
+ */
+#ifdef H5_HAVE_FCNTL
+int
+Pflock(int fd, int operation) {
+
+ struct flock flk;
+
+ /* Set the lock type */
+ if(operation & LOCK_UN)
+ flk.l_type = F_UNLCK;
+ 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 */
+
+ /* Lock or unlock */
+ if(HDfcntl(fd, F_SETLK, flk) < 0)
+ return -1;
+
+ return 0;
+
+} /* end Pflock() */
+#endif /* H5_HAVE_FCNTL */
+
+
+/*-------------------------------------------------------------------------
+ * Function: Nflock
+ *
+ * Purpose: Wrapper function for systems where no file locking is
+ * available.
+ *
+ * Return: Failure: -1 (always fails)
+ *
+ *-------------------------------------------------------------------------
+ */
+int H5_ATTR_CONST
+Nflock(int H5_ATTR_UNUSED fd, int H5_ATTR_UNUSED operation) {
+ /* just fail */
+ return -1;
+} /* end Nflock() */
+
+
/*-------------------------------------------------------------------------
* Function: H5_make_time
*
@@ -767,7 +829,55 @@ int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap)
return count;
}
-#endif
+
+/*-------------------------------------------------------------------------
+ * Function: Wflock
+ *
+ * Purpose: Wrapper function for flock on Windows systems
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+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) {
+
+ 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};
+
+ /* Get Windows HANDLE */
+ hFile = _get_osfhandle(fd);
+
+ /* Convert to Windows flags */
+ 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))
+ return -1;
+#endif /* 0 */
+ return 0;
+} /* end Wflock() */
+
+#endif /* H5_HAVE_VISUAL_STUDIO */
/*-------------------------------------------------------------------------
diff --git a/src/H5win32defs.h b/src/H5win32defs.h
index 73d8417..e84def9 100644
--- a/src/H5win32defs.h
+++ b/src/H5win32defs.h
@@ -74,6 +74,7 @@ struct timezone {
extern "C" {
#endif /* __cplusplus */
H5_DLL int Wgettimeofday(struct timeval *tv, struct timezone *tz);
+ H5_DLL int Wflock(int fd, int operation);
H5_DLL char* Wgetlogin(void);
H5_DLL int c99_snprintf(char* str, size_t size, const char* format, ...);
H5_DLL int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap);
@@ -81,6 +82,7 @@ struct timezone {
}
#endif /* __cplusplus */
#define HDgettimeofday(V,Z) Wgettimeofday(V,Z)
+#define HDflock(F,L) Wflock(F,L)
#define HDgetlogin() Wgetlogin()
#define HDsnprintf c99_snprintf /*varargs*/
#define HDvsnprintf c99_vsnprintf