diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -149,6 +149,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 diff --git a/libcxx/include/__threading_support b/libcxx/include/__threading_support --- a/libcxx/include/__threading_support +++ b/libcxx/include/__threading_support @@ -16,6 +16,10 @@ #include #include +#ifdef __MVS__ +# include +#endif + #ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER #pragma GCC system_header #endif diff --git a/libcxx/include/support/ibm/nanosleep.h b/libcxx/include/support/ibm/nanosleep.h new file mode 100644 --- /dev/null +++ b/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_SUPPORT_IBM_NANOSLEEP_H +#define _LIBCPP_SUPPORT_IBM_NANOSLEEP_H + +#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_SUPPORT_IBM_NANOSLEEP_H diff --git a/libcxx/src/filesystem/filesystem_common.h b/libcxx/src/filesystem/filesystem_common.h --- a/libcxx/src/filesystem/filesystem_common.h +++ b/libcxx/src/filesystem/filesystem_common.h @@ -198,7 +198,8 @@ using chrono::duration; using chrono::duration_cast; -using TimeSpec = timespec; +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;