@@ -71,6 +71,61 @@ static int fat_error_remap(FRESULT res)
71
71
}
72
72
}
73
73
74
+ // Helper class for deferring operations when variable falls out of scope
75
+ template <typename T>
76
+ class Deferred {
77
+ public:
78
+ T _t;
79
+ Callback<void (T)> _ondefer;
80
+
81
+ Deferred (const Deferred&);
82
+ Deferred &operator =(const Deferred&);
83
+
84
+ public:
85
+ Deferred (T t, Callback<void (T)> ondefer = NULL )
86
+ : _t(t), _ondefer(ondefer)
87
+ {
88
+ }
89
+
90
+ operator T ()
91
+ {
92
+ return _t;
93
+ }
94
+
95
+ ~Deferred ()
96
+ {
97
+ if (_ondefer) {
98
+ _ondefer (_t);
99
+ }
100
+ }
101
+ };
102
+
103
+ static void dodelete (const char *data)
104
+ {
105
+ delete[] data;
106
+ }
107
+
108
+ // Adds prefix needed internally by fatfs, this can be avoided for the first fatfs
109
+ // (id 0) otherwise a prefix of "id:/" is inserted in front of the string.
110
+ static Deferred<const char *> fat_path_prefix (int id, const char *path)
111
+ {
112
+ // We can avoid dynamic allocation when only on fatfs is in use
113
+ if (id == 0 ) {
114
+ return path;
115
+ }
116
+
117
+ // Prefix path with id, will look something like 2:/hi/hello/filehere.txt
118
+ char *buffer = new char [strlen (" 0:/" ) + strlen (path) + 1 ];
119
+ if (!buffer) {
120
+ return NULL ;
121
+ }
122
+
123
+ buffer[0 ] = ' 0' + id;
124
+ buffer[1 ] = ' :' ;
125
+ buffer[2 ] = ' /' ;
126
+ strcpy (buffer + strlen (" 0:/" ), path);
127
+ return Deferred<const char *>(buffer, dodelete);
128
+ }
74
129
75
130
76
131
// //// Disk operations //////
@@ -263,9 +318,11 @@ int FATFileSystem::format(BlockDevice *bd, int allocation_unit) {
263
318
return 0 ;
264
319
}
265
320
266
- int FATFileSystem::remove (const char *filename) {
321
+ int FATFileSystem::remove (const char *path) {
322
+ Deferred<const char *> fpath = fat_path_prefix (_id, path);
323
+
267
324
lock ();
268
- FRESULT res = f_unlink (filename );
325
+ FRESULT res = f_unlink (fpath );
269
326
unlock ();
270
327
271
328
if (res != FR_OK) {
@@ -274,9 +331,12 @@ int FATFileSystem::remove(const char *filename) {
274
331
return fat_error_remap (res);
275
332
}
276
333
277
- int FATFileSystem::rename (const char *oldname, const char *newname) {
334
+ int FATFileSystem::rename (const char *oldpath, const char *newpath) {
335
+ Deferred<const char *> oldfpath = fat_path_prefix (_id, oldpath);
336
+ Deferred<const char *> newfpath = fat_path_prefix (_id, newpath);
337
+
278
338
lock ();
279
- FRESULT res = f_rename (oldname, newname );
339
+ FRESULT res = f_rename (oldfpath, newfpath );
280
340
unlock ();
281
341
282
342
if (res != FR_OK) {
@@ -285,9 +345,11 @@ int FATFileSystem::rename(const char *oldname, const char *newname) {
285
345
return fat_error_remap (res);
286
346
}
287
347
288
- int FATFileSystem::mkdir (const char *name, mode_t mode) {
348
+ int FATFileSystem::mkdir (const char *path, mode_t mode) {
349
+ Deferred<const char *> fpath = fat_path_prefix (_id, path);
350
+
289
351
lock ();
290
- FRESULT res = f_mkdir (name );
352
+ FRESULT res = f_mkdir (fpath );
291
353
unlock ();
292
354
293
355
if (res != FR_OK) {
@@ -296,12 +358,14 @@ int FATFileSystem::mkdir(const char *name, mode_t mode) {
296
358
return fat_error_remap (res);
297
359
}
298
360
299
- int FATFileSystem::stat (const char *name, struct stat *st) {
361
+ int FATFileSystem::stat (const char *path, struct stat *st) {
362
+ Deferred<const char *> fpath = fat_path_prefix (_id, path);
363
+
300
364
lock ();
301
365
FILINFO f;
302
366
memset (&f, 0 , sizeof (f));
303
367
304
- FRESULT res = f_stat (name , &f);
368
+ FRESULT res = f_stat (fpath , &f);
305
369
if (res != FR_OK) {
306
370
unlock ();
307
371
return fat_error_remap (res);
@@ -332,13 +396,10 @@ void FATFileSystem::unlock() {
332
396
333
397
// //// File operations //////
334
398
int FATFileSystem::file_open (fs_file_t *file, const char *path, int flags) {
335
- debug_if (FFS_DBG, " open(%s) on filesystem [%s], drv [%s]\n " , path, getName (), _fsid );
399
+ debug_if (FFS_DBG, " open(%s) on filesystem [%s], drv [%s]\n " , path, getName (), _id );
336
400
337
401
FIL *fh = new FIL;
338
- char *buffer = new char [strlen (_fsid) + strlen (path) + 3 ];
339
- strcpy (buffer, _fsid);
340
- strcat (buffer, " /" );
341
- strcat (buffer, path);
402
+ Deferred<const char *> fpath = fat_path_prefix (_id, path);
342
403
343
404
/* POSIX flags -> FatFS open mode */
344
405
BYTE openmode;
@@ -358,12 +419,11 @@ int FATFileSystem::file_open(fs_file_t *file, const char *path, int flags) {
358
419
}
359
420
360
421
lock ();
361
- FRESULT res = f_open (fh, buffer , openmode);
422
+ FRESULT res = f_open (fh, fpath , openmode);
362
423
363
424
if (res != FR_OK) {
364
425
unlock ();
365
426
debug_if (FFS_DBG, " f_open('w') failed: %d\n " , res);
366
- delete[] buffer;
367
427
delete fh;
368
428
return fat_error_remap (res);
369
429
}
@@ -373,7 +433,6 @@ int FATFileSystem::file_open(fs_file_t *file, const char *path, int flags) {
373
433
}
374
434
unlock ();
375
435
376
- delete[] buffer;
377
436
*file = fh;
378
437
return 0 ;
379
438
}
@@ -480,9 +539,10 @@ off_t FATFileSystem::file_size(fs_file_t file) {
480
539
// //// Dir operations //////
481
540
int FATFileSystem::dir_open (fs_dir_t *dir, const char *path) {
482
541
FATFS_DIR *dh = new FATFS_DIR;
542
+ Deferred<const char *> fpath = fat_path_prefix (_id, path);
483
543
484
544
lock ();
485
- FRESULT res = f_opendir (dh, path );
545
+ FRESULT res = f_opendir (dh, fpath );
486
546
unlock ();
487
547
488
548
if (res != FR_OK) {
0 commit comments