1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 /* Foreign builtins. */
13 #include "vg/valgrind.h"
21 #if !defined(__WIN32__)
23 #include <sys/types.h>
36 #include <TargetConditionals.h>
37 #include <mach/mach_time.h>
39 #if !(TARGET_OS_IPHONE)
40 #include <crt_externs.h>
68 #if (TARGET_OS_IPHONE)
69 extern char **environ;
73 #if defined(__FreeBSD__) || defined(__linux__) || defined(__ANDROID__)
74 extern char **environ;
77 #if defined(__WIN32__)
85 #if defined(__APPLE__) && !(TARGET_OS_IPHONE)
86 char **environ = *_NSGetEnviron();
93 #if defined(__WIN32__)
94 rust_list_dir_val(WIN32_FIND_DATA* entry_ptr) {
95 return entry_ptr->cFileName;
98 rust_list_dir_val(struct dirent* entry_ptr) {
99 return entry_ptr->d_name;
104 #if defined(__WIN32__)
105 rust_list_dir_wfd_size() {
106 return sizeof(WIN32_FIND_DATAW);
109 rust_list_dir_wfd_size() {
115 #if defined(__WIN32__)
116 rust_list_dir_wfd_fp_buf(WIN32_FIND_DATAW* wfd) {
121 return wfd->cFileName;
125 rust_list_dir_wfd_fp_buf(void* wfd) {
132 size_t fill; // in bytes; if zero, heapified
133 size_t alloc; // in bytes
137 typedef rust_vec rust_str;
154 void rust_tm_to_tm(rust_tm* in_tm, struct tm* out_tm) {
155 memset(out_tm, 0, sizeof(struct tm));
156 out_tm->tm_sec = in_tm->tm_sec;
157 out_tm->tm_min = in_tm->tm_min;
158 out_tm->tm_hour = in_tm->tm_hour;
159 out_tm->tm_mday = in_tm->tm_mday;
160 out_tm->tm_mon = in_tm->tm_mon;
161 out_tm->tm_year = in_tm->tm_year;
162 out_tm->tm_wday = in_tm->tm_wday;
163 out_tm->tm_yday = in_tm->tm_yday;
164 out_tm->tm_isdst = in_tm->tm_isdst;
167 void tm_to_rust_tm(struct tm* in_tm, rust_tm* out_tm, int32_t gmtoff,
168 const char *zone, int32_t nsec) {
169 out_tm->tm_sec = in_tm->tm_sec;
170 out_tm->tm_min = in_tm->tm_min;
171 out_tm->tm_hour = in_tm->tm_hour;
172 out_tm->tm_mday = in_tm->tm_mday;
173 out_tm->tm_mon = in_tm->tm_mon;
174 out_tm->tm_year = in_tm->tm_year;
175 out_tm->tm_wday = in_tm->tm_wday;
176 out_tm->tm_yday = in_tm->tm_yday;
177 out_tm->tm_isdst = in_tm->tm_isdst;
178 out_tm->tm_gmtoff = gmtoff;
179 out_tm->tm_nsec = nsec;
182 size_t size = strlen(zone);
183 assert(out_tm->tm_zone->alloc >= size);
184 memcpy(out_tm->tm_zone->data, zone, size);
185 out_tm->tm_zone->fill = size;
189 #if defined(__WIN32__)
190 #define TZSET() _tzset()
191 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
192 #define GMTIME(clock, result) gmtime_s((result), (clock))
193 #define LOCALTIME(clock, result) localtime_s((result), (clock))
194 #define TIMEGM(result) _mkgmtime64(result)
196 struct tm* GMTIME(const time_t *clock, struct tm *result) {
197 struct tm* t = gmtime(clock);
198 if (t == NULL || result == NULL) { return NULL; }
202 struct tm* LOCALTIME(const time_t *clock, struct tm *result) {
203 struct tm* t = localtime(clock);
204 if (t == NULL || result == NULL) { return NULL; }
208 #define TIMEGM(result) mktime((result)) - _timezone
211 #define TZSET() tzset()
212 #define GMTIME(clock, result) gmtime_r((clock), (result))
213 #define LOCALTIME(clock, result) localtime_r((clock), (result))
214 #define TIMEGM(result) timegm(result)
223 rust_gmtime(int64_t sec, int32_t nsec, rust_tm *timeptr) {
228 tm_to_rust_tm(&tm, timeptr, 0, "UTC", nsec);
232 rust_localtime(int64_t sec, int32_t nsec, rust_tm *timeptr) {
237 const char* zone = NULL;
238 #if defined(__WIN32__)
239 int32_t gmtoff = -timezone;
240 wchar_t wbuffer[64] = {0};
241 char buffer[256] = {0};
242 // strftime("%Z") can contain non-UTF-8 characters on non-English locale (issue #9418),
243 // so time zone should be converted from UTF-16 string.
244 // Since wcsftime depends on setlocale() result,
245 // instead we convert it using MultiByteToWideChar.
246 if (strftime(buffer, sizeof(buffer) / sizeof(char), "%Z", &tm) > 0) {
248 MultiByteToWideChar(CP_ACP, 0, buffer, -1, wbuffer, sizeof(wbuffer) / sizeof(wchar_t));
250 WideCharToMultiByte(CP_UTF8, 0, wbuffer, -1, buffer, sizeof(buffer), NULL, NULL);
254 int32_t gmtoff = tm.tm_gmtoff;
258 tm_to_rust_tm(&tm, timeptr, gmtoff, zone, nsec);
262 rust_timegm(rust_tm* timeptr) {
264 rust_tm_to_tm(timeptr, &t);
269 rust_mktime(rust_tm* timeptr) {
271 rust_tm_to_tm(timeptr, &t);
278 rust_opendir(char *dirname) {
279 return opendir(dirname);
283 rust_readdir(DIR *dirp) {
284 return readdir(dirp);
300 rust_running_on_valgrind() {
301 return RUNNING_ON_VALGRIND;
304 #if defined(__WIN32__)
308 GetSystemInfo(&sysinfo);
310 return (int) sysinfo.dwNumberOfProcessors;
312 #elif defined(__BSD__)
315 /* swiped from http://stackoverflow.com/questions/150355/
316 programmatically-find-the-number-of-cores-on-a-machine */
320 size_t len = sizeof(numCPU);
322 /* set the mib for hw.ncpu */
324 mib[1] = HW_AVAILCPU; // alternatively, try HW_NCPU;
326 /* get the number of CPUs from the system */
327 sysctl(mib, 2, &numCPU, &len, NULL, 0);
331 sysctl( mib, 2, &numCPU, &len, NULL, 0 );
339 #elif defined(__GNUC__)
342 return sysconf(_SC_NPROCESSORS_ONLN);
347 rust_get_num_cpus() {
348 return get_num_cpus();
352 rust_valgrind_stack_register(void *start, void *end) {
353 return VALGRIND_STACK_REGISTER(start, end);
357 rust_valgrind_stack_deregister(unsigned int id) {
358 VALGRIND_STACK_DEREGISTER(id);
361 #if defined(__WIN32__)
364 rust_unset_sigprocmask() {
365 // empty stub for windows to keep linker happy
371 rust_unset_sigprocmask() {
372 // this can't be safely converted to rust code because the
373 // representation of sigset_t is platform-dependent
376 sigprocmask(SIG_SETMASK, &sset, NULL);
381 #if defined(__WIN32__)
383 win32_require(LPCTSTR fn, BOOL ok) {
386 DWORD err = GetLastError();
387 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
388 FORMAT_MESSAGE_FROM_SYSTEM |
389 FORMAT_MESSAGE_IGNORE_INSERTS,
391 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
392 (LPTSTR) &buf, 0, NULL );
393 fprintf(stderr, "%s failed with error %ld: %s", fn, err, buf);
394 LocalFree((HLOCAL)buf);
400 rust_win32_rand_acquire(HCRYPTPROV* phProv) {
402 (_T("CryptAcquireContext"),
403 // changes to the parameters here should be reflected in the docs of
404 // std::rand::os::OSRng
405 CryptAcquireContext(phProv, NULL, NULL, PROV_RSA_FULL,
406 CRYPT_VERIFYCONTEXT|CRYPT_SILENT));
410 rust_win32_rand_gen(HCRYPTPROV hProv, DWORD dwLen, BYTE* pbBuffer) {
412 (_T("CryptGenRandom"), CryptGenRandom(hProv, dwLen, pbBuffer));
415 rust_win32_rand_release(HCRYPTPROV hProv) {
417 (_T("CryptReleaseContext"), CryptReleaseContext(hProv, 0));
422 // these symbols are listed in rustrt.def.in, so they need to exist; but they
423 // should never be called.
426 rust_win32_rand_acquire() {
430 rust_win32_rand_gen() {
434 rust_win32_rand_release() {
444 // indent-tabs-mode: nil
446 // buffer-file-coding-system: utf-8-unix