6 #ifndef SPDLOG_HEADER_ONLY
22 #include <sys/types.h>
34 # if defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)
46 # include <sys/syscall.h>
51 # elif defined(__DragonFly__) || defined(__FreeBSD__)
52 # include <pthread_np.h>
54 # elif defined(__NetBSD__)
63 #ifndef __has_feature // Clang - feature checking macros.
64 # define __has_feature(x) 0 // Compatibility with non-clang compilers.
74 #if defined __linux__ && defined SPDLOG_CLOCK_COARSE
76 ::clock_gettime(CLOCK_REALTIME_COARSE, &ts);
77 return std::chrono::time_point<log_clock, typename log_clock::duration>(
78 std::chrono::duration_cast<typename log_clock::duration>(std::chrono::seconds(ts.tv_sec) + std::chrono::nanoseconds(ts.tv_nsec)));
99 std::time_t now_t = ::time(
nullptr);
118 std::time_t now_t = ::time(
nullptr);
126 # ifdef SPDLOG_WCHAR_FILENAMES
127 *fp = ::_wfsopen((
filename.c_str()),
mode.c_str(), _SH_DENYNO);
129 *fp = ::_fsopen((
filename.c_str()),
mode.c_str(), _SH_DENYNO);
131 # if defined(SPDLOG_PREVENT_CHILD_FD)
134 auto file_handle =
reinterpret_cast<HANDLE
>(_get_osfhandle(::_fileno(*fp)));
135 if (!::SetHandleInformation(file_handle, HANDLE_FLAG_INHERIT, 0))
143 # if defined(SPDLOG_PREVENT_CHILD_FD)
145 const int fd = ::open((
filename.c_str()), O_CREAT | O_WRONLY | O_CLOEXEC | mode_flag, mode_t(0644));
150 *fp = ::fdopen(fd,
mode.c_str());
160 return *fp ==
nullptr;
165 #if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
166 return ::_wremove(
filename.c_str());
179 #if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
180 return ::_wrename(filename1.c_str(), filename2.c_str());
182 return std::rename(filename1.c_str(), filename2.c_str());
190 # ifdef SPDLOG_WCHAR_FILENAMES
191 auto attribs = ::GetFileAttributesW(
filename.c_str());
193 auto attribs = ::GetFileAttributesA(
filename.c_str());
195 return attribs != INVALID_FILE_ATTRIBUTES;
196 #else // common linux/unix all have the stat system call
198 return (::stat(
filename.c_str(), &buffer) == 0);
204 # pragma warning(push)
205 # pragma warning(disable : 4702)
215 #if defined(_WIN32) && !defined(__CYGWIN__)
216 int fd = ::_fileno(f);
217 # if defined(_WIN64) // 64 bits
218 __int64 ret = ::_filelengthi64(fd);
221 return static_cast<size_t>(ret);
224 # else // windows 32 bits
225 long ret = ::_filelength(fd);
228 return static_cast<size_t>(ret);
234 # if defined(__OpenBSD__) || defined(_AIX)
237 int fd = ::fileno(f);
240 # if (defined(__linux__) || defined(__sun) || defined(_AIX)) && (defined(__LP64__) || defined(_LP64))
242 if (::fstat64(fd, &st) == 0)
244 return static_cast<size_t>(st.st_size);
246 # else // other unix or linux 32 bits or cygwin
248 if (::fstat(fd, &st) == 0)
250 return static_cast<size_t>(st.st_size);
259 # pragma warning(pop)
267 # if _WIN32_WINNT < _WIN32_WINNT_WS08
268 TIME_ZONE_INFORMATION tzinfo;
269 auto rv = ::GetTimeZoneInformation(&tzinfo);
271 DYNAMIC_TIME_ZONE_INFORMATION tzinfo;
272 auto rv = ::GetDynamicTimeZoneInformation(&tzinfo);
274 if (rv == TIME_ZONE_ID_INVALID)
277 int offset = -tzinfo.Bias;
280 offset -= tzinfo.DaylightBias;
284 offset -= tzinfo.StandardBias;
289 # if defined(sun) || defined(__sun) || defined(_AIX) || (!defined(_BSD_SOURCE) && !defined(_GNU_SOURCE))
295 int local_year = localtm.tm_year + (1900 - 1);
296 int gmt_year = gmtm.tm_year + (1900 - 1);
304 + ((local_year >> 2) - (gmt_year >> 2)) - (local_year / 100 - gmt_year / 100) +
305 ((local_year / 100 >> 2) - (gmt_year / 100 >> 2))
308 +
static_cast<long int>(local_year - gmt_year) * 365);
310 long int hours = (24 *
days) + (localtm.tm_hour - gmtm.tm_hour);
311 long int mins = (60 * hours) + (localtm.tm_min - gmtm.tm_min);
312 long int secs = (60 * mins) + (localtm.tm_sec - gmtm.tm_sec);
318 auto offset_seconds = helper::calculate_gmt_offset(tm);
320 auto offset_seconds = tm.tm_gmtoff;
323 return static_cast<int>(offset_seconds / 60);
333 return static_cast<size_t>(::GetCurrentThreadId());
334 #elif defined(__linux__)
335 # if defined(__ANDROID__) && defined(__ANDROID_API__) && (__ANDROID_API__ < 21)
336 # define SYS_gettid __NR_gettid
338 return static_cast<size_t>(::syscall(SYS_gettid));
340 struct __pthrdsinfo buf;
342 pthread_t pt = pthread_self();
343 int retval = pthread_getthrds_np(&pt, PTHRDSINFO_QUERY_TID, &buf,
sizeof(buf), NULL, ®_size);
344 int tid = (!retval) ? buf.__pi_tid : 0;
345 return static_cast<size_t>(tid);
346 #elif defined(__DragonFly__) || defined(__FreeBSD__)
347 return static_cast<size_t>(::pthread_getthreadid_np());
348 #elif defined(__NetBSD__)
349 return static_cast<size_t>(::_lwp_self());
350 #elif defined(__OpenBSD__)
351 return static_cast<size_t>(::getthrid());
353 return static_cast<size_t>(::thr_self());
356 pthread_threadid_np(
nullptr, &tid);
357 return static_cast<size_t>(tid);
358 #else // Default to standard C++11 (other Unix)
359 return static_cast<size_t>(std::hash<std::thread::id>()(std::this_thread::get_id()));
366 #if defined(SPDLOG_NO_TLS)
368 #else // cache thread id in tls
369 static thread_local
const size_t tid =
_thread_id();
379 ::Sleep(milliseconds);
381 std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds));
386 #if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
391 # ifdef SPDLOG_USE_STD_FORMAT
408 return conditional_static_cast<int>(::GetCurrentProcessId());
410 return conditional_static_cast<int>(::getpid());
422 static const bool result = []() {
423 const char *env_colorterm_p =
std::getenv(
"COLORTERM");
424 if (env_colorterm_p !=
nullptr)
429 static constexpr std::array<const char *, 16> terms = {{
"ansi",
"color",
"console",
"cygwin",
"gnome",
"konsole",
"kterm",
"linux",
430 "msys",
"putty",
"rxvt",
"screen",
"vt100",
"xterm",
"alacritty",
"vt102"}};
433 if (env_term_p ==
nullptr)
438 return std::any_of(terms.begin(), terms.end(), [&](
const char *term) { return std::strstr(env_term_p, term) != nullptr; });
451 return ::_isatty(_fileno(file)) != 0;
453 return ::isatty(fileno(file)) != 0;
457 #if (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) && defined(_WIN32)
465 int wstr_size =
static_cast<int>(wstr.size());
472 int result_size =
static_cast<int>(
target.capacity());
473 if ((wstr_size + 1) * 2 > result_size)
475 result_size = ::WideCharToMultiByte(CP_UTF8, 0, wstr.data(), wstr_size, NULL, 0, NULL, NULL);
480 target.resize(result_size);
481 result_size = ::WideCharToMultiByte(CP_UTF8, 0, wstr.data(), wstr_size,
target.data(), result_size, NULL, NULL);
485 target.resize(result_size);
500 int str_size =
static_cast<int>(str.size());
507 int result_size =
static_cast<int>(
target.capacity());
508 if (str_size + 1 > result_size)
510 result_size = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str.data(), str_size, NULL, 0);
515 target.resize(result_size);
516 result_size = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str.data(), str_size,
target.data(), result_size);
520 target.resize(result_size);
527 #endif // (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) && defined(_WIN32)
533 # ifdef SPDLOG_WCHAR_FILENAMES
534 return ::_wmkdir(path.c_str()) == 0;
536 return ::_mkdir(path.c_str()) == 0;
539 return ::mkdir(path.c_str(), mode_t(0755)) == 0;
557 size_t search_offset = 0;
562 if (token_pos == filename_t::npos)
564 token_pos = path.size();
567 auto subdir = path.substr(0, token_pos);
573 search_offset = token_pos + 1;
574 }
while (search_offset < path.size());
587 return pos != filename_t::npos ? path.substr(0, pos) :
filename_t{};
593 #if defined(_MSC_VER)
594 # if defined(__cplusplus_winrt)
595 return std::string{};
599 bool ok = ::getenv_s(&
len, buf,
sizeof(buf), field) == 0;
600 return ok ? buf : std::string{};
602 #else // revert to getenv
604 return buf ? buf : std::string{};