| From 5234a25254d53034f8706ac172f32fffdd237a69 Mon Sep 17 00:00:00 2001 |
| From: Chih-Hung Hsieh <chh@google.com> |
| Date: Mon, 22 Feb 2021 15:57:50 -0800 |
| Subject: [PATCH] Revert babd3aefc91 and 6 changes after it. |
| |
| * Revert "[libcxx] Avoid overflows in the windows __libcpp_steady_clock_now()" |
| This reverts commit 02f1d28ed6b8f33445dae3beed8b6cc8dada4312. |
| |
| * Revert "[libc++] NFCI: Refactor chrono.cpp to make it easier to support new platforms" |
| This reverts commit 2dec36e5326eae08507464bbe19bf1004898293a. |
| |
| * Revert "[libc++] Check _LIBCPP_USE_CLOCK_GETTIME before using clock_gettime" |
| This reverts commit f78bb4d84eee55c5d3bb1f3322c1e346e3388572. |
| |
| * Revert "[libcxx] Avoid double frees of file descriptors in the fallback ifstream/ofstream codepath" |
| This reverts commit 08b4cc5e0d2625e85ed4af9aad17ccc0876e3bd3. |
| |
| * Revert "[libc++] Fix a few warnings" |
| This reverts commit acd7be74ca12f8f08e52d6d80850a9b230109134. |
| |
| * Revert "[libc++][filesystem] Only include <fstream> when we actually need it in copy_file_impl" |
| This reverts commit 17dcf85ebe4cfbd3f811848f6d9ebc486b3387e9. |
| |
| * Revert "[libc++] Remove workarounds for the lack of clock_gettime on older macOS platforms" |
| This reverts commit babd3aefc9193b44ad0620a2cfd63ebb6ad7e952. |
| --- |
| libcxx/docs/index.rst | 35 +--- |
| libcxx/src/chrono.cpp | 188 +++++++++++------- |
| libcxx/src/filesystem/operations.cpp | 186 +++++++++-------- |
| libcxx/src/include/apple_availability.h | 18 ++ |
| libcxx/src/locale.cpp | 2 +- |
| .../time.clock/time.clock.steady/now.pass.cpp | 2 - |
| 6 files changed, 250 insertions(+), 181 deletions(-) |
| |
| diff --git a/libcxx/docs/index.rst b/libcxx/docs/index.rst |
| index ecece32228d9..7fee601fdf67 100644 |
| --- a/libcxx/docs/index.rst |
| +++ b/libcxx/docs/index.rst |
| @@ -92,46 +92,25 @@ reasons, but some of the major ones are: |
| Platform and Compiler Support |
| ----------------------------- |
| |
| -For using the libc++ headers |
| -############################ |
| -The libc++ headers are known to work on the following platforms, using GCC and |
| -Clang. Note that functionality provided by ``<atomic>`` is only functional with |
| -Clang and GCC. |
| - |
| -============ ==================== ============ |
| -OS Arch Compilers |
| -============ ==================== ============ |
| -macOS 10.9+ i386, x86_64 Clang, GCC |
| -FreeBSD 10+ i386, x86_64, ARM Clang, GCC |
| -Linux i386, x86_64 Clang, GCC |
| -============ ==================== ============ |
| - |
| -The following minimum compiler versions are required: |
| - |
| -* Clang 4.0 and above |
| -* GCC 5.0 and above. |
| - |
| -The C++03 dialect is only supported with Clang. |
| - |
| -For building the libc++ library |
| -############################### |
| -Building the libc++ library (static or shared) requires some features from |
| -the operating system. As such, it has its own set of (slightly different) |
| -system requirements. |
| +libc++ is known to work on the following platforms, using gcc and |
| +clang. |
| +Note that functionality provided by ``<atomic>`` is only functional with clang |
| +and GCC. |
| |
| ============ ==================== ============ ======================== |
| OS Arch Compilers ABI Library |
| ============ ==================== ============ ======================== |
| -macOS 10.12+ i386, x86_64 Clang, GCC libc++abi |
| +macOS i386, x86_64 Clang, GCC libc++abi |
| FreeBSD 10+ i386, x86_64, ARM Clang, GCC libcxxrt, libc++abi |
| Linux i386, x86_64 Clang, GCC libc++abi |
| ============ ==================== ============ ======================== |
| |
| -The following minimum compiler versions are required: |
| +The following minimum compiler versions are strongly recommended. |
| |
| * Clang 4.0 and above |
| * GCC 5.0 and above. |
| |
| +The C++03 dialect is only supported for Clang compilers. |
| |
| C++ Dialect Support |
| --------------------- |
| diff --git a/libcxx/src/chrono.cpp b/libcxx/src/chrono.cpp |
| index 5291d4fa8dc6..a1a456faf2d3 100644 |
| --- a/libcxx/src/chrono.cpp |
| +++ b/libcxx/src/chrono.cpp |
| @@ -9,32 +9,40 @@ |
| #include "chrono" |
| #include "cerrno" // errno |
| #include "system_error" // __throw_system_error |
| -#include <time.h> // clock_gettime and CLOCK_{MONOTONIC,REALTIME,MONOTONIC_RAW} |
| +#include <time.h> // clock_gettime, CLOCK_MONOTONIC and CLOCK_REALTIME |
| #include "include/apple_availability.h" |
| |
| #if __has_include(<unistd.h>) |
| -# include <unistd.h> |
| -#endif |
| - |
| -#if __has_include(<sys/time.h>) |
| -# include <sys/time.h> // for gettimeofday and timeval |
| +#include <unistd.h> |
| #endif |
| |
| #if !defined(__APPLE__) && _POSIX_TIMERS > 0 |
| -# define _LIBCPP_USE_CLOCK_GETTIME |
| +#define _LIBCPP_USE_CLOCK_GETTIME |
| #endif |
| |
| #if defined(_LIBCPP_WIN32API) |
| -# define WIN32_LEAN_AND_MEAN |
| -# define VC_EXTRA_LEAN |
| -# include <windows.h> |
| -# if _WIN32_WINNT >= _WIN32_WINNT_WIN8 |
| -# include <winapifamily.h> |
| -# endif |
| +#define WIN32_LEAN_AND_MEAN |
| +#define VC_EXTRA_LEAN |
| +#include <windows.h> |
| +#if _WIN32_WINNT >= _WIN32_WINNT_WIN8 |
| +#include <winapifamily.h> |
| +#endif |
| +#else |
| +#if !defined(CLOCK_REALTIME) || !defined(_LIBCPP_USE_CLOCK_GETTIME) |
| +#include <sys/time.h> // for gettimeofday and timeval |
| +#endif |
| #endif // defined(_LIBCPP_WIN32API) |
| |
| +#if !defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK) |
| +#if __APPLE__ |
| +#include <mach/mach_time.h> // mach_absolute_time, mach_timebase_info_data_t |
| +#elif !defined(_LIBCPP_WIN32API) && !defined(CLOCK_MONOTONIC) |
| +#error "Monotonic clock not implemented" |
| +#endif |
| +#endif |
| + |
| #if defined(__ELF__) && defined(_LIBCPP_LINK_RT_LIB) |
| -# pragma comment(lib, "rt") |
| +#pragma comment(lib, "rt") |
| #endif |
| |
| _LIBCPP_BEGIN_NAMESPACE_STD |
| @@ -42,13 +50,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| namespace chrono |
| { |
| |
| -// |
| // system_clock |
| -// |
| |
| -#if defined(_LIBCPP_WIN32API) |
| +const bool system_clock::is_steady; |
| |
| -static system_clock::time_point __libcpp_system_clock_now() { |
| +system_clock::time_point |
| +system_clock::now() _NOEXCEPT |
| +{ |
| +#if defined(_LIBCPP_WIN32API) |
| // FILETIME is in 100ns units |
| using filetime_duration = |
| _VSTD::chrono::duration<__int64, |
| @@ -59,42 +68,31 @@ static system_clock::time_point __libcpp_system_clock_now() { |
| static _LIBCPP_CONSTEXPR const seconds nt_to_unix_epoch{11644473600}; |
| |
| FILETIME ft; |
| -#if _WIN32_WINNT >= _WIN32_WINNT_WIN8 && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) |
| +#if _WIN32_WINNT >= _WIN32_WINNT_WIN8 |
| +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) |
| GetSystemTimePreciseAsFileTime(&ft); |
| +#else |
| + GetSystemTimeAsFileTime(&ft); |
| +#endif |
| #else |
| GetSystemTimeAsFileTime(&ft); |
| #endif |
| |
| filetime_duration d{(static_cast<__int64>(ft.dwHighDateTime) << 32) | |
| static_cast<__int64>(ft.dwLowDateTime)}; |
| - return system_clock::time_point(duration_cast<system_clock::duration>(d - nt_to_unix_epoch)); |
| -} |
| - |
| -#elif defined(CLOCK_REALTIME) && defined(_LIBCPP_USE_CLOCK_GETTIME) |
| - |
| -static system_clock::time_point __libcpp_system_clock_now() { |
| + return time_point(duration_cast<duration>(d - nt_to_unix_epoch)); |
| +#else |
| +#if defined(_LIBCPP_USE_CLOCK_GETTIME) && defined(CLOCK_REALTIME) |
| struct timespec tp; |
| if (0 != clock_gettime(CLOCK_REALTIME, &tp)) |
| __throw_system_error(errno, "clock_gettime(CLOCK_REALTIME) failed"); |
| - return system_clock::time_point(seconds(tp.tv_sec) + microseconds(tp.tv_nsec / 1000)); |
| -} |
| - |
| + return time_point(seconds(tp.tv_sec) + microseconds(tp.tv_nsec / 1000)); |
| #else |
| - |
| -static system_clock::time_point __libcpp_system_clock_now() { |
| timeval tv; |
| gettimeofday(&tv, 0); |
| - return system_clock::time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec)); |
| -} |
| - |
| + return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec)); |
| +#endif // _LIBCPP_USE_CLOCK_GETTIME && CLOCK_REALTIME |
| #endif |
| - |
| -const bool system_clock::is_steady; |
| - |
| -system_clock::time_point |
| -system_clock::now() _NOEXCEPT |
| -{ |
| - return __libcpp_system_clock_now(); |
| } |
| |
| time_t |
| @@ -109,29 +107,81 @@ system_clock::from_time_t(time_t t) _NOEXCEPT |
| return system_clock::time_point(seconds(t)); |
| } |
| |
| -// |
| +#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK |
| // steady_clock |
| // |
| // Warning: If this is not truly steady, then it is non-conforming. It is |
| // better for it to not exist and have the rest of libc++ use system_clock |
| // instead. |
| -// |
| |
| -#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK |
| +const bool steady_clock::is_steady; |
| |
| #if defined(__APPLE__) |
| |
| -// On Apple platforms, only CLOCK_UPTIME_RAW, CLOCK_MONOTONIC_RAW or |
| -// mach_absolute_time are able to time functions in the nanosecond range. |
| -// Furthermore, only CLOCK_MONOTONIC_RAW is truly monotonic, because it |
| -// also counts cycles when the system is asleep. Thus, it is the only |
| -// acceptable implementation of steady_clock. |
| -static steady_clock::time_point __libcpp_steady_clock_now() { |
| +// Darwin libc versions >= 1133 provide ns precision via CLOCK_MONOTONIC_RAW |
| +#if defined(_LIBCPP_USE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC_RAW) |
| +steady_clock::time_point |
| +steady_clock::now() _NOEXCEPT |
| +{ |
| struct timespec tp; |
| if (0 != clock_gettime(CLOCK_MONOTONIC_RAW, &tp)) |
| __throw_system_error(errno, "clock_gettime(CLOCK_MONOTONIC_RAW) failed"); |
| - return steady_clock::time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec)); |
| + return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec)); |
| +} |
| + |
| +#else |
| +// mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of |
| +// nanoseconds since the computer booted up. MachInfo.numer and MachInfo.denom |
| +// are run time constants supplied by the OS. This clock has no relationship |
| +// to the Gregorian calendar. It's main use is as a high resolution timer. |
| + |
| +// MachInfo.numer / MachInfo.denom is often 1 on the latest equipment. Specialize |
| +// for that case as an optimization. |
| + |
| +static |
| +steady_clock::rep |
| +steady_simplified() |
| +{ |
| + return static_cast<steady_clock::rep>(mach_absolute_time()); |
| +} |
| + |
| +static |
| +double |
| +compute_steady_factor() |
| +{ |
| + mach_timebase_info_data_t MachInfo; |
| + mach_timebase_info(&MachInfo); |
| + return static_cast<double>(MachInfo.numer) / MachInfo.denom; |
| +} |
| + |
| +static |
| +steady_clock::rep |
| +steady_full() |
| +{ |
| + static const double factor = compute_steady_factor(); |
| + return static_cast<steady_clock::rep>(mach_absolute_time() * factor); |
| +} |
| + |
| +typedef steady_clock::rep (*FP)(); |
| + |
| +static |
| +FP |
| +init_steady_clock() |
| +{ |
| + mach_timebase_info_data_t MachInfo; |
| + mach_timebase_info(&MachInfo); |
| + if (MachInfo.numer == MachInfo.denom) |
| + return &steady_simplified; |
| + return &steady_full; |
| +} |
| + |
| +steady_clock::time_point |
| +steady_clock::now() _NOEXCEPT |
| +{ |
| + static FP fp = init_steady_clock(); |
| + return time_point(duration(fp())); |
| } |
| +#endif // defined(_LIBCPP_USE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC_RAW) |
| |
| #elif defined(_LIBCPP_WIN32API) |
| |
| @@ -143,43 +193,43 @@ static steady_clock::time_point __libcpp_steady_clock_now() { |
| static LARGE_INTEGER |
| __QueryPerformanceFrequency() |
| { |
| - LARGE_INTEGER val; |
| - (void) QueryPerformanceFrequency(&val); |
| - return val; |
| + LARGE_INTEGER val; |
| + (void) QueryPerformanceFrequency(&val); |
| + return val; |
| } |
| |
| -static steady_clock::time_point __libcpp_steady_clock_now() { |
| +steady_clock::time_point |
| +steady_clock::now() _NOEXCEPT |
| +{ |
| static const LARGE_INTEGER freq = __QueryPerformanceFrequency(); |
| |
| LARGE_INTEGER counter; |
| (void) QueryPerformanceCounter(&counter); |
| - auto seconds = counter.QuadPart / freq.QuadPart; |
| - auto fractions = counter.QuadPart % freq.QuadPart; |
| - auto dur = seconds * nano::den + fractions * nano::den / freq.QuadPart; |
| - return steady_clock::time_point(steady_clock::duration(dur)); |
| + return time_point(duration(counter.QuadPart * nano::den / freq.QuadPart)); |
| } |
| |
| #elif defined(CLOCK_MONOTONIC) |
| |
| -static steady_clock::time_point __libcpp_steady_clock_now() { |
| +// On Apple platforms only CLOCK_UPTIME_RAW, CLOCK_MONOTONIC_RAW or |
| +// mach_absolute_time are able to time functions in the nanosecond range. |
| +// Thus, they are the only acceptable implementations of steady_clock. |
| +#ifdef __APPLE__ |
| +#error "Never use CLOCK_MONOTONIC for steady_clock::now on Apple platforms" |
| +#endif |
| + |
| +steady_clock::time_point |
| +steady_clock::now() _NOEXCEPT |
| +{ |
| struct timespec tp; |
| if (0 != clock_gettime(CLOCK_MONOTONIC, &tp)) |
| __throw_system_error(errno, "clock_gettime(CLOCK_MONOTONIC) failed"); |
| - return steady_clock::time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec)); |
| + return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec)); |
| } |
| |
| #else |
| -# error "Monotonic clock not implemented on this platform" |
| +#error "Monotonic clock not implemented" |
| #endif |
| |
| -const bool steady_clock::is_steady; |
| - |
| -steady_clock::time_point |
| -steady_clock::now() _NOEXCEPT |
| -{ |
| - return __libcpp_steady_clock_now(); |
| -} |
| - |
| #endif // !_LIBCPP_HAS_NO_MONOTONIC_CLOCK |
| |
| } |
| diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp |
| index 7db2d1ff0074..12cf5b399e90 100644 |
| --- a/libcxx/src/filesystem/operations.cpp |
| +++ b/libcxx/src/filesystem/operations.cpp |
| @@ -9,6 +9,7 @@ |
| #include "filesystem" |
| #include "array" |
| #include "iterator" |
| +#include "fstream" |
| #include "string_view" |
| #include "type_traits" |
| #include "vector" |
| @@ -29,23 +30,33 @@ |
| #include <time.h> |
| #include <fcntl.h> /* values for fchmodat */ |
| |
| -#if __has_include(<sys/sendfile.h>) |
| -# include <sys/sendfile.h> |
| -# define _LIBCPP_FILESYSTEM_USE_SENDFILE |
| +#if defined(__linux__) |
| +#include <linux/version.h> |
| +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33) |
| +#include <sys/sendfile.h> |
| +#define _LIBCPP_USE_SENDFILE |
| +#endif |
| #elif defined(__APPLE__) || __has_include(<copyfile.h>) |
| -# include <copyfile.h> |
| -# define _LIBCPP_FILESYSTEM_USE_COPYFILE |
| -#else |
| -# include "fstream" |
| -# define _LIBCPP_FILESYSTEM_USE_FSTREAM |
| +#include <copyfile.h> |
| +#define _LIBCPP_USE_COPYFILE |
| #endif |
| |
| -#if !defined(CLOCK_REALTIME) |
| -# include <sys/time.h> // for gettimeofday and timeval |
| +#if !defined(__APPLE__) && _POSIX_TIMERS > 0 |
| +#define _LIBCPP_USE_CLOCK_GETTIME |
| #endif |
| |
| +#if !defined(CLOCK_REALTIME) || !defined(_LIBCPP_USE_CLOCK_GETTIME) |
| +#include <sys/time.h> // for gettimeofday and timeval |
| +#endif // !defined(CLOCK_REALTIME) |
| + |
| #if defined(__ELF__) && defined(_LIBCPP_LINK_RT_LIB) |
| -# pragma comment(lib, "rt") |
| +#pragma comment(lib, "rt") |
| +#endif |
| + |
| +#if defined(_LIBCPP_COMPILER_GCC) |
| +#if _GNUC_VER < 500 |
| +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" |
| +#endif |
| #endif |
| |
| _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM |
| @@ -565,7 +576,7 @@ const bool _FilesystemClock::is_steady; |
| |
| _FilesystemClock::time_point _FilesystemClock::now() noexcept { |
| typedef chrono::duration<rep> __secs; |
| -#if defined(CLOCK_REALTIME) |
| +#if defined(_LIBCPP_USE_CLOCK_GETTIME) && defined(CLOCK_REALTIME) |
| typedef chrono::duration<rep, nano> __nsecs; |
| struct timespec tp; |
| if (0 != clock_gettime(CLOCK_REALTIME, &tp)) |
| @@ -577,7 +588,7 @@ _FilesystemClock::time_point _FilesystemClock::now() noexcept { |
| timeval tv; |
| gettimeofday(&tv, 0); |
| return time_point(__secs(tv.tv_sec) + __microsecs(tv.tv_usec)); |
| -#endif // CLOCK_REALTIME |
| +#endif // _LIBCPP_USE_CLOCK_GETTIME && CLOCK_REALTIME |
| } |
| |
| filesystem_error::~filesystem_error() {} |
| @@ -627,7 +638,7 @@ path __canonical(path const& orig_p, error_code* ec) { |
| ErrorHandler<path> err("canonical", ec, &orig_p, &cwd); |
| |
| path p = __do_absolute(orig_p, &cwd, ec); |
| -#if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112 |
| +#if _POSIX_VERSION >= 200112 |
| std::unique_ptr<char, decltype(&::free)> |
| hold(::realpath(p.c_str(), nullptr), &::free); |
| if (hold.get() == nullptr) |
| @@ -731,83 +742,96 @@ void __copy(const path& from, const path& to, copy_options options, |
| namespace detail { |
| namespace { |
| |
| -#if defined(_LIBCPP_FILESYSTEM_USE_SENDFILE) |
| - bool copy_file_impl(FileDescriptor& read_fd, FileDescriptor& write_fd, error_code& ec) { |
| - size_t count = read_fd.get_stat().st_size; |
| - do { |
| - ssize_t res; |
| - if ((res = ::sendfile(write_fd.fd, read_fd.fd, nullptr, count)) == -1) { |
| - ec = capture_errno(); |
| - return false; |
| - } |
| - count -= res; |
| - } while (count > 0); |
| - |
| - ec.clear(); |
| - |
| - return true; |
| - } |
| -#elif defined(_LIBCPP_FILESYSTEM_USE_COPYFILE) |
| - bool copy_file_impl(FileDescriptor& read_fd, FileDescriptor& write_fd, error_code& ec) { |
| - struct CopyFileState { |
| - copyfile_state_t state; |
| - CopyFileState() { state = copyfile_state_alloc(); } |
| - ~CopyFileState() { copyfile_state_free(state); } |
| - |
| - private: |
| - CopyFileState(CopyFileState const&) = delete; |
| - CopyFileState& operator=(CopyFileState const&) = delete; |
| - }; |
| +#ifdef _LIBCPP_USE_SENDFILE |
| +bool copy_file_impl_sendfile(FileDescriptor& read_fd, FileDescriptor& write_fd, |
| + error_code& ec) { |
| |
| - CopyFileState cfs; |
| - if (fcopyfile(read_fd.fd, write_fd.fd, cfs.state, COPYFILE_DATA) < 0) { |
| + size_t count = read_fd.get_stat().st_size; |
| + do { |
| + ssize_t res; |
| + if ((res = ::sendfile(write_fd.fd, read_fd.fd, nullptr, count)) == -1) { |
| ec = capture_errno(); |
| return false; |
| } |
| + count -= res; |
| + } while (count > 0); |
| |
| - ec.clear(); |
| - return true; |
| + ec.clear(); |
| + |
| + return true; |
| +} |
| +#elif defined(_LIBCPP_USE_COPYFILE) |
| +bool copy_file_impl_copyfile(FileDescriptor& read_fd, FileDescriptor& write_fd, |
| + error_code& ec) { |
| + struct CopyFileState { |
| + copyfile_state_t state; |
| + CopyFileState() { state = copyfile_state_alloc(); } |
| + ~CopyFileState() { copyfile_state_free(state); } |
| + |
| + private: |
| + CopyFileState(CopyFileState const&) = delete; |
| + CopyFileState& operator=(CopyFileState const&) = delete; |
| + }; |
| + |
| + CopyFileState cfs; |
| + if (fcopyfile(read_fd.fd, write_fd.fd, cfs.state, COPYFILE_DATA) < 0) { |
| + ec = capture_errno(); |
| + return false; |
| } |
| -#elif defined(_LIBCPP_FILESYSTEM_USE_FSTREAM) |
| - bool copy_file_impl(FileDescriptor& read_fd, FileDescriptor& write_fd, error_code& ec) { |
| - ifstream in; |
| - in.__open(read_fd.fd, ios::binary); |
| - if (!in.is_open()) { |
| - // This assumes that __open didn't reset the error code. |
| - ec = capture_errno(); |
| - return false; |
| - } |
| - read_fd.fd = -1; |
| - ofstream out; |
| - out.__open(write_fd.fd, ios::binary); |
| - if (!out.is_open()) { |
| - ec = capture_errno(); |
| - return false; |
| - } |
| - write_fd.fd = -1; |
| - |
| - if (in.good() && out.good()) { |
| - using InIt = istreambuf_iterator<char>; |
| - using OutIt = ostreambuf_iterator<char>; |
| - InIt bin(in); |
| - InIt ein; |
| - OutIt bout(out); |
| - copy(bin, ein, bout); |
| - } |
| - if (out.fail() || in.fail()) { |
| - ec = make_error_code(errc::io_error); |
| - return false; |
| - } |
| |
| - ec.clear(); |
| - return true; |
| + ec.clear(); |
| + return true; |
| +} |
| +#endif |
| + |
| +// Note: This function isn't guarded by ifdef's even though it may be unused |
| +// in order to assure it still compiles. |
| +__attribute__((unused)) bool copy_file_impl_default(FileDescriptor& read_fd, |
| + FileDescriptor& write_fd, |
| + error_code& ec) { |
| + ifstream in; |
| + in.__open(read_fd.fd, ios::binary); |
| + if (!in.is_open()) { |
| + // This assumes that __open didn't reset the error code. |
| + ec = capture_errno(); |
| + return false; |
| + } |
| + ofstream out; |
| + out.__open(write_fd.fd, ios::binary); |
| + if (!out.is_open()) { |
| + ec = capture_errno(); |
| + return false; |
| + } |
| + |
| + if (in.good() && out.good()) { |
| + using InIt = istreambuf_iterator<char>; |
| + using OutIt = ostreambuf_iterator<char>; |
| + InIt bin(in); |
| + InIt ein; |
| + OutIt bout(out); |
| + copy(bin, ein, bout); |
| + } |
| + if (out.fail() || in.fail()) { |
| + ec = make_error_code(errc::io_error); |
| + return false; |
| } |
| + |
| + ec.clear(); |
| + return true; |
| +} |
| + |
| +bool copy_file_impl(FileDescriptor& from, FileDescriptor& to, error_code& ec) { |
| +#if defined(_LIBCPP_USE_SENDFILE) |
| + return copy_file_impl_sendfile(from, to, ec); |
| +#elif defined(_LIBCPP_USE_COPYFILE) |
| + return copy_file_impl_copyfile(from, to, ec); |
| #else |
| -# error "Unknown implementation for copy_file_impl" |
| -#endif // copy_file_impl implementation |
| + return copy_file_impl_default(from, to, ec); |
| +#endif |
| +} |
| |
| -} // end anonymous namespace |
| -} // end namespace detail |
| +} // namespace |
| +} // namespace detail |
| |
| bool __copy_file(const path& from, const path& to, copy_options options, |
| error_code* ec) { |
| diff --git a/libcxx/src/include/apple_availability.h b/libcxx/src/include/apple_availability.h |
| index 0f999d3feafb..f0a5800e8f3a 100644 |
| --- a/libcxx/src/include/apple_availability.h |
| +++ b/libcxx/src/include/apple_availability.h |
| @@ -28,6 +28,24 @@ |
| #endif |
| #endif // __ENVIRONMENT_.*_VERSION_MIN_REQUIRED__ |
| |
| +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) |
| +#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101200 |
| +#define _LIBCPP_USE_CLOCK_GETTIME |
| +#endif |
| +#elif defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) |
| +#if __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 100000 |
| +#define _LIBCPP_USE_CLOCK_GETTIME |
| +#endif |
| +#elif defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) |
| +#if __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ >= 100000 |
| +#define _LIBCPP_USE_CLOCK_GETTIME |
| +#endif |
| +#elif defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) |
| +#if __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ >= 30000 |
| +#define _LIBCPP_USE_CLOCK_GETTIME |
| +#endif |
| +#endif // __ENVIRONMENT_.*_VERSION_MIN_REQUIRED__ |
| + |
| #if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) |
| #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101500 |
| #define _LIBCPP_USE_ULOCK |
| diff --git a/libcxx/src/locale.cpp b/libcxx/src/locale.cpp |
| index f109389f68f3..1bab117ca5c2 100644 |
| --- a/libcxx/src/locale.cpp |
| +++ b/libcxx/src/locale.cpp |
| @@ -1173,7 +1173,7 @@ ctype<char>::__classic_upper_table() _NOEXCEPT |
| { |
| return _LIBCPP_GET_C_LOCALE->__ctype_toupper; |
| } |
| -#elif defined(__NetBSD__) |
| +#elif __NetBSD__ |
| const short* |
| ctype<char>::__classic_lower_table() _NOEXCEPT |
| { |
| diff --git a/libcxx/test/std/utilities/time/time.clock/time.clock.steady/now.pass.cpp b/libcxx/test/std/utilities/time/time.clock/time.clock.steady/now.pass.cpp |
| index 14dc9a9832dc..4b8104dd1a6f 100644 |
| --- a/libcxx/test/std/utilities/time/time.clock/time.clock.steady/now.pass.cpp |
| +++ b/libcxx/test/std/utilities/time/time.clock/time.clock.steady/now.pass.cpp |
| @@ -25,8 +25,6 @@ int main(int, char**) |
| C::time_point t1 = C::now(); |
| C::time_point t2 = C::now(); |
| assert(t2 >= t1); |
| - // make sure t2 didn't wrap around |
| - assert(t2 > std::chrono::time_point<C>()); |
| |
| return 0; |
| } |
| -- |
| 2.30.0.617.g56c4b15f3c-goog |
| |