Dear Community, > This change adds new test to assess mktime's functionality. > > To be more specific - following use cases are checked: > - Pass struct tm as epoch time > - Pass struct tm as value just before Y2038 threshold (returned > value shall be 0x7FFFFFFF) > - Pass struct tm as the first value after Y2038 threshold > (expected value - 0x80000000) > > --- > Changes for v2: > - Remove FAIL_UNSUPPORTED() when sizeof (time_t) <= 4 > - Remove tzset () as it is already done in mktime () > - Use TEST_COMPARE to check if correct result is received > - Use "TZ=:" glibc extension to guarantee UTC time zone > - Add two more checks - prepare struct tm in a way that mktime will > return 0xFFFFFFFF and 0x100000000 > > Changes for v3: > - Remove .tm_wday and .tm_yday as are irrelevant > - Add (time_t) -1 cast when checking mktime return value > - Replace "executed" with "compiled". > - Use long long int as the exp_val type to avoid overflow compilation > error > - Rename tm1 to tm32bitmax > - Define tm0, tmY2038, tm32bitmax as const > - Pass the pointer to copy of aforementioned structs to > test_mktime_helper > > Changes for v4: > - Use __builtin_add_overflow instead of sizeof (time_t) > 4 to check > if time_t has overflowed. > > Changes for v5: > - Fix indentation of the struct tm > - Add more verbose error message when expected value is different han > result > - Add test prefix to commit message > > Changes for v6: > - Add line parameter to test_mktime_helper() definition > > Changes for v7: > - Replace FAIL_EXIT1 with FAIL_RET to not exit immediately after error > - Change signature of test_mktime_helper() function to return value Are there any more comments regarding this test? Is it eligible for pulling? > --- > time/Makefile | 2 +- > time/tst-mktime4.c | 109 > +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 > insertions(+), 1 deletion(-) create mode 100644 time/tst-mktime4.c > > diff --git a/time/Makefile b/time/Makefile > index 7caec2b271..a52b6b94bc 100644 > --- a/time/Makefile > +++ b/time/Makefile > @@ -48,7 +48,7 @@ tests := test_time clocktest tst-posixtz > tst-strptime tst_wcsftime \ tst-strptime3 bug-getdate1 > tst-strptime-whitespace tst-ftime \ tst-tzname tst-y2039 bug-mktime4 > tst-strftime2 tst-strftime3 \ tst-clock tst-clock2 > tst-clock_nanosleep tst-cpuclock1 \ > - tst-adjtime tst-ctime tst-difftime > + tst-adjtime tst-ctime tst-difftime tst-mktime4 > > include ../Rules > > diff --git a/time/tst-mktime4.c b/time/tst-mktime4.c > new file mode 100644 > index 0000000000..30c5f131e4 > --- /dev/null > +++ b/time/tst-mktime4.c > @@ -0,0 +1,109 @@ > +/* Test for mktime (4) > + Copyright (C) 2021 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be > useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + . */ > + > +#include > +#include > +#include > + > +const struct tm tm0 = > + { > + .tm_year = 70, > + .tm_mon = 0, > + .tm_mday = 1, > + .tm_hour = 0, > + .tm_min = 0, > + .tm_sec = 0, > + .tm_wday = 4, > + .tm_yday = 0, > + }; > + > +const struct tm tmY2038 = > + { > + .tm_year = 138, > + .tm_mon = 0, > + .tm_mday = 19, > + .tm_hour = 3, > + .tm_min = 14, > + .tm_sec = 7, > + }; > + > +const struct tm tm32bitmax = > + { > + .tm_year = 206, > + .tm_mon = 1, > + .tm_mday = 7, > + .tm_hour = 6, > + .tm_min = 28, > + .tm_sec = 15, > + }; > + > +static > +int test_mktime_helper (struct tm *tm, long long int exp_val, int > line) +{ > + time_t result, t; > + > + /* Check if we run on port with 32 bit time_t size */ > + if (__builtin_add_overflow (exp_val, 0, &t)) > + return 0; > + > + result = mktime (tm); > + if (result == (time_t) -1) > + FAIL_RET ("*** mktime failed: %m in line: %d", line); > + > + if ((long long int) result != exp_val) > + FAIL_RET ("*** Result different than expected (%lld != %lld) in > %d\n", > + (long long int) result, exp_val, line); > + > + return 0; > +} > + > +static int > +do_test (void) > +{ > + struct tm t; > + /* Use glibc time zone extension "TZ=:" to to guarantee that UTC > + without leap seconds is used for the test. */ > + TEST_VERIFY_EXIT (setenv ("TZ", ":", 1) == 0); > + > + /* Check that mktime (1970-01-01 00:00:00) returns 0. */ > + t = tm0; > + test_mktime_helper (&t, 0, __LINE__); > + > + /* Check that mktime (2038-01-19 03:14:07) returns 0x7FFFFFFF. */ > + t = tmY2038; > + test_mktime_helper (&t, 0x7fffffff, __LINE__); > + > + /* Check that mktime (2038-01-19 03:14:08) returns 0x80000000 > + (time_t overflow). */ > + t = tmY2038; > + t.tm_sec++; > + test_mktime_helper (&t, 0x80000000, __LINE__); > + > + /* Check that mktime (2106-02-07 06:28:15) returns 0xFFFFFFFF. */ > + t = tm32bitmax; > + test_mktime_helper (&t, 0xFFFFFFFF, __LINE__); > + > + /* Check that mktime (2106-02-07 06:28:16) returns 0x100000000. */ > + t = tm32bitmax; > + t.tm_sec++; > + test_mktime_helper (&t, 0x100000000, __LINE__); > + > + return 0; > +} > + > +#include Best regards, Lukasz Majewski -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de