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 "aemu/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
mkstemp(char * t)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
asprintf(char ** buf,const char * format,...)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
vasprintf(char ** buf,const char * format,va_list args)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
getntptimeofday(struct timespec * tp,struct timezone * z)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
gettimeofday(struct timeval * p,struct timezone * z)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 }
141