time: Provide y2038 safe mktime() replacement

As part of addressing "y2038 problem" for in-kernel uses, this
patch adds safe mktime64() using time64_t.

After this patch, mktime() is deprecated and all its call sites
will be fixed using mktime64(), after that it can be removed.

Signed-off-by: pang.xunlei <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
This commit is contained in:
pang.xunlei 2014-11-18 19:15:18 +08:00 committed by John Stultz
parent 04d9089086
commit 90b6ce9c40
2 changed files with 22 additions and 15 deletions

View File

@ -39,9 +39,20 @@ static inline int timeval_compare(const struct timeval *lhs, const struct timeva
return lhs->tv_usec - rhs->tv_usec; return lhs->tv_usec - rhs->tv_usec;
} }
extern unsigned long mktime(const unsigned int year, const unsigned int mon, extern time64_t mktime64(const unsigned int year, const unsigned int mon,
const unsigned int day, const unsigned int hour, const unsigned int day, const unsigned int hour,
const unsigned int min, const unsigned int sec); const unsigned int min, const unsigned int sec);
/**
* Deprecated. Use mktime64().
*/
static inline unsigned long mktime(const unsigned int year,
const unsigned int mon, const unsigned int day,
const unsigned int hour, const unsigned int min,
const unsigned int sec)
{
return mktime64(year, mon, day, hour, min, sec);
}
extern void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec); extern void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec);

View File

@ -304,7 +304,9 @@ struct timespec timespec_trunc(struct timespec t, unsigned gran)
} }
EXPORT_SYMBOL(timespec_trunc); EXPORT_SYMBOL(timespec_trunc);
/* Converts Gregorian date to seconds since 1970-01-01 00:00:00. /*
* mktime64 - Converts date to seconds.
* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
* Assumes input in normal date format, i.e. 1980-12-31 23:59:59 * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
* => year=1980, mon=12, day=31, hour=23, min=59, sec=59. * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
* *
@ -314,15 +316,10 @@ EXPORT_SYMBOL(timespec_trunc);
* -year/100+year/400 terms, and add 10.] * -year/100+year/400 terms, and add 10.]
* *
* This algorithm was first published by Gauss (I think). * This algorithm was first published by Gauss (I think).
*
* WARNING: this function will overflow on 2106-02-07 06:28:16 on
* machines where long is 32-bit! (However, as time_t is signed, we
* will already get problems at other places on 2038-01-19 03:14:08)
*/ */
unsigned long time64_t mktime64(const unsigned int year0, const unsigned int mon0,
mktime(const unsigned int year0, const unsigned int mon0, const unsigned int day, const unsigned int hour,
const unsigned int day, const unsigned int hour, const unsigned int min, const unsigned int sec)
const unsigned int min, const unsigned int sec)
{ {
unsigned int mon = mon0, year = year0; unsigned int mon = mon0, year = year0;
@ -332,15 +329,14 @@ mktime(const unsigned int year0, const unsigned int mon0,
year -= 1; year -= 1;
} }
return ((((unsigned long) return ((((time64_t)
(year/4 - year/100 + year/400 + 367*mon/12 + day) + (year/4 - year/100 + year/400 + 367*mon/12 + day) +
year*365 - 719499 year*365 - 719499
)*24 + hour /* now have hours */ )*24 + hour /* now have hours */
)*60 + min /* now have minutes */ )*60 + min /* now have minutes */
)*60 + sec; /* finally seconds */ )*60 + sec; /* finally seconds */
} }
EXPORT_SYMBOL(mktime64);
EXPORT_SYMBOL(mktime);
/** /**
* set_normalized_timespec - set timespec sec and nsec parts and normalize * set_normalized_timespec - set timespec sec and nsec parts and normalize