@@ -1257,7 +1257,7 @@ AC_HEADER_SYS_WAIT
AC_HEADER_TIOCGWINSZ
AC_CHECK_HEADERS(limits.h stddef.h string.h strings.h stdlib.h time.h iconv.h \
fcntl.h ftw.h unistd.h sys/file.h sys/time.h sys/mman.h \
- sys/resource.h sys/param.h sys/times.h sys/stat.h \
+ sys/resource.h sys/param.h sys/times.h sys/stat.h sys/locking.h \
direct.h malloc.h langinfo.h ldfcn.h locale.h wchar.h)
# Check for thread headers.
@@ -1711,6 +1711,19 @@ if test $ac_cv_af_inet6 = yes; then
[Define if AF_INET6 supported.])
fi
+# Check if _LK_LOCK is supported by _locking
+AC_CACHE_CHECK(for _LK_LOCK, ac_cv_lk_lock, [
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <io.h>
+#include <sys/locking.h>]], [[
+ int fd;
+ return _locking (fd, _LK_LOCK, 0);]])],
+[ac_cv_lk_lock=yes],[ac_cv_lk_lock=no])])
+if test $ac_cv_lk_lock = yes; then
+ AC_DEFINE(HOST_HAS_LK_LOCK, 1,
+ [Define if _LK_LOC supported by _locking.])
+fi
+
# Restore CFLAGS, CXXFLAGS from before the gcc_AC_NEED_DECLARATIONS tests.
CFLAGS="$saved_CFLAGS"
CXXFLAGS="$saved_CXXFLAGS"
@@ -137,6 +137,8 @@ gcov_open (const char *name, int mode)
s_flock.l_start = 0;
s_flock.l_len = 0; /* Until EOF. */
s_flock.l_pid = getpid ();
+#elif GCOV_LOCKED_WITH_LOCKING
+ int fd;
#endif
gcov_nonruntime_assert (!gcov_var.file);
@@ -170,6 +172,34 @@ gcov_open (const char *name, int mode)
gcov_var.file = fdopen (fd, (mode > 0) ? "rb" : "r+b");
+ if (!gcov_var.file)
+ {
+ close (fd);
+ return 0;
+ }
+#elif GCOV_LOCKED_WITH_LOCKING
+ if (mode > 0)
+ {
+ /* pass mode (ignored) for compatibility */
+ fd = open (name, O_RDONLY | O_BINARY, S_IRUSR | S_IWUSR);
+ }
+ else
+ {
+ /* Truncate if force new mode. */
+ fd = open (name, O_RDWR | O_BINARY | O_CREAT | (mode < 0 ? O_TRUNC : 0),
+ 0666);
+ }
+ if (fd < 0)
+ return 0;
+
+ if (_locking (fd, _LK_LOCK, LONG_MAX) < 0)
+ {
+ close (fd);
+ return 0;
+ }
+
+ gcov_var.file = fdopen (fd, (mode > 0) ? "rb" : "r+b");
+
if (!gcov_var.file)
{
close (fd);
@@ -202,6 +202,12 @@ typedef uint64_t gcov_type_unsigned;
#define GCOV_LOCKED 0
#endif
+#if defined (HOST_HAS_LK_LOCK)
+#define GCOV_LOCKED_WITH_LOCKING 1
+#else
+#define GCOV_LOCKED_WITH_LOCKING 0
+#endif
+
#define ATTRIBUTE_HIDDEN
#endif /* !IN_LIBGCOV */
@@ -360,6 +360,10 @@ extern int errno;
# endif
#endif
+#ifdef HAVE_SYS_LOCKING_H
+# include <sys/locking.h>
+#endif
+
#ifndef SEEK_SET
# define SEEK_SET 0
# define SEEK_CUR 1
@@ -36,10 +36,15 @@ void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {}
#else /* inhibit_libc */
#include <string.h>
+
#if GCOV_LOCKED
#include <fcntl.h>
#include <errno.h>
#include <sys/stat.h>
+#elif GCOV_LOCKED_WITH_LOCKING
+#include <fcntl.h>
+#include <sys/locking.h>
+#include <sys/stat.h>
#endif
#if HAVE_SYS_MMAN_H
@@ -89,6 +89,12 @@ typedef unsigned gcov_type_unsigned __attribute__ ((mode (QI)));
#define GCOV_LOCKED 0
#endif
+#if defined (__MSVCRT__)
+#define GCOV_LOCKED_WITH_LOCKING 1
+#else
+#define GCOV_LOCKED_WITH_LOCKING 0
+#endif
+
#ifndef GCOV_SUPPORTS_ATOMIC
/* Detect whether target can support atomic update of profilers. */
#if __SIZEOF_LONG_LONG__ == 4 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
@@ -133,12 +139,19 @@ typedef unsigned gcov_type_unsigned __attribute__ ((mode (QI)));
typedef unsigned gcov_unsigned_t;
typedef unsigned gcov_position_t;
/* gcov_type is typedef'd elsewhere for the compiler */
+
#if defined (HOST_HAS_F_SETLKW)
#define GCOV_LOCKED 1
#else
#define GCOV_LOCKED 0
#endif
+#if defined (HOST_HAS_LK_LOCK)
+#define GCOV_LOCKED_WITH_LOCKING 1
+#else
+#define GCOV_LOCKED_WITH_LOCKING 0
+#endif
+
/* Some Macros specific to gcov-tool. */
#define L_gcov 1