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 9 static long __timezone = 0; 10 static int dst_off = 0; 11 const char __utc[] = "UTC"; 12 static const char *__tzname[2] = { __utc, __utc }; 13 14 15 static 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 25 struct 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 39 time_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 61 error: 62 errno = EOVERFLOW; 63 return -1; 64 } 65 66 67 time_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