Merge branch 'bugfix/fatfs_mtime_dst' into 'master'

fatfs: fix incorrect mtime returned for files created during DST

Closes IDFGH-7467

See merge request espressif/esp-idf!18333
This commit is contained in:
Martin Vychodil 2022-06-10 17:18:01 +08:00
commit aa2cf79e13
4 changed files with 52 additions and 8 deletions

View File

@ -382,13 +382,14 @@ void test_fatfs_ftruncate_file(const char* filename)
void test_fatfs_stat(const char* filename, const char* root_dir)
{
struct tm tm;
tm.tm_year = 2017 - 1900;
tm.tm_mon = 11;
tm.tm_mday = 8;
tm.tm_hour = 19;
tm.tm_min = 51;
tm.tm_sec = 10;
struct tm tm = {
.tm_year = 2017 - 1900,
.tm_mon = 11,
.tm_mday = 8,
.tm_hour = 19,
.tm_min = 51,
.tm_sec = 10
};
time_t t = mktime(&tm);
printf("Setting time: %s", asctime(&tm));
struct timeval now = { .tv_sec = t };
@ -413,6 +414,34 @@ void test_fatfs_stat(const char* filename, const char* root_dir)
TEST_ASSERT_FALSE(st.st_mode & S_IFREG);
}
void test_fatfs_mtime_dst(const char* filename, const char* root_dir)
{
struct timeval tv = { 1653638041, 0 };
settimeofday(&tv, NULL);
setenv("TZ", "MST7MDT,M3.2.0,M11.1.0", 1);
tzset();
struct tm tm;
time_t sys_time = tv.tv_sec;
localtime_r(&sys_time, &tm);
printf("Setting time: %s", asctime(&tm));
test_fatfs_create_file_with_text(filename, "foo\n");
struct stat st;
TEST_ASSERT_EQUAL(0, stat(filename, &st));
time_t mtime = st.st_mtime;
struct tm mtm;
localtime_r(&mtime, &mtm);
printf("File time: %s", asctime(&mtm));
TEST_ASSERT(llabs(mtime - sys_time) < 2); // fatfs library stores time with 2 second precision
unsetenv("TZ");
tzset();
}
void test_fatfs_utime(const char* filename, const char* root_dir)
{
struct stat achieved_stat;

View File

@ -47,6 +47,8 @@ void test_fatfs_ftruncate_file(const char* path);
void test_fatfs_stat(const char* filename, const char* root_dir);
void test_fatfs_mtime_dst(const char* filename, const char* root_dir);
void test_fatfs_utime(const char* filename, const char* root_dir);
void test_fatfs_unlink(const char* filename);

View File

@ -119,6 +119,13 @@ TEST_CASE("(WL) stat returns correct values", "[fatfs][wear_levelling]")
test_teardown();
}
TEST_CASE("(WL) stat returns correct mtime if DST is enabled", "[fatfs][wear_levelling]")
{
test_setup();
test_fatfs_mtime_dst("/spiflash/statdst.txt", "/spiflash");
test_teardown();
}
TEST_CASE("(WL) utime sets modification time", "[fatfs][wear_levelling]")
{
test_setup();

View File

@ -637,7 +637,13 @@ static int vfs_fat_stat(void* ctx, const char * path, struct stat * st)
.tm_year = fdate.year + 80,
.tm_sec = ftime.sec * 2,
.tm_min = ftime.min,
.tm_hour = ftime.hour
.tm_hour = ftime.hour,
/* FAT doesn't keep track if the time was DST or not, ask the C library
* to try to figure this out. Note that this may yield incorrect result
* in the hour before the DST comes in effect, when the local time can't
* be converted to UTC uniquely.
*/
.tm_isdst = -1
};
st->st_mtime = mktime(&tm);
st->st_atime = 0;