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