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::gLocaleBackend; 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. They are implemented in localtime_fading_out.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 44 tzset(void) 45 { 46 if (gLocaleBackend == 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 gLocaleBackend->TZSet(timeZoneID, getenv("TZ")); 53 } 54 55 56 extern "C" struct tm* 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* 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 if (gLocaleBackend != NULL) { 75 status_t status = gLocaleBackend->Localtime(inTime, tmOut); 76 77 if (status != B_OK) 78 __set_errno(EOVERFLOW); 79 80 return tmOut; 81 } 82 83 // without a locale backend, there are no timezones, so we fall back to 84 // using a basic gmtime_r implementation. 85 return __gmtime_r_fallback(inTime, tmOut); 86 } 87 88 89 extern "C" struct tm* 90 gmtime(const time_t* inTime) 91 { 92 static tm tm; 93 94 return gmtime_r(inTime, &tm); 95 } 96 97 98 extern "C" struct tm* 99 gmtime_r(const time_t* inTime, struct tm* tmOut) 100 { 101 if (inTime == NULL) { 102 __set_errno(EINVAL); 103 return NULL; 104 } 105 106 tzset(); 107 if (gLocaleBackend != NULL) { 108 status_t status = gLocaleBackend->Gmtime(inTime, tmOut); 109 110 if (status != B_OK) 111 __set_errno(EOVERFLOW); 112 113 return tmOut; 114 } 115 116 // without a locale backend, we fall back to using a basic gmtime_r 117 // implementation. 118 return __gmtime_r_fallback(inTime, tmOut); 119 } 120 121 122 extern "C" time_t 123 mktime(struct tm* inTm) 124 { 125 if (inTm == NULL) { 126 __set_errno(EINVAL); 127 return -1; 128 } 129 130 tzset(); 131 if (gLocaleBackend != NULL) { 132 time_t timeOut; 133 status_t status = gLocaleBackend->Mktime(inTm, timeOut); 134 135 if (status != B_OK) { 136 __set_errno(EOVERFLOW); 137 return -1; 138 } 139 140 return timeOut; 141 } 142 143 // without a locale backend, we fall back to using a basic gmtime_r 144 // implementation. 145 return __mktime_fallback(inTm); 146 } 147 148 149 extern "C" time_t 150 timegm(struct tm* inTm) 151 { 152 if (inTm == NULL) { 153 __set_errno(EINVAL); 154 return -1; 155 } 156 tzset(); 157 if (gLocaleBackend != NULL) { 158 time_t timeOut; 159 status_t status = gLocaleBackend->Timegm(inTm, timeOut); 160 161 if (status != B_OK) { 162 __set_errno(EOVERFLOW); 163 return -1; 164 } 165 166 return timeOut; 167 } 168 169 // without a locale backend, we fall back to using a basic timegm 170 // implementation. 171 return __timegm_fallback(inTm); 172 } 173