diff --git a/tests/abortutil.cpp b/tests/abortutil.cpp index 0fca9ba96..c3f912267 100644 --- a/tests/abortutil.cpp +++ b/tests/abortutil.cpp @@ -1,11 +1,11 @@ #include "abortutil.hpp" -#ifdef __linux__ +#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) void Disable_Console_Output() { // close C file descriptors fclose(stdout); fclose(stderr); } #endif diff --git a/tests/abortutil.hpp b/tests/abortutil.hpp index a7563444e..f486203db 100644 --- a/tests/abortutil.hpp +++ b/tests/abortutil.hpp @@ -1,90 +1,90 @@ #pragma once -#ifdef __linux__ +#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) #include #include #include #include #include #include #include // copied from cppreference as possible implementation namespace detail { template inline auto INVOKE(F &&f, Args &&... args) -> decltype(std::forward(f)(std::forward(args)...)) { return std::forward(f)(std::forward(args)...); } template inline auto INVOKE(T Base::*pmd, Derived &&ref) -> decltype(std::forward(ref).*pmd) { return std::forward(ref).*pmd; } template inline auto INVOKE(PMD pmd, Pointer &&ptr) -> decltype((*std::forward(ptr)).*pmd) { return (*std::forward(ptr)).*pmd; } template inline auto INVOKE(T Base::*pmf, Derived &&ref, Args &&... args) -> decltype((std::forward(ref).*pmf)(std::forward(args)...)) { return (std::forward(ref).*pmf)(std::forward(args)...); } template inline auto INVOKE(PMF pmf, Pointer &&ptr, Args &&... args) -> decltype(((*std::forward(ptr)).*pmf)(std::forward(args)...)) { return ((*std::forward(ptr)).*pmf)(std::forward(args)...); } } // namespace detail namespace util { template decltype(auto) invoke(F &&f, ArgTypes &&... args) { return detail::INVOKE(std::forward(f), std::forward(args)...); } } // namespace util void Disable_Console_Output(); template bool ABORTS(F &&f, Args &&... args) { // pipe int fd[2]; pipe(fd); // spawn a new process auto child_pid = fork(); bool aborted = false; // if the fork succeeded if (child_pid >= 0) { // if we are in the child process if (child_pid == 0) { close(fd[0]); // call the function that we expect to abort Disable_Console_Output(); util::invoke(std::forward(f), std::forward(args)...); char succ[] = "1"; write(fd[1], succ, 2); // if the function didn't abort, we'll exit cleanly std::exit(EXIT_SUCCESS); } else { close(fd[1]); char buff[128]; int n = read(fd[0], buff, 127); aborted = n == 0; } } return aborted; } #else template bool ABORTS(F &&, Args &&...) { return true; } #endif