From: Max Kellermann Date: Fri, 4 Oct 2024 13:34:00 +0000 (+0200) Subject: include/utime: un-inline several functions to reduce header dependencies X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=192e9691c520cb458129e88b18bc2f72d245e3f2;p=ceph.git include/utime: un-inline several functions to reduce header dependencies Signed-off-by: Max Kellermann --- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 88fd41b9640..b4a467ef129 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -500,6 +500,8 @@ set(libcommon_files ceph_ver.c global/global_context.cc xxHash/xxhash.c + include/invoke_date.cc + include/utime.cc common/error_code.cc common/tracer.cc log/Log.cc diff --git a/src/crimson/CMakeLists.txt b/src/crimson/CMakeLists.txt index ce9b44cb0d9..46c6aa54e5c 100644 --- a/src/crimson/CMakeLists.txt +++ b/src/crimson/CMakeLists.txt @@ -97,6 +97,7 @@ add_library(crimson-common STATIC ${PROJECT_SOURCE_DIR}/src/crush/CrushTester.cc ${PROJECT_SOURCE_DIR}/src/global/global_context.cc ${PROJECT_SOURCE_DIR}/src/global/pidfile.cc + ${PROJECT_SOURCE_DIR}/src/include/utime.cc ${PROJECT_SOURCE_DIR}/src/librbd/Features.cc ${PROJECT_SOURCE_DIR}/src/librbd/io/IoOperations.cc ${PROJECT_SOURCE_DIR}/src/mgr/ServiceMap.cc diff --git a/src/include/invoke_date.cc b/src/include/invoke_date.cc new file mode 100644 index 00000000000..4680b3cd7ed --- /dev/null +++ b/src/include/invoke_date.cc @@ -0,0 +1,47 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2019 Red Hat + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#include "utime.h" +#include "common/safe_io.h" +#include "common/SubProcess.h" + +#include + +#include + +int utime_t::invoke_date(const std::string& date_str, utime_t *result) { + char buf[256]; + + SubProcess bin_date("/bin/date", SubProcess::CLOSE, SubProcess::PIPE, + SubProcess::KEEP); + bin_date.add_cmd_args("-d", date_str.c_str(), "+%s %N", NULL); + + int r = bin_date.spawn(); + if (r < 0) return r; + + ssize_t n = safe_read(bin_date.get_stdout(), buf, sizeof(buf)); + + r = bin_date.join(); + if (r || n <= 0) return -EINVAL; + + uint64_t epoch, nsec; + std::istringstream iss(buf); + + iss >> epoch; + iss >> nsec; + + *result = utime_t(epoch, nsec); + + return 0; +} diff --git a/src/include/utime.cc b/src/include/utime.cc index 2252a1ca4fd..4f9658ebf78 100644 --- a/src/include/utime.cc +++ b/src/include/utime.cc @@ -14,6 +14,10 @@ #include "utime.h" #include "common/Formatter.h" +#include "common/strtol.h" +#include "include/timegm.h" + +#include void utime_t::dump(ceph::Formatter *f) const { @@ -29,3 +33,110 @@ void utime_t::generate_test_instances(std::list& o) o.push_back(new utime_t()); o.back()->tv.tv_nsec = static_cast<__u32>((1L << 32) - 1); } + +int utime_t::parse_date(const std::string& date, uint64_t *epoch, uint64_t *nsec, + std::string *out_date, + std::string *out_time) { + struct tm tm; + memset(&tm, 0, sizeof(tm)); + + if (nsec) + *nsec = 0; + + const char *p = strptime(date.c_str(), "%Y-%m-%d", &tm); + if (p) { + if (*p == ' ' || *p == 'T') { + p++; + // strptime doesn't understand fractional/decimal seconds, and + // it also only takes format chars or literals, so we have to + // get creative. + char fmt[32] = {0}; + strncpy(fmt, p, sizeof(fmt) - 1); + fmt[0] = '%'; + fmt[1] = 'H'; + fmt[2] = ':'; + fmt[3] = '%'; + fmt[4] = 'M'; + fmt[6] = '%'; + fmt[7] = 'S'; + const char *subsec = 0; + char *q = fmt + 8; + if (*q == '.') { + ++q; + subsec = p + 9; + q = fmt + 9; + while (*q && isdigit(*q)) { + ++q; + } + } + // look for tz... + if (*q == '-' || *q == '+') { + *q = '%'; + *(q+1) = 'z'; + *(q+2) = 0; + } + p = strptime(p, fmt, &tm); + if (!p) { + return -EINVAL; + } + if (nsec && subsec) { + unsigned i; + char buf[10]; /* 9 digit + null termination */ + for (i = 0; (i < sizeof(buf) - 1) && isdigit(*subsec); ++i, ++subsec) { + buf[i] = *subsec; + } + for (; i < sizeof(buf) - 1; ++i) { + buf[i] = '0'; + } + buf[i] = '\0'; + std::string err; + *nsec = (uint64_t)strict_strtol(buf, 10, &err); + if (!err.empty()) { + return -EINVAL; + } + } + } + } else { + int sec, usec; + int r = sscanf(date.c_str(), "%d.%d", &sec, &usec); + if (r != 2) { + return -EINVAL; + } + + time_t tt = sec; + gmtime_r(&tt, &tm); + + if (nsec) { + *nsec = (uint64_t)usec * 1000; + } + } + + #ifndef _WIN32 + // apply the tm_gmtoff manually below, since none of mktime, + // gmtime, and localtime seem to do it. zero it out here just in + // case some other libc *does* apply it. :( + auto gmtoff = tm.tm_gmtoff; + tm.tm_gmtoff = 0; + #else + auto gmtoff = _timezone; + #endif /* _WIN32 */ + + time_t t = internal_timegm(&tm); + if (epoch) + *epoch = (uint64_t)t; + + *epoch -= gmtoff; + + if (out_date) { + char buf[32]; + strftime(buf, sizeof(buf), "%Y-%m-%d", &tm); + *out_date = buf; + } + if (out_time) { + char buf[32]; + strftime(buf, sizeof(buf), "%H:%M:%S", &tm); + *out_time = buf; + } + + return 0; +} diff --git a/src/include/utime.h b/src/include/utime.h index 1b7b600c23c..8eb96a25fd9 100644 --- a/src/include/utime.h +++ b/src/include/utime.h @@ -18,21 +18,17 @@ #include #include #include -#include #ifdef WITH_CRIMSON #include #endif -#include "include/compat.h" -#include "include/types.h" -#include "include/timegm.h" -#include "common/strtol.h" #include "common/ceph_time.h" -#include "common/safe_io.h" -#include "common/SubProcess.h" #include "include/denc.h" +#include "include/encoding.h" // for WRITE_CLASS_ENCODER() +#include "include/rados.h" // for struct ceph_timespec +namespace ceph { class Formatter; } // -------- // utime_t @@ -367,139 +363,11 @@ public: return out; } - static int invoke_date(const std::string& date_str, utime_t *result) { - char buf[256]; - - SubProcess bin_date("/bin/date", SubProcess::CLOSE, SubProcess::PIPE, - SubProcess::KEEP); - bin_date.add_cmd_args("-d", date_str.c_str(), "+%s %N", NULL); - - int r = bin_date.spawn(); - if (r < 0) return r; - - ssize_t n = safe_read(bin_date.get_stdout(), buf, sizeof(buf)); - - r = bin_date.join(); - if (r || n <= 0) return -EINVAL; - - uint64_t epoch, nsec; - std::istringstream iss(buf); - - iss >> epoch; - iss >> nsec; - - *result = utime_t(epoch, nsec); - - return 0; - } - + static int invoke_date(const std::string& date_str, utime_t *result); static int parse_date(const std::string& date, uint64_t *epoch, uint64_t *nsec, std::string *out_date=nullptr, - std::string *out_time=nullptr) { - struct tm tm; - memset(&tm, 0, sizeof(tm)); - - if (nsec) - *nsec = 0; - - const char *p = strptime(date.c_str(), "%Y-%m-%d", &tm); - if (p) { - if (*p == ' ' || *p == 'T') { - p++; - // strptime doesn't understand fractional/decimal seconds, and - // it also only takes format chars or literals, so we have to - // get creative. - char fmt[32] = {0}; - strncpy(fmt, p, sizeof(fmt) - 1); - fmt[0] = '%'; - fmt[1] = 'H'; - fmt[2] = ':'; - fmt[3] = '%'; - fmt[4] = 'M'; - fmt[6] = '%'; - fmt[7] = 'S'; - const char *subsec = 0; - char *q = fmt + 8; - if (*q == '.') { - ++q; - subsec = p + 9; - q = fmt + 9; - while (*q && isdigit(*q)) { - ++q; - } - } - // look for tz... - if (*q == '-' || *q == '+') { - *q = '%'; - *(q+1) = 'z'; - *(q+2) = 0; - } - p = strptime(p, fmt, &tm); - if (!p) { - return -EINVAL; - } - if (nsec && subsec) { - unsigned i; - char buf[10]; /* 9 digit + null termination */ - for (i = 0; (i < sizeof(buf) - 1) && isdigit(*subsec); ++i, ++subsec) { - buf[i] = *subsec; - } - for (; i < sizeof(buf) - 1; ++i) { - buf[i] = '0'; - } - buf[i] = '\0'; - std::string err; - *nsec = (uint64_t)strict_strtol(buf, 10, &err); - if (!err.empty()) { - return -EINVAL; - } - } - } - } else { - int sec, usec; - int r = sscanf(date.c_str(), "%d.%d", &sec, &usec); - if (r != 2) { - return -EINVAL; - } - - time_t tt = sec; - gmtime_r(&tt, &tm); - - if (nsec) { - *nsec = (uint64_t)usec * 1000; - } - } - - #ifndef _WIN32 - // apply the tm_gmtoff manually below, since none of mktime, - // gmtime, and localtime seem to do it. zero it out here just in - // case some other libc *does* apply it. :( - auto gmtoff = tm.tm_gmtoff; - tm.tm_gmtoff = 0; - #else - auto gmtoff = _timezone; - #endif /* _WIN32 */ - - time_t t = internal_timegm(&tm); - if (epoch) - *epoch = (uint64_t)t; - - *epoch -= gmtoff; - - if (out_date) { - char buf[32]; - strftime(buf, sizeof(buf), "%Y-%m-%d", &tm); - *out_date = buf; - } - if (out_time) { - char buf[32]; - strftime(buf, sizeof(buf), "%H:%M:%S", &tm); - *out_time = buf; - } - - return 0; - } + std::string *out_time=nullptr); bool parse(const std::string& s) { uint64_t epoch, nsec; diff --git a/src/tools/ceph-dencoder/CMakeLists.txt b/src/tools/ceph-dencoder/CMakeLists.txt index 1cd85189a6a..1b7bbbf3dbc 100644 --- a/src/tools/ceph-dencoder/CMakeLists.txt +++ b/src/tools/ceph-dencoder/CMakeLists.txt @@ -11,7 +11,6 @@ endif() set(dencoder_srcs ceph_dencoder.cc ../../include/uuid.cc - ../../include/utime.cc $) add_executable(ceph-dencoder ${dencoder_srcs}) set_target_properties(ceph-dencoder PROPERTIES @@ -39,7 +38,6 @@ endfunction() add_denc_mod(denc-mod-common ../../include/uuid.cc - ../../include/utime.cc common_types.cc) target_link_libraries(denc-mod-common ceph-common