Re: [Nagios-devel] Fix for mktime() issue
Posted: Tue Mar 16, 2010 5:52 pm
--=-mIA06h0SM3zY9/9NUEKG
Content-Type: multipart/mixed; boundary="=-Zj2YvbHa+PT9jwzfX0HI"
--=-Zj2YvbHa+PT9jwzfX0HI
Content-Type: text/plain; charset=us-ascii; DelSp=Yes; Format=Flowed
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
Am 16.03.10 10:30 schrieb(en) Ton Voon:
>> The POSIX standard says [1]
>>=20
>>
>> A positive or 0 value for tm_isdst shall cause mktime() to presume initi=
ally that Daylight Savings Time, respectively, is or is not in effect for t=
he specified time. A negative value for tm_isdst shall cause mktime() to at=
tempt to determine whether Daylight Savings Time is in effect for the speci=
fied time.
>>
[snip]
>> Note that tm_isdst > What should be the purpose of a test case if the code strictly follows P=
OSIX?
>=20
> Because the test cases proves real-world usage, rather than some spec?
I don't think that POSIX and ISO 9899 are just "some spec". If my proper u=
sage of a well-defined library function produces weird results, I wouldn't =
assume that I am right and all those IEEE and ISO people (and glibc coders)=
are wrong. The usual approach IMHO would be looking at *my* code, which m=
ight be /slightly/ less perfect at second glance...
> What I don't have, are tests for the other 18 cases where is_dst has been=
initialised, and so I didn't revert those other changes. But my opinion is=
now that this is too cautious and we should just revert back to Nagios pre=
-3.2.0 behaviour.
If you don't believe me, run the attached little C test app which takes the=
current time, simulates your approach of the unitialised field, and conver=
ts back, which should of course give the initial value. For me (CET, no ds=
t in effect) the code always fails (=3D=3Dproduces an off-by-one-hour error=
) if the tm_isdst is > 0. I don't think you will find any box with time zo=
ne !=3D UTC where it doesn't...
Regarding Nagios, I can at least confirm that the wrong usage of the mktime=
() function (i.e. not initialising the tm_isdst field properly) does lead t=
o time calculation bugs. See [2. 3] for details.
Best, Albrecht.
[1]
[2]
[3]
--=-Zj2YvbHa+PT9jwzfX0HI
Content-Type: text/x-csrc; charset=us-ascii; name=mktime-test.c
Content-Disposition: attachment; filename=mktime-test.c
Content-Transfer-Encoding: quoted-printable
#include
#include
#include
#include
#include
int main(int argc, char **argv)
{
time_t now;
struct tm * local_t;
srand((unsigned int) getpid());
now =3D time(NULL);
local_t =3D localtime(&now);
printf("%u: sec=3D%d, min=3D%d, hour=3D%d, mday=3D%d, mon=3D%d, year=3D%d,=
wday=3D%d, yday=3D%d, isdst=3D%d\n",
(unsigned) now, local_t->tm_sec, local_t->tm_min,
local_t->tm_hour, local_t->tm_mday, local_t->tm_mon,
local_t->tm_year, local_t->tm_wday, local_t->tm_yday,
local_t->tm_isdst);
=20
/* set isdst to something random (simulate uninitalised) */
local_t->tm_isdst =3D rand() - (RAND_MAX / 2);
printf("using isdst=3D%d\n", local_t->tm_isdst);
now =3D mktime(local_t);
local_t =3D localtime(&now);
printf("%u: sec=3D%d, min=3D%d, hour=3D%d, mday=3D%d, mon=3D%d, year=3D%d,=
wday=3D%d, yday=3D%d, isdst=3D%d\n",
(unsigned) now, local_t->tm_sec, local_t->tm_min,
local_t->tm_hour, local_t->tm_mday, local_t->tm_mon,
local_t->tm_year, local_t->tm_wday, local_t->tm_yday,
local_t->tm_isdst);
return 0;
}
--=-Zj2YvbHa+PT9jwzfX0HI--
--=-mIA06h0SM3zY9/9NUEKG
Content-Type: application/pgp-signature
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.12 (GNU/Linux)
iD8DBQBLn9NOn/9unNAn/9ERAlpfAJ9dD0n1D9YkHfjubhiDk3mTS2EdxQCghUsy
m03R/u3t70tLQ4Lj9W1OALU=
=1zus
-----END PGP SIGNATURE-----
--=-mIA06h0SM3zY9/9NUEKG--
This post was automatically imported from historical nagios-devel mailing list archives
Original poster: [email protected]
Content-Type: multipart/mixed; boundary="=-Zj2YvbHa+PT9jwzfX0HI"
--=-Zj2YvbHa+PT9jwzfX0HI
Content-Type: text/plain; charset=us-ascii; DelSp=Yes; Format=Flowed
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
Am 16.03.10 10:30 schrieb(en) Ton Voon:
>> The POSIX standard says [1]
>>=20
>>
>> A positive or 0 value for tm_isdst shall cause mktime() to presume initi=
ally that Daylight Savings Time, respectively, is or is not in effect for t=
he specified time. A negative value for tm_isdst shall cause mktime() to at=
tempt to determine whether Daylight Savings Time is in effect for the speci=
fied time.
>>
[snip]
>> Note that tm_isdst > What should be the purpose of a test case if the code strictly follows P=
OSIX?
>=20
> Because the test cases proves real-world usage, rather than some spec?
I don't think that POSIX and ISO 9899 are just "some spec". If my proper u=
sage of a well-defined library function produces weird results, I wouldn't =
assume that I am right and all those IEEE and ISO people (and glibc coders)=
are wrong. The usual approach IMHO would be looking at *my* code, which m=
ight be /slightly/ less perfect at second glance...
> What I don't have, are tests for the other 18 cases where is_dst has been=
initialised, and so I didn't revert those other changes. But my opinion is=
now that this is too cautious and we should just revert back to Nagios pre=
-3.2.0 behaviour.
If you don't believe me, run the attached little C test app which takes the=
current time, simulates your approach of the unitialised field, and conver=
ts back, which should of course give the initial value. For me (CET, no ds=
t in effect) the code always fails (=3D=3Dproduces an off-by-one-hour error=
) if the tm_isdst is > 0. I don't think you will find any box with time zo=
ne !=3D UTC where it doesn't...
Regarding Nagios, I can at least confirm that the wrong usage of the mktime=
() function (i.e. not initialising the tm_isdst field properly) does lead t=
o time calculation bugs. See [2. 3] for details.
Best, Albrecht.
[1]
[2]
[3]
--=-Zj2YvbHa+PT9jwzfX0HI
Content-Type: text/x-csrc; charset=us-ascii; name=mktime-test.c
Content-Disposition: attachment; filename=mktime-test.c
Content-Transfer-Encoding: quoted-printable
#include
#include
#include
#include
#include
int main(int argc, char **argv)
{
time_t now;
struct tm * local_t;
srand((unsigned int) getpid());
now =3D time(NULL);
local_t =3D localtime(&now);
printf("%u: sec=3D%d, min=3D%d, hour=3D%d, mday=3D%d, mon=3D%d, year=3D%d,=
wday=3D%d, yday=3D%d, isdst=3D%d\n",
(unsigned) now, local_t->tm_sec, local_t->tm_min,
local_t->tm_hour, local_t->tm_mday, local_t->tm_mon,
local_t->tm_year, local_t->tm_wday, local_t->tm_yday,
local_t->tm_isdst);
=20
/* set isdst to something random (simulate uninitalised) */
local_t->tm_isdst =3D rand() - (RAND_MAX / 2);
printf("using isdst=3D%d\n", local_t->tm_isdst);
now =3D mktime(local_t);
local_t =3D localtime(&now);
printf("%u: sec=3D%d, min=3D%d, hour=3D%d, mday=3D%d, mon=3D%d, year=3D%d,=
wday=3D%d, yday=3D%d, isdst=3D%d\n",
(unsigned) now, local_t->tm_sec, local_t->tm_min,
local_t->tm_hour, local_t->tm_mday, local_t->tm_mon,
local_t->tm_year, local_t->tm_wday, local_t->tm_yday,
local_t->tm_isdst);
return 0;
}
--=-Zj2YvbHa+PT9jwzfX0HI--
--=-mIA06h0SM3zY9/9NUEKG
Content-Type: application/pgp-signature
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.12 (GNU/Linux)
iD8DBQBLn9NOn/9unNAn/9ERAlpfAJ9dD0n1D9YkHfjubhiDk3mTS2EdxQCghUsy
m03R/u3t70tLQ4Lj9W1OALU=
=1zus
-----END PGP SIGNATURE-----
--=-mIA06h0SM3zY9/9NUEKG--
This post was automatically imported from historical nagios-devel mailing list archives
Original poster: [email protected]