Skip to content

Commit ec7ce19

Browse files
thinkyheadvgadreau
authored andcommitted
Fix diveToFile with open Dir object (MarlinFirmware#19539)
* Fix CardReader diveToFile * Add CardReader::fileExists
1 parent 061a2c3 commit ec7ce19

File tree

2 files changed

+46
-23
lines changed

2 files changed

+46
-23
lines changed

Marlin/src/sd/cardreader.cpp

+45-23
Original file line numberDiff line numberDiff line change
@@ -571,11 +571,11 @@ void CardReader::openFileRead(char * const path, const uint8_t subcall_type/*=0*
571571

572572
endFilePrint();
573573

574-
SdFile *curDir;
575-
const char * const fname = diveToFile(true, curDir, path);
574+
SdFile *diveDir;
575+
const char * const fname = diveToFile(true, diveDir, path);
576576
if (!fname) return;
577577

578-
if (file.open(curDir, fname, O_READ)) {
578+
if (file.open(diveDir, fname, O_READ)) {
579579
filesize = file.fileSize();
580580
sdpos = 0;
581581

@@ -606,14 +606,14 @@ void CardReader::openFileWrite(char * const path) {
606606

607607
endFilePrint();
608608

609-
SdFile *curDir;
610-
const char * const fname = diveToFile(false, curDir, path);
609+
SdFile *diveDir;
610+
const char * const fname = diveToFile(false, diveDir, path);
611611
if (!fname) return;
612612

613613
#if ENABLED(SDCARD_READONLY)
614614
openFailed(fname);
615615
#else
616-
if (file.open(curDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) {
616+
if (file.open(diveDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) {
617617
flag.saving = true;
618618
selectFileByName(fname);
619619
TERN_(EMERGENCY_PARSER, emergency_parser.disable());
@@ -625,6 +625,16 @@ void CardReader::openFileWrite(char * const path) {
625625
#endif
626626
}
627627

628+
//
629+
// Check if a file exists by absolute or workDir-relative path
630+
//
631+
bool CardReader::fileExists(const char * const path) {
632+
if (!isMounted()) return false;
633+
SdFile *diveDir = nullptr;
634+
const char * const fname = diveToFile(false, diveDir, path);
635+
return fname != nullptr;
636+
}
637+
628638
//
629639
// Delete a file by name in the working directory
630640
//
@@ -770,13 +780,15 @@ uint16_t CardReader::countFilesInWorkDir() {
770780
/**
771781
* Dive to the given DOS 8.3 file path, with optional echo of the dive paths.
772782
*
773-
* On exit, curDir contains an SdFile reference to the file's directory.
783+
* On exit:
784+
* - Your curDir pointer contains an SdFile reference to the file's directory.
785+
* - If update_cwd was 'true' the workDir now points to the file's directory.
774786
*
775787
* Returns a pointer to the last segment (filename) of the given DOS 8.3 path.
776788
*
777789
* A nullptr result indicates an unrecoverable error.
778790
*/
779-
const char* CardReader::diveToFile(const bool update_cwd, SdFile*& curDir, const char * const path, const bool echo/*=false*/) {
791+
const char* CardReader::diveToFile(const bool update_cwd, SdFile*& diveDir, const char * const path, const bool echo/*=false*/) {
780792
// Track both parent and subfolder
781793
static SdFile newDir1, newDir2;
782794
SdFile *sub = &newDir1, *startDir;
@@ -785,14 +797,15 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile*& curDir, const
785797
const char *item_name_adr = path;
786798

787799
if (path[0] == '/') { // Starting at the root directory?
788-
curDir = &root;
789-
if (update_cwd) workDirDepth = 0; // The cwd can be updated for the benefit of sub-programs
800+
diveDir = &root;
790801
item_name_adr++;
802+
if (update_cwd) workDirDepth = 0; // The cwd can be updated for the benefit of sub-programs
791803
}
792804
else
793-
curDir = &workDir; // Dive from workDir (as set by the UI)
805+
diveDir = &workDir; // Dive from workDir (as set by the UI)
806+
807+
startDir = diveDir;
794808

795-
startDir = curDir;
796809
while (item_name_adr) {
797810
// Find next subdirectory delimiter
798811
char * const name_end = strchr(item_name_adr, '/');
@@ -808,30 +821,39 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile*& curDir, const
808821

809822
if (echo) SERIAL_ECHOLN(dosSubdirname);
810823

811-
// Open curDir
812-
if (!sub->open(curDir, dosSubdirname, O_READ)) {
824+
// Open diveDir (closing first)
825+
sub->close();
826+
if (!sub->open(diveDir, dosSubdirname, O_READ)) {
813827
openFailed(dosSubdirname);
814-
return nullptr;
828+
item_name_adr = nullptr;
829+
break;
815830
}
816831

817-
// Close curDir if not at starting-point
818-
if (curDir != startDir) curDir->close();
832+
// Close diveDir if not at starting-point
833+
if (diveDir != startDir) diveDir->close();
819834

820-
// curDir now subDir
821-
curDir = sub;
835+
// diveDir now subDir
836+
diveDir = sub;
822837

823-
// Update workDirParents, workDirDepth, and workDir
838+
// Update workDirParents and workDirDepth
824839
if (update_cwd) {
825-
if (workDirDepth < MAX_DIR_DEPTH) workDirParents[workDirDepth++] = *curDir;
826-
workDir = *curDir;
840+
if (workDirDepth < MAX_DIR_DEPTH)
841+
workDirParents[workDirDepth++] = *diveDir;
827842
}
828843

829844
// Point sub at the other scratch object
830-
sub = (curDir != &newDir1) ? &newDir1 : &newDir2;
845+
sub = (diveDir != &newDir1) ? &newDir1 : &newDir2;
831846

832847
// Next path atom address
833848
item_name_adr = name_end + 1;
834849
}
850+
851+
if (update_cwd) {
852+
workDir = *diveDir;
853+
flag.workDirIsRoot = (workDirDepth == 0);
854+
TERN_(SDCARD_SORT_ALPHA, presort());
855+
}
856+
835857
return item_name_adr;
836858
}
837859

Marlin/src/sd/cardreader.h

+1
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ class CardReader {
9999
static void openFileRead(char * const path, const uint8_t subcall=0);
100100
static void openFileWrite(char * const path);
101101
static void closefile(const bool store_location=false);
102+
static bool fileExists(const char * const name);
102103
static void removeFile(const char * const name);
103104

104105
static inline char* longest_filename() { return longFilename[0] ? longFilename : filename; }

0 commit comments

Comments
 (0)