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