]> granicus.if.org Git - esp-idf/commitdiff
vfs/fatfs: fix stat call failing when called for mount point
authorIvan Grokhotkov <ivan@espressif.com>
Fri, 8 Dec 2017 11:58:39 +0000 (19:58 +0800)
committerIvan Grokhotkov <ivan@espressif.com>
Fri, 8 Dec 2017 12:04:27 +0000 (20:04 +0800)
FATFS does not support f_stat call for drive root. When handling stat
for drive root, don't call f_stat and just return struct st with S_IFDIR
flag set.

Closes #984

components/fatfs/src/vfs_fat.c
components/fatfs/test/test_fatfs_common.c
components/fatfs/test/test_fatfs_common.h
components/fatfs/test/test_fatfs_sdmmc.c
components/fatfs/test/test_fatfs_spiflash.c

index a5a12d5b65972cc8d809bf5b6670cd1f3e54575d..6829abdbd9fa52b2b224e1767f0f04df14a7b6a6 100644 (file)
@@ -392,8 +392,23 @@ static int vfs_fat_fstat(void* ctx, int fd, struct stat * st)
     return 0;
 }
 
+static inline mode_t get_stat_mode(bool is_dir)
+{
+    return S_IRWXU | S_IRWXG | S_IRWXO |
+            ((is_dir) ? S_IFDIR : S_IFREG);
+}
+
 static int vfs_fat_stat(void* ctx, const char * path, struct stat * st)
 {
+    if (strcmp(path, "/") == 0) {
+        /* FatFS f_stat function does not work for the drive root.
+         * Just pretend that this is a directory.
+         */
+        memset(st, 0, sizeof(*st));
+        st->st_mode = get_stat_mode(true);
+        return 0;
+    }
+
     vfs_fat_ctx_t* fat_ctx = (vfs_fat_ctx_t*) ctx;
     _lock_acquire(&fat_ctx->lock);
     prepend_drive_to_path(fat_ctx, &path, NULL);
@@ -405,9 +420,10 @@ static int vfs_fat_stat(void* ctx, const char * path, struct stat * st)
         errno = fresult_to_errno(res);
         return -1;
     }
+
+    memset(st, 0, sizeof(*st));
     st->st_size = info.fsize;
-    st->st_mode = S_IRWXU | S_IRWXG | S_IRWXO |
-            ((info.fattrib & AM_DIR) ? S_IFDIR : S_IFREG);
+    st->st_mode = get_stat_mode((info.fattrib & AM_DIR) != 0);
     struct tm tm;
     uint16_t fdate = info.fdate;
     tm.tm_mday = fdate & 0x1f;
index ca27cdd4ba03d84b8da1364e118694e6bbd2a50e..799d36f1b743f31a43516f38d4c40075f5eac966 100644 (file)
@@ -125,15 +125,15 @@ void test_fatfs_lseek(const char* filename)
     TEST_ASSERT_EQUAL(0, fclose(f));
 }
 
-void test_fatfs_stat(const char* filename)
+void test_fatfs_stat(const char* filename, const char* root_dir)
 {
     struct tm tm;
-    tm.tm_year = 2016 - 1900;
-    tm.tm_mon = 0;
-    tm.tm_mday = 10;
-    tm.tm_hour = 16;
-    tm.tm_min = 30;
-    tm.tm_sec = 0;
+    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;
     time_t t = mktime(&tm);
     printf("Setting time: %s", asctime(&tm));
     struct timeval now = { .tv_sec = t };
@@ -151,6 +151,11 @@ void test_fatfs_stat(const char* filename)
 
     TEST_ASSERT(st.st_mode & S_IFREG);
     TEST_ASSERT_FALSE(st.st_mode & S_IFDIR);
+
+    memset(&st, 0, sizeof(st));
+    TEST_ASSERT_EQUAL(0, stat(root_dir, &st));
+    TEST_ASSERT(st.st_mode & S_IFDIR);
+    TEST_ASSERT_FALSE(st.st_mode & S_IFREG);
 }
 
 void test_fatfs_unlink(const char* filename)
index dcc31e37d44124a2ec3ef03c2c2d6517138535df..36e7ca62b6da8f8a8a5aef028df4caa7e2ec1c80 100644 (file)
@@ -43,7 +43,7 @@ void test_fatfs_open_max_files(const char* filename_prefix, size_t files_count);
 
 void test_fatfs_lseek(const char* filename);
 
-void test_fatfs_stat(const char* filename);
+void test_fatfs_stat(const char* filename, const char* root_dir);
 
 void test_fatfs_unlink(const char* filename);
 
index 6935fc7083438393ea6b68390005aee9400eec5e..3610511a917346addadc4fa1623fe0eee149291b 100644 (file)
@@ -105,7 +105,7 @@ TEST_CASE("(SD) can lseek", "[fatfs][sdcard][ignore]")
 TEST_CASE("(SD) stat returns correct values", "[fatfs][ignore]")
 {
     test_setup();
-    test_fatfs_stat("/sdcard/stat.txt");
+    test_fatfs_stat("/sdcard/stat.txt", "/sdcard");
     test_teardown();
 }
 
index bcc396b93cc80668875b6204a35b1b31da273771..47116cd8d5caa15336ba0276b913e13a6448fc19 100644 (file)
@@ -100,7 +100,7 @@ TEST_CASE("(WL) can lseek", "[fatfs][wear_levelling]")
 TEST_CASE("(WL) stat returns correct values", "[fatfs][wear_levelling]")
 {
     test_setup();
-    test_fatfs_stat("/spiflash/stat.txt");
+    test_fatfs_stat("/spiflash/stat.txt", "/spiflash");
     test_teardown();
 }