This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
The mktime() function has an error wherein it does not work properly in all cases if the user gives a positive tm_isdst value other than 1. This is at odds with the 1999 C standard declaring all positive values to mean the same thing. (There are not problems when it is called with tm_isdst <= 0.) The bug only causes an operational error if the user calls mktime() with tm_isdst > 1 when the final resolved date is actually standard time. I have attached an updated mktime.c (which started with the released 16.0 version) that corrects the problem in the mktime.tgz archive, along with a ChangeLog. In the fix I kept a side-effect of mktime() that changes any positive tm_isdst value into a 1 when it is done when the result is daylight time. In the diff below, you can see that a comment was extended to point out that no correction is made for negative values. There was no change needed in the code for this, but it is only an addition to the comment to make more clear what is being done. Also attached are a test program and its output (run on my embedded target) for the 16.0 mktime() and my corrected mktime()--test_mktime.c, test.16.0, and test.new, respectively. (The test program is intended for my embedded target, and needs minor tweaking to run standalone.) It can be seen in the third test case that the Newlib 16.0 mktime() fails to adjust the user-supplied time by the DST offset when tm_isdst=2. While not shown in the test outputs that I have sent, it does when tm_isdst=1. Out of curiousity, I ran the test on Cygwin (which appears to be using Newlib 14.0) and on RHEL3. The former surprisingly did not display the problem, although the latter did. Craig Howland $ diff -u -p mktime.c.orig mktime.c --- mktime.c.orig 2005-02-25 17:31:20.000000000 -0500 +++ mktime.c 2008-08-27 16:36:42.406250000 -0400 @@ -9,6 +9,8 @@ * the fields of the structure are set to represent the specified calendar * time. Returns the specified calendar time. If the calendar time can not be * represented, returns the value (time_t) -1. + * + * Modifications: Fixed tm_isdst usage - 27 August 2008 Craig Howland. */ /* @@ -157,7 +159,7 @@ mktime (tim_p) { time_t tim = 0; long days = 0; - int year, isdst; + int year, isdst, tm_isdst; __tzinfo_type *tz = __gettzinfo (); /* validate structure */ @@ -202,7 +204,9 @@ mktime (tim_p) /* compute total seconds */ tim += (days * _SEC_IN_DAY); - isdst = tim_p->tm_isdst; + /* Convert user positive into 1 */ + tm_isdst = tim_p->tm_isdst > 0 ? 1 : tim_p->tm_isdst; + isdst = tm_isdst; if (_daylight) { @@ -225,8 +229,10 @@ mktime (tim_p) isdst = (tz->__tznorth ? (tim >= startdst_dst && tim < startstd_std) : (tim >= startdst_dst || tim < startstd_std)); - /* if user committed and was wrong, perform correction */ - if ((isdst ^ tim_p->tm_isdst) == 1) + /* if user committed and was wrong, perform correction, but no + * correction to make if user has given negative value (which + * asks mktime() to determine if DST is in effect or not) */ + if (tm_isdst >= 0 && (isdst ^ tm_isdst) == 1) { /* we either subtract or add the difference between time zone offsets, depending on which way the user got it
Attachment:
mktime.tgz
Description: mktime.tgz
Attachment:
test_mktime.c
Description: test_mktime.c
Attachment:
test.16.0
Description: test.16.0
Attachment:
test.new
Description: test.new
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |