1 /**
2  * D header file for POSIX.
3  *
4  * Copyright: Copyright Sean Kelly 2005 - 2009.
5  * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6  * Authors:   Sean Kelly,
7               Alex Rønne Petersen
8  * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
9  */
10 
11 /*          Copyright Sean Kelly 2005 - 2009.
12  * Distributed under the Boost Software License, Version 1.0.
13  *    (See accompanying file LICENSE or copy at
14  *          http://www.boost.org/LICENSE_1_0.txt)
15  */
16 module core.sys.posix.time;
17 
18 import core.sys.posix.config;
19 public import core.stdc.time;
20 public import core.sys.posix.sys.types;
21 public import core.sys.posix.signal; // for sigevent
22 
23 version (OSX)
24     version = Darwin;
25 else version (iOS)
26     version = Darwin;
27 else version (TVOS)
28     version = Darwin;
29 else version (WatchOS)
30     version = Darwin;
31 
32 version (Posix):
33 extern (C):
34 nothrow:
35 @nogc:
36 
37 //
38 // Required (defined in core.stdc.time)
39 //
40 /*
41 char* asctime(const scope tm*);
42 clock_t clock();
43 char* ctime(const scope time_t*);
44 double difftime(time_t, time_t);
45 tm* gmtime(const scope time_t*);
46 tm* localtime(const scope time_t*);
47 time_t mktime(tm*);
48 size_t strftime(char*, size_t, const scope char*, const scope tm*);
49 time_t time(time_t*);
50 */
51 
52 version (CRuntime_Glibc)
53 {
54     time_t timegm(tm*); // non-standard
55 }
56 else version (Darwin)
57 {
58     time_t timegm(tm*); // non-standard
59 }
60 else version (FreeBSD)
61 {
62     time_t timegm(tm*); // non-standard
63 }
64 else version (NetBSD)
65 {
66     time_t timegm(tm*); // non-standard
67 }
68 else version (OpenBSD)
69 {
70     time_t timegm(tm*); // non-standard
71 }
72 else version (DragonFlyBSD)
73 {
74     time_t timegm(tm*); // non-standard
75 }
76 else version (Solaris)
77 {
78     time_t timegm(tm*); // non-standard
79 }
80 else version (CRuntime_Bionic)
81 {
82     // Not supported.
83 }
84 else version (CRuntime_Musl)
85 {
86     pragma(mangle, muslRedirTime64Mangle!("timegm", "__timegm_time64"))
87     time_t timegm(tm*);
88 }
89 else version (CRuntime_UClibc)
90 {
91     time_t timegm(tm*);
92 }
93 else
94 {
95     static assert(false, "Unsupported platform");
96 }
97 
98 //
99 // C Extension (CX)
100 // (defined in core.stdc.time)
101 //
102 /*
103 char* tzname[];
104 void tzset();
105 */
106 
107 //
108 // Process CPU-Time Clocks (CPT)
109 //
110 /*
111 int clock_getcpuclockid(pid_t, clockid_t*);
112 */
113 
114 //
115 // Clock Selection (CS)
116 //
117 /*
118 int clock_nanosleep(clockid_t, int, const scope timespec*, timespec*);
119 */
120 
121 //
122 // Monotonic Clock (MON)
123 //
124 /*
125 CLOCK_MONOTONIC
126 */
127 
128 version (linux)
129 {
130     enum CLOCK_MONOTONIC          = 1;
131 }
132 else version (FreeBSD)
133 {   // time.h
134     enum CLOCK_MONOTONIC         = 4;
135 }
136 else version (NetBSD)
137 {
138     // time.h
139     enum CLOCK_MONOTONIC         = 3;
140 }
141 else version (OpenBSD)
142 {
143     // time.h
144     enum CLOCK_MONOTONIC         = 3;
145 }
146 else version (DragonFlyBSD)
147 {   // time.h
148     enum CLOCK_MONOTONIC         = 4;
149 }
150 else version (Darwin)
151 {
152     // No CLOCK_MONOTONIC defined
153 }
154 else version (Solaris)
155 {
156     enum CLOCK_MONOTONIC = 4;
157 }
158 else
159 {
160     static assert(0);
161 }
162 
163 //
164 // Timer (TMR)
165 //
166 /*
167 CLOCK_PROCESS_CPUTIME_ID (TMR|CPT)
168 CLOCK_THREAD_CPUTIME_ID (TMR|TCT)
169 
170 struct timespec
171 {
172     time_t  tv_sec;
173     int     tv_nsec;
174 }
175 
176 struct itimerspec
177 {
178     timespec it_interval;
179     timespec it_value;
180 }
181 
182 CLOCK_REALTIME
183 TIMER_ABSTIME
184 
185 clockid_t
186 timer_t
187 
188 int clock_getres(clockid_t, timespec*);
189 int clock_gettime(clockid_t, timespec*);
190 int clock_settime(clockid_t, const scope timespec*);
191 int nanosleep(const scope timespec*, timespec*);
192 int timer_create(clockid_t, sigevent*, timer_t*);
193 int timer_delete(timer_t);
194 int timer_gettime(timer_t, itimerspec*);
195 int timer_getoverrun(timer_t);
196 int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*);
197 */
198 
199 version (linux)
200 {
201     struct timespec
202     {
203         time_t  tv_sec;
204         c_long  tv_nsec;
205     }
206 }
207 else version (Darwin)
208 {
209     struct timespec
210     {
211         time_t  tv_sec;
212         c_long  tv_nsec;
213     }
214 }
215 else version (FreeBSD)
216 {
217     struct timespec
218     {
219         time_t  tv_sec;
220         c_long  tv_nsec;
221     }
222 }
223 else version (NetBSD)
224 {
225     struct timespec
226     {
227         time_t  tv_sec;
228         c_long  tv_nsec;
229     }
230 }
231 else version (OpenBSD)
232 {
233     struct timespec
234     {
235         time_t  tv_sec;
236         c_long  tv_nsec;
237     }
238 }
239 else version (DragonFlyBSD)
240 {
241     struct timespec
242     {
243         time_t  tv_sec;
244         c_long  tv_nsec;
245     }
246 }
247 else version (Solaris)
248 {
249     struct timespec
250     {
251         time_t tv_sec;
252         c_long tv_nsec;
253     }
254 
255     alias timespec timestruc_t;
256 }
257 else
258 {
259     static assert(false, "Unsupported platform");
260 }
261 
262 version (CRuntime_Glibc)
263 {
264     enum CLOCK_PROCESS_CPUTIME_ID = 2;
265     enum CLOCK_THREAD_CPUTIME_ID  = 3;
266 
267     // NOTE: See above for why this is commented out.
268     //
269     //struct timespec
270     //{
271     //    time_t  tv_sec;
272     //    c_long  tv_nsec;
273     //}
274 
275     struct itimerspec
276     {
277         timespec it_interval;
278         timespec it_value;
279     }
280 
281     enum CLOCK_REALTIME         = 0;
282     enum TIMER_ABSTIME          = 0x01;
283 
284     alias int clockid_t;
285     alias void* timer_t;
286 
287     int clock_getres(clockid_t, timespec*);
288     int clock_gettime(clockid_t, timespec*);
289     int clock_settime(clockid_t, const scope timespec*);
290     int nanosleep(const scope timespec*, timespec*);
291     int timer_create(clockid_t, sigevent*, timer_t*);
292     int timer_delete(timer_t);
293     int timer_gettime(timer_t, itimerspec*);
294     int timer_getoverrun(timer_t);
295     int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*);
296 }
297 else version (Darwin)
298 {
299     int nanosleep(const scope timespec*, timespec*);
300 }
301 else version (FreeBSD)
302 {
303     //enum CLOCK_PROCESS_CPUTIME_ID = ??;
304     enum CLOCK_THREAD_CPUTIME_ID  = 15;
305 
306     // NOTE: See above for why this is commented out.
307     //
308     //struct timespec
309     //{
310     //    time_t  tv_sec;
311     //    c_long  tv_nsec;
312     //}
313 
314     struct itimerspec
315     {
316         timespec it_interval;
317         timespec it_value;
318     }
319 
320     enum CLOCK_REALTIME      = 0;
321     enum TIMER_ABSTIME       = 0x01;
322 
323     alias int clockid_t; // <sys/_types.h>
324     alias int timer_t;
325 
326     int clock_getres(clockid_t, timespec*);
327     int clock_gettime(clockid_t, timespec*);
328     int clock_settime(clockid_t, const scope timespec*);
329     int nanosleep(const scope timespec*, timespec*);
330     int timer_create(clockid_t, sigevent*, timer_t*);
331     int timer_delete(timer_t);
332     int timer_gettime(timer_t, itimerspec*);
333     int timer_getoverrun(timer_t);
334     int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*);
335 }
336 else version (DragonFlyBSD)
337 {
338     enum CLOCK_THREAD_CPUTIME_ID  = 15;
339 
340     struct itimerspec
341     {
342         timespec it_interval;
343         timespec it_value;
344     }
345 
346     enum CLOCK_REALTIME      = 0;
347     enum TIMER_ABSTIME       = 0x01;
348 
349     alias int clockid_t; // <sys/_types.h>
350     alias int timer_t;
351 
352     int clock_getres(clockid_t, timespec*);
353     int clock_gettime(clockid_t, timespec*);
354     int clock_settime(clockid_t, const scope timespec*);
355     int nanosleep(const scope timespec*, timespec*);
356     int timer_create(clockid_t, sigevent*, timer_t*);
357     int timer_delete(timer_t);
358     int timer_gettime(timer_t, itimerspec*);
359     int timer_getoverrun(timer_t);
360     int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*);
361 }
362 else version (NetBSD)
363 {
364     struct itimerspec
365     {
366         timespec it_interval;
367         timespec it_value;
368     }
369 
370     enum CLOCK_REALTIME      = 0;
371     enum TIMER_ABSTIME       = 0x01;
372 
373     alias int clockid_t; // <sys/_types.h>
374     alias int timer_t;
375 
376     int clock_getres(clockid_t, timespec*);
377     int clock_gettime(clockid_t, timespec*);
378     int clock_settime(clockid_t, const scope timespec*);
379     int nanosleep(const scope timespec*, timespec*);
380     int timer_create(clockid_t, sigevent*, timer_t*);
381     int timer_delete(timer_t);
382     int timer_gettime(timer_t, itimerspec*);
383     int timer_getoverrun(timer_t);
384     int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*);
385 }
386 else version (OpenBSD)
387 {
388     struct itimerspec
389     {
390         timespec it_interval;
391         timespec it_value;
392     }
393 
394     enum CLOCK_REALTIME      = 0;
395     enum TIMER_ABSTIME       = 0x1;
396 
397     alias int clockid_t; // <sys/_types.h>
398     alias int timer_t;
399 
400     int clock_getres(clockid_t, timespec*);
401     int clock_gettime(clockid_t, timespec*);
402     int clock_settime(clockid_t, const scope timespec*);
403     int nanosleep(const scope timespec*, timespec*);
404 }
405 else version (Solaris)
406 {
407     enum CLOCK_PROCESS_CPUTIME_ID = 5; // <sys/time_impl.h>
408     enum CLOCK_THREAD_CPUTIME_ID  = 2; // <sys/time_impl.h>
409 
410     struct itimerspec
411     {
412         timespec it_interval;
413         timespec it_value;
414     }
415 
416     enum CLOCK_REALTIME = 3; // <sys/time_impl.h>
417     enum TIMER_ABSOLUTE = 0x1;
418 
419     alias int clockid_t;
420     alias int timer_t;
421 
422     int clock_getres(clockid_t, timespec*);
423     int clock_gettime(clockid_t, timespec*);
424     int clock_settime(clockid_t, const scope timespec*);
425     int clock_nanosleep(clockid_t, int, const scope timespec*, timespec*);
426 
427     int nanosleep(const scope timespec*, timespec*);
428 
429     int timer_create(clockid_t, sigevent*, timer_t*);
430     int timer_delete(timer_t);
431     int timer_getoverrun(timer_t);
432     int timer_gettime(timer_t, itimerspec*);
433     int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*);
434 }
435 else version (CRuntime_Bionic)
436 {
437     enum CLOCK_PROCESS_CPUTIME_ID = 2;
438     enum CLOCK_THREAD_CPUTIME_ID  = 3;
439 
440     struct itimerspec
441     {
442         timespec it_interval;
443         timespec it_value;
444     }
445 
446     enum CLOCK_REALTIME    = 0;
447     enum CLOCK_REALTIME_HR = 4;
448     enum TIMER_ABSTIME     = 0x01;
449 
450     alias int   clockid_t;
451     alias void* timer_t; // Updated since Lollipop
452 
453     int clock_getres(int, timespec*);
454     int clock_gettime(int, timespec*);
455     int nanosleep(const scope timespec*, timespec*);
456     int timer_create(int, sigevent*, timer_t*);
457     int timer_delete(timer_t);
458     int timer_gettime(timer_t, itimerspec*);
459     int timer_getoverrun(timer_t);
460     int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*);
461 }
462 else version (CRuntime_Musl)
463 {
464     alias int clockid_t;
465     alias void* timer_t;
466 
467     struct itimerspec
468     {
469         timespec it_interval;
470         timespec it_value;
471     }
472 
473     enum TIMER_ABSTIME = 1;
474 
475     enum CLOCK_REALTIME = 0;
476     enum CLOCK_PROCESS_CPUTIME_ID = 2;
477     enum CLOCK_THREAD_CPUTIME_ID = 3;
478     enum CLOCK_REALTIME_COARSE = 5;
479     enum CLOCK_BOOTTIME = 7;
480     enum CLOCK_REALTIME_ALARM = 8;
481     enum CLOCK_BOOTTIME_ALARM = 9;
482     enum CLOCK_SGI_CYCLE = 10;
483     enum CLOCK_TAI = 11;
484 
485     int nanosleep(const scope timespec*, timespec*);
486 
487     pragma(mangle, muslRedirTime64Mangle!("clock_getres", "__clock_getres_time64"))
488     int clock_getres(clockid_t, timespec*);
489     pragma(mangle, muslRedirTime64Mangle!("clock_gettime", "__clock_gettime64"))
490     int clock_gettime(clockid_t, timespec*);
491     pragma(mangle, muslRedirTime64Mangle!("clock_settime", "__clock_settime64"))
492     int clock_settime(clockid_t, const scope timespec*);
493     pragma(mangle, muslRedirTime64Mangle!("clock_nanosleep", "__clock_nanosleep_time64"))
494     int clock_nanosleep(clockid_t, int, const scope timespec*, timespec*);
495     int clock_getcpuclockid(pid_t, clockid_t *);
496 
497     int timer_create(clockid_t, sigevent*, timer_t*);
498     int timer_delete(timer_t);
499     pragma(mangle, muslRedirTime64Mangle!("timer_gettime", "__timer_gettime64"))
500     int timer_gettime(timer_t, itimerspec*);
501     pragma(mangle, muslRedirTime64Mangle!("timer_settime", "__timer_settime64"))
502     int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*);
503     int timer_getoverrun(timer_t);
504 }
505 else version (CRuntime_UClibc)
506 {
507     enum CLOCK_REALTIME             = 0;
508     enum CLOCK_PROCESS_CPUTIME_ID   = 2;
509     enum CLOCK_THREAD_CPUTIME_ID    = 3;
510 
511     struct itimerspec
512     {
513         timespec it_interval;
514         timespec it_value;
515     }
516 
517     enum TIMER_ABSTIME          = 0x01;
518 
519     alias int clockid_t;
520     alias void* timer_t;
521 
522     int clock_getres(clockid_t, timespec*);
523     int clock_gettime(clockid_t, timespec*);
524     int clock_settime(clockid_t, const scope timespec*);
525     int nanosleep(const scope timespec*, timespec*);
526     int timer_create(clockid_t, sigevent*, timer_t*);
527     int timer_delete(timer_t);
528     int timer_gettime(timer_t, itimerspec*);
529     int timer_getoverrun(timer_t);
530     int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*);
531 }
532 else
533 {
534     static assert(false, "Unsupported platform");
535 }
536 
537 //
538 // Thread-Safe Functions (TSF)
539 //
540 /*
541 char* asctime_r(const scope tm*, char*);
542 char* ctime_r(const scope time_t*, char*);
543 tm*   gmtime_r(const scope time_t*, tm*);
544 tm*   localtime_r(const scope time_t*, tm*);
545 */
546 
547 version (CRuntime_Glibc)
548 {
549     char* asctime_r(const scope tm*, char*);
550     char* ctime_r(const scope time_t*, char*);
551     tm*   gmtime_r(const scope time_t*, tm*);
552     tm*   localtime_r(const scope time_t*, tm*);
553 }
554 else version (Darwin)
555 {
556     char* asctime_r(const scope tm*, char*);
557     char* ctime_r(const scope time_t*, char*);
558     tm*   gmtime_r(const scope time_t*, tm*);
559     tm*   localtime_r(const scope time_t*, tm*);
560 }
561 else version (FreeBSD)
562 {
563     char* asctime_r(const scope tm*, char*);
564     char* ctime_r(const scope time_t*, char*);
565     tm*   gmtime_r(const scope time_t*, tm*);
566     tm*   localtime_r(const scope time_t*, tm*);
567 }
568 else version (NetBSD)
569 {
570     char* asctime_r(const scope tm*, char*);
571     char* ctime_r(const scope time_t*, char*);
572     tm*   gmtime_r(const scope time_t*, tm*);
573     tm*   localtime_r(const scope time_t*, tm*);
574 }
575 else version (OpenBSD)
576 {
577     char* asctime_r(const scope tm*, char*);
578     char* ctime_r(const scope time_t*, char*);
579     tm*   gmtime_r(const scope time_t*, tm*);
580     tm*   localtime_r(const scope time_t*, tm*);
581 }
582 else version (DragonFlyBSD)
583 {
584     char* asctime_r(const scope tm*, char*);
585     char* ctime_r(const scope time_t*, char*);
586     tm*   gmtime_r(const scope time_t*, tm*);
587     tm*   localtime_r(const scope time_t*, tm*);
588 }
589 else version (Solaris)
590 {
591     char* asctime_r(const scope tm*, char*);
592     char* ctime_r(const scope time_t*, char*);
593     tm* gmtime_r(const scope time_t*, tm*);
594     tm* localtime_r(const scope time_t*, tm*);
595 }
596 else version (CRuntime_Bionic)
597 {
598     char* asctime_r(const scope tm*, char*);
599     char* ctime_r(const scope time_t*, char*);
600     tm* gmtime_r(const scope time_t*, tm*);
601     tm* localtime_r(const scope time_t*, tm*);
602 }
603 else version (CRuntime_Musl)
604 {
605     char* asctime_r(const scope tm*, char*);
606     pragma(mangle, muslRedirTime64Mangle!("ctime_r", "__ctime64_r"))
607     char* ctime_r(const scope time_t*, char*);
608     pragma(mangle, muslRedirTime64Mangle!("gmtime_r", "__gmtime64_r"))
609     tm*   gmtime_r(const scope time_t*, tm*);
610     pragma(mangle, muslRedirTime64Mangle!("localtime_r", "__localtime64_r"))
611     tm*   localtime_r(const scope time_t*, tm*);
612 }
613 else version (CRuntime_UClibc)
614 {
615     char* asctime_r(const scope tm*, char*);
616     char* ctime_r(const scope time_t*, char*);
617     tm*   gmtime_r(const scope time_t*, tm*);
618     tm*   localtime_r(const scope time_t*, tm*);
619 }
620 else
621 {
622     static assert(false, "Unsupported platform");
623 }
624 
625 //
626 // XOpen (XSI)
627 //
628 /*
629 getdate_err
630 
631 int daylight;
632 int timezone;
633 
634 tm* getdate(const scope char*);
635 char* strptime(const scope char*, const scope char*, tm*);
636 */
637 
638 version (CRuntime_Glibc)
639 {
640     extern __gshared int    daylight;
641     extern __gshared c_long timezone;
642 
643     tm*   getdate(const scope char*);
644     char* strptime(const scope char*, const scope char*, tm*);
645 }
646 else version (Darwin)
647 {
648     extern __gshared c_long timezone;
649     extern __gshared int    daylight;
650 
651     tm*   getdate(const scope char*);
652     char* strptime(const scope char*, const scope char*, tm*);
653 }
654 else version (FreeBSD)
655 {
656     //tm*   getdate(const scope char*);
657     char* strptime(const scope char*, const scope char*, tm*);
658 }
659 else version (NetBSD)
660 {
661     tm*   getdate(const scope char*);
662     char* strptime(const scope char*, const scope char*, tm*);
663 }
664 else version (OpenBSD)
665 {
666     //tm*   getdate(const scope char*);
667     char* strptime(const scope char*, const scope char*, tm*);
668 }
669 else version (DragonFlyBSD)
670 {
671     //tm*   getdate(const scope char*);
672     char* strptime(const scope char*, const scope char*, tm*);
673 }
674 else version (Solaris)
675 {
676     extern __gshared c_long timezone, altzone;
677     extern __gshared int daylight;
678 
679     tm* getdate(const scope char*);
680     char* __strptime_dontzero(const scope char*, const scope char*, tm*);
681     alias __strptime_dontzero strptime;
682 }
683 else version (CRuntime_Bionic)
684 {
685     extern __gshared int    daylight;
686     extern __gshared c_long timezone;
687 
688     char* strptime(const scope char*, const scope char*, tm*);
689 }
690 else version (CRuntime_Musl)
691 {
692     extern __gshared int daylight;
693     extern __gshared c_long timezone;
694 
695     tm*   getdate(const scope char*);
696     char* strptime(const scope char*, const scope char*, tm*);
697 }
698 else version (CRuntime_UClibc)
699 {
700     extern __gshared int    daylight;
701     extern __gshared c_long timezone;
702 
703     tm*   getdate(const scope char*);
704     char* strptime(const scope char*, const scope char*, tm*);
705 }
706 else
707 {
708     static assert(false, "Unsupported platform");
709 }