Index: libcxx/include/CMakeLists.txt =================================================================== --- libcxx/include/CMakeLists.txt +++ libcxx/include/CMakeLists.txt @@ -169,6 +169,7 @@ support/fuchsia/xlocale.h support/ibm/limits.h support/ibm/locale_mgmt_aix.h + support/ibm/nanosleep.h support/ibm/support.h support/ibm/xlocale.h support/musl/xlocale.h Index: libcxx/include/__threading_support =================================================================== --- libcxx/include/__threading_support +++ libcxx/include/__threading_support @@ -15,6 +15,10 @@ #include #include +#ifdef __MVS__ +#include +#endif + #ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER #pragma GCC system_header #endif Index: libcxx/include/support/ibm/nanosleep.h =================================================================== --- /dev/null +++ libcxx/include/support/ibm/nanosleep.h @@ -0,0 +1,38 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_ZOS_NANOSLEEP +#define _LIBCPP_ZOS_NANOSLEEP + +#include + +inline int nanosleep(const struct timespec* req, struct timespec* rem) +{ + // The nanosleep() function is not available on z/OS. Therefore, we will call + // sleep() to sleep for whole seconds and usleep() to sleep for any remaining + // fraction of a second. Any remaining nanoseconds will round up to the next + // microsecond. + + useconds_t __micro_sec = (rem->tv_nsec + 999) / 1000; + if (__micro_sec > 999999) + { + ++rem->tv_sec; + __micro_sec -= 1000000; + } + while (rem->tv_sec) + rem->tv_sec = sleep(rem->tv_sec); + if (__micro_sec) { + rem->tv_nsec = __micro_sec * 1000; + return usleep(__micro_sec); + } + rem->tv_nsec = 0; + return 0; +} + +#endif // _LIBCPP_ZOS_NANOSLEEP Index: libcxx/src/filesystem/filesystem_common.h =================================================================== --- libcxx/src/filesystem/filesystem_common.h +++ libcxx/src/filesystem/filesystem_common.h @@ -198,6 +198,7 @@ using chrono::duration_cast; using TimeSpec = struct ::timespec; +using TimeVal = struct ::timeval; using StatT = struct ::stat; template ; #if defined(__APPLE__) -TimeSpec extract_mtime(StatT const& st) { return st.st_mtimespec; } -TimeSpec extract_atime(StatT const& st) { return st.st_atimespec; } +inline TimeSpec extract_mtime(StatT const& st) { return st.st_mtimespec; } +inline TimeSpec extract_atime(StatT const& st) { return st.st_atimespec; } +#elif defined(__MVS__) +inline TimeSpec extract_mtime(StatT const& st) { + TimeSpec TS = {st.st_mtime, 0}; + return TS; +} +inline TimeSpec extract_atime(StatT const& st) { + TimeSpec TS = {st.st_atime, 0}; + return TS; +} #else -TimeSpec extract_mtime(StatT const& st) { return st.st_mtim; } -TimeSpec extract_atime(StatT const& st) { return st.st_atim; } +inline TimeSpec extract_mtime(StatT const& st) { return st.st_mtim; } +inline TimeSpec extract_atime(StatT const& st) { return st.st_atim; } #endif -// allow the utimes implementation to compile even it we're not going -// to use it. - -bool posix_utimes(const path& p, std::array const& TS, - error_code& ec) { +inline TimeVal make_timeval(TimeSpec const& ts) { using namespace chrono; auto Convert = [](long nsec) { - using int_type = decltype(std::declval< ::timeval>().tv_usec); + using int_type = decltype(std::declval().tv_usec); auto dur = duration_cast(nanoseconds(nsec)).count(); return static_cast(dur); }; - struct ::timeval ConvertedTS[2] = {{TS[0].tv_sec, Convert(TS[0].tv_nsec)}, - {TS[1].tv_sec, Convert(TS[1].tv_nsec)}}; + TimeVal TV = {}; + TV.tv_sec = ts.tv_sec; + TV.tv_usec = Convert(ts.tv_nsec); + return TV; +} + +inline bool posix_utimes(const path& p, std::array const& TS, + error_code& ec) { + TimeVal ConvertedTS[2] = {make_timeval(TS[0]), make_timeval(TS[1])}; if (::utimes(p.c_str(), ConvertedTS) == -1) { ec = capture_errno(); return true;