SdFat-beta icon indicating copy to clipboard operation
SdFat-beta copied to clipboard

openNext fails when used with O_RDWR

Open Vargnath opened this issue 5 years ago • 3 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!

Vargnath avatar Dec 04 '19 10:12 Vargnath

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.

greiman avatar Dec 04 '19 13:12 greiman

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.

greiman avatar Dec 05 '19 13:12 greiman

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");
    }
  // ....

greiman avatar Dec 05 '19 14:12 greiman