【挑单3.2Release】修复time中TIMEZONE优先使用RTC模块的问题

方案描述:
1、time中timezone全局变量修改为优先从RTC获取
2、settimeofday接口,linux和posix标准有差异,m核中对齐posix标准,具体如下:
int settimeofday(const struct timeval *tv, const struct timezone *tz)
2.1、linux中:
        tz参数已弃用,一般设置为NULL;
        tv参数,为NULL时返回0,不设置错误码,表示不修改当前时间;
2.2、posix中:
        tv或tz全部为NULL时,返回-1,设置错误码EFAULT;
        tv或tz有一个不为NULL时,不设置相应的参数,返回0;不设置错误码;
3、新增settimeofday接口设置timezone测试用例

BREAKING CHANGE:
修复time中TIMEZONE优先使用RTC模块的问题对外变更描述:
修改int settimeofday(const struct timeval *tv, const struct timezone *tz)接口
settimeofday接口对入参的判断逻辑修改:
1、tv或tz全部为NULL时,返回-1,设置错误码EFAULT;
2、tv或tz有一个不为NULL时,不设置相应的参数,返回0;不设置错误码;

Close: #I73MT7

Signed-off-by: zhangdengyu <zhangdengyu2@huawei.com>
Change-Id: If16491f909e9564010cf4bb291f0d92b5b8fce3c
This commit is contained in:
zhangdengyu 2023-05-16 20:41:45 +08:00
parent 9c79993721
commit 9603f02f6a
2 changed files with 82 additions and 18 deletions

View File

@ -617,11 +617,22 @@ struct tm *gmtime(const time_t *timer)
struct tm *localtime_r(const time_t *timep, struct tm *result)
{
INT32 ret;
if ((timep == NULL) || (result == NULL)) {
errno = EFAULT;
return NULL;
}
if (!ConvertSecs2Utc(*timep, -g_timezone, result)) {
if (g_rtcTimeFunc.RtcGetTimezoneHook != NULL) {
INT32 tempTimezone = 0;
g_rtcTimeFunc.RtcGetTimezoneHook(&tempTimezone);
ret = ConvertSecs2Utc(*timep, -tempTimezone, result);
} else {
ret = ConvertSecs2Utc(*timep, -g_timezone, result);
}
if (!ret) {
errno = EINVAL;
return NULL;
}
@ -664,7 +675,14 @@ static time_t ConvertUtc2Secs(struct tm *tm)
seconds += (tm->tm_mday - 1) * SECS_PER_DAY;
seconds += tm->tm_hour * SECS_PER_HOUR + tm->tm_min * SECS_PER_MIN + tm->tm_sec;
seconds += g_timezone;
if (g_rtcTimeFunc.RtcGetTimezoneHook != NULL) {
INT32 tempTimezone = 0;
g_rtcTimeFunc.RtcGetTimezoneHook(&tempTimezone);
seconds += tempTimezone;
} else {
seconds += g_timezone;
}
return seconds;
}
@ -690,7 +708,14 @@ time_t mktime(struct tm *tmptr)
}
timeInSeconds = ConvertUtc2Secs(tmptr);
/* normalize tm_wday and tm_yday */
ConvertSecs2Utc(timeInSeconds, -g_timezone, tmptr);
if (g_rtcTimeFunc.RtcGetTimezoneHook != NULL) {
INT32 tempTimezone = 0;
g_rtcTimeFunc.RtcGetTimezoneHook(&tempTimezone);
ConvertSecs2Utc(timeInSeconds, -tempTimezone, tmptr);
} else {
ConvertSecs2Utc(timeInSeconds, -g_timezone, tmptr);
}
return timeInSeconds;
}
@ -722,7 +747,7 @@ int gettimeofday(struct timeval *tv, void *ptz)
tv->tv_usec = ts.tv_nsec / OS_SYS_NS_PER_US;
}
}
if (tz != NULL) {
INT32 timeZone = 0;
if (g_rtcTimeFunc.RtcGetTimezoneHook != NULL) {
@ -742,12 +767,12 @@ int settimeofday(const struct timeval *tv, const struct timezone *tz)
{
struct timespec ts;
if (tv == NULL) {
if ((tv == NULL) && (tz == NULL)) {
errno = EFAULT;
return -1;
}
if (tv->tv_usec >= OS_SYS_US_PER_SECOND) {
if ((tv != NULL) && (tv->tv_usec >= OS_SYS_US_PER_SECOND)) {
errno = EINVAL;
return -1;
}
@ -766,18 +791,20 @@ int settimeofday(const struct timeval *tv, const struct timezone *tz)
}
}
if (g_rtcTimeFunc.RtcSetTimeHook != NULL) {
UINT64 usec;
g_rtcTimeBase = tv->tv_sec * OS_SYS_MS_PER_SECOND + tv->tv_usec / OS_SYS_MS_PER_SECOND;
usec = tv->tv_sec * OS_SYS_US_PER_SECOND + tv->tv_usec;
if (-1 == g_rtcTimeFunc.RtcSetTimeHook(g_rtcTimeBase, &usec)) {
return -1;
}
} else {
ts.tv_sec = tv->tv_sec;
ts.tv_nsec = tv->tv_usec * OS_SYS_NS_PER_US;
if (-1 == clock_settime(CLOCK_REALTIME, &ts)) {
return -1;
if (tv != NULL) {
if (g_rtcTimeFunc.RtcSetTimeHook != NULL) {
UINT64 usec;
g_rtcTimeBase = tv->tv_sec * OS_SYS_MS_PER_SECOND + tv->tv_usec / OS_SYS_MS_PER_SECOND;
usec = tv->tv_sec * OS_SYS_US_PER_SECOND + tv->tv_usec;
if (g_rtcTimeFunc.RtcSetTimeHook(g_rtcTimeBase, &usec) < 0) {
return -1;
}
} else {
ts.tv_sec = tv->tv_sec;
ts.tv_nsec = tv->tv_usec * OS_SYS_NS_PER_US;
if (clock_settime(CLOCK_REALTIME, &ts) < 0) {
return -1;
}
}
}

View File

@ -288,6 +288,42 @@ LITE_TEST_CASE(PosixTimeFuncTestSuite, testTimeLocaltime002, Function | MediumTe
return 0;
}
/* *
* @tc.number SUB_KERNEL_TIME_LOCALTIME_003
* @tc.name test settimeofday api
* @tc.desc [C- SOFTWARE -0200]
*/
LITE_TEST_CASE(PosixTimeFuncTestSuite, testTimeLocaltime003, Function | MediumTest | Level1)
{
char cTime[32]; /* 32, no special meaning */
time_t tStart;
time_t tEnd;
struct timezone tz;
struct timeval timeSet = {
.tv_sec = 86399, /* 86399, no special meaning */
.tv_usec = 0
};
int ret = gettimeofday(NULL, &tz);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = settimeofday(&timeSet, &tz);
time(&tStart);
sleep(2); /* 2, no special meaning */
time(&tEnd);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
struct tm *tmStart = localtime(&tStart);
strftime(cTime, sizeof(cTime), "%H:%M:%S", tmStart);
ICUNIT_ASSERT_STRING_EQUAL(cTime, "07:59:59", 0);
LOG("\n time_t=%lld, first time:%s", tStart, cTime);
struct tm *tmEnd = localtime(&tEnd);
strftime(cTime, sizeof(cTime), "%H:%M:%S", tmEnd);
ICUNIT_ASSERT_STRING_EQUAL(cTime, "08:00:01", 0);
LOG("\n time_t=%lld, first time:%s", tEnd, cTime);
return 0;
}
/* *
* @tc.number SUB_KERNEL_TIME_LOCALTIMER_001
* @tc.name localtime_r api base test
@ -579,6 +615,7 @@ void PosixTimeFuncTest(void)
#if (LOSCFG_LIBC_MUSL == 1)
RUN_ONE_TESTCASE(testTimeLocaltime001);
RUN_ONE_TESTCASE(testTimeLocaltime002);
RUN_ONE_TESTCASE(testTimeLocaltime003);
RUN_ONE_TESTCASE(testTimeLocaltimer001);
RUN_ONE_TESTCASE(testTimeLocaltimer002);
#endif