]> git.lizzy.rs Git - rust.git/blob - src/rt/rust_builtin.c
auto merge of #15999 : Kimundi/rust/fix_folder, r=nikomatsakis
[rust.git] / src / rt / rust_builtin.c
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.
4 //
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.
10
11 /* Foreign builtins. */
12
13 #include "valgrind/valgrind.h"
14
15 #include <stdint.h>
16 #include <time.h>
17 #include <string.h>
18 #include <assert.h>
19 #include <stdlib.h>
20
21 #if !defined(__WIN32__)
22 #include <sys/time.h>
23 #include <sys/types.h>
24 #include <dirent.h>
25 #include <signal.h>
26 #include <unistd.h>
27 #include <pthread.h>
28 #else
29 #include <windows.h>
30 #include <wincrypt.h>
31 #include <stdio.h>
32 #include <tchar.h>
33 #endif
34
35 #ifdef __APPLE__
36 #include <TargetConditionals.h>
37 #include <mach/mach_time.h>
38
39 #if !(TARGET_OS_IPHONE)
40 #include <crt_externs.h>
41 #endif
42 #endif
43
44 #ifdef __ANDROID__
45 time_t
46 timegm(struct tm *tm)
47 {
48     time_t ret;
49     char *tz;
50
51     tz = getenv("TZ");
52     if (tz)
53         tz = strdup(tz);
54     setenv("TZ", "", 1);
55     tzset();
56     ret = mktime(tm);
57     if (tz) {
58         setenv("TZ", tz, 1);
59         free(tz);
60     } else
61         unsetenv("TZ");
62     tzset();
63     return ret;
64 }
65 #endif
66
67 #ifdef __APPLE__
68 #if (TARGET_OS_IPHONE)
69 extern char **environ;
70 #endif
71 #endif
72
73 #if defined(__FreeBSD__) || defined(__linux__) || defined(__ANDROID__) || defined(__DragonFly__)
74 extern char **environ;
75 #endif
76
77 #if defined(__WIN32__)
78 char**
79 rust_env_pairs() {
80     return 0;
81 }
82 #else
83 char**
84 rust_env_pairs() {
85 #if defined(__APPLE__) && !(TARGET_OS_IPHONE)
86     char **environ = *_NSGetEnviron();
87 #endif
88     return environ;
89 }
90 #endif
91
92 char*
93 #if defined(__WIN32__)
94 rust_list_dir_val(WIN32_FIND_DATA* entry_ptr) {
95     return entry_ptr->cFileName;
96 }
97 #else
98 rust_list_dir_val(struct dirent* entry_ptr) {
99     return entry_ptr->d_name;
100 }
101 #endif
102
103 size_t
104 #if defined(__WIN32__)
105 rust_list_dir_wfd_size() {
106     return sizeof(WIN32_FIND_DATAW);
107 }
108 #else
109 rust_list_dir_wfd_size() {
110     return 0;
111 }
112 #endif
113
114 void*
115 #if defined(__WIN32__)
116 rust_list_dir_wfd_fp_buf(WIN32_FIND_DATAW* wfd) {
117     if(wfd == NULL) {
118         return 0;
119     }
120     else {
121         return wfd->cFileName;
122     }
123 }
124 #else
125 rust_list_dir_wfd_fp_buf(void* wfd) {
126     return 0;
127 }
128 #endif
129
130 typedef struct {
131     int32_t tm_sec;
132     int32_t tm_min;
133     int32_t tm_hour;
134     int32_t tm_mday;
135     int32_t tm_mon;
136     int32_t tm_year;
137     int32_t tm_wday;
138     int32_t tm_yday;
139     int32_t tm_isdst;
140     int32_t tm_gmtoff;
141     int32_t tm_nsec;
142 } rust_tm;
143
144 void rust_tm_to_tm(rust_tm* in_tm, struct tm* out_tm) {
145     memset(out_tm, 0, sizeof(struct tm));
146     out_tm->tm_sec = in_tm->tm_sec;
147     out_tm->tm_min = in_tm->tm_min;
148     out_tm->tm_hour = in_tm->tm_hour;
149     out_tm->tm_mday = in_tm->tm_mday;
150     out_tm->tm_mon = in_tm->tm_mon;
151     out_tm->tm_year = in_tm->tm_year;
152     out_tm->tm_wday = in_tm->tm_wday;
153     out_tm->tm_yday = in_tm->tm_yday;
154     out_tm->tm_isdst = in_tm->tm_isdst;
155 }
156
157 void tm_to_rust_tm(struct tm* in_tm,
158                    rust_tm* out_tm,
159                    int32_t gmtoff,
160                    int32_t nsec) {
161     out_tm->tm_sec = in_tm->tm_sec;
162     out_tm->tm_min = in_tm->tm_min;
163     out_tm->tm_hour = in_tm->tm_hour;
164     out_tm->tm_mday = in_tm->tm_mday;
165     out_tm->tm_mon = in_tm->tm_mon;
166     out_tm->tm_year = in_tm->tm_year;
167     out_tm->tm_wday = in_tm->tm_wday;
168     out_tm->tm_yday = in_tm->tm_yday;
169     out_tm->tm_isdst = in_tm->tm_isdst;
170     out_tm->tm_gmtoff = gmtoff;
171     out_tm->tm_nsec = nsec;
172 }
173
174 #if defined(__WIN32__)
175 #define TZSET() _tzset()
176 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
177 #define GMTIME(clock, result) gmtime_s((result), (clock))
178 #define LOCALTIME(clock, result) localtime_s((result), (clock))
179 #define TIMEGM(result) _mkgmtime64(result)
180 #else
181 struct tm* GMTIME(const time_t *clock, struct tm *result) {
182     struct tm* t = gmtime(clock);
183     if (t == NULL || result == NULL) { return NULL; }
184     *result = *t;
185     return result;
186 }
187 struct tm* LOCALTIME(const time_t *clock, struct tm *result) {
188     struct tm* t = localtime(clock);
189     if (t == NULL || result == NULL) { return NULL; }
190     *result = *t;
191     return result;
192 }
193 #define TIMEGM(result) mktime((result)) - _timezone
194 #endif
195 #else
196 #define TZSET() tzset()
197 #define GMTIME(clock, result) gmtime_r((clock), (result))
198 #define LOCALTIME(clock, result) localtime_r((clock), (result))
199 #define TIMEGM(result) timegm(result)
200 #endif
201
202 void
203 rust_tzset() {
204     TZSET();
205 }
206
207 void
208 rust_gmtime(int64_t sec, int32_t nsec, rust_tm *timeptr) {
209     struct tm tm;
210     time_t s = sec;
211     GMTIME(&s, &tm);
212
213     tm_to_rust_tm(&tm, timeptr, 0, nsec);
214 }
215
216 void
217 rust_localtime(int64_t sec, int32_t nsec, rust_tm *timeptr) {
218     struct tm tm;
219     time_t s = sec;
220     LOCALTIME(&s, &tm);
221
222 #if defined(__WIN32__)
223     int32_t gmtoff = -timezone;
224 #else
225     int32_t gmtoff = tm.tm_gmtoff;
226 #endif
227
228     tm_to_rust_tm(&tm, timeptr, gmtoff, nsec);
229 }
230
231 int64_t
232 rust_timegm(rust_tm* timeptr) {
233     struct tm t;
234     rust_tm_to_tm(timeptr, &t);
235     return TIMEGM(&t);
236 }
237
238 int64_t
239 rust_mktime(rust_tm* timeptr) {
240     struct tm t;
241     rust_tm_to_tm(timeptr, &t);
242     return mktime(&t);
243 }
244
245 #ifndef _WIN32
246
247 DIR*
248 rust_opendir(char *dirname) {
249     return opendir(dirname);
250 }
251
252 int
253 rust_readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) {
254     return readdir_r(dirp, entry, result);
255 }
256
257 int
258 rust_dirent_t_size() {
259     return sizeof(struct dirent);
260 }
261
262 #else
263
264 void
265 rust_opendir() {
266 }
267
268 void
269 rust_readdir() {
270 }
271
272 void
273 rust_dirent_t_size() {
274 }
275
276 #endif
277
278 uintptr_t
279 rust_running_on_valgrind() {
280     return RUNNING_ON_VALGRIND;
281 }
282
283 #if defined(__WIN32__)
284 int
285 get_num_cpus() {
286     SYSTEM_INFO sysinfo;
287     GetSystemInfo(&sysinfo);
288
289     return (int) sysinfo.dwNumberOfProcessors;
290 }
291 #elif defined(__BSD__)
292 int
293 get_num_cpus() {
294     /* swiped from http://stackoverflow.com/questions/150355/
295        programmatically-find-the-number-of-cores-on-a-machine */
296
297     unsigned int numCPU;
298     int mib[4];
299     size_t len = sizeof(numCPU);
300
301     /* set the mib for hw.ncpu */
302     mib[0] = CTL_HW;
303     mib[1] = HW_AVAILCPU;  // alternatively, try HW_NCPU;
304
305     /* get the number of CPUs from the system */
306     sysctl(mib, 2, &numCPU, &len, NULL, 0);
307
308     if( numCPU < 1 ) {
309         mib[1] = HW_NCPU;
310         sysctl( mib, 2, &numCPU, &len, NULL, 0 );
311
312         if( numCPU < 1 ) {
313             numCPU = 1;
314         }
315     }
316     return numCPU;
317 }
318 #elif defined(__GNUC__)
319 int
320 get_num_cpus() {
321     return sysconf(_SC_NPROCESSORS_ONLN);
322 }
323 #endif
324
325 uintptr_t
326 rust_get_num_cpus() {
327     return get_num_cpus();
328 }
329
330 unsigned int
331 rust_valgrind_stack_register(void *start, void *end) {
332   return VALGRIND_STACK_REGISTER(start, end);
333 }
334
335 void
336 rust_valgrind_stack_deregister(unsigned int id) {
337   VALGRIND_STACK_DEREGISTER(id);
338 }
339
340 #if defined(__WIN32__)
341
342 void
343 rust_unset_sigprocmask() {
344     // empty stub for windows to keep linker happy
345 }
346
347 #else
348
349 void
350 rust_unset_sigprocmask() {
351     // this can't be safely converted to rust code because the
352     // representation of sigset_t is platform-dependent
353     sigset_t sset;
354     sigemptyset(&sset);
355     sigprocmask(SIG_SETMASK, &sset, NULL);
356 }
357
358 #endif
359
360 #if defined(__DragonFly__)
361 #include <errno.h>
362 // In DragonFly __error() is an inline function and as such
363 // no symbol exists for it.
364 int *__dfly_error(void) { return __error(); }
365 #endif
366
367 //
368 // Local Variables:
369 // mode: C++
370 // fill-column: 78;
371 // indent-tabs-mode: nil
372 // c-basic-offset: 4
373 // buffer-file-coding-system: utf-8-unix
374 // End:
375 //