greiman / SdFat-beta

Beta SdFat for test of new features

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

openNext fails when used with O_RDWR

Vargnath opened this issue · comments

When I use O_RDWR as oflag value for openNext, it fails to open the next file.
O_WRITE and O_WRONLY also don't seem to work.

I'm running the code on a Teensy 3.6 with an ExFat formatted SD card.

I was able to reproduce the issue with the OpenNext example and the following changes:

diff --git a/SdFat-beta/examples/OpenNext/OpenNext.ino b/SdFat-beta/examples/OpenNext/OpenNext.ino
index a00dcdb..d4aa16e 100644
--- a/SdFat-beta/examples/OpenNext/OpenNext.ino
+++ b/SdFat-beta/examples/OpenNext/OpenNext.ino
@@ -5,7 +5,7 @@

 // SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
 // 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
-#define SD_FAT_TYPE 0
# Note: The issue also occurs when using 2
+#define SD_FAT_TYPE 3
 /*
   Change the value of SD_CS_PIN if you are using SPI and
   your hardware does not use the default value, SS.
@@ -79,7 +79,7 @@ void setup() {
   // Open next file in root.
   // Warning, openNext starts at the current position of dir so a
   // rewind may be necessary in your application.
-  while (file.openNext(&dir, O_RDONLY)) {
+  while (file.openNext(&dir, O_RDWR)) {
     file.printFileSize(&Serial);
     Serial.write(' ');
     file.printModifyDateTime(&Serial);

Expected output:

Type any character to start
      131072 2019-01-08 16:06 System Volume Information/
          35 2019-08-28 14:25 RtcTest.txt
          14 2019-09-09 13:28 boot.txt
         385 2019-10-21 15:47 1571672835.txt
      153300 2019-10-21 16:17 1571672907.txt
        3264 2019-11-05 16:31 1572971445.txt
Done!

Actual output:

Type any character to start
Done!

openNext fails if the directory contains any files that are not writable. The root directory has the directory "System Volume Information" which is not writable.

Guess something like the C function freopen() is needed to change the mode.

The Linux solution for walking a directory tree is ftw(3). fts_open(3) is even more complex.

I need a simpler idea.

One possibility is to use openNext to find the file, check if the file is write-able, then use open by index to reopen it. I have not verified this will leave the directory positioned correctly.

This seems to work.

  while (file.openNext(&dir, O_RDONLY)) {
    if (file.isDir() || file.isReadOnly()) {
      file.close();
      continue;
    }
    uint32_t index = file.dirIndex();
    file.close();
    if (!file.open(&dir, index, O_RDWR)) {
      Serial.println("Idea failed");
    }
  // ....