From f041812939db26215861af0364ea402dffbcda82 Mon Sep 17 00:00:00 2001 From: Andrew Gaul Date: Mon, 27 Nov 2023 00:51:17 +0900 Subject: [PATCH] Revert "Call C++11 get_time and put_time (#2375)" (#2381) This reverts commit 10a72bfd0f52bc70ad7f1dd6fbb92dbea376614c. These commit is incompatible with older CentOS 7 libstdc++. --- src/metaheader.cpp | 10 ++++------ src/s3fs_logger.cpp | 5 +++-- src/string_util.cpp | 42 ++++++++++++++++++++++++++++++------------ src/string_util.h | 6 ++++++ 4 files changed, 43 insertions(+), 20 deletions(-) diff --git a/src/metaheader.cpp b/src/metaheader.cpp index 90a4895..69e97e8 100644 --- a/src/metaheader.cpp +++ b/src/metaheader.cpp @@ -19,8 +19,6 @@ */ #include -#include -#include #include #include #include @@ -256,8 +254,8 @@ time_t cvtIAMExpireStringToTime(const char* s) if(!s){ return 0L; } - std::istringstream ss(s); - ss >> std::get_time(&tm, "%Y-%m-%dT%H:%M:%S"); + memset(&tm, 0, sizeof(struct tm)); + strptime(s, "%Y-%m-%dT%H:%M:%S", &tm); return timegm(&tm); // GMT } @@ -267,8 +265,8 @@ time_t get_lastmodified(const char* s) if(!s){ return -1; } - std::istringstream ss(s); - ss >> std::get_time(&tm, "%a, %d %b %Y %H:%M:%S %Z"); + memset(&tm, 0, sizeof(struct tm)); + strptime(s, "%a, %d %b %Y %H:%M:%S %Z", &tm); return timegm(&tm); // GMT } diff --git a/src/s3fs_logger.cpp b/src/s3fs_logger.cpp index ddee301..12b93cb 100644 --- a/src/s3fs_logger.cpp +++ b/src/s3fs_logger.cpp @@ -54,14 +54,15 @@ std::string S3fsLog::GetCurrentTime() struct timeval now; struct timespec tsnow; struct tm res; + char tmp[32]; if(-1 == clock_gettime(S3FS_CLOCK_MONOTONIC, &tsnow)){ now.tv_sec = tsnow.tv_sec; now.tv_usec = (tsnow.tv_nsec / 1000); }else{ gettimeofday(&now, nullptr); } - current_time << std::put_time(gmtime_r(&now.tv_sec, &res), "%Y-%m-%dT%H:%M:%S") - << "." << std::setfill('0') << std::setw(3) << (now.tv_usec / 1000) << "Z "; + strftime(tmp, sizeof(tmp), "%Y-%m-%dT%H:%M:%S", gmtime_r(&now.tv_sec, &res)); + current_time << tmp << "." << std::setfill('0') << std::setw(3) << (now.tv_usec / 1000) << "Z "; } return current_time.str(); } diff --git a/src/string_util.cpp b/src/string_util.cpp index 235f912..a1ab4cd 100644 --- a/src/string_util.cpp +++ b/src/string_util.cpp @@ -23,6 +23,7 @@ #include #include #include + #include #include "s3fs_logger.h" @@ -46,6 +47,24 @@ std::string str(const struct timespec value) return s.str(); } +#ifdef __MSYS__ +/* + * Polyfill for strptime function + * + * This source code is from https://gist.github.com/jeremyfromearth/5694aa3a66714254752179ecf3c95582 . + */ +char* strptime(const char* s, const char* f, struct tm* tm) +{ + std::istringstream input(s); + input.imbue(std::locale(setlocale(LC_ALL, nullptr))); + input >> std::get_time(tm, f); + if (input.fail()) { + return nullptr; + } + return (char*)(s + input.tellg()); +} +#endif + bool s3fs_strtoofft(off_t* value, const char* str, int base) { if(value == nullptr || str == nullptr){ @@ -240,11 +259,11 @@ bool get_keyword_value(const std::string& target, const char* keyword, std::stri // std::string get_date_rfc850() { - std::ostringstream ss; + char buf[100]; time_t t = time(nullptr); struct tm res; - ss << std::put_time(gmtime_r(&t, &res), "%a, %d %b %Y %H:%M:%S GMT"); - return ss.str(); + strftime(buf, sizeof(buf), "%a, %d %b %Y %H:%M:%S GMT", gmtime_r(&t, &res)); + return buf; } void get_date_sigv3(std::string& date, std::string& date8601) @@ -256,18 +275,18 @@ void get_date_sigv3(std::string& date, std::string& date8601) std::string get_date_string(time_t tm) { - std::ostringstream ss; + char buf[100]; struct tm res; - ss << std::put_time(gmtime_r(&tm, &res), "%Y%m%d"); - return ss.str(); + strftime(buf, sizeof(buf), "%Y%m%d", gmtime_r(&tm, &res)); + return buf; } std::string get_date_iso8601(time_t tm) { - std::ostringstream s; + char buf[100]; struct tm res; - s << std::put_time(gmtime_r(&tm, &res), "%Y%m%dT%H%M%SZ"); - return s.str(); + strftime(buf, sizeof(buf), "%Y%m%dT%H%M%SZ", gmtime_r(&tm, &res)); + return buf; } bool get_unixtime_from_iso8601(const char* pdate, time_t& unixtime) @@ -277,9 +296,8 @@ bool get_unixtime_from_iso8601(const char* pdate, time_t& unixtime) } struct tm tm; - std::istringstream ss(pdate); - ss >> std::get_time(&tm, "%Y-%m-%dT%T"); - if(ss.fail()){ + const char* prest = strptime(pdate, "%Y-%m-%dT%T", &tm); + if(prest == pdate){ // wrong format return false; } diff --git a/src/string_util.h b/src/string_util.h index e2eeaf6..2577d49 100644 --- a/src/string_util.h +++ b/src/string_util.h @@ -55,6 +55,12 @@ static inline const char* SAFESTRPTR(const char *strptr) { return strptr ? strpt // TODO: rename to to_string? std::string str(const struct timespec value); +#ifdef __MSYS__ +// +// Polyfill for strptime function. +// +char* strptime(const char* s, const char* f, struct tm* tm); +#endif // // Convert string to off_t. Returns false on bad input. // Replacement for C++11 std::stoll.