Bug#874798: libc6: mktime() does not set errno when it fails
From
g1@21:1/5 to
All on Sat Sep 9 20:40:01 2017
XPost: linux.debian.bugs.dist
Package: libc6
Version: 2.24-11+deb9u1
Severity: normal
Tags: upstream
When mktime() fails to convert a struct tm to a time_t, it returns -1.
It should also set errno to EOVERFLOW in order to distinguish the failure
from the legitimate case of converting "1 second before the epoch".
The following program, when run on a 32-bit system, shows that mktime
does not comply to the standard. On recent amd64 systems, time_t is 64
bit long, therefore failure doesn't occur for the same broken down times.
Best regards,
g.b.
#define _POSIX_C_SOURCE 200112L
#include <stdio.h>
#include <time.h>
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
int main() {
struct tm tm0;
struct tm *ptm;
time_t t;
int eno;
assert(sizeof t == 4); /* need 32 bit to trigger failure in 1900 */
/* nail timezone to UTC */
setenv("TZ", "UTC", 1);
tzset();
t = -1; /* 1 sec before epoch */
ptm = gmtime_r(&t, &tm0);
assert(ptm != NULL);
errno = 0;
t = mktime(&tm0);
eno = errno;
printf("struct TM: %d-%d-%d %02d:%02d:%02d (dst=%d)\n", 1900 + tm0.tm_year,
1 + tm0.tm_mon, tm0.tm_mday, tm0.tm_hour, tm0.tm_min,
tm0.tm_sec, tm0.tm_isdst);
printf("mktime(): retval %ld (expected -1), "
"errno %d (expected 0)\n", (long) t, eno);
tm0.tm_year = 0; /* warp to year 1900 */
/* bad conversion for 32-bit time_t, should return -1 and set errno */
errno = 0;
t = mktime(&tm0);
eno = errno;
printf("struct TM: %d-%d-%d %02d:%02d:%02d (dst=%d)\n", 1900 + tm0.tm_year,
1 + tm0.tm_mon, tm0.tm_mday, tm0.tm_hour, tm0.tm_min,
tm0.tm_sec, tm0.tm_isdst);
printf("mktime(): retval %ld (expected -1), "
"errno %d (expected EOVERFLOW=%d)\n", (long) t, eno, EOVERFLOW);
return 0;
}
-- System Information:
Debian Release: 9.1
APT prefers stable
APT policy: (500, 'stable')
Architecture: i386 (i686)
Kernel: Linux 4.9.0-3-686 (SMP w/1 CPU core)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: sysvinit (via /sbin/init)
Versions of packages libc6 depends on:
ii libgcc1 1:6.3.0-18
libc6 recommends no packages.
Versions of packages libc6 suggests:
ii debconf [debconf-2.0] 1.5.61
pn glibc-doc <none>
ii libc-l10n 2.24-11+deb9u1
ii locales 2.24-11+deb9u1
-- debconf information excluded
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)