Deprecating calls to not-thread safe asctime(), ctime(), and localtime()
calls is pretty close to pointless change. Lets do it to reduce lgtm scan
warnings with justification it's nicer to use static analysis tools when
they have very few positives.
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
The parse-date.y is used only for hwclock, let's keep it together.
Note that the file (originally from gnulib) has GPLv3 license, so it's
better to make it obvious that we use it really only for hwclock (also
GPL).
Signed-off-by: Karel Zak <kzak@redhat.com>
Assumption all years since 1970 have been exactly 365 days long has it's
problems when leap years happen. Lets use struct tm fields that are
provided by localtime_r(), making year and day to be correctly compared even
when it's late new years eve somewhere else than UTC-0.
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
* Start the ISO format flags at bit 0 instead of bit 1.
* Remove unnecessary _8601 from ISO format flag names to
avoid line wrapping and to ease readability.
* ISO timestamps have date-time-timzone in common, so move
the TIMEZONE flag to bit 2 causing all timestamp masks
to have the first three bits set and the last four bits
as timestamp 'options'.
* Change the 'SPACE' flag to a 'T' flag, because it makes
the code and comments more concise.
* Add common ISO timestamp masks.
* Implement the ISO timestamp masks in all applicable code
using the strxxx_iso() functions.
Signed-off-by: J William Piggott <elseifthen@gmx.com>
This new function returns the GMT offset relative to its
argument. It is used in this patch to fix two bugs:
1) On platforms that the tm struct excludes tm_gmtoff,
hwclock assumes a one hour DST offset. This can cause
an incorrect kernel timezone setting. For example:
Master branch tested with tm_gmtoff illustrates the correct offset:
$ TZ="Australia/Lord_Howe" hwclock --hctosys --test | grep settimeofday
Calling settimeofday(1507494204.192398, -660)
Master branch tested without tm_gmtoff has an incorrect offset:
$ TZ="Australia/Lord_Howe" hwclock --hctosys --test | grep settimeofday
Calling settimeofday(1507494249.193852, -690)
Patched tested without tm_gmtoff has the correct offset:
$ TZ="Australia/Lord_Howe" hwclock --hctosys --test | grep settimeofday
Calling settimeofday(1507494260.194208, -660)
2) ISO 8601 'extended' format requires all time elements
to use a colon (:).
Current invalid ISO 8601:
$ hwclock
2017-10-08 16:25:17.895462-0400
Patched:
$ hwclock
2017-10-08 16:25:34.141895-04:00
Also required by this change:
login-utils/last.c: increase ISO out_len and in_len by one to
accommodate the addition of the timezone colon.
Signed-off-by: J William Piggott <elseifthen@gmx.com>
Although iso-8601 specifies years as 4 digits, it allows
them to be wider.
The current POSIX year width is limited by 'int tm_year'
at 10 digits plus a negative sign.
That, and the possibility of nanosecond time makes the
widest POSIX iso-8601 time 41 characters. Plus the \0
string terminator yields a buffer size of 42.
Before truncated output:
/sbin/hwclock --utc --noadjfile --predict --date '-2147483765 years'
-2147481748-09-25 20:29:45.0000
Patched:
./hwclock --utc --noadjfile --predict --date '-2147483765 years'
-2147481748-09-25 20:17:21.000000-0456
./hwclock --utc --noadjfile --predict --date '-2147483766 years'
hwclock: invalid date '-2147483766 years'
Comparable to coreutils 'date' command:
date -Ins --date '-2147483765 years'
-2147481748-09-25T19:49:31,578899297-0456
date -Ins --date '-2147483766 years'
date: invalid date '-2147483766 years'
The 'date' output illustrates the full 41 character POSIX iso-8601
Signed-off-by: J William Piggott <elseifthen@gmx.com>
* include/timeutils.h
Add parse-date API
* lib/parse-date.y - new file
Lib function that parses a date string into a timespec struct.
Derived from gnulib-dd7a871 parse-datetime.y with these changes:
* reduced to a single function API renamed to parse_date()
* removed gnulib dependencies
* removed debugging
* converted to util-linux coding style
* include/cctype.h - new file
Like ctype.h only hard coded to the 'C' locale.
Used by lib/parse-date.y.
Derived from gnulib-dd7a871 c-ctype.h with these changes:
* removed gnulib dependencies
* converted to util-linux coding style
* add requisite util-linux constants
Signed-off-by: J William Piggott <elseifthen@gmx.com>
Local timegm() is a replacement function in cases it is missing from libc
implementation. Hopefully the replacement is never, or very rarely, used.
CC: Ruediger Meier <ruediger.meier@ga-group.nl>
Reviewed-by: J William Piggott <elseifthen@gmx.com>
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
When timestamps are intented to be conversable back from string to binary it
is best to stick with UTC-0 timezone. This is needed in utmpdump(1).
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
- use buffers rather than allocate memory
- support .usec and ,usec convention
- use strftime for timezone (we need to care about daylight
saving time)
Signed-off-by: Karel Zak <kzak@redhat.com>