mktime() failures under PCTS testing [forwarded with permission]

From grant@osf.org Tue Mar 22 17:47:33 1994 Return-Path: <grant@osf.org> Received: from postman.osf.org by elsie.nci.nih.gov (4.1/SMI-4.1) id AA07444; Tue, 22 Mar 94 17:47:32 EST Received: from vishnu.osf.org by postman.osf.org (5.64+/OSF 1.0) id AA27681; Tue, 22 Mar 94 17:47:26 -0500 Message-Id: <9403222247.AA27681@postman.osf.org> To: ado@elsie.nci.nih.gov (Arthur David Olson) Cc: grant@osf.org Subject: mktime() failures under PCTS testing Date: Tue, 22 Mar 1994 17:47:21 -0500 From: Grant Sullivan <grant@osf.org> Status: RO
Hi Arthur,
I am a contractor at the Open Software Foundation, Cambridge, MA, responsible for helping to make sure that OSF/1 R1.3 utlities and libraries are conforming to POSIX.1, POSIX.2, XPG4, and other standards.
My department's QA group recently completed a PCTS test of our current OSF/1 libc, and reported to me that there were a number of mktime() failures in PCTS STD/LS/mktime, such as the following:
5.<p1>.5.1.1. Preparation [4009] Setup environment for testing.
5.<p1>.5.1.2. Testing [4009] TZ is of the form: TZ=dst0std,J057,J059 Non-leap year, one second prior to Jstart_day time.
MESSAGE (5.<p1>.5.1.2.): Testing local time of: Tue Feb 26 01:59:59 1991 PCTS action taken: CONTINUE
5.<p1>.5.1.3. Testing [4009] Non-leap year, at ambiguous Jstart_day time.
MESSAGE (5.<p1>.5.1.3.): Testing local time of: Tue Feb 26 02:00:00 1991 PCTS action taken: CONTINUE
ERROR (5.<p1>.5.1.3.): Call to mktime() failed (returned -1). PCTS action taken: CONTINUE
ERROR (5.<p1>.5.1.3.): Incorrect time returned by call to mktime(). Expected: 667530000 Or: 667533600 Actual: -1 PCTS action taken: CONTINUE
This particular test calls mktime() with tm_isdst set to -1, so it is expecting mktime() to return either the standard time value (667530000), or the daylight time value (667533600), under the apparent assumption that if tm_isdst == -1, then mktime() would attempt to determine if tm_isdst should be 0 or 1 and return the proper seconds, and adjust the struct tm accordingly.
Our current OSF/1 libc ctime.c is based on BSD 4.4-alpha snapshot "@(#)ctime.c 5.26 (Berkeley) 2/23/91" with additional fixes from your June'93 kit: elsieid[] = "@(#)localtime.c 7.9" plus some other adjustments.
There are quite a few PCTS failures, but I think they all boil down to a common cause: mktime() returns -1 when tm_isdst = -1 and the tm structure specifies the daylight savings time day, and a time at or within the first hour of daylight savings time.
I have created a simple test program, based on the XPG4 mktime() example, which exercises the first PCTS failure case above. I've tried this on several systems which have older versions of the Zoneinfo package, and on several systems which don't have the package. I got the same failure on the older Zoneinfo systems I tested, and mktime() returned 667530000, and set tm_isdst to 0 on the several systems I tested which don't use the package.
My own interpretation of the XPG4 and POSIX.2 standards suggest that mktime() should return 667533600, and reset the passed tm_isdst to 1, under the belief that for the above case, daylight savings starts exactly at Tue Feb 26 02:00:00 1991 for TZ=dst0std,J057,J059, instead of after this time, i.e. instead of at Tue Feb 26 02:00:01 1991
A friend of mine at another company told me he had run into similar mktime() problems with the FIPS151-2 test suite. He made alterations which resulted in mktime() returning 667533600, and tm_isdst reset to 1, so we both have the same interpretations of the XPG4 and POSIX.1 standards. His version of mktime() was based on something older than your June'93 kit.
I am wondering what mktime() in your current kit does in this case? Do you think it should return:
-1 , tm_isdst = -1 or 667530000, tm_isdst = 0 or 667533600, tm_isdst = 1
?
I am attaching a test program.
Thanks very much for your help,
Grant W. Sullivan, grant@osf.org Open Software Foundation 11 Cambridge Center, Cambridge, MA 02142
mktime_XPG4_example.c ========================================================================== /* XPG4, pg. 276 mktime() example * * with input data from PCTS STD/LS/mktime 8.1.58_09 5.1.3 test * */
#include <stdio.h> #include <time.h>
#include <stdlib.h>
struct tm time_str;
char daybuf[20];
/* values for struct tm; from PCTS STD/LS/mktime 8.1.58_09.c */ #define TZ_value "std0dst,J057,J059" #define TM_year 1991 /* non-leap year */ #define TM_mon 2 /* dst start month -- February */ #define TM_mday 26 /* dst start day J057 non-leap year */ #define TM_hour 2 /* for J057 dst start hour */ #define TM_min 0 /* for J057 dst start hour/min */ #define TM_sec 0 /* for J057 dst start hour/min/sec */ #define TM_wday -1 /* don't know */ #define TM_yday -1 /* don't know */ #define TM_isdst -1 /* don't know if std or dst */ #define MKTIME_expected 667530000L
main() { time_t mktime_returned;
printf("mktime test: PCTS/STD/LS/mktime 8.1.58_9 Assert 5.1.3\n"); printf("mktime test: for this test, set TZ=dst0std,J057,J059\n"); printf("current value of TZ = %s\n", getenv("TZ"));
if (setenv("TZ", TZ_value, 1) != 0) { printf("resetting TZ failed\n"); exit(1); } printf("new value of TZ = %s\n", getenv("TZ"));
time_str.tm_year = TM_year - 1900; time_str.tm_mon = TM_mon - 1; time_str.tm_mday = TM_mday; time_str.tm_hour = TM_hour; time_str.tm_min = TM_min; time_str.tm_sec = TM_sec; time_str.tm_wday = TM_wday; time_str.tm_yday = TM_yday; time_str.tm_isdst = TM_isdst;
printf("time_str tm struct set to:\n year = %d, mon = %d, mday = %d, hour = %d, min = %d, sec = %d, wday = %d, yday = %d, isdst = %d\n", time_str.tm_year, time_str.tm_mon, time_str.tm_mday, time_str.tm_hour, time_str.tm_min, time_str.tm_sec, time_str.tm_wday, time_str.tm_yday, time_str.tm_isdst); printf("expected value from mktime = %d\n", MKTIME_expected);
if ((mktime_returned = mktime(&time_str)) == (time_t)-1) { (void)puts("mktime returned -1 (-unknown-)"); printf("mktime() final time_str tm struct reset to:\n year = %d, mon = %d, mday = %d, hour = %d, min = %d, sec = %d, wday = %d, yday = %d, isdst = %d\n", time_str.tm_year, time_str.tm_mon, time_str.tm_mday, time_str.tm_hour, time_str.tm_min, time_str.tm_sec, time_str.tm_wday, time_str.tm_yday, time_str.tm_isdst); exit(1); } else { printf("mktime returned value = %d\n", (int) mktime_returned); printf("mktime() final time_str tm struct reset to:\n year = %d, mon = %d, mday = %d, hour = %d, min = %d, sec = %d, wday = %d, yday = %d, isdst = %d\n", time_str.tm_year, time_str.tm_mon, time_str.tm_mday, time_str.tm_hour, time_str.tm_min, time_str.tm_sec, time_str.tm_wday, time_str.tm_yday, time_str.tm_isdst);
(void)strftime(daybuf, sizeof(daybuf), "%A", &time_str); (void)puts(daybuf); }
exit(0); } ==========================================================================

From: grant@osf.org A friend of mine at another company told me he had run into similar mktime() problems with the FIPS151-2 test suite. He made alterations which resulted in mktime() returning 667533600, and tm_isdst reset to 1, so we both have the same interpretations of the XPG4 and POSIX.1 standards. His version of mktime() was based on something older than your June'93 kit.
I had forgotten to include in my original note to Arthur that not only was the returned tm_isdst adjusted to "1", but the entire tm struct was adjusted forward by one hour, in accordance with the returned value of 667533600. My friend at the other company sent me the new output of my test program after he had modified mktime() and tzset(). The test program output changed to: mktime test: PCTS/STD/LS/mktime 8.1.58_9 Assert 5.1.3 mktime test: for this test, set TZ=dst0std,J057,J059 current value of TZ = (null) new value of TZ = std0dst,J057,J059 time_str tm struct set to: year = 91, mon = 1, mday = 26, hour = 2, min = 0, sec = 0, wday = -1, yd ay = -1, isdst = -1 expected value from mktime = 667530000 mktime returned value = 667533600 mktime() final time_str tm struct reset to: year = 91, mon = 1, mday = 26, hour = 3, min = 0, sec = 0, wday = 2, yda y = 56, isdst = 1 Tuesday His company's version of mktime() and tzset() is based on BSD 4.3-Tahoe, so his changes are not directly appliable to the current code. Grant Sullivan Open Software Foundation
participants (2)
-
ado
-
Grant Sullivan