diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/time/__tz.c | 20 | ||||
| -rw-r--r-- | src/time/gmtime_r.c | 4 | ||||
| -rw-r--r-- | src/time/strftime.c | 16 | ||||
| -rw-r--r-- | src/time/timegm.c | 4 | 
4 files changed, 36 insertions, 8 deletions
| diff --git a/src/time/__tz.c b/src/time/__tz.c index 36b59802..dfeac519 100644 --- a/src/time/__tz.c +++ b/src/time/__tz.c @@ -15,11 +15,12 @@ weak_alias(__tzname, tzname);  static char std_name[TZNAME_MAX+1];  static char dst_name[TZNAME_MAX+1]; +const char __gmt[] = "GMT";  static int dst_off;  static int r0[5], r1[5]; -static const unsigned char *zi, *trans, *index, *types, *abbrevs; +static const unsigned char *zi, *trans, *index, *types, *abbrevs, *abbrevs_end;  static size_t map_size;  static char old_tz_buf[32]; @@ -127,7 +128,7 @@ static void do_tzset()  		"/usr/share/zoneinfo/\0/share/zoneinfo/\0/etc/zoneinfo/\0";  	s = getenv("TZ"); -	if (!s || !*s) s = "GMT0"; +	if (!s || !*s) s = __gmt;  	if (old_tz && !strcmp(s, old_tz)) return; @@ -184,6 +185,7 @@ static void do_tzset()  		index = trans + (zi_read32(trans-12) << scale);  		types = index + zi_read32(trans-12);  		abbrevs = types + 6*zi_read32(trans-8); +		abbrevs_end = abbrevs + zi_read32(trans-4);  		if (zi[map_size-1] == '\n') {  			for (s = (const char *)zi+map_size-2; *s!='\n'; s--);  			s++; @@ -192,7 +194,7 @@ static void do_tzset()  		}  	} -	if (!s) s = "GMT0"; +	if (!s) s = __gmt;  	getname(std_name, &s);  	__tzname[0] = std_name;  	__timezone = getoff(&s); @@ -387,3 +389,15 @@ void __tzset()  }  weak_alias(__tzset, tzset); + +const char *__tm_to_tzname(const struct tm *tm) +{ +	const void *p = tm->__tm_zone; +	LOCK(lock); +	do_tzset(); +	if (p != __gmt && p != __tzname[0] && p != __tzname[1] +	    && (uintptr_t)p-(uintptr_t)abbrevs >= abbrevs_end - abbrevs) +		p = ""; +	UNLOCK(lock); +	return p; +} diff --git a/src/time/gmtime_r.c b/src/time/gmtime_r.c index fee01bd6..8cbdadcb 100644 --- a/src/time/gmtime_r.c +++ b/src/time/gmtime_r.c @@ -2,6 +2,8 @@  #include <errno.h>  #include "libc.h" +extern const char __gmt[]; +  struct tm *__gmtime_r(const time_t *restrict t, struct tm *restrict tm)  {  	if (__secs_to_tm(*t, tm) < 0) { @@ -10,7 +12,7 @@ struct tm *__gmtime_r(const time_t *restrict t, struct tm *restrict tm)  	}  	tm->tm_isdst = 0;  	tm->__tm_gmtoff = 0; -	tm->__tm_zone = "GMT"; +	tm->__tm_zone = __gmt;  	return tm;  } diff --git a/src/time/strftime.c b/src/time/strftime.c index 24000f3b..48f65320 100644 --- a/src/time/strftime.c +++ b/src/time/strftime.c @@ -43,6 +43,7 @@ static int week_num(const struct tm *tm)  	return val;  } +const char *__tm_to_tzname(const struct tm *);  size_t __strftime_l(char *restrict, size_t, const char *restrict, const struct tm *restrict, locale_t);  const char *__strftime_fmt_1(char (*s)[100], size_t *l, int f, const struct tm *tm, locale_t loc) @@ -166,11 +167,20 @@ const char *__strftime_fmt_1(char (*s)[100], size_t *l, int f, const struct tm *  		width = 4;  		goto number;  	case 'z': -		val = -tm->__tm_gmtoff; -		*l = snprintf(*s, sizeof *s, "%+.2d%.2d", val/3600, abs(val%3600)/60); +		if (tm->tm_isdst < 0) { +			*l = 0; +			return ""; +		} +		*l = snprintf(*s, sizeof *s, "%+.2d%.2d", +			(-tm->__tm_gmtoff)/3600, +			abs(tm->__tm_gmtoff%3600)/60);  		return *s;  	case 'Z': -		fmt = tm->__tm_zone; +		if (tm->tm_isdst < 0) { +			*l = 0; +			return ""; +		} +		fmt = __tm_to_tzname(tm);  		goto string;  	case '%':  		*l = 1; diff --git a/src/time/timegm.c b/src/time/timegm.c index e7a7939b..b5dae8b6 100644 --- a/src/time/timegm.c +++ b/src/time/timegm.c @@ -2,6 +2,8 @@  #include "time_impl.h"  #include <errno.h> +extern const char __gmt[]; +  time_t timegm(struct tm *tm)  {  	struct tm new; @@ -13,6 +15,6 @@ time_t timegm(struct tm *tm)  	*tm = new;  	tm->tm_isdst = 0;  	tm->__tm_gmtoff = 0; -	tm->__tm_zone = "GMT"; +	tm->__tm_zone = __gmt;  	return t;  } | 
