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