Lingfeng Yang | c9feed7 | 2020-11-05 10:18:12 -0800 | [diff] [blame] | 1 | // Copyright 2020 The Android Open Source Project |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | |
| 15 | #include <io.h> |
| 16 | |
| 17 | #include "base/msvc.h" |
| 18 | |
| 19 | #include <stdarg.h> |
| 20 | #include <stdio.h> |
| 21 | #include <stdlib.h> |
| 22 | #include <string.h> |
| 23 | #include <sysinfoapi.h> |
| 24 | |
| 25 | #define FILETIME_1970 116444736000000000ull |
| 26 | #define HECTONANOSEC_PER_SEC 10000000ull |
| 27 | |
| 28 | int mkstemp(char* t) { |
| 29 | // TODO(joshuaduong): Support unicode (b/117322783) |
| 30 | int len = strlen(t) + 1; |
| 31 | errno_t err = _mktemp_s(t, len); |
| 32 | |
| 33 | if (err != 0) { |
| 34 | return -1; |
| 35 | } |
| 36 | |
| 37 | return _sopen(t, _O_RDWR | _O_CREAT | _O_EXCL | _O_BINARY, _SH_DENYRW, |
| 38 | _S_IREAD | _S_IWRITE); |
| 39 | } |
| 40 | |
| 41 | // From https://msdn.microsoft.com/en-us/library/28d5ce15.aspx |
| 42 | int asprintf(char** buf, const char* format, ...) { |
| 43 | va_list args; |
| 44 | int len; |
| 45 | |
| 46 | if (buf == NULL) { |
| 47 | return -1; |
| 48 | } |
| 49 | |
| 50 | // retrieve the variable arguments |
| 51 | va_start(args, format); |
| 52 | |
| 53 | len = _vscprintf(format, args) // _vscprintf doesn't count |
| 54 | + 1; // terminating '\0' |
| 55 | |
| 56 | if (len <= 0) { |
| 57 | return len; |
| 58 | } |
| 59 | |
| 60 | *buf = (char*)malloc(len * sizeof(char)); |
| 61 | |
| 62 | vsprintf(*buf, format, args); // C4996 |
| 63 | // Note: vsprintf is deprecated; consider using vsprintf_s instead |
| 64 | return len; |
| 65 | } |
| 66 | |
| 67 | // From https://msdn.microsoft.com/en-us/library/28d5ce15.aspx |
| 68 | static int vasprintf(char** buf, const char* format, va_list args) { |
| 69 | int len; |
| 70 | |
| 71 | if (buf == NULL) { |
| 72 | return -1; |
| 73 | } |
| 74 | |
| 75 | len = _vscprintf(format, args) // _vscprintf doesn't count |
| 76 | + 1; // terminating '\0' |
| 77 | |
| 78 | if (len <= 0) { |
| 79 | return len; |
| 80 | } |
| 81 | |
| 82 | *buf = (char*)malloc(len * sizeof(char)); |
| 83 | |
| 84 | vsprintf(*buf, format, args); // C4996 |
| 85 | // Note: vsprintf is deprecated; consider using vsprintf_s instead |
| 86 | return len; |
| 87 | } |
| 88 | |
| 89 | // This is a poor resolution timer, but at least it |
| 90 | // is available on Win7 and older. System.cpp will install |
| 91 | // a better one. |
| 92 | static SystemTime getSystemTime = (SystemTime)GetSystemTimeAsFileTime; |
| 93 | |
| 94 | int getntptimeofday(struct timespec*, struct timezone*); |
| 95 | |
| 96 | int getntptimeofday(struct timespec* tp, struct timezone* z) { |
| 97 | int res = 0; |
| 98 | union { |
| 99 | unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */ |
| 100 | FILETIME ft; |
| 101 | } _now; |
| 102 | TIME_ZONE_INFORMATION TimeZoneInformation; |
| 103 | DWORD tzi; |
| 104 | |
| 105 | if (z != NULL) { |
| 106 | if ((tzi = GetTimeZoneInformation(&TimeZoneInformation)) != |
| 107 | TIME_ZONE_ID_INVALID) { |
| 108 | z->tz_minuteswest = TimeZoneInformation.Bias; |
| 109 | if (tzi == TIME_ZONE_ID_DAYLIGHT) |
| 110 | z->tz_dsttime = 1; |
| 111 | else |
| 112 | z->tz_dsttime = 0; |
| 113 | } else { |
| 114 | z->tz_minuteswest = 0; |
| 115 | z->tz_dsttime = 0; |
| 116 | } |
| 117 | } |
| 118 | |
| 119 | if (tp != NULL) { |
| 120 | getSystemTime((FileTime*)&_now.ft); /* 100-nanoseconds since 1-1-1601 */ |
| 121 | /* The actual accuracy on XP seems to be 125,000 nanoseconds = 125 |
| 122 | * microseconds = 0.125 milliseconds */ |
| 123 | _now.ns100 -= FILETIME_1970; /* 100 nano-seconds since 1-1-1970 */ |
| 124 | tp->tv_sec = |
| 125 | _now.ns100 / HECTONANOSEC_PER_SEC; /* seconds since 1-1-1970 */ |
| 126 | tp->tv_nsec = (long)(_now.ns100 % HECTONANOSEC_PER_SEC) * |
| 127 | 100; /* nanoseconds */ |
| 128 | } |
| 129 | return res; |
| 130 | } |
| 131 | |
| 132 | int gettimeofday(struct timeval* p, struct timezone* z) { |
| 133 | struct timespec tp; |
| 134 | |
| 135 | if (getntptimeofday(&tp, z)) |
| 136 | return -1; |
| 137 | p->tv_sec = tp.tv_sec; |
| 138 | p->tv_usec = (tp.tv_nsec / 1000); |
| 139 | return 0; |
| 140 | } |