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 two 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 41 42 extern "C" void 43 tzset(void) 44 { 45 if (gLocaleBackend == NULL && LocaleBackend::LoadBackend() != B_OK) 46 return; 47 48 char timeZoneID[B_FILE_NAME_LENGTH] = { "GMT" }; 49 _kern_get_timezone(NULL, timeZoneID, sizeof(timeZoneID)); 50 51 gLocaleBackend->TZSet(timeZoneID, getenv("TZ")); 52 } 53 54 55 extern "C" struct tm* 56 localtime(const time_t* inTime) 57 { 58 static tm tm; 59 60 return localtime_r(inTime, &tm); 61 } 62 63 64 extern "C" struct tm* 65 localtime_r(const time_t* inTime, struct tm* tmOut) 66 { 67 if (inTime == NULL) { 68 __set_errno(EINVAL); 69 return NULL; 70 } 71 72 tzset(); 73 if (gLocaleBackend != NULL) { 74 status_t status = gLocaleBackend->Localtime(inTime, tmOut); 75 76 if (status != B_OK) 77 __set_errno(EOVERFLOW); 78 79 return tmOut; 80 } 81 82 // without a locale backend, there are no timezones, so we fall back to 83 // using a basic gmtime_r implementation. 84 return __gmtime_r_fallback(inTime, tmOut); 85 } 86 87 88 extern "C" struct tm* 89 gmtime(const time_t* inTime) 90 { 91 static tm tm; 92 93 return gmtime_r(inTime, &tm); 94 } 95 96 97 extern "C" struct tm* 98 gmtime_r(const time_t* inTime, struct tm* tmOut) 99 { 100 if (inTime == NULL) { 101 __set_errno(EINVAL); 102 return NULL; 103 } 104 105 tzset(); 106 if (gLocaleBackend != NULL) { 107 status_t status = gLocaleBackend->Gmtime(inTime, tmOut); 108 109 if (status != B_OK) 110 __set_errno(EOVERFLOW); 111 112 return tmOut; 113 } 114 115 // without a locale backend, we fall back to using a basic gmtime_r 116 // implementation. 117 return __gmtime_r_fallback(inTime, tmOut); 118 } 119 120 121 extern "C" time_t 122 mktime(struct tm* inTm) 123 { 124 if (inTm == NULL) { 125 __set_errno(EINVAL); 126 return -1; 127 } 128 129 tzset(); 130 if (gLocaleBackend != NULL) { 131 time_t timeOut; 132 status_t status = gLocaleBackend->Mktime(inTm, timeOut); 133 134 if (status != B_OK) { 135 __set_errno(EOVERFLOW); 136 return -1; 137 } 138 139 return timeOut; 140 } 141 142 // without a locale backend, we fall back to using a basic gmtime_r 143 // implementation. 144 return __mktime_fallback(inTm); 145 } 146