1/* The following methods were adapted from musl.
2 * See musl/COPYRIGHT for license information. */
3
4#include <errno.h>
5
6#include "../musl/time/time_impl.h"
7
8
9static long  __timezone = 0;
10static int dst_off = 0;
11const char __utc[] = "UTC";
12static const char *__tzname[2] = { __utc, __utc };
13
14
15static void
16__secs_to_zone(long long t, int local, int *isdst, int *offset, long *oppoff, const char **zonename)
17{
18	*isdst = 0;
19	*offset = -__timezone;
20	if (oppoff) *oppoff = -dst_off;
21	*zonename = __tzname[0];
22}
23
24
25struct tm *
26__gmtime_r_fallback(const time_t *restrict t, struct tm *restrict tm)
27{
28	if (__secs_to_tm(*t, tm) < 0) {
29		errno = EOVERFLOW;
30		return 0;
31	}
32	tm->tm_isdst = 0;
33	tm->__tm_gmtoff = 0;
34	tm->__tm_zone = __utc;
35	return tm;
36}
37
38
39time_t
40__mktime_fallback(struct tm *tm)
41{
42	struct tm new;
43	long opp;
44	long long t = __tm_to_secs(tm);
45
46	__secs_to_zone(t, 1, &new.tm_isdst, &new.__tm_gmtoff, &opp, &new.__tm_zone);
47
48	if (tm->tm_isdst>=0 && new.tm_isdst!=tm->tm_isdst)
49		t -= opp - new.__tm_gmtoff;
50
51	t -= new.__tm_gmtoff;
52	if ((time_t)t != t) goto error;
53
54	__secs_to_zone(t, 0, &new.tm_isdst, &new.__tm_gmtoff, &opp, &new.__tm_zone);
55
56	if (__secs_to_tm(t + new.__tm_gmtoff, &new) < 0) goto error;
57
58	*tm = new;
59	return t;
60
61error:
62	errno = EOVERFLOW;
63	return -1;
64}
65
66
67time_t
68__timegm_fallback(struct tm *tm)
69{
70	struct tm new;
71	long long t = __tm_to_secs(tm);
72	if (__secs_to_tm(t, &new) < 0) {
73		errno = EOVERFLOW;
74		return -1;
75	}
76	*tm = new;
77	tm->tm_isdst = 0;
78	tm->__tm_gmtoff = 0;
79	tm->__tm_zone = __utc;
80	return t;
81}
82