Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
authorMartin Hořeňovský2017-03-06 21:51:22 +0100
committerMartin Hořeňovský2017-03-06 21:51:22 +0100
commit613e1466f9ef7e068fd08327fd04cfd25df4fb3b (patch)
tree71afe7179e45c8b5b30755c9daf2b0336efe0e12 /include
parente95bf48445f60e8cdb720962685d26476964cf22 (diff)
downloadcatch3-613e1466f9ef7e068fd08327fd04cfd25df4fb3b.tar.gz
Save errno before using sprintf, ifstream.
std::ifstream in libstdc++ contains a bug, where it sets errno to zero. To work around it, we manually save the errno before using std::ifstream in debugger check, and reset it after we are done. We also preventively save errno before using sprintf. Fixes #835
Diffstat (limited to 'include')
-rw-r--r--include/internal/catch_debugger.hpp4
-rw-r--r--include/internal/catch_errno_guard.hpp25
-rw-r--r--include/reporters/catch_reporter_bases.hpp4
3 files changed, 33 insertions, 0 deletions
diff --git a/include/internal/catch_debugger.hpp b/include/internal/catch_debugger.hpp
index 47daf8ad..00017d16 100644
--- a/include/internal/catch_debugger.hpp
+++ b/include/internal/catch_debugger.hpp
@@ -10,6 +10,7 @@
#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
#include "catch_debugger.h"
+#include "catch_errno_guard.hpp"
#ifdef CATCH_PLATFORM_MAC
@@ -72,6 +73,9 @@
// be strace, for example) in /proc/$PID/status, so just get it from
// there instead.
bool isDebuggerActive(){
+ // Libstdc++ has a bug, where std::ifstream sets errno to 0
+ // This way our users can properly assert over errno values
+ ErrnoGuard guard;
std::ifstream in("/proc/self/status");
for( std::string line; std::getline(in, line); ) {
static const int PREFIX_LEN = 11;
diff --git a/include/internal/catch_errno_guard.hpp b/include/internal/catch_errno_guard.hpp
new file mode 100644
index 00000000..48794b08
--- /dev/null
+++ b/include/internal/catch_errno_guard.hpp
@@ -0,0 +1,25 @@
+/*
+ * Created by Martin on 06/03/2017.
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+#ifndef TWOBLUECUBES_CATCH_ERRNO_GUARD_HPP_INCLUDED
+#define TWOBLUECUBES_CATCH_ERRNO_GUARD_HPP_INCLUDED
+
+#include <cerrno>
+
+
+namespace Catch {
+
+ class ErrnoGuard {
+ public:
+ ErrnoGuard():m_oldErrno(errno){}
+ ~ErrnoGuard() { errno = m_oldErrno; }
+ private:
+ int m_oldErrno;
+ };
+
+}
+
+#endif // TWOBLUECUBES_CATCH_ERRNO_GUARD_HPP_INCLUDED
diff --git a/include/reporters/catch_reporter_bases.hpp b/include/reporters/catch_reporter_bases.hpp
index 8fc8554b..aca5f355 100644
--- a/include/reporters/catch_reporter_bases.hpp
+++ b/include/reporters/catch_reporter_bases.hpp
@@ -9,6 +9,7 @@
#define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
#include "../internal/catch_interfaces_reporter.h"
+#include "../internal/catch_errno_guard.hpp"
#include <cstring>
#include <cfloat>
@@ -27,6 +28,9 @@ namespace Catch {
// + 1 for null terminator
const size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
char buffer[maxDoubleSize];
+
+ // Save previous errno, to prevent sprintf from overwriting it
+ ErrnoGuard guard;
#ifdef _MSC_VER
sprintf_s(buffer, "%.3f", duration);
#else