xref: /aosp_15_r20/external/gmmlib/Source/GmmLib/Utility/GmmLog/spdlog/details/os.h (revision 35ffd701415c9e32e53136d61a677a8d0a8fc4a5)
1 //
2 // Copyright(c) 2015 Gabi Melman.
3 // Distributed under the MIT License (http://opensource.org/licenses/MIT)
4 //
5 #pragma once
6 
7 #include <spdlog/common.h>
8 
9 #include <cstdio>
10 #include <ctime>
11 #include <functional>
12 #include <string>
13 #include <stdio.h>
14 #include <string.h>
15 #include <sys/stat.h>
16 
17 
18 #ifdef _WIN32
19 
20 #ifndef NOMINMAX
21 #define NOMINMAX //prevent windows redefining min/max
22 #endif
23 
24 #ifndef WIN32_LEAN_AND_MEAN
25 #define WIN32_LEAN_AND_MEAN
26 #endif
27 #include <windows.h>
28 
29 #ifdef __MINGW32__
30 #include <share.h>
31 #endif
32 
33 #include <sys/types.h>
34 #include <io.h>
35 
36 #elif __linux__
37 
38 #include <sys/syscall.h> //Use gettid() syscall under linux to get thread id
39 #include <unistd.h>
40 #include <chrono>
41 
42 #elif __FreeBSD__
43 #include <sys/thr.h> //Use thr_self() syscall under FreeBSD to get thread id
44 
45 #else
46 #include <thread>
47 
48 #endif
49 
50 namespace spdlog
51 {
52 namespace details
53 {
54 namespace os
55 {
56 
now()57 inline spdlog::log_clock::time_point now()
58 {
59 
60 #if defined __linux__ && defined SPDLOG_CLOCK_COARSE
61     timespec ts;
62     ::clock_gettime(CLOCK_REALTIME_COARSE, &ts);
63     return std::chrono::time_point<log_clock, typename log_clock::duration>(
64                std::chrono::duration_cast<typename log_clock::duration>(
65                    std::chrono::seconds(ts.tv_sec) + std::chrono::nanoseconds(ts.tv_nsec)));
66 
67 
68 #else
69     return log_clock::now();
70 #endif
71 
72 }
localtime(const std::time_t & time_tt)73 inline std::tm localtime(const std::time_t &time_tt)
74 {
75 
76 #ifdef _WIN32
77     std::tm tm;
78     localtime_s(&tm, &time_tt);
79 #else
80     std::tm tm;
81     localtime_r(&time_tt, &tm);
82 #endif
83     return tm;
84 }
85 
localtime()86 inline std::tm localtime()
87 {
88     std::time_t now_t = time(nullptr);
89     return localtime(now_t);
90 }
91 
92 
gmtime(const std::time_t & time_tt)93 inline std::tm gmtime(const std::time_t &time_tt)
94 {
95 
96 #ifdef _WIN32
97     std::tm tm;
98     gmtime_s(&tm, &time_tt);
99 #else
100     std::tm tm;
101     gmtime_r(&time_tt, &tm);
102 #endif
103     return tm;
104 }
105 
gmtime()106 inline std::tm gmtime()
107 {
108     std::time_t now_t = time(nullptr);
109     return gmtime(now_t);
110 }
111 inline bool operator==(const std::tm& tm1, const std::tm& tm2)
112 {
113     return (tm1.tm_sec == tm2.tm_sec &&
114             tm1.tm_min == tm2.tm_min &&
115             tm1.tm_hour == tm2.tm_hour &&
116             tm1.tm_mday == tm2.tm_mday &&
117             tm1.tm_mon == tm2.tm_mon &&
118             tm1.tm_year == tm2.tm_year &&
119             tm1.tm_isdst == tm2.tm_isdst);
120 }
121 
122 inline bool operator!=(const std::tm& tm1, const std::tm& tm2)
123 {
124     return !(tm1 == tm2);
125 }
126 
127 // eol definition
128 #if !defined (SPDLOG_EOL)
129 #ifdef _WIN32
130 #define SPDLOG_EOL "\r\n"
131 #else
132 #define SPDLOG_EOL "\n"
133 #endif
134 #endif
135 
136 SPDLOG_CONSTEXPR static const char* eol = SPDLOG_EOL;
137 SPDLOG_CONSTEXPR static int eol_size = sizeof(SPDLOG_EOL) - 1;
138 
139 
140 
141 //fopen_s on non windows for writing
fopen_s(FILE ** fp,const filename_t & filename,const filename_t & mode)142 inline int fopen_s(FILE** fp, const filename_t& filename, const filename_t& mode)
143 {
144 #ifdef _WIN32
145 #ifdef SPDLOG_WCHAR_FILENAMES
146     *fp = _wfsopen((filename.c_str()), mode.c_str(), _SH_DENYWR);
147 #else
148     *fp = _fsopen((filename.c_str()), mode.c_str(), _SH_DENYWR);
149 #endif
150     return *fp == nullptr;
151 #else
152     *fp = fopen((filename.c_str()), mode.c_str());
153     return *fp == nullptr;
154 #endif
155 }
156 
remove(const filename_t & filename)157 inline int remove(const filename_t &filename)
158 {
159 #if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
160     return _wremove(filename.c_str());
161 #else
162     return std::remove(filename.c_str());
163 #endif
164 }
165 
rename(const filename_t & filename1,const filename_t & filename2)166 inline int rename(const filename_t& filename1, const filename_t& filename2)
167 {
168 #if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
169     return _wrename(filename1.c_str(), filename2.c_str());
170 #else
171     return std::rename(filename1.c_str(), filename2.c_str());
172 #endif
173 }
174 
175 
176 //Return if file exists
file_exists(const filename_t & filename)177 inline bool file_exists(const filename_t& filename)
178 {
179 #ifdef _WIN32
180 #ifdef SPDLOG_WCHAR_FILENAMES
181     auto attribs = GetFileAttributesW(filename.c_str());
182 #else
183     auto attribs = GetFileAttributesA(filename.c_str());
184 #endif
185     return (attribs != INVALID_FILE_ATTRIBUTES && !(attribs & FILE_ATTRIBUTE_DIRECTORY));
186 #else //common linux/unix all have the stat system call
187     struct stat buffer;
188     return (stat (filename.c_str(), &buffer) == 0);
189 #endif
190 }
191 
192 
193 
194 
195 //Return file size according to open FILE* object
filesize(FILE * f)196 inline size_t filesize(FILE *f)
197 {
198     if (f == nullptr)
199         throw spdlog_ex("Failed getting file size. fd is null");
200 #ifdef _WIN32
201     int fd = _fileno(f);
202 #if _WIN64 //64 bits
203     struct _stat64 st;
204     if (_fstat64(fd, &st) == 0)
205         return st.st_size;
206 
207 #else //windows 32 bits
208     long ret = _filelength(fd);
209     if (ret >= 0)
210         return static_cast<size_t>(ret);
211 #endif
212 
213 #else // unix
214     int fd = fileno(f);
215     //64 bits(but not in osx, where fstat64 is deprecated)
216 #if !defined(__FreeBSD__) && !defined(__APPLE__) && (defined(__x86_64__) || defined(__ppc64__))
217     struct stat64 st;
218     if (fstat64(fd, &st) == 0)
219         return static_cast<size_t>(st.st_size);
220 #else // unix 32 bits or osx
221     struct stat st;
222     if (fstat(fd, &st) == 0)
223         return static_cast<size_t>(st.st_size);
224 #endif
225 #endif
226     throw spdlog_ex("Failed getting file size from fd", errno);
227 }
228 
229 
230 
231 
232 //Return utc offset in minutes or throw spdlog_ex on failure
233 inline int utc_minutes_offset(const std::tm& tm = details::os::localtime())
234 {
235 
236 #ifdef _WIN32
237 #if _WIN32_WINNT < _WIN32_WINNT_WS08
238     TIME_ZONE_INFORMATION tzinfo;
239     auto rv = GetTimeZoneInformation(&tzinfo);
240 #else
241     DYNAMIC_TIME_ZONE_INFORMATION tzinfo;
242     auto rv = GetDynamicTimeZoneInformation(&tzinfo);
243 #endif
244     if (rv == TIME_ZONE_ID_INVALID)
245         throw spdlog::spdlog_ex("Failed getting timezone info. ", errno);
246 
247     int offset = -tzinfo.Bias;
248     if (tm.tm_isdst)
249         offset -= tzinfo.DaylightBias;
250     else
251         offset -= tzinfo.StandardBias;
252     return offset;
253 #else
254 
255 #if defined(sun) || defined(__sun)
256     // 'tm_gmtoff' field is BSD extension and it's missing on SunOS/Solaris
257     struct helper
258     {
259         static long int calculate_gmt_offset(const std::tm & localtm = details::os::localtime(), const std::tm & gmtm = details::os::gmtime())
260         {
261             int local_year = localtm.tm_year + (1900 - 1);
262             int gmt_year = gmtm.tm_year + (1900 - 1);
263 
264             long int days = (
265                                 // difference in day of year
266                                 localtm.tm_yday - gmtm.tm_yday
267 
268                                 // + intervening leap days
269                                 + ((local_year >> 2) - (gmt_year >> 2))
270                                 - (local_year / 100 - gmt_year / 100)
271                                 + ((local_year / 100 >> 2) - (gmt_year / 100 >> 2))
272 
273                                 // + difference in years * 365 */
274                                 + (long int)(local_year - gmt_year) * 365
275                             );
276 
277             long int hours = (24 * days) + (localtm.tm_hour - gmtm.tm_hour);
278             long int mins = (60 * hours) + (localtm.tm_min - gmtm.tm_min);
279             long int secs = (60 * mins) + (localtm.tm_sec - gmtm.tm_sec);
280 
281             return secs;
282         }
283     };
284 
285     long int offset_seconds = helper::calculate_gmt_offset(tm);
286 #else
287     long int offset_seconds = tm.tm_gmtoff;
288 #endif
289 
290     return static_cast<int>(offset_seconds / 60);
291 #endif
292 }
293 
294 //Return current thread id as size_t
295 //It exists because the std::this_thread::get_id() is much slower(espcially under VS 2013)
thread_id()296 inline size_t thread_id()
297 {
298 #ifdef _WIN32
299     return  static_cast<size_t>(::GetCurrentThreadId());
300 #elif __linux__
301 # if defined(__ANDROID__) && defined(__ANDROID_API__) && (__ANDROID_API__ < 21)
302 #  define SYS_gettid __NR_gettid
303 # endif
304     return  static_cast<size_t>(syscall(SYS_gettid));
305 #elif __FreeBSD__
306     long tid;
307     thr_self(&tid);
308     return static_cast<size_t>(tid);
309 #else //Default to standard C++11 (OSX and other Unix)
310     return static_cast<size_t>(std::hash<std::thread::id>()(std::this_thread::get_id()));
311 #endif
312 
313 
314 }
315 
316 
317 // wchar support for windows file names (SPDLOG_WCHAR_FILENAMES must be defined)
318 #if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
319 #define SPDLOG_FILENAME_T(s) L ## s
filename_to_str(const filename_t & filename)320 inline std::string filename_to_str(const filename_t& filename)
321 {
322     std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> c;
323     return c.to_bytes(filename);
324 }
325 #else
326 #define SPDLOG_FILENAME_T(s) s
filename_to_str(const filename_t & filename)327 inline std::string filename_to_str(const filename_t& filename)
328 {
329     return filename;
330 }
331 #endif
332 
333 
334 // Return errno string (thread safe)
errno_str(int err_num)335 inline std::string errno_str(int err_num)
336 {
337     char buf[256];
338     SPDLOG_CONSTEXPR auto buf_size = sizeof(buf);
339 
340 #ifdef _WIN32
341     if(strerror_s(buf, buf_size, err_num) == 0)
342         return std::string(buf);
343     else
344         return "Unkown error";
345 
346 #elif defined(__FreeBSD__) || defined(__APPLE__) || defined(ANDROID) || defined(__QNX__) || \
347       ((_POSIX_C_SOURCE >= 200112L) && ! _GNU_SOURCE) // posix version
348 
349     if (strerror_r(err_num, buf, buf_size) == 0)
350         return std::string(buf);
351     else
352         return "Unkown error";
353 
354 #else  // gnu version (might not use the given buf, so its retval pointer must be used)
355     return std::string(strerror_r(err_num, buf, buf_size));
356 #endif
357 }
358 
359 } //os
360 } //details
361 } //spdlog
362