diff options
Diffstat (limited to 'time')
48 files changed, 424 insertions, 336 deletions
diff --git a/time/Makefile b/time/Makefile index 227a4a0c44..a411f62042 100644 --- a/time/Makefile +++ b/time/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1991-2014 Free Software Foundation, Inc. +# Copyright (C) 1991-2015 Free Software Foundation, Inc. # This file is part of the GNU C Library. # The GNU C Library is free software; you can redistribute it and/or @@ -20,6 +20,8 @@ # subdir := time +include ../Makeconfig + headers := time.h sys/time.h sys/timeb.h bits/time.h routines := offtime asctime clock ctime ctime_r difftime \ @@ -35,7 +37,7 @@ aux := era alt_digit lc-time-cleanup tests := test_time clocktest tst-posixtz tst-strptime tst_wcsftime \ tst-getdate tst-mktime tst-mktime2 tst-ftime_l tst-strftime \ tst-mktime3 tst-strptime2 bug-asctime bug-asctime_r bug-mktime1 \ - tst-strptime3 bug-getdate1 tst-strptime-whitespace + tst-strptime3 bug-getdate1 tst-strptime-whitespace tst-ftime include ../Rules @@ -53,7 +55,4 @@ CFLAGS-test_time.c = -Wno-format tst-getdate-ENV= DATEMSK=datemsk TZDIR=${common-objpfx}timezone/testdata test_time-ARGS= EST5EDT CST -tst-strptime-ENV = LOCPATH=${common-objpfx}localedata -tst-ftime_l-ENV = LOCPATH=${common-objpfx}localedata - bug-getdate1-ARGS = ${objpfx}bug-getdate1-fmt diff --git a/time/adjtime.c b/time/adjtime.c index 734a8002c7..052931d4e9 100644 --- a/time/adjtime.c +++ b/time/adjtime.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2014 Free Software Foundation, Inc. +/* Copyright (C) 1991-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/time/alt_digit.c b/time/alt_digit.c index bd13abdd9c..81fb77b9cf 100644 --- a/time/alt_digit.c +++ b/time/alt_digit.c @@ -1,5 +1,5 @@ /* Helper functions used by strftime/strptime to handle alternate digits. - Copyright (C) 1995-2014 Free Software Foundation, Inc. + Copyright (C) 1995-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -132,7 +132,7 @@ _nl_get_walt_digit (unsigned int number, struct __locale_data *current) data->walt_digits[cnt] = ptr; /* Skip digit format. */ - ptr = wcschr (ptr, L'\0') + 1; + ptr = __wcschr (ptr, L'\0') + 1; } } } diff --git a/time/asctime.c b/time/asctime.c index dfbafbff09..fd0ed243a5 100644 --- a/time/asctime.c +++ b/time/asctime.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2014 Free Software Foundation, Inc. +/* Copyright (C) 1991-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -46,7 +46,7 @@ asctime_internal (const struct tm *tp, char *buf, size_t buflen) this would mean the output needs more space. This would not be a problem if the 'asctime_r' interface would be defined sanely and a buffer size would be passed. */ - if (__builtin_expect (tp->tm_year > INT_MAX - 1900, 0)) + if (__glibc_unlikely (tp->tm_year > INT_MAX - 1900)) { eoverflow: __set_errno (EOVERFLOW); diff --git a/time/clock.c b/time/clock.c index dd09fb55e0..5378a69731 100644 --- a/time/clock.c +++ b/time/clock.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2014 Free Software Foundation, Inc. +/* Copyright (C) 1991-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/time/clocktest.c b/time/clocktest.c index f2b3ea73a1..13b7420e2e 100644 --- a/time/clocktest.c +++ b/time/clocktest.c @@ -28,9 +28,9 @@ main (int argc, char ** argv) while (!gotit); stop = clock (); - printf ("%ld clock ticks per second (start=%ld,stop=%ld)\n", - stop - start, start, stop); - printf ("CLOCKS_PER_SEC=%ld, sysconf(_SC_CLK_TCK)=%ld\n", - CLOCKS_PER_SEC, sysconf(_SC_CLK_TCK)); + printf ("%jd clock ticks per second (start=%jd,stop=%jd)\n", + (intmax_t) (stop - start), (intmax_t) start, (intmax_t) stop); + printf ("CLOCKS_PER_SEC=%jd, sysconf(_SC_CLK_TCK)=%ld\n", + (intmax_t) CLOCKS_PER_SEC, sysconf(_SC_CLK_TCK)); return 0; } diff --git a/time/ctime.c b/time/ctime.c index da5be5c379..618f3b7fcf 100644 --- a/time/ctime.c +++ b/time/ctime.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2014 Free Software Foundation, Inc. +/* Copyright (C) 1991-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/time/ctime_r.c b/time/ctime_r.c index d1f9e6b6fe..8dec2835e7 100644 --- a/time/ctime_r.c +++ b/time/ctime_r.c @@ -1,5 +1,5 @@ /* Return in BUF representation of time T in form of asctime - Copyright (C) 1996-2014 Free Software Foundation, Inc. + Copyright (C) 1996-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. diff --git a/time/difftime.c b/time/difftime.c index 056a27c401..45ec613ab6 100644 --- a/time/difftime.c +++ b/time/difftime.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2014 Free Software Foundation, Inc. +/* Copyright (C) 1991-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/time/dysize.c b/time/dysize.c index 5b15242ddc..95b6095b37 100644 --- a/time/dysize.c +++ b/time/dysize.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1994-2014 Free Software Foundation, Inc. +/* Copyright (C) 1994-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/time/era.c b/time/era.c index fd311c625f..d6dc489d69 100644 --- a/time/era.c +++ b/time/era.c @@ -1,5 +1,5 @@ /* Helper functions used by strftime/strptime to handle locale-specific "eras". - Copyright (C) 1995-2014 Free Software Foundation, Inc. + Copyright (C) 1995-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -122,11 +122,11 @@ _nl_init_era_entries (struct __locale_data *current) /* Set and skip wide era name. */ new_eras[cnt].era_wname = (wchar_t *) ptr; - ptr = (char *) (wcschr ((wchar_t *) ptr, L'\0') + 1); + ptr = (char *) (__wcschr ((wchar_t *) ptr, L'\0') + 1); /* Set and skip wide era format. */ new_eras[cnt].era_wformat = (wchar_t *) ptr; - ptr = (char *) (wcschr ((wchar_t *) ptr, L'\0') + 1); + ptr = (char *) (__wcschr ((wchar_t *) ptr, L'\0') + 1); } } } diff --git a/time/ftime.c b/time/ftime.c index 557f4c5195..607467242d 100644 --- a/time/ftime.c +++ b/time/ftime.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1994-2014 Free Software Foundation, Inc. +/* Copyright (C) 1994-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/time/getdate.c b/time/getdate.c index 4754d12d28..26e3f487bb 100644 --- a/time/getdate.c +++ b/time/getdate.c @@ -1,5 +1,5 @@ /* Convert a string representation of time to a time value. - Copyright (C) 1997-2014 Free Software Foundation, Inc. + Copyright (C) 1997-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1997. @@ -21,6 +21,7 @@ #include <stdio.h> #include <stdio_ext.h> #include <stdlib.h> +#include <stdbool.h> #include <string.h> #include <time.h> #include <unistd.h> diff --git a/time/getitimer.c b/time/getitimer.c index 926a4857f6..e9d2920a56 100644 --- a/time/getitimer.c +++ b/time/getitimer.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2014 Free Software Foundation, Inc. +/* Copyright (C) 1991-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/time/gettimeofday.c b/time/gettimeofday.c index a4d3cd87fa..399eb60846 100644 --- a/time/gettimeofday.c +++ b/time/gettimeofday.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2014 Free Software Foundation, Inc. +/* Copyright (C) 1991-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/time/gmtime.c b/time/gmtime.c index 7c618917ff..60ac207b63 100644 --- a/time/gmtime.c +++ b/time/gmtime.c @@ -1,5 +1,5 @@ /* Convert `time_t' to `struct tm' in UTC. - Copyright (C) 1991-2014 Free Software Foundation, Inc. + Copyright (C) 1991-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/time/lc-time-cleanup.c b/time/lc-time-cleanup.c index 8c5599bb20..e143408c84 100644 --- a/time/lc-time-cleanup.c +++ b/time/lc-time-cleanup.c @@ -1,5 +1,5 @@ /* Cleanup code for data structures kept by strftime/strptime helper functions. - Copyright (C) 2002-2014 Free Software Foundation, Inc. + Copyright (C) 2002-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/time/localtime.c b/time/localtime.c index d6c5ef9a7e..38f3123d9a 100644 --- a/time/localtime.c +++ b/time/localtime.c @@ -1,5 +1,5 @@ /* Convert `time_t' to `struct tm' in local time zone. - Copyright (C) 1991-2014 Free Software Foundation, Inc. + Copyright (C) 1991-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/time/mktime.c b/time/mktime.c index 963e4b985a..7b125a79e9 100644 --- a/time/mktime.c +++ b/time/mktime.c @@ -1,5 +1,5 @@ /* Convert a 'struct tm' to a time_t value. - Copyright (C) 1993-2014 Free Software Foundation, Inc. + Copyright (C) 1993-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Paul Eggert <eggert@twinsun.com>. @@ -38,7 +38,7 @@ #include <string.h> /* For the real memcpy prototype. */ -#if DEBUG +#if defined DEBUG && DEBUG # include <stdio.h> # include <stdlib.h> /* Make it work even if the system's libc has its own mktime routine. */ @@ -142,7 +142,7 @@ verify (twos_complement_arithmetic, verify (base_year_is_a_multiple_of_100, TM_YEAR_BASE % 100 == 0); /* Return 1 if YEAR + TM_YEAR_BASE is a leap year. */ -static inline int +static int leapyear (long_int year) { /* Don't add YEAR to TM_YEAR_BASE, as that might overflow. @@ -600,7 +600,7 @@ libc_hidden_def (mktime) libc_hidden_weak (timelocal) #endif -#if DEBUG +#if defined DEBUG && DEBUG static int not_equal_tm (const struct tm *a, const struct tm *b) diff --git a/time/offtime.c b/time/offtime.c index f5a270d85b..a437266e95 100644 --- a/time/offtime.c +++ b/time/offtime.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2014 Free Software Foundation, Inc. +/* Copyright (C) 1991-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/time/setitimer.c b/time/setitimer.c index 4e7609f7b7..6b49a603b1 100644 --- a/time/setitimer.c +++ b/time/setitimer.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2014 Free Software Foundation, Inc. +/* Copyright (C) 1991-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/time/settimeofday.c b/time/settimeofday.c index a523ab79fd..513e194af2 100644 --- a/time/settimeofday.c +++ b/time/settimeofday.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2014 Free Software Foundation, Inc. +/* Copyright (C) 1991-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/time/stime.c b/time/stime.c index f46c695b1a..b86b152c5e 100644 --- a/time/stime.c +++ b/time/stime.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1992-2014 Free Software Foundation, Inc. +/* Copyright (C) 1992-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/time/strftime.c b/time/strftime.c index 8134d75de7..b71907e83c 100644 --- a/time/strftime.c +++ b/time/strftime.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2014 Free Software Foundation, Inc. +/* Copyright (C) 1991-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/time/strftime_l.c b/time/strftime_l.c index dfb7b4c483..b48ef34034 100644 --- a/time/strftime_l.c +++ b/time/strftime_l.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2014 Free Software Foundation, Inc. +/* Copyright (C) 2002-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -29,6 +29,7 @@ # define HAVE_TM_ZONE 1 # define HAVE_TZNAME 1 # define HAVE_TZSET 1 +# define HAVE_STRFTIME 0 # define MULTIBYTE_IS_FORMAT_SAFE 1 # define STDC_HEADERS 1 # include "../locale/localeinfo.h" diff --git a/time/strptime.c b/time/strptime.c index 81cdbbdd30..fb98c62c22 100644 --- a/time/strptime.c +++ b/time/strptime.c @@ -1,5 +1,5 @@ /* Convert a string representation of time to a time value. - Copyright (C) 1996-2014 Free Software Foundation, Inc. + Copyright (C) 1996-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. diff --git a/time/strptime_l.c b/time/strptime_l.c index 8fe623d579..5640ccecce 100644 --- a/time/strptime_l.c +++ b/time/strptime_l.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2014 Free Software Foundation, Inc. +/* Copyright (C) 2002-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,6 +28,7 @@ #include <stdbool.h> #ifdef _LIBC +# define HAVE_LOCALTIME_R 0 # include "../locale/localeinfo.h" #endif diff --git a/time/sys/time.h b/time/sys/time.h index c01b23bc66..bca62fac53 100644 --- a/time/sys/time.h +++ b/time/sys/time.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2014 Free Software Foundation, Inc. +/* Copyright (C) 1991-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -49,7 +49,7 @@ __BEGIN_DECLS #endif -#ifdef __USE_BSD +#ifdef __USE_MISC /* Structure crudely representing a timezone. This is obsolete and should never be used. */ struct timezone @@ -71,7 +71,7 @@ typedef void *__restrict __timezone_ptr_t; extern int gettimeofday (struct timeval *__restrict __tv, __timezone_ptr_t __tz) __THROW __nonnull ((1)); -#ifdef __USE_BSD +#ifdef __USE_MISC /* Set the current time of day and timezone information. This call is restricted to the super-user. */ extern int settimeofday (const struct timeval *__tv, @@ -138,7 +138,7 @@ extern int setitimer (__itimer_which_t __which, extern int utimes (const char *__file, const struct timeval __tvp[2]) __THROW __nonnull ((1)); -#ifdef __USE_BSD +#ifdef __USE_MISC /* Same as `utimes', but does not follow symbolic links. */ extern int lutimes (const char *__file, const struct timeval __tvp[2]) __THROW __nonnull ((1)); @@ -156,7 +156,7 @@ extern int futimesat (int __fd, const char *__file, #endif -#ifdef __USE_BSD +#ifdef __USE_MISC /* Convenience macros for operations on timevals. NOTE: `timercmp' does not work for >= or <=. */ # define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) @@ -184,7 +184,7 @@ extern int futimesat (int __fd, const char *__file, (result)->tv_usec += 1000000; \ } \ } while (0) -#endif /* BSD */ +#endif /* Misc. */ __END_DECLS diff --git a/time/sys/timeb.h b/time/sys/timeb.h index 3c36f02871..1ac721e5af 100644 --- a/time/sys/timeb.h +++ b/time/sys/timeb.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1994-2014 Free Software Foundation, Inc. +/* Copyright (C) 1994-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/time/test_time.c b/time/test_time.c index 57a2de922f..44fa4231ea 100644 --- a/time/test_time.c +++ b/time/test_time.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2014 Free Software Foundation, Inc. +/* Copyright (C) 1991-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/time/time.c b/time/time.c index cacccf9ca2..ee313e370c 100644 --- a/time/time.c +++ b/time/time.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2014 Free Software Foundation, Inc. +/* Copyright (C) 1991-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/time/time.h b/time/time.h index 9777dd9684..87b9ba1596 100644 --- a/time/time.h +++ b/time/time.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2014 Free Software Foundation, Inc. +/* Copyright (C) 1991-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -58,7 +58,7 @@ __BEGIN_NAMESPACE_STD /* Returned by `clock'. */ typedef __clock_t clock_t; __END_NAMESPACE_STD -#if defined __USE_XOPEN || defined __USE_POSIX || defined __USE_MISC +#if defined __USE_XOPEN || defined __USE_POSIX __USING_NAMESPACE_STD(clock_t) #endif @@ -74,7 +74,7 @@ __BEGIN_NAMESPACE_STD /* Returned by `time'. */ typedef __time_t time_t; __END_NAMESPACE_STD -#if defined __USE_POSIX || defined __USE_MISC || defined __USE_SVID +#ifdef __USE_POSIX __USING_NAMESPACE_STD(time_t) #endif @@ -108,7 +108,7 @@ typedef __timer_t timer_t; #if (!defined __timespec_defined \ && ((defined _TIME_H \ - && (defined __USE_POSIX199309 || defined __USE_MISC \ + && (defined __USE_POSIX199309 \ || defined __USE_ISOC11)) \ || defined __need_timespec)) # define __timespec_defined 1 @@ -142,7 +142,7 @@ struct tm int tm_yday; /* Days in year.[0-365] */ int tm_isdst; /* DST. [-1/0/1]*/ -# ifdef __USE_BSD +# ifdef __USE_MISC long int tm_gmtoff; /* Seconds east of UTC. */ const char *tm_zone; /* Timezone abbreviation. */ # else @@ -151,7 +151,7 @@ struct tm # endif }; __END_NAMESPACE_STD -#if defined __USE_XOPEN || defined __USE_POSIX || defined __USE_MISC +#if defined __USE_XOPEN || defined __USE_POSIX __USING_NAMESPACE_STD(tm) #endif @@ -243,7 +243,7 @@ extern struct tm *gmtime (const time_t *__timer) __THROW; extern struct tm *localtime (const time_t *__timer) __THROW; __END_NAMESPACE_STD -# if defined __USE_POSIX || defined __USE_MISC +# ifdef __USE_POSIX /* Return the `struct tm' representation of *TIMER in UTC, using *TP to store the result. */ extern struct tm *gmtime_r (const time_t *__restrict __timer, @@ -253,7 +253,7 @@ extern struct tm *gmtime_r (const time_t *__restrict __timer, using *TP to store the result. */ extern struct tm *localtime_r (const time_t *__restrict __timer, struct tm *__restrict __tp) __THROW; -# endif /* POSIX or misc */ +# endif /* POSIX */ __BEGIN_NAMESPACE_STD /* Return a string of the form "Day Mon dd hh:mm:ss yyyy\n" @@ -264,7 +264,7 @@ extern char *asctime (const struct tm *__tp) __THROW; extern char *ctime (const time_t *__timer) __THROW; __END_NAMESPACE_STD -# if defined __USE_POSIX || defined __USE_MISC +# ifdef __USE_POSIX /* Reentrant versions of the above functions. */ /* Return in BUF a string of the form "Day Mon dd hh:mm:ss yyyy\n" @@ -275,7 +275,7 @@ extern char *asctime_r (const struct tm *__restrict __tp, /* Equivalent to `asctime_r (localtime_r (timer, *TMP*), buf)'. */ extern char *ctime_r (const time_t *__restrict __timer, char *__restrict __buf) __THROW; -# endif /* POSIX or misc */ +# endif /* POSIX */ /* Defined in localtime.c. */ @@ -293,12 +293,12 @@ extern char *tzname[2]; extern void tzset (void) __THROW; # endif -# if defined __USE_SVID || defined __USE_XOPEN +# if defined __USE_MISC || defined __USE_XOPEN extern int daylight; extern long int timezone; # endif -# ifdef __USE_SVID +# ifdef __USE_MISC /* Set the system time to *WHEN. This call is restricted to the superuser. */ extern int stime (const time_t *__when) __THROW; diff --git a/time/timegm.c b/time/timegm.c index 212bfa7327..50612cafd5 100644 --- a/time/timegm.c +++ b/time/timegm.c @@ -1,6 +1,6 @@ /* Convert UTC calendar time to simple time. Like mktime but assumes UTC. - Copyright (C) 1994-2014 Free Software Foundation, Inc. + Copyright (C) 1994-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/time/timespec_get.c b/time/timespec_get.c index ece0ca0050..28772d5a05 100644 --- a/time/timespec_get.c +++ b/time/timespec_get.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2011-2014 Free Software Foundation, Inc. +/* Copyright (C) 2011-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/time/tst-ftime.c b/time/tst-ftime.c new file mode 100644 index 0000000000..0ead53977d --- /dev/null +++ b/time/tst-ftime.c @@ -0,0 +1,59 @@ +/* Verify that ftime is sane. + Copyright (C) 2014-2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sys/timeb.h> +#include <stdio.h> + +static int +do_test (void) +{ + struct timeb prev, curr = {.time = 0, .millitm = 0}; + int sec = 0; + + while (sec != 3) + { + prev = curr; + + if (ftime (&curr)) + { + printf ("ftime returned an error\n"); + return 1; + } + + if (curr.time < prev.time) + { + printf ("ftime's time flowed backwards\n"); + return 1; + } + + if (curr.time == prev.time + && curr.millitm < prev.millitm) + { + printf ("ftime's millitm flowed backwards\n"); + return 1; + } + + if (curr.time > prev.time) + sec ++; + } + return 0; +} + +#define TIMEOUT 3 +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/time/tst-ftime_l.c b/time/tst-ftime_l.c index fc3d78d689..6690efeb9c 100644 --- a/time/tst-ftime_l.c +++ b/time/tst-ftime_l.c @@ -6,8 +6,8 @@ #include <wchar.h> -int -main (void) +static int +do_test (void) { locale_t l; locale_t old; @@ -124,3 +124,6 @@ main (void) return result; } + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/time/tst-getdate.c b/time/tst-getdate.c index fd879239c3..5fe049d9bb 100644 --- a/time/tst-getdate.c +++ b/time/tst-getdate.c @@ -1,5 +1,5 @@ /* Test for getdate. - Copyright (C) 2000-2014 Free Software Foundation, Inc. + Copyright (C) 2000-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Andreas Jaeger <aj@suse.de>, 2000. @@ -76,8 +76,8 @@ report_date_error (int err) } -int -main (void) +static int +do_test (void) { int errors = 0; size_t i; @@ -121,3 +121,6 @@ main (void) printf ("No errors found.\n"); return errors != 0; } + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/time/tst-mktime.c b/time/tst-mktime.c index 416a85616c..c1473600dd 100644 --- a/time/tst-mktime.c +++ b/time/tst-mktime.c @@ -3,8 +3,8 @@ #include <string.h> #include <time.h> -int -main (void) +static int +do_test (void) { struct tm time_str, *tm; time_t t; @@ -68,3 +68,6 @@ main (void) return result; } + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/time/tst-mktime3.c b/time/tst-mktime3.c index 60d0e0b32c..c738e5384a 100644 --- a/time/tst-mktime3.c +++ b/time/tst-mktime3.c @@ -17,8 +17,8 @@ struct tm expected[] = { .tm_sec = 5, .tm_mday = 1, .tm_year = 102, .tm_wday = 2 } }; -int -main (void) +static int +do_test (void) { setenv ("TZ", "UTC", 1); int i; @@ -48,3 +48,6 @@ main (void) } return 0; } + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/time/tst-posixtz.c b/time/tst-posixtz.c index 019d92ada0..16aa19d654 100644 --- a/time/tst-posixtz.c +++ b/time/tst-posixtz.c @@ -28,8 +28,8 @@ struct "1999/02/25 15:18:12 dst=0 zone=EST" }, }; -int -main (void) +static int +do_test (void) { int result = 0; size_t cnt; @@ -39,7 +39,8 @@ main (void) char buf[100]; struct tm *tmp; - printf ("TZ = \"%s\", time = %ld => ", tests[cnt].tz, tests[cnt].when); + printf ("TZ = \"%s\", time = %jd => ", tests[cnt].tz, + (intmax_t) tests[cnt].when); fflush (stdout); setenv ("TZ", tests[cnt].tz, 1); @@ -116,3 +117,6 @@ main (void) return result; } + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/time/tst-strptime-whitespace.c b/time/tst-strptime-whitespace.c index 692794876d..c26ff3ebea 100644 --- a/time/tst-strptime-whitespace.c +++ b/time/tst-strptime-whitespace.c @@ -1,6 +1,6 @@ /* Verify that strptime accepts arbitrary whitespace between tokens. - Copyright (C) 2013-2014 Free Software Foundation, Inc. + Copyright (C) 2013-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/time/tst-strptime.c b/time/tst-strptime.c index 42e99bd469..8c0a947ad9 100644 --- a/time/tst-strptime.c +++ b/time/tst-strptime.c @@ -1,5 +1,5 @@ /* Test for strptime. - Copyright (C) 1998-2014 Free Software Foundation, Inc. + Copyright (C) 1998-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. diff --git a/time/tst-strptime2.c b/time/tst-strptime2.c index 73552bb8f8..a08e6d7cb7 100644 --- a/time/tst-strptime2.c +++ b/time/tst-strptime2.c @@ -26,8 +26,8 @@ static const struct #define ntests (sizeof (tests) / sizeof (tests[0])) -int -main (void) +static int +do_test (void) { int result = 0; @@ -52,8 +52,8 @@ main (void) } } - if (result == 0) - puts ("all OK"); - - return 0; + return result; } + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/time/tst-strptime3.c b/time/tst-strptime3.c index 9a8c6485e7..d53f51ee22 100644 --- a/time/tst-strptime3.c +++ b/time/tst-strptime3.c @@ -4,8 +4,8 @@ #include <time.h> -int -main (void) +static int +do_test (void) { int result = 0; struct tm tm; @@ -48,8 +48,8 @@ main (void) result = 1; } - if (result == 0) - puts ("all OK"); - - return 0; + return result; } + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/time/tzfile.c b/time/tzfile.c index deef58ef34..57abbb8c14 100644 --- a/time/tzfile.c +++ b/time/tzfile.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2014 Free Software Foundation, Inc. +/* Copyright (C) 1991-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -170,7 +170,7 @@ __tzfile_read (const char *file, size_t extra, char **extrap) goto ret_free_transitions; /* Get information about the file we are actually using. */ - if (fstat64 (fileno (f), &st) != 0) + if (fstat64 (__fileno (f), &st) != 0) { fclose (f); goto ret_free_transitions; @@ -188,8 +188,8 @@ __tzfile_read (const char *file, size_t extra, char **extrap) __fsetlocking (f, FSETLOCKING_BYCALLER); read_again: - if (__builtin_expect (fread_unlocked ((void *) &tzhead, sizeof (tzhead), - 1, f) != 1, 0) + if (__builtin_expect (__fread_unlocked ((void *) &tzhead, sizeof (tzhead), + 1, f) != 1, 0) || memcmp (tzhead.tzh_magic, TZ_MAGIC, sizeof (tzhead.tzh_magic)) != 0) goto lose; @@ -200,6 +200,9 @@ __tzfile_read (const char *file, size_t extra, char **extrap) num_isstd = (size_t) decode (tzhead.tzh_ttisstdcnt); num_isgmt = (size_t) decode (tzhead.tzh_ttisgmtcnt); + if (__glibc_unlikely (num_isstd > num_types || num_isgmt > num_types)) + goto lose; + /* For platforms with 64-bit time_t we use the new format if available. */ if (sizeof (time_t) == 8 && trans_width == 4 && tzhead.tzh_version[0] != '\0') @@ -232,7 +235,7 @@ __tzfile_read (const char *file, size_t extra, char **extrap) > (SIZE_MAX - total_size) / sizeof (struct ttinfo), 0)) goto lose; total_size += num_types * sizeof (struct ttinfo); - if (__builtin_expect (chars > SIZE_MAX - total_size, 0)) + if (__glibc_unlikely (chars > SIZE_MAX - total_size)) goto lose; total_size += chars; if (__builtin_expect (__alignof__ (struct leap) - 1 @@ -248,7 +251,7 @@ __tzfile_read (const char *file, size_t extra, char **extrap) tzspec_len = 0; if (sizeof (time_t) == 8 && trans_width == 8) { - off_t rem = st.st_size - ftello (f); + off_t rem = st.st_size - __ftello (f); if (__builtin_expect (rem < 0 || (size_t) rem < (num_transitions * (8 + 1) + num_types * 6 @@ -261,16 +264,17 @@ __tzfile_read (const char *file, size_t extra, char **extrap) || tzspec_len < num_leaps * 12, 0)) goto lose; tzspec_len -= num_leaps * 12; - if (__builtin_expect (tzspec_len < num_isstd, 0)) + if (__glibc_unlikely (tzspec_len < num_isstd)) goto lose; tzspec_len -= num_isstd; - if (__builtin_expect (tzspec_len == 0 || tzspec_len - 1 < num_isgmt, 0)) + if (__glibc_unlikely (tzspec_len == 0 || tzspec_len - 1 < num_isgmt)) goto lose; tzspec_len -= num_isgmt + 1; - if (__builtin_expect (SIZE_MAX - total_size < tzspec_len, 0)) + if (__glibc_unlikely (tzspec_len == 0 + || SIZE_MAX - total_size < tzspec_len)) goto lose; } - if (__builtin_expect (SIZE_MAX - total_size - tzspec_len < extra, 0)) + if (__glibc_unlikely (SIZE_MAX - total_size - tzspec_len < extra)) goto lose; /* Allocate enough memory including the extra block requested by the @@ -293,24 +297,25 @@ __tzfile_read (const char *file, size_t extra, char **extrap) if (sizeof (time_t) == 4 || __builtin_expect (trans_width == 8, 1)) { - if (__builtin_expect (fread_unlocked (transitions, trans_width + 1, - num_transitions, f) + if (__builtin_expect (__fread_unlocked (transitions, trans_width + 1, + num_transitions, f) != num_transitions, 0)) goto lose; } else { - if (__builtin_expect (fread_unlocked (transitions, 4, num_transitions, f) + if (__builtin_expect (__fread_unlocked (transitions, 4, + num_transitions, f) != num_transitions, 0) - || __builtin_expect (fread_unlocked (type_idxs, 1, num_transitions, - f) != num_transitions, 0)) + || __builtin_expect (__fread_unlocked (type_idxs, 1, num_transitions, + f) != num_transitions, 0)) goto lose; } /* Check for bogus indices in the data file, so we can hereafter safely use type_idxs[T] as indices into `types' and never crash. */ for (i = 0; i < num_transitions; ++i) - if (__builtin_expect (type_idxs[i] >= num_types, 0)) + if (__glibc_unlikely (type_idxs[i] >= num_types)) goto lose; if ((BYTE_ORDER != BIG_ENDIAN && (sizeof (time_t) == 4 || trans_width == 4)) @@ -337,28 +342,29 @@ __tzfile_read (const char *file, size_t extra, char **extrap) { unsigned char x[4]; int c; - if (__builtin_expect (fread_unlocked (x, 1, sizeof (x), f) != sizeof (x), + if (__builtin_expect (__fread_unlocked (x, 1, + sizeof (x), f) != sizeof (x), 0)) goto lose; c = getc_unlocked (f); - if (__builtin_expect ((unsigned int) c > 1u, 0)) + if (__glibc_unlikely ((unsigned int) c > 1u)) goto lose; types[i].isdst = c; c = getc_unlocked (f); - if (__builtin_expect ((size_t) c > chars, 0)) + if (__glibc_unlikely ((size_t) c > chars)) /* Bogus index in data file. */ goto lose; types[i].idx = c; types[i].offset = (long int) decode (x); } - if (__builtin_expect (fread_unlocked (zone_names, 1, chars, f) != chars, 0)) + if (__glibc_unlikely (__fread_unlocked (zone_names, 1, chars, f) != chars)) goto lose; for (i = 0; i < num_leaps; ++i) { unsigned char x[8]; - if (__builtin_expect (fread_unlocked (x, 1, trans_width, f) + if (__builtin_expect (__fread_unlocked (x, 1, trans_width, f) != trans_width, 0)) goto lose; if (sizeof (time_t) == 4 || trans_width == 4) @@ -366,7 +372,7 @@ __tzfile_read (const char *file, size_t extra, char **extrap) else leaps[i].transition = (time_t) decode64 (x); - if (__builtin_expect (fread_unlocked (x, 1, 4, f) != 4, 0)) + if (__glibc_unlikely (__fread_unlocked (x, 1, 4, f) != 4)) goto lose; leaps[i].change = (long int) decode (x); } @@ -374,7 +380,7 @@ __tzfile_read (const char *file, size_t extra, char **extrap) for (i = 0; i < num_isstd; ++i) { int c = getc_unlocked (f); - if (__builtin_expect (c == EOF, 0)) + if (__glibc_unlikely (c == EOF)) goto lose; types[i].isstd = c != 0; } @@ -384,7 +390,7 @@ __tzfile_read (const char *file, size_t extra, char **extrap) for (i = 0; i < num_isgmt; ++i) { int c = getc_unlocked (f); - if (__builtin_expect (c == EOF, 0)) + if (__glibc_unlikely (c == EOF)) goto lose; types[i].isgmt = c != 0; } @@ -396,7 +402,7 @@ __tzfile_read (const char *file, size_t extra, char **extrap) { /* Skip over the newline first. */ if (getc_unlocked (f) != '\n' - || (fread_unlocked (tzspec, 1, tzspec_len - 1, f) + || (__fread_unlocked (tzspec, 1, tzspec_len - 1, f) != tzspec_len - 1)) tzspec = NULL; else @@ -405,8 +411,8 @@ __tzfile_read (const char *file, size_t extra, char **extrap) else if (sizeof (time_t) == 4 && tzhead.tzh_version[0] != '\0') { /* Get the TZ string. */ - if (__builtin_expect (fread_unlocked ((void *) &tzhead, sizeof (tzhead), - 1, f) != 1, 0) + if (__builtin_expect (__fread_unlocked ((void *) &tzhead, + sizeof (tzhead), 1, f) != 1, 0) || (memcmp (tzhead.tzh_magic, TZ_MAGIC, sizeof (tzhead.tzh_magic)) != 0)) goto lose; @@ -427,17 +433,26 @@ __tzfile_read (const char *file, size_t extra, char **extrap) + num_isgmt2); off_t off; if (fseek (f, to_skip, SEEK_CUR) != 0 - || (off = ftello (f)) < 0 + || (off = __ftello (f)) < 0 || st.st_size < off + 2) goto lose; tzspec_len = st.st_size - off - 1; - char *tzstr = alloca (tzspec_len); - if (getc_unlocked (f) != '\n' - || (fread_unlocked (tzstr, 1, tzspec_len - 1, f) != tzspec_len - 1)) + if (tzspec_len == 0) + goto lose; + char *tzstr = malloc (tzspec_len); + if (tzstr == NULL) goto lose; + if (getc_unlocked (f) != '\n' + || (__fread_unlocked (tzstr, 1, tzspec_len - 1, f) + != tzspec_len - 1)) + { + free (tzstr); + goto lose; + } tzstr[tzspec_len - 1] = '\0'; tzspec = __tzstring (tzstr); + free (tzstr); } /* Don't use an empty TZ string. */ @@ -627,7 +642,7 @@ __tzfile_compute (time_t timer, int use_localtime, __tzname[0] = NULL; __tzname[1] = NULL; - if (__builtin_expect (num_transitions == 0 || timer < transitions[0], 0)) + if (__glibc_unlikely (num_transitions == 0 || timer < transitions[0])) { /* TIMER is before any transition (or there are no transitions). Choose the first non-DST type @@ -657,9 +672,9 @@ __tzfile_compute (time_t timer, int use_localtime, ++j; } } - else if (__builtin_expect (timer >= transitions[num_transitions - 1], 0)) + else if (__glibc_unlikely (timer >= transitions[num_transitions - 1])) { - if (__builtin_expect (tzspec == NULL, 0)) + if (__glibc_unlikely (tzspec == NULL)) { use_last: i = num_transitions; @@ -671,7 +686,7 @@ __tzfile_compute (time_t timer, int use_localtime, /* Convert to broken down structure. If this fails do not use the string. */ - if (__builtin_expect (! __offtime (&timer, 0, tp), 0)) + if (__glibc_unlikely (! __offtime (&timer, 0, tp))) goto use_last; /* Use the rules from the TZ string to compute the change. */ @@ -680,7 +695,7 @@ __tzfile_compute (time_t timer, int use_localtime, /* If tzspec comes from posixrules loaded by __tzfile_default, override the STD and DST zone names with the ones user requested in TZ envvar. */ - if (__builtin_expect (zone_names == (char *) &leaps[num_leaps], 0)) + if (__glibc_unlikely (zone_names == (char *) &leaps[num_leaps])) { assert (num_types == 2); __tzname[0] = __tzstring (zone_names); @@ -762,7 +777,7 @@ __tzfile_compute (time_t timer, int use_localtime, ++j; } - if (__builtin_expect (__tzname[0] == NULL, 0)) + if (__glibc_unlikely (__tzname[0] == NULL)) __tzname[0] = __tzname[1]; i = type_idxs[i - 1]; diff --git a/time/tzset.c b/time/tzset.c index bfcd943436..160f5ad460 100644 --- a/time/tzset.c +++ b/time/tzset.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2014 Free Software Foundation, Inc. +/* Copyright (C) 1991-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -18,6 +18,7 @@ #include <ctype.h> #include <errno.h> #include <bits/libc-lock.h> +#include <stdbool.h> #include <stddef.h> #include <stdio.h> #include <stdlib.h> @@ -82,15 +83,14 @@ struct tzstring_l static struct tzstring_l *tzstring_list; -/* Allocate a permanent home for S. It will never be moved or deallocated, - but may share space with other strings. - Don't modify the returned string. */ -char * -__tzstring (const char *s) +/* Allocate a permanent home for the first LEN characters of S. It + will never be moved or deallocated, but may share space with other + strings. Don't modify the returned string. */ +static char * +__tzstring_len (const char *s, size_t len) { char *p; struct tzstring_l *t, *u, *new; - size_t len = strlen (s); /* Walk the list and look for a match. If this string is the same as the end of an already-allocated string, it can share space. */ @@ -98,7 +98,7 @@ __tzstring (const char *s) if (len <= t->len) { p = &t->data[t->len - len]; - if (strcmp (s, p) == 0) + if (memcmp (s, p, len) == 0) return p; } @@ -109,7 +109,8 @@ __tzstring (const char *s) new->next = NULL; new->len = len; - strcpy (new->data, s); + memcpy (new->data, s, len); + new->data[len] = '\0'; if (u) u->next = new; @@ -118,6 +119,15 @@ __tzstring (const char *s) return new->data; } + +/* Allocate a permanent home for S. It will never be moved or + deallocated, but may share space with other strings. Don't modify + the returned string. */ +char * +__tzstring (const char *s) +{ + return __tzstring_len (s, strlen (s)); +} /* Maximum length of a timezone name. tzset_internal keeps this up to date (never decreasing it) when ! __use_tzfile. @@ -164,234 +174,220 @@ compute_offset (unsigned int ss, unsigned int mm, unsigned int hh) return min (ss, 59) + min (mm, 59) * 60 + min (hh, 24) * 60 * 60; } - -/* Parse the POSIX TZ-style string. */ -void -__tzset_parse_tz (tz) - const char *tz; +/* Parses the time zone name at *TZP, and writes a pointer to an + interned string to tz_rules[WHICHRULE].name. On success, advances + *TZP, and returns true. Returns false otherwise. */ +static bool +parse_tzname (const char **tzp, int whichrule) { - unsigned short int hh, mm, ss; - - /* Clear out old state and reset to unnamed UTC. */ - memset (tz_rules, '\0', sizeof tz_rules); - tz_rules[0].name = tz_rules[1].name = ""; - - /* Get the standard timezone name. */ - char *tzbuf = strdupa (tz); - - int consumed; - if (sscanf (tz, "%[A-Za-z]%n", tzbuf, &consumed) != 1) + const char *start = *tzp; + const char *p = start; + while (('a' <= *p && *p <= 'z') + || ('A' <= *p && *p <= 'Z')) + ++p; + size_t len = p - start; + if (len < 3) { - /* Check for the quoted version. */ - char *wp = tzbuf; - if (__builtin_expect (*tz++ != '<', 0)) - goto out; - - while (isalnum (*tz) || *tz == '+' || *tz == '-') - *wp++ = *tz++; - if (__builtin_expect (*tz++ != '>' || wp - tzbuf < 3, 0)) - goto out; - *wp = '\0'; + p = *tzp; + if (__glibc_unlikely (*p++ != '<')) + return false; + start = p; + while (('a' <= *p && *p <= 'z') + || ('A' <= *p && *p <= 'Z') + || ('0' <= *p && *p <= '9') + || *p == '+' || *p == '-') + ++p; + len = p - start; + if (*p++ != '>' || len < 3) + return false; } - else if (__builtin_expect (consumed < 3, 0)) - goto out; - else - tz += consumed; - tz_rules[0].name = __tzstring (tzbuf); + const char *name = __tzstring_len (start, len); + if (name == NULL) + return false; + tz_rules[whichrule].name = name; - /* Figure out the standard offset from UTC. */ - if (*tz == '\0' || (*tz != '+' && *tz != '-' && !isdigit (*tz))) - goto out; + *tzp = p; + return true; +} + +/* Parses the time zone offset at *TZP, and writes it to + tz_rules[WHICHRULE].offset. Returns true if the parse was + successful. */ +static bool +parse_offset (const char **tzp, int whichrule) +{ + const char *tz = *tzp; + if (whichrule == 0 + && (*tz == '\0' || (*tz != '+' && *tz != '-' && !isdigit (*tz)))) + return false; + long sign; if (*tz == '-' || *tz == '+') - tz_rules[0].offset = *tz++ == '-' ? 1L : -1L; + sign = *tz++ == '-' ? 1L : -1L; else - tz_rules[0].offset = -1L; - switch (sscanf (tz, "%hu%n:%hu%n:%hu%n", - &hh, &consumed, &mm, &consumed, &ss, &consumed)) - { - default: - tz_rules[0].offset = 0; - goto out; - case 1: - mm = 0; - case 2: - ss = 0; - case 3: - break; - } - tz_rules[0].offset *= compute_offset (ss, mm, hh); - tz += consumed; - - /* Get the DST timezone name (if any). */ - if (*tz != '\0') - { - if (sscanf (tz, "%[A-Za-z]%n", tzbuf, &consumed) != 1) - { - /* Check for the quoted version. */ - char *wp = tzbuf; - const char *rp = tz; - if (__builtin_expect (*rp++ != '<', 0)) - /* Punt on name, set up the offsets. */ - goto done_names; - - while (isalnum (*rp) || *rp == '+' || *rp == '-') - *wp++ = *rp++; - if (__builtin_expect (*rp++ != '>' || wp - tzbuf < 3, 0)) - /* Punt on name, set up the offsets. */ - goto done_names; - *wp = '\0'; - tz = rp; - } - else if (__builtin_expect (consumed < 3, 0)) - /* Punt on name, set up the offsets. */ - goto done_names; + sign = -1L; + *tzp = tz; + + unsigned short int hh; + unsigned short mm = 0; + unsigned short ss = 0; + int consumed = 0; + if (sscanf (tz, "%hu%n:%hu%n:%hu%n", + &hh, &consumed, &mm, &consumed, &ss, &consumed) > 0) + tz_rules[whichrule].offset = sign * compute_offset (ss, mm, hh); + else + /* Nothing could be parsed. */ + if (whichrule == 0) + { + /* Standard time defaults to offset zero. */ + tz_rules[0].offset = 0; + return false; + } else - tz += consumed; + /* DST defaults to one hour later than standard time. */ + tz_rules[1].offset = tz_rules[0].offset + (60 * 60); + *tzp = tz + consumed; + return true; +} - tz_rules[1].name = __tzstring (tzbuf); +/* Parses the standard <-> DST rules at *TZP. Updates + tz_rule[WHICHRULE]. On success, advances *TZP and returns true. + Otherwise, returns false. */ +static bool +parse_rule (const char **tzp, int whichrule) +{ + const char *tz = *tzp; + tz_rule *tzr = &tz_rules[whichrule]; - /* Figure out the DST offset from GMT. */ - if (*tz == '-' || *tz == '+') - tz_rules[1].offset = *tz++ == '-' ? 1L : -1L; - else - tz_rules[1].offset = -1L; + /* Ignore comma to support string following the incorrect + specification in early POSIX.1 printings. */ + tz += *tz == ','; - switch (sscanf (tz, "%hu%n:%hu%n:%hu%n", - &hh, &consumed, &mm, &consumed, &ss, &consumed)) + /* Get the date of the change. */ + if (*tz == 'J' || isdigit (*tz)) + { + char *end; + tzr->type = *tz == 'J' ? J1 : J0; + if (tzr->type == J1 && !isdigit (*++tz)) + return false; + unsigned long int d = strtoul (tz, &end, 10); + if (end == tz || d > 365) + return false; + if (tzr->type == J1 && d == 0) + return false; + tzr->d = d; + tz = end; + } + else if (*tz == 'M') + { + tzr->type = M; + int consumed; + if (sscanf (tz, "M%hu.%hu.%hu%n", + &tzr->m, &tzr->n, &tzr->d, &consumed) != 3 + || tzr->m < 1 || tzr->m > 12 + || tzr->n < 1 || tzr->n > 5 || tzr->d > 6) + return false; + tz += consumed; + } + else if (*tz == '\0') + { + /* Daylight time rules in the U.S. are defined in the U.S. Code, + Title 15, Chapter 6, Subchapter IX - Standard Time. These + dates were established by Congress in the Energy Policy Act + of 2005 [Pub. L. no. 109-58, 119 Stat 594 (2005)]. + Below is the equivalent of "M3.2.0,M11.1.0" [/2 not needed + since 2:00AM is the default]. */ + tzr->type = M; + if (tzr == &tz_rules[0]) { - default: - /* Default to one hour later than standard time. */ - tz_rules[1].offset = tz_rules[0].offset + (60 * 60); - break; - - case 1: - mm = 0; - case 2: - ss = 0; - case 3: - tz_rules[1].offset *= compute_offset (ss, mm, hh); - tz += consumed; - break; + tzr->m = 3; + tzr->n = 2; + tzr->d = 0; } - if (*tz == '\0' || (tz[0] == ',' && tz[1] == '\0')) + else { - /* There is no rule. See if there is a default rule file. */ - __tzfile_default (tz_rules[0].name, tz_rules[1].name, - tz_rules[0].offset, tz_rules[1].offset); - if (__use_tzfile) - { - free (old_tz); - old_tz = NULL; - return; - } + tzr->m = 11; + tzr->n = 1; + tzr->d = 0; } } else + return false; + + if (*tz != '\0' && *tz != '/' && *tz != ',') + return false; + else if (*tz == '/') { - /* There is no DST. */ - tz_rules[1].name = tz_rules[0].name; - tz_rules[1].offset = tz_rules[0].offset; - goto out; + /* Get the time of day of the change. */ + int negative; + ++tz; + if (*tz == '\0') + return false; + negative = *tz == '-'; + tz += negative; + /* Default to 2:00 AM. */ + unsigned short hh = 2; + unsigned short mm = 0; + unsigned short ss = 0; + int consumed = 0; + sscanf (tz, "%hu%n:%hu%n:%hu%n", + &hh, &consumed, &mm, &consumed, &ss, &consumed);; + tz += consumed; + tzr->secs = (negative ? -1 : 1) * ((hh * 60 * 60) + (mm * 60) + ss); } + else + /* Default to 2:00 AM. */ + tzr->secs = 2 * 60 * 60; - done_names: - /* Figure out the standard <-> DST rules. */ - for (unsigned int whichrule = 0; whichrule < 2; ++whichrule) - { - tz_rule *tzr = &tz_rules[whichrule]; + tzr->computed_for = -1; + *tzp = tz; + return true; +} - /* Ignore comma to support string following the incorrect - specification in early POSIX.1 printings. */ - tz += *tz == ','; +/* Parse the POSIX TZ-style string. */ +void +__tzset_parse_tz (const char *tz) +{ + /* Clear out old state and reset to unnamed UTC. */ + memset (tz_rules, '\0', sizeof tz_rules); + tz_rules[0].name = tz_rules[1].name = ""; - /* Get the date of the change. */ - if (*tz == 'J' || isdigit (*tz)) - { - char *end; - tzr->type = *tz == 'J' ? J1 : J0; - if (tzr->type == J1 && !isdigit (*++tz)) - goto out; - unsigned long int d = strtoul (tz, &end, 10); - if (end == tz || d > 365) - goto out; - if (tzr->type == J1 && d == 0) - goto out; - tzr->d = d; - tz = end; - } - else if (*tz == 'M') - { - tzr->type = M; - if (sscanf (tz, "M%hu.%hu.%hu%n", - &tzr->m, &tzr->n, &tzr->d, &consumed) != 3 - || tzr->m < 1 || tzr->m > 12 - || tzr->n < 1 || tzr->n > 5 || tzr->d > 6) - goto out; - tz += consumed; - } - else if (*tz == '\0') + /* Get the standard timezone name. */ + if (parse_tzname (&tz, 0) && parse_offset (&tz, 0)) + { + /* Get the DST timezone name (if any). */ + if (*tz != '\0') { - /* Daylight time rules in the U.S. are defined in the - U.S. Code, Title 15, Chapter 6, Subchapter IX - Standard - Time. These dates were established by Congress in the - Energy Policy Act of 2005 [Pub. L. no. 109-58, 119 Stat 594 - (2005)]. - Below is the equivalent of "M3.2.0,M11.1.0" [/2 not needed - since 2:00AM is the default]. */ - tzr->type = M; - if (tzr == &tz_rules[0]) + if (parse_tzname (&tz, 1)) { - tzr->m = 3; - tzr->n = 2; - tzr->d = 0; - } - else - { - tzr->m = 11; - tzr->n = 1; - tzr->d = 0; + parse_offset (&tz, 1); + if (*tz == '\0' || (tz[0] == ',' && tz[1] == '\0')) + { + /* There is no rule. See if there is a default rule + file. */ + __tzfile_default (tz_rules[0].name, tz_rules[1].name, + tz_rules[0].offset, tz_rules[1].offset); + if (__use_tzfile) + { + free (old_tz); + old_tz = NULL; + return; + } + } } + /* Figure out the standard <-> DST rules. */ + if (parse_rule (&tz, 0)) + parse_rule (&tz, 1); } else - goto out; - - if (*tz != '\0' && *tz != '/' && *tz != ',') - goto out; - else if (*tz == '/') { - /* Get the time of day of the change. */ - int negative; - ++tz; - if (*tz == '\0') - goto out; - negative = *tz == '-'; - tz += negative; - consumed = 0; - switch (sscanf (tz, "%hu%n:%hu%n:%hu%n", - &hh, &consumed, &mm, &consumed, &ss, &consumed)) - { - default: - hh = 2; /* Default to 2:00 AM. */ - case 1: - mm = 0; - case 2: - ss = 0; - case 3: - break; - } - tz += consumed; - tzr->secs = (negative ? -1 : 1) * ((hh * 60 * 60) + (mm * 60) + ss); + /* There is no DST. */ + tz_rules[1].name = tz_rules[0].name; + tz_rules[1].offset = tz_rules[0].offset; } - else - /* Default to 2:00 AM. */ - tzr->secs = 2 * 60 * 60; - - tzr->computed_for = -1; } - out: update_vars (); } @@ -644,6 +640,8 @@ __tz_convert (const time_t *timer, int use_localtime, struct tm *tp) leap_extra_secs = 0; } + __libc_lock_unlock (tzset_lock); + if (tp) { if (! use_localtime) @@ -659,8 +657,6 @@ __tz_convert (const time_t *timer, int use_localtime, struct tm *tp) tp = NULL; } - __libc_lock_unlock (tzset_lock); - return tp; } diff --git a/time/wcsftime.c b/time/wcsftime.c index 0ed3882f14..c23d87323f 100644 --- a/time/wcsftime.c +++ b/time/wcsftime.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2014 Free Software Foundation, Inc. +/* Copyright (C) 1991-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/time/wcsftime_l.c b/time/wcsftime_l.c index 8185d91d38..15a152bf86 100644 --- a/time/wcsftime_l.c +++ b/time/wcsftime_l.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2014 Free Software Foundation, Inc. +/* Copyright (C) 2002-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or |