#include <folly/portability/Fcntl.h>
#include <folly/portability/Unistd.h>
+#ifdef _WIN32
+#include <crtdbg.h>
+#endif
+
namespace folly {
namespace test {
namespace detail {
+SavedState disableInvalidParameters() {
+#ifdef _WIN32
+ SavedState ret;
+ ret.previousThreadLocalHandler = _set_thread_local_invalid_parameter_handler(
+ [](const wchar_t*,
+ const wchar_t*,
+ const wchar_t*,
+ unsigned int,
+ uintptr_t) {});
+ ret.previousCrtReportMode = _CrtSetReportMode(_CRT_ASSERT, 0);
+ return ret;
+#else
+ return SavedState();
+#endif
+}
+
+#ifdef _WIN32
+void enableInvalidParameters(SavedState state) {
+ _set_thread_local_invalid_parameter_handler(
+ (_invalid_parameter_handler)state.previousThreadLocalHandler);
+ _CrtSetReportMode(_CRT_ASSERT, state.previousCrtReportMode);
+}
+#else
+void enableInvalidParameters(SavedState) {}
+#endif
+
bool hasPCREPatternMatch(StringPiece pattern, StringPiece target) {
return boost::regex_match(
target.begin(),
#include <map>
#include <string>
#include <folly/Range.h>
+#include <folly/ScopeGuard.h>
#include <folly/experimental/io/FsUtil.h>
namespace folly {
TemporaryDirectory dir_;
};
+namespace detail {
+struct SavedState {
+ void* previousThreadLocalHandler;
+ int previousCrtReportMode;
+};
+SavedState disableInvalidParameters();
+void enableInvalidParameters(SavedState state);
+}
+
+// Ok, so fun fact: The CRT on windows will actually abort
+// on certain failed parameter validation checks in debug
+// mode rather than simply returning -1 as it does in release
+// mode. We can however, ensure consistent behavior by
+// registering our own thread-local invalid parameter handler
+// for the duration of the call, and just have that handler
+// immediately return. We also have to disable CRT asertion
+// alerts for the duration of the call, otherwise we get
+// the abort-retry-ignore window.
+template <typename Func>
+auto msvcSuppressAbortOnInvalidParams(Func func) -> decltype(func()) {
+ auto savedState = detail::disableInvalidParameters();
+ SCOPE_EXIT {
+ detail::enableInvalidParameters(savedState);
+ };
+ return func();
+}
+
/**
* Easy PCRE regex matching. Note that pattern must match the ENTIRE target,
* so use .* at the start and end of the pattern, as appropriate. See
EXPECT_EQ(1, r);
}
- // The file must have been closed. This assumes that no other thread
- // has opened another file in the meanwhile, which is a sane assumption
- // to make in this test.
- ssize_t r = write(fd, &c, 1);
- int savedErrno = errno;
- EXPECT_EQ(-1, r);
- EXPECT_EQ(EBADF, savedErrno);
+ msvcSuppressAbortOnInvalidParams([&] {
+ // The file must have been closed. This assumes that no other thread
+ // has opened another file in the meanwhile, which is a sane assumption
+ // to make in this test.
+ ssize_t r = write(fd, &c, 1);
+ int savedErrno = errno;
+ EXPECT_EQ(-1, r);
+ EXPECT_EQ(EBADF, savedErrno);
+ });
}
TEST(TemporaryFile, Prefix) {