Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,12 @@ check_function_exists(fts_open HAVE_FTS_OPEN)
check_function_exists(strsep HAVE_STRSEP)
check_function_exists(strptime HAVE_STRPTIME)

# struct tm.tm_gmtoff is a BSD/GNU extension (present on glibc, musl, the BSDs
# and macOS, absent on the MSVC runtime). When available it carries the UTC
# offset including daylight saving time, unlike the global timezone variable.
include(CheckStructHasMember)
check_struct_has_member("struct tm" tm_gmtoff time.h HAVE_STRUCT_TM_TM_GMTOFF)

check_include_file(syslog.h HAVE_SYSLOG_H)
check_include_file(stdio_ext.h HAVE_STDIO_EXT_H)
check_include_file(shadow.h HAVE_SHADOW_H)
Expand Down
1 change: 1 addition & 0 deletions config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
#cmakedefine HAVE_STRSEP
#cmakedefine HAVE_FLOCK
#cmakedefine HAVE_STRPTIME
#cmakedefine HAVE_STRUCT_TM_TM_GMTOFF

#cmakedefine OPENSCAP_PROBE_INDEPENDENT_ENVIRONMENTVARIABLE
#cmakedefine OPENSCAP_PROBE_INDEPENDENT_ENVIRONMENTVARIABLE58
Expand Down
26 changes: 15 additions & 11 deletions src/XCCDF/result.c
Original file line number Diff line number Diff line change
Expand Up @@ -1842,7 +1842,10 @@ static inline const char *_get_timestamp(void)
if (!lt)
return NULL;

#if defined(OS_FREEBSD)
#if defined(HAVE_STRUCT_TM_TM_GMTOFF)
/* tm_gmtoff is the offset east of UTC in seconds and already accounts
* for daylight saving time, so it reflects the actual offset in effect
* at the represented local time. */
tz_diff = lt->tm_gmtoff;

if (tz_diff < 0) {
Expand All @@ -1851,20 +1854,21 @@ static inline const char *_get_timestamp(void)
} else {
tz_sign = '+';
}

/* glibc's timezone offset does not account for daylight savings time.
* So we match that behavior here by adding 3600 seconds
*/
if (lt->tm_isdst)
tz_diff += 3600;
#else
/* timezone is a global variable set by localtime(3) */
if (timezone <= 0) {
/* Fallback for platforms without tm_gmtoff (e.g. the MSVC runtime).
* timezone is a global variable set by localtime(3) holding the number
* of seconds west of UTC of standard time. Daylight saving time moves
* the local time one hour east, i.e. closer to UTC, so subtract 3600
* seconds from the westward offset when DST is in effect. */
long std_diff = timezone;
if (lt->tm_isdst > 0)
std_diff -= 3600;
Comment on lines +1858 to +1865
if (std_diff <= 0) {
tz_sign = '+';
tz_diff = -timezone;
tz_diff = -std_diff;
} else {
tz_sign = '-';
tz_diff = timezone;
tz_diff = std_diff;
}
#endif
tz_diff /= 60;
Expand Down