getopt_long
getpwuid
gettimeofday
- localtime_r
mkstemp
posix_fallocate
realpath
/* Define to 1 if you have the <linux/fs.h> header file. */
#cmakedefine HAVE_LINUX_FS_H
-/* Define to 1 if you have the `localtime_r' function. */
-#cmakedefine HAVE_LOCALTIME_R
-
/* Define to 1 if the system has the type `long long'. */
#cmakedefine HAVE_LONG_LONG
# endif
#endif
+using nonstd::nullopt;
+using nonstd::optional;
using nonstd::string_view;
namespace {
|| get_extension(dir_name(path)) == ".gch";
}
+optional<tm>
+localtime(optional<time_t> time)
+{
+ time_t timestamp = time ? *time : ::time(nullptr);
+ tm result;
+ if (localtime_r(×tamp, &result)) {
+ return result;
+ } else {
+ return nullopt;
+ }
+}
+
std::string
make_relative_path(const Context& ctx, string_view path)
{
#include "CacheFile.hpp"
#include "Config.hpp"
+#include "third_party/nonstd/optional.hpp"
#include "third_party/nonstd/string_view.hpp"
#include <functional>
// Headers" in GCC docs).
bool is_precompiled_header(nonstd::string_view path);
+// Thread-safe version of `localtime(3)`. If `time` is not specified the current
+// time of day is used.
+nonstd::optional<tm> localtime(nonstd::optional<time_t> time = {});
+
// Make a relative path from current working directory to `path` if `path` is
// under the base directory.
std::string make_relative_path(const Context& ctx, nonstd::string_view path);
static int
cache_compilation(int argc, const char* const* argv)
{
- // Needed for portability when using localtime_r.
- tzset();
+ tzset(); // Needed for localtime_r.
auto ctx = std::make_unique<Context>();
SignalHandler signal_handler(*ctx);
// Make sure that the hash sum changes if the (potential) expansion of
// __DATE__ changes.
- time_t t = time(nullptr);
- struct tm now;
hash.hash_delimiter("date");
- if (!localtime_r(&t, &now)) {
+ auto now = Util::localtime();
+ if (!now) {
return HASH_SOURCE_CODE_ERROR;
}
- hash.hash(now.tm_year);
- hash.hash(now.tm_mon);
- hash.hash(now.tm_mday);
+ hash.hash(now->tm_year);
+ hash.hash(now->tm_mon);
+ hash.hash(now->tm_mday);
}
if (result & HASH_SOURCE_CODE_FOUND_TIME) {
// We don't know for sure that the program actually uses the __TIME__ macro,
return HASH_SOURCE_CODE_ERROR;
}
- time_t t = stat.mtime();
- tm modified;
- hash.hash_delimiter("timestamp");
- if (!localtime_r(&t, &modified)) {
+ auto modified_time = Util::localtime(stat.mtime());
+ if (!modified_time) {
return HASH_SOURCE_CODE_ERROR;
}
-
+ hash.hash_delimiter("timestamp");
#ifdef HAVE_ASCTIME_R
char buffer[26];
- auto timestamp = asctime_r(&modified, buffer);
+ auto timestamp = asctime_r(&*modified_time, buffer);
#else
- auto timestamp = asctime(&modified);
+ auto timestamp = asctime(&*modified_time);
#endif
if (!timestamp) {
return HASH_SOURCE_CODE_ERROR;
# include <sys/time.h>
#endif
-#if !defined(_WIN32) && !defined(HAVE_LOCALTIME_R)
-// localtime_r replacement. (Mingw-w64 has an inline localtime_r which is not
-// detected by AC_CHECK_FUNCS.)
-struct tm*
-localtime_r(const time_t* timep, struct tm* result)
-{
- struct tm* tm = localtime(timep);
- if (tm) {
- *result = *tm;
- return result;
- } else {
- memset(result, 0, sizeof(*result));
- return NULL;
- }
-}
-#endif
-
// Return current user's home directory, or throw FatalError if it can't be
// determined.
const char*
#include <string>
-#ifndef HAVE_LOCALTIME_R
-struct tm* localtime_r(const time_t* timep, struct tm* result);
-#endif
const char* get_home_directory();
bool is_full_path(const char* path);
void update_mtime(const char* path);
#include "Config.hpp"
#include "File.hpp"
+#include "Util.hpp"
#include "exceptions.hpp"
#include "execute.hpp"
#ifdef HAVE_GETTIMEOFDAY
if (log_updated_time) {
char timestamp[100];
- struct tm tm;
struct timeval tv;
gettimeofday(&tv, nullptr);
- if (localtime_r((time_t*)&tv.tv_sec, &tm) != nullptr) {
- strftime(timestamp, sizeof(timestamp), "%Y-%m-%dT%H:%M:%S", &tm);
+ auto tm = Util::localtime(tv.tv_sec);
+ if (tm) {
+ strftime(timestamp, sizeof(timestamp), "%Y-%m-%dT%H:%M:%S", &*tm);
} else {
snprintf(timestamp, sizeof(timestamp), "%lu", tv.tv_sec);
}
format_timestamp(uint64_t timestamp)
{
if (timestamp > 0) {
- struct tm tm;
- localtime_r(reinterpret_cast<time_t*>(×tamp), &tm);
- char buffer[100];
- strftime(buffer, sizeof(buffer), "%c", &tm);
+ auto tm = Util::localtime(timestamp);
+ char buffer[100] = "?";
+ if (tm) {
+ strftime(buffer, sizeof(buffer), "%c", &*tm);
+ }
return std::string(" ") + buffer;
} else {
return {};
fmt::print("secondary config (readonly) {}\n",
ctx.config.secondary_config_path());
if (last_updated > 0) {
- struct tm tm;
- localtime_r(&last_updated, &tm);
- char timestamp[100];
- strftime(timestamp, sizeof(timestamp), "%c", &tm);
+ auto tm = Util::localtime(last_updated);
+ char timestamp[100] = "?";
+ if (tm) {
+ strftime(timestamp, sizeof(timestamp), "%c", &*tm);
+ }
fmt::print("stats updated {}\n", timestamp);
}