1 /*
2 * Copyright 2010, Oliver Tappe, zooey@hirschkaefer.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7 #include <errno.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <time.h>
11
12 #include <syscalls.h>
13
14 #include <StorageDefs.h>
15
16 #include <errno_private.h>
17 #include "LocaleBackend.h"
18
19
20 using BPrivate::Libroot::GetCurrentLocaleBackend;
21 using BPrivate::Libroot::LocaleBackend;
22
23
24 static char sStandardTZName[64] = { "GMT" };
25 static char sDaylightSavingTZName[64] = { "GMT" };
26
27
28 char* tzname[2] = {
29 sStandardTZName,
30 sDaylightSavingTZName
31 };
32 long timezone = 0;
33 int daylight = 0;
34
35
36 // These three functions are used as a fallback when the locale backend could not
37 // be loaded, or for the POSIX locale. They are implemented in localtime_fallback.c.
38 extern "C" struct tm* __gmtime_r_fallback(const time_t* timep, struct tm* tmp);
39 extern "C" time_t __mktime_fallback(struct tm* tmp);
40 extern "C" time_t __timegm_fallback(struct tm* tmp);
41
42
43 extern "C" void
tzset(void)44 tzset(void)
45 {
46 if (GetCurrentLocaleBackend() == NULL && LocaleBackend::LoadBackend() != B_OK)
47 return;
48
49 char timeZoneID[B_FILE_NAME_LENGTH] = { "GMT" };
50 _kern_get_timezone(NULL, timeZoneID, sizeof(timeZoneID));
51
52 GetCurrentLocaleBackend()->TZSet(timeZoneID, getenv("TZ"));
53 }
54
55
56 extern "C" struct tm*
localtime(const time_t * inTime)57 localtime(const time_t* inTime)
58 {
59 static tm tm;
60
61 return localtime_r(inTime, &tm);
62 }
63
64
65 extern "C" struct tm*
localtime_r(const time_t * inTime,struct tm * tmOut)66 localtime_r(const time_t* inTime, struct tm* tmOut)
67 {
68 if (inTime == NULL) {
69 __set_errno(EINVAL);
70 return NULL;
71 }
72
73 tzset();
74
75 LocaleBackend* backend = GetCurrentLocaleBackend();
76
77 if (backend != NULL) {
78 status_t status = backend->Localtime(inTime, tmOut);
79
80 if (status != B_OK)
81 __set_errno(EOVERFLOW);
82
83 return tmOut;
84 }
85
86 // without a locale backend, there are no timezones, so we fall back to
87 // using a basic gmtime_r implementation.
88 return __gmtime_r_fallback(inTime, tmOut);
89 }
90
91
92 extern "C" struct tm*
gmtime(const time_t * inTime)93 gmtime(const time_t* inTime)
94 {
95 static tm tm;
96
97 return gmtime_r(inTime, &tm);
98 }
99
100
101 extern "C" struct tm*
gmtime_r(const time_t * inTime,struct tm * tmOut)102 gmtime_r(const time_t* inTime, struct tm* tmOut)
103 {
104 if (inTime == NULL) {
105 __set_errno(EINVAL);
106 return NULL;
107 }
108
109 tzset();
110
111 LocaleBackend* backend = GetCurrentLocaleBackend();
112
113 if (backend != NULL) {
114 status_t status = backend->Gmtime(inTime, tmOut);
115
116 if (status != B_OK)
117 __set_errno(EOVERFLOW);
118
119 return tmOut;
120 }
121
122 // without a locale backend, we fall back to using a basic gmtime_r
123 // implementation.
124 return __gmtime_r_fallback(inTime, tmOut);
125 }
126
127
128 extern "C" time_t
mktime(struct tm * inTm)129 mktime(struct tm* inTm)
130 {
131 if (inTm == NULL) {
132 __set_errno(EINVAL);
133 return -1;
134 }
135
136 tzset();
137
138 LocaleBackend* backend = GetCurrentLocaleBackend();
139
140 if (backend != NULL) {
141 time_t timeOut;
142 status_t status = backend->Mktime(inTm, timeOut);
143
144 if (status != B_OK) {
145 __set_errno(EOVERFLOW);
146 return -1;
147 }
148
149 return timeOut;
150 }
151
152 // without a locale backend, we fall back to using a basic gmtime_r
153 // implementation.
154 return __mktime_fallback(inTm);
155 }
156
157
158 extern "C" time_t
timegm(struct tm * inTm)159 timegm(struct tm* inTm)
160 {
161 if (inTm == NULL) {
162 __set_errno(EINVAL);
163 return -1;
164 }
165 tzset();
166
167 LocaleBackend* backend = GetCurrentLocaleBackend();
168
169 if (backend != NULL) {
170 time_t timeOut;
171 status_t status = backend->Timegm(inTm, timeOut);
172
173 if (status != B_OK) {
174 __set_errno(EOVERFLOW);
175 return -1;
176 }
177
178 return timeOut;
179 }
180
181 // without a locale backend, we fall back to using a basic timegm
182 // implementation.
183 return __timegm_fallback(inTm);
184 }
185