skalibs

Mirror/fork of https://skarnet.org/software/skalibs/
git clone https://ccx.te2000.cz/git/skalibs
Log | Files | Refs | README | LICENSE

commit 805729e206b7586c57483aa0f4a90f7e0e2c9661
parent 2e0421fc58922697f2bb51c428599fbd44055556
Author: Laurent Bercot <ska-skaware@skarnet.org>
Date:   Wed, 14 Oct 2015 22:54:08 +0000

 - Remove /etc/leapsecs.dat
 - Publish tools to create the leap second table as a .c
 - Simplify functions using leap seconds
 - rc for 2.3.8.0

Diffstat:
Mdoc/index.html | 2+-
Mdoc/libstddjb/djbtime.html | 23++++-------------------
Mdoc/libstddjb/tai.html | 25+------------------------
Mdoc/upgrade.html | 6++++++
Mpackage/deps.mak | 5++---
Mpackage/info | 2+-
Dsrc/etc/leapsecs.dat | 0
Msrc/libstddjb/djbtime-internal.h | 21++++-----------------
Msrc/libstddjb/leapsecs_add.c | 11++++-------
Dsrc/libstddjb/leapsecs_here.c | 9---------
Dsrc/libstddjb/leapsecs_init.c | 34----------------------------------
Msrc/libstddjb/leapsecs_sub.c | 10++++------
Asrc/libstddjb/leapsecs_table.c | 39+++++++++++++++++++++++++++++++++++++++
Msrc/libstddjb/ltm64_from_utc.c | 2+-
Msrc/libstddjb/tai_from_utc.c | 2+-
Msrc/libstddjb/utc_from_localtm.c | 6++----
Msrc/libstddjb/utc_from_ltm64.c | 14+++-----------
Msrc/libstddjb/utc_from_tai.c | 2+-
Atools/convert-leapsecs.c | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Atools/leapsecs.txt | 29+++++++++++++++++++++++++++++
Atools/make-leapsecs_table | 39+++++++++++++++++++++++++++++++++++++++
21 files changed, 195 insertions(+), 139 deletions(-)

diff --git a/doc/index.html b/doc/index.html @@ -60,7 +60,7 @@ with a standard C development environment </li> <h3> Download </h3> <ul> - <li> The current released version of skalibs is <a href="skalibs-2.3.7.1.tar.gz">2.3.7.1</a>. </li> + <li> The current released version of skalibs is <a href="skalibs-2.3.8.0.tar.gz">2.3.8.0</a>. </li> <li> Alternatively, you can checkout a copy of the skalibs git repository: <pre> git clone git://git.skarnet.org/skalibs </pre> </li> </ul> diff --git a/doc/libstddjb/djbtime.html b/doc/libstddjb/djbtime.html @@ -34,21 +34,6 @@ and implemented in the <tt>libskarnet.a</tt> or <tt>libskarnet.so</tt> library. other time formats and user-friendly representations. </p> -<h2> The <tt>/etc/leapsecs.dat</tt> file </h2> - -<p> - User-friendly time is calculated from UTC. Internal time computations -should be performed on TAI time - because TAI flows linearly whereas -UTC does not. To convert between UTC and TAI time, you need a -<em>leap second table</em>. skalibs provides such a file in its -<tt>src/etc/leapsecs.dat</tt> subdirectory, which is copied -to <tt>/etc/leapsecs.dat</tt> at installation time (unless you specify -a --prefix or --datadir option to configure). -<strong>The <tt>/etc/leapsecs.dat</tt> file must remain accessible -on your system, else time conversions will not be computed -properly.</strong> -</p> - <h2> Data structures </h2> <ul> @@ -72,7 +57,7 @@ Converts the absolute TAI64 time in *<em>t</em> to an UTC time, stored in *<em>u</em> as an unsigned 64-bit integer. *<em>u</em> is actually 2^62 plus the number of seconds since the Epoch. The function returns 1 if it succeeds, or 0 (and sets errno) if an -error occurs (for instance: the leap second table cannot be found). +error occurs. </p> <p> @@ -81,7 +66,7 @@ Converts the UTC time in <em>u</em>, stored as an unsigned 64-bit integer (2^62 plus the number of seconds since the Epoch), to a TAI64 time in *<em>t</em>. The function returns 1 if it succeeds, or 0 (and sets errno) if an -error occurs (for instance: the leap second table cannot be found). +error occurs. </p> <h3> NTP </h3> @@ -92,7 +77,7 @@ Converts the absolute TAI64N time in *<em>a</em> to a 64-bit NTP timestamp, stored in *<em>ntp</em>. The higher 32 bits of *<em>ntp</em> represent a number of seconds ; the lower 32 bits are the fractional part of the timestamp. The function returns 1 if it succeeds, or 0 (and sets errno) if an -error occurs (for instance: the leap second table cannot be found, or +error occurs (for instance: *<em>a</em> cannot be represented in the valid NTP range). </p> @@ -101,7 +86,7 @@ error occurs (for instance: the leap second table cannot be found, or Converts the NTP timestamp in <em>ntp</em> to a TAI64N time in *<em>a</em>. The function returns 1 if it succeeds, or 0 (and sets errno) if an -error occurs (for instance: the leap second table cannot be found). +error occurs. </p> <h3> Local time </h3> diff --git a/doc/libstddjb/tai.html b/doc/libstddjb/tai.html @@ -112,28 +112,6 @@ dates. It is up to the programmer to make sure that a relative time is never interpreted as an absolute TAI64 date, and vice-versa. </p> -<h3> The leap second table </h3> - -<p> - skalibs provides a <tt>src/etc/leapsecs.dat</tt> file, -which is copied to <tt>/etc/leapsecs.dat</tt> at installation time -(or wherever you specified with the <tt>--prefix</tt> or <tt>--datadir</tt> -options to configure). -<strong>Make sure this file is always present and readable.</strong> -This file contains the <em>leap second table</em>, which is needed for -conversions between TAI and UTC. If you call a function that needs such -a conversion (for instance, you call <tt>tain_sysclock()</tt> and your -system clock is set to UTC) and the file cannot be read, the function -call will fail. -</p> - -<p> - The leap second table is read once in every process that needs it -(the first time a TAI &harr; UTC conversion is made) and then is -stored in memory. If the <tt>leapsecs.dat</tt> file changes, long-lived -processes will need to be restarted to take the change into account. -</p> - <h2> Functions </h2> <h3> Wallclock operations </h3> @@ -343,8 +321,7 @@ could not be performed; in which case errno is set to EINVAL if the input argument was not a valid timestamp, to EOVERFLOW if the output could not be represented in the chosen format (which may happen on systems with a 32 bit <tt>time_t</tt>), or other error -codes - for instance related to the leap second table when a -lookup was necessary. +codes. </p> <code> int tai_from_time_sysclock (tai_t *a, time_t t) <br /> diff --git a/doc/upgrade.html b/doc/upgrade.html @@ -18,6 +18,12 @@ <h1> What has changed in skalibs </h1> +<h2> in 2.3.8.0 </h2> + +<ul> + <li> The <tt>/etc/leapsecs.dat</tt> file is no longer necessary. </li> +</ul> + <h2> in 2.3.7.1 </h2> <ul> diff --git a/package/deps.mak b/package/deps.mak @@ -68,7 +68,7 @@ src/libstdcrypto/sha1-internal.h: src/include/skalibs/sha1.h src/include/skalibs src/libstdcrypto/sha256-internal.h: src/include/skalibs/sha256.h src/include/skalibs/uint32.h src/libstdcrypto/sha512-internal.h: src/include/skalibs/sha512.h src/libstddjb/alloc-internal.h: src/include/skalibs/alloc.h src/include/skalibs/sysdeps.h -src/libstddjb/djbtime-internal.h: src/include/skalibs/config.h src/include/skalibs/uint64.h +src/libstddjb/djbtime-internal.h: src/include/skalibs/uint64.h src/libstddjb/fmtscan-internal.h: src/include/skalibs/bytestr.h src/include/skalibs/fmtscan.h src/libstddjb/selfpipe-internal.h: src/include/skalibs/sig.h src/include/skalibs/sysdeps.h src/libunixonacid/skaclient-internal.h: src/include/skalibs/kolbak.h src/include/skalibs/skaclient.h src/include/skalibs/unixmessage.h @@ -405,9 +405,8 @@ src/libstddjb/ipc_send.o src/libstddjb/ipc_send.lo: src/libstddjb/ipc_send.c src src/libstddjb/ipc_stream.o src/libstddjb/ipc_stream.lo: src/libstddjb/ipc_stream.c src/include/skalibs/djbunix.h src/include/skalibs/nonposix.h src/include/skalibs/webipc.h src/libstddjb/ipc_timed_connect.o src/libstddjb/ipc_timed_connect.lo: src/libstddjb/ipc_timed_connect.c src/include/skalibs/error.h src/include/skalibs/iopause.h src/include/skalibs/tai.h src/include/skalibs/webipc.h src/libstddjb/leapsecs_add.o src/libstddjb/leapsecs_add.lo: src/libstddjb/leapsecs_add.c src/libstddjb/djbtime-internal.h src/include/skalibs/uint64.h -src/libstddjb/leapsecs_here.o src/libstddjb/leapsecs_here.lo: src/libstddjb/leapsecs_here.c src/libstddjb/djbtime-internal.h src/include/skalibs/uint64.h -src/libstddjb/leapsecs_init.o src/libstddjb/leapsecs_init.lo: src/libstddjb/leapsecs_init.c src/libstddjb/djbtime-internal.h src/include/skalibs/djbunix.h src/include/skalibs/uint64.h src/libstddjb/leapsecs_sub.o src/libstddjb/leapsecs_sub.lo: src/libstddjb/leapsecs_sub.c src/libstddjb/djbtime-internal.h src/include/skalibs/uint64.h +src/libstddjb/leapsecs_table.o src/libstddjb/leapsecs_table.lo: src/libstddjb/leapsecs_table.c src/libstddjb/djbtime-internal.h src/include/skalibs/tai.h src/include/skalibs/uint64.h src/libstddjb/localtm_fmt.o src/libstddjb/localtm_fmt.lo: src/libstddjb/localtm_fmt.c src/include/skalibs/djbtime.h src/include/skalibs/uint.h src/libstddjb/localtm_from_ltm64.o src/libstddjb/localtm_from_ltm64.lo: src/libstddjb/localtm_from_ltm64.c src/include/skalibs/djbtime.h src/include/skalibs/tai.h src/include/skalibs/uint64.h src/libstddjb/localtm_from_sysclock.o src/libstddjb/localtm_from_sysclock.lo: src/libstddjb/localtm_from_sysclock.c src/include/skalibs/djbtime.h src/include/skalibs/uint64.h diff --git a/package/info b/package/info @@ -1,4 +1,4 @@ package=skalibs -version=2.3.7.1 +version=2.3.8.0 category=prog package_macro_name=SKALIBS diff --git a/src/etc/leapsecs.dat b/src/etc/leapsecs.dat Binary files differ. diff --git a/src/libstddjb/djbtime-internal.h b/src/libstddjb/djbtime-internal.h @@ -3,26 +3,13 @@ #ifndef DJBTIME_INTERNAL_H #define DJBTIME_INTERNAL_H -#include <skalibs/config.h> #include <skalibs/uint64.h> +extern unsigned int const leapsecs_table_len ; +extern uint64 const *const leapsecs_table ; - /* Leap second handling, for UTC <--> TAI conversions */ - -#define LEAPSECS_MAX 39 -#define LEAPSECS_FILE SKALIBS_ETC "/leapsecs.dat" -extern uint64 *leapsecs_here ; - -extern int leapsecs_init_r (char const *, uint64 *) ; -#define leapsecs_init() leapsecs_init_r(LEAPSECS_FILE, leapsecs_here) -extern int leapsecs_add_r (uint64 *, char const *, uint64 *, int) ; -#define leapsecs_add(t, h) leapsecs_add_r(t, LEAPSECS_FILE, leapsecs_here, h) -extern int leapsecs_sub_r (uint64 *, char const *, uint64 *) ; -#define leapsecs_sub(t) leapsecs_sub_r((t), LEAPSECS_FILE, leapsecs_here) - - - /* Run-time test: does the current timezone handle leap seconds ? */ - +extern void leapsecs_add (uint64 *, int) ; +extern int leapsecs_sub (uint64 *) ; extern int skalibs_tzisright (void) ; #endif diff --git a/src/libstddjb/leapsecs_add.c b/src/libstddjb/leapsecs_add.c @@ -3,17 +3,14 @@ #include <skalibs/uint64.h> #include "djbtime-internal.h" -int leapsecs_add_r (uint64 *t, char const *file, uint64 *leapsecs, int hit) +void leapsecs_add (uint64 *t, int hit) { uint64 u = *t ; - int n = leapsecs_init_r(file, leapsecs) ; register unsigned int i = 0 ; - if (n < 0) return -1 ; - for (; i < (unsigned int)n ; i++) + for (; i < leapsecs_table_len ; i++) { - if (u < leapsecs[i]) break ; - if (!hit || (leapsecs[i] < u)) ++u ; + if (u < leapsecs_table[i]) break ; + if (!hit || (leapsecs_table[i] < u)) ++u ; } *t = u ; - return n ; } diff --git a/src/libstddjb/leapsecs_here.c b/src/libstddjb/leapsecs_here.c @@ -1,9 +0,0 @@ -/* ISC license. */ - -/* MT-unsafe */ - -#include <skalibs/uint64.h> -#include "djbtime-internal.h" - -static uint64 leapsecs_here_tab[LEAPSECS_MAX+1] ; -uint64 *leapsecs_here = leapsecs_here_tab ; diff --git a/src/libstddjb/leapsecs_init.c b/src/libstddjb/leapsecs_init.c @@ -1,34 +0,0 @@ -/* ISC license. */ - -#include <errno.h> -#include <skalibs/uint64.h> -#include <skalibs/djbunix.h> -#include "djbtime-internal.h" - -static unsigned int leapsecs_len (uint64 const *data) -{ - register unsigned int i = 1 ; - while (data[i]) i++ ; - return i ; -} - -static int leapsecs_read (char const *file, uint64 *data) -{ - char s[LEAPSECS_MAX * sizeof(uint64)] ; - register int n = openreadnclose(file, s, LEAPSECS_MAX * sizeof(uint64)) ; - if (n < 0) return -1 ; - if (n % sizeof(uint64)) return (errno = EINVAL, -1) ; - n /= sizeof(uint64) ; - { - register unsigned int i = 0 ; - for (; i < (unsigned int)n ; i++) - uint64_unpack_big(s + i * sizeof(uint64), data + i) ; - } - data[n] = 0 ; - return n ; -} - -int leapsecs_init_r (char const *file, uint64 *data) -{ - return data[0] ? (int)leapsecs_len(data) : leapsecs_read(file, data) ; -} diff --git a/src/libstddjb/leapsecs_sub.c b/src/libstddjb/leapsecs_sub.c @@ -3,19 +3,17 @@ #include <skalibs/uint64.h> #include "djbtime-internal.h" -int leapsecs_sub_r (uint64 *t, char const *file, uint64 *leapsecs) +int leapsecs_sub (uint64 *t) { uint64 u = *t ; uint64 d = 0 ; - int n = leapsecs_init_r(file, leapsecs) ; register unsigned int i = 0 ; register int hit = 0 ; - if (n < 0) return -1 ; - for (; i < (unsigned int)n ; i++) + for (; i < leapsecs_table_len ; i++) { - if (u < leapsecs[i]) break ; + if (u < leapsecs_table[i]) break ; ++d ; - if (u == leapsecs[i]) hit = 1 ; + if (u == leapsecs_table[i]) hit = 1 ; } *t = u - d ; return hit ; diff --git a/src/libstddjb/leapsecs_table.c b/src/libstddjb/leapsecs_table.c @@ -0,0 +1,39 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/uint64.h> +#include <skalibs/tai.h> +#include "djbtime-internal.h" + +unsigned int const leapsecs_table_len = 26 ; +static uint64 const leapsecs_table_[26] = +{ + TAI_MAGIC + 78796809, + TAI_MAGIC + 94694410, + TAI_MAGIC + 126230411, + TAI_MAGIC + 157766412, + TAI_MAGIC + 189302413, + TAI_MAGIC + 220924814, + TAI_MAGIC + 252460815, + TAI_MAGIC + 283996816, + TAI_MAGIC + 315532817, + TAI_MAGIC + 362793618, + TAI_MAGIC + 394329619, + TAI_MAGIC + 425865620, + TAI_MAGIC + 489024021, + TAI_MAGIC + 567993622, + TAI_MAGIC + 631152023, + TAI_MAGIC + 662688024, + TAI_MAGIC + 709948825, + TAI_MAGIC + 741484826, + TAI_MAGIC + 773020827, + TAI_MAGIC + 820454428, + TAI_MAGIC + 867715229, + TAI_MAGIC + 915148830, + TAI_MAGIC + 1136073631, + TAI_MAGIC + 1230768032, + TAI_MAGIC + 1341100833, + TAI_MAGIC + 1435708834 +} ; +uint64 const *const leapsecs_table = leapsecs_table_ ; diff --git a/src/libstddjb/ltm64_from_utc.c b/src/libstddjb/ltm64_from_utc.c @@ -8,7 +8,7 @@ int ltm64_from_utc (uint64 *u) { switch (skalibs_tzisright()) { - case 1 : return leapsecs_add(u, 0) >= 0 ; + case 1 : leapsecs_add(u, 0) ; case 0 : return 1 ; default : return 0 ; } diff --git a/src/libstddjb/tai_from_utc.c b/src/libstddjb/tai_from_utc.c @@ -7,6 +7,6 @@ int tai_from_utc (tai_t *t, uint64 u) { - if (leapsecs_add(&u, 0) < 0) return 0 ; + leapsecs_add(&u, 0) ; return tai_u64(t, u + 10) ; } diff --git a/src/libstddjb/utc_from_localtm.c b/src/libstddjb/utc_from_localtm.c @@ -7,9 +7,7 @@ int utc_from_localtm (uint64 *uu, struct tm const *l) { - uint64 u ; - if (!ltm64_from_localtm(&u, l)) return 0 ; - if (!utc_from_ltm64(&u)) return 0 ; - *uu = u ; + if (!ltm64_from_localtm(uu, l)) return 0 ; + utc_from_ltm64(uu) ; return 1 ; } diff --git a/src/libstddjb/utc_from_ltm64.c b/src/libstddjb/utc_from_ltm64.c @@ -5,19 +5,11 @@ #include <skalibs/djbtime.h> #include "djbtime-internal.h" -#ifdef SKALIBS_FLAG_CLOCKISTAI - -int utc_from_ltm64 (uint64 *u) -{ - return (leapsecs_sub(u) > 0) ; -} - -#else int utc_from_ltm64 (uint64 *u) { - (void)u ; +#ifdef SKALIBS_FLAG_CLOCKISTAI + leapsecs_sub(u) ; +#endif return 1 ; } - -#endif diff --git a/src/libstddjb/utc_from_tai.c b/src/libstddjb/utc_from_tai.c @@ -10,7 +10,7 @@ int utc_from_tai (uint64 *u, tai_t const *t) { uint64 tt = t->x - 10 ; if (t->x < 10U) return (errno = EINVAL, 0) ; - if (leapsecs_sub(&tt) < 0) return 0 ; + leapsecs_sub(&tt) ; *u = tt ; return 1 ; } diff --git a/tools/convert-leapsecs.c b/tools/convert-leapsecs.c @@ -0,0 +1,53 @@ +#include <time.h> +#include <skalibs/uint64.h> +#include <skalibs/buffer.h> +#include <skalibs/strerr2.h> +#include <skalibs/stralloc.h> +#include <skalibs/genalloc.h> +#include <skalibs/skamisc.h> + +static genalloc table = GENALLOC_ZERO ; /* uint64 */ + +static void add_leapsecs (uint64 *t) +{ + uint64 *tab = genalloc_s(uint64, &table) ; + unsigned int n = genalloc_len(uint64, &table) ; + unsigned int i = 0 ; + for (; i < n ; i++) if (*t >= tab[i]) (*t)++ ; +} + +int main (int argc, char const *const *argv) +{ + stralloc sa = STRALLOC_ZERO ; + for (;;) + { + struct tm tm ; + uint64 tt ; + time_t t ; + char *p ; + int r ; + char fmt[UINT64_FMT] ; + sa.len = 0 ; + r = skagetln(buffer_0, &sa, '\n') ; + if (r < 0) strerr_diefu1sys(111, "read from stdin") ; + if (!r) break ; + sa.s[sa.len-1] = 0 ; + if (!strptime(sa.s, "+%Y-%m-%d", &tm)) continue ; + tm.tm_sec = 59 ; + tm.tm_min = 59 ; + tm.tm_hour = 23 ; + t = mktime(&tm) ; + if (t < 0) strerr_diefu1sys(111, "mktime") ; + tt = t + 10 ; + add_leapsecs(&tt) ; + if (!genalloc_append(uint64, &table, &tt)) + strerr_diefu1sys(111, "genalloc_append") ; + fmt[uint64_fmt(fmt, tt)] = 0 ; + buffer_puts(buffer_1, " TAI_MAGIC + ") ; + buffer_puts(buffer_1, fmt) ; + buffer_puts(buffer_1, ",\n") ; + } + buffer_unput(buffer_1, 2) ; + buffer_putsflush(buffer_1, "\n") ; + return 0 ; +} diff --git a/tools/leapsecs.txt b/tools/leapsecs.txt @@ -0,0 +1,29 @@ +# +# 1972-01-01 00:00:00 UTC was 1972-01-01 00:00:10 TAI. +# ++1972-06-30 ++1972-12-31 ++1973-12-31 ++1974-12-31 ++1975-12-31 ++1976-12-31 ++1977-12-31 ++1978-12-31 ++1979-12-31 ++1981-06-30 ++1982-06-30 ++1983-06-30 ++1985-06-30 ++1987-12-31 ++1989-12-31 ++1990-12-31 ++1992-06-30 ++1993-06-30 ++1994-06-30 ++1995-12-31 ++1997-06-30 ++1998-12-31 ++2005-12-31 ++2008-12-31 ++2012-06-30 ++2015-06-30 diff --git a/tools/make-leapsecs_table b/tools/make-leapsecs_table @@ -0,0 +1,39 @@ +#!/command/execlineb -P + +# Compile convert-leapsecs.c, then use this to create +# src/libstddjb/leapsecs_table.c + +define PREFIX ./tools + +backtick -n N +{ + pipeline + { + redirfd -r 0 ${PREFIX}/leapsecs.txt + ${PREFIX}/convert-leapsecs + } + wc -l +} +import -u N + +if +{ + s6-echo "/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/uint64.h> +#include <skalibs/tai.h> +#include \"djbtime-internal.h\" + +unsigned int const leapsecs_table_len = ${N} ; +static uint64 const leapsecs_table_[${N}] =\n{" +} + +if +{ + redirfd -r 0 ${PREFIX}/leapsecs.txt + ${PREFIX}/convert-leapsecs +} + +s6-echo "} ;\nuint64 const *const leapsecs_table = leapsecs_table_ ;"