28
28
#include "py/mpconfig.h"
29
29
#if MICROPY_VFS_FAT
30
30
31
+ #if !MICROPY_FATFS_OO
32
+ #error "with MICROPY_VFS_FAT enabled, must also enable MICROPY_FATFS_OO"
33
+ #endif
34
+
31
35
#include <string.h>
32
36
#include "py/nlr.h"
33
37
#include "py/runtime.h"
34
38
#include "py/mperrno.h"
35
- #include "lib/fatfs/ff.h"
36
- #include "lib/fatfs/diskio.h"
39
+ #include "lib/oofatfs/ff.h"
37
40
#include "extmod/vfs_fat_file.h"
38
41
#include "extmod/fsusermount.h"
39
42
#include "timeutils.h"
@@ -55,13 +58,10 @@ STATIC mp_obj_t fat_vfs_mkfs(mp_obj_t bdev_in) {
55
58
STATIC MP_DEFINE_CONST_FUN_OBJ_1 (fat_vfs_mkfs_fun_obj , fat_vfs_mkfs );
56
59
STATIC MP_DEFINE_CONST_STATICMETHOD_OBJ (fat_vfs_mkfs_obj , MP_ROM_PTR (& fat_vfs_mkfs_fun_obj ));
57
60
58
- STATIC mp_obj_t fat_vfs_open (size_t n_args , const mp_obj_t * args , mp_map_t * kwargs ) {
59
- // Skip self
60
- return fatfs_builtin_open (n_args - 1 , args + 1 , kwargs );
61
- }
62
- MP_DEFINE_CONST_FUN_OBJ_KW (fat_vfs_open_obj , 2 , fat_vfs_open );
61
+ STATIC MP_DEFINE_CONST_FUN_OBJ_KW (fat_vfs_open_obj , 2 , fatfs_builtin_open_self );
63
62
64
63
STATIC mp_obj_t fat_vfs_listdir_func (size_t n_args , const mp_obj_t * args ) {
64
+ mp_obj_fat_vfs_t * self = MP_OBJ_TO_PTR (args [0 ]);
65
65
bool is_str_type = true;
66
66
const char * path ;
67
67
if (n_args == 2 ) {
@@ -73,27 +73,24 @@ STATIC mp_obj_t fat_vfs_listdir_func(size_t n_args, const mp_obj_t *args) {
73
73
path = "" ;
74
74
}
75
75
76
- return fat_vfs_listdir ( path , is_str_type );
76
+ return fat_vfs_listdir2 ( self , path , is_str_type );
77
77
}
78
78
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (fat_vfs_listdir_obj , 1 , 2 , fat_vfs_listdir_func );
79
79
80
- STATIC mp_obj_t fat_vfs_remove_internal (mp_obj_t path_in , mp_int_t attr ) {
80
+ STATIC mp_obj_t fat_vfs_remove_internal (mp_obj_t vfs_in , mp_obj_t path_in , mp_int_t attr ) {
81
+ mp_obj_fat_vfs_t * self = MP_OBJ_TO_PTR (vfs_in );
81
82
const char * path = mp_obj_str_get_str (path_in );
82
83
83
84
FILINFO fno ;
84
- #if _USE_LFN
85
- fno .lfname = NULL ;
86
- fno .lfsize = 0 ;
87
- #endif
88
- FRESULT res = f_stat (path , & fno );
85
+ FRESULT res = f_stat (& self -> fatfs , path , & fno );
89
86
90
87
if (res != FR_OK ) {
91
88
mp_raise_OSError (fresult_to_errno_table [res ]);
92
89
}
93
90
94
91
// check if path is a file or directory
95
92
if ((fno .fattrib & AM_DIR ) == attr ) {
96
- res = f_unlink (path );
93
+ res = f_unlink (& self -> fatfs , path );
97
94
98
95
if (res != FR_OK ) {
99
96
mp_raise_OSError (fresult_to_errno_table [res ]);
@@ -105,27 +102,25 @@ STATIC mp_obj_t fat_vfs_remove_internal(mp_obj_t path_in, mp_int_t attr) {
105
102
}
106
103
107
104
STATIC mp_obj_t fat_vfs_remove (mp_obj_t vfs_in , mp_obj_t path_in ) {
108
- (void )vfs_in ;
109
- return fat_vfs_remove_internal (path_in , 0 ); // 0 == file attribute
105
+ return fat_vfs_remove_internal (vfs_in , path_in , 0 ); // 0 == file attribute
110
106
}
111
107
STATIC MP_DEFINE_CONST_FUN_OBJ_2 (fat_vfs_remove_obj , fat_vfs_remove );
112
108
113
109
STATIC mp_obj_t fat_vfs_rmdir (mp_obj_t vfs_in , mp_obj_t path_in ) {
114
- (void ) vfs_in ;
115
- return fat_vfs_remove_internal (path_in , AM_DIR );
110
+ return fat_vfs_remove_internal (vfs_in , path_in , AM_DIR );
116
111
}
117
112
STATIC MP_DEFINE_CONST_FUN_OBJ_2 (fat_vfs_rmdir_obj , fat_vfs_rmdir );
118
113
119
114
STATIC mp_obj_t fat_vfs_rename (mp_obj_t vfs_in , mp_obj_t path_in , mp_obj_t path_out ) {
120
- ( void ) vfs_in ;
115
+ mp_obj_fat_vfs_t * self = MP_OBJ_TO_PTR ( vfs_in ) ;
121
116
const char * old_path = mp_obj_str_get_str (path_in );
122
117
const char * new_path = mp_obj_str_get_str (path_out );
123
- FRESULT res = f_rename (old_path , new_path );
118
+ FRESULT res = f_rename (& self -> fatfs , old_path , new_path );
124
119
if (res == FR_EXIST ) {
125
120
// if new_path exists then try removing it (but only if it's a file)
126
- fat_vfs_remove_internal (path_out , 0 ); // 0 == file attribute
121
+ fat_vfs_remove_internal (vfs_in , path_out , 0 ); // 0 == file attribute
127
122
// try to rename again
128
- res = f_rename (old_path , new_path );
123
+ res = f_rename (& self -> fatfs , old_path , new_path );
129
124
}
130
125
if (res == FR_OK ) {
131
126
return mp_const_none ;
@@ -137,9 +132,9 @@ STATIC mp_obj_t fat_vfs_rename(mp_obj_t vfs_in, mp_obj_t path_in, mp_obj_t path_
137
132
STATIC MP_DEFINE_CONST_FUN_OBJ_3 (fat_vfs_rename_obj , fat_vfs_rename );
138
133
139
134
STATIC mp_obj_t fat_vfs_mkdir (mp_obj_t vfs_in , mp_obj_t path_o ) {
140
- ( void ) vfs_in ;
135
+ mp_obj_fat_vfs_t * self = MP_OBJ_TO_PTR ( vfs_in ) ;
141
136
const char * path = mp_obj_str_get_str (path_o );
142
- FRESULT res = f_mkdir (path );
137
+ FRESULT res = f_mkdir (& self -> fatfs , path );
143
138
if (res == FR_OK ) {
144
139
return mp_const_none ;
145
140
} else {
@@ -150,15 +145,11 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_mkdir_obj, fat_vfs_mkdir);
150
145
151
146
/// Change current directory.
152
147
STATIC mp_obj_t fat_vfs_chdir (mp_obj_t vfs_in , mp_obj_t path_in ) {
153
- ( void ) vfs_in ;
148
+ mp_obj_fat_vfs_t * self = MP_OBJ_TO_PTR ( vfs_in ) ;
154
149
const char * path ;
155
150
path = mp_obj_str_get_str (path_in );
156
151
157
- FRESULT res = f_chdrive (path );
158
-
159
- if (res == FR_OK ) {
160
- res = f_chdir (path );
161
- }
152
+ FRESULT res = f_chdir (& self -> fatfs , path );
162
153
163
154
if (res != FR_OK ) {
164
155
mp_raise_OSError (fresult_to_errno_table [res ]);
@@ -170,14 +161,18 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_chdir_obj, fat_vfs_chdir);
170
161
171
162
/// Get the current directory.
172
163
STATIC mp_obj_t fat_vfs_getcwd (mp_obj_t vfs_in ) {
173
- ( void ) vfs_in ;
164
+ mp_obj_fat_vfs_t * self = MP_OBJ_TO_PTR ( vfs_in ) ;
174
165
char buf [MICROPY_ALLOC_PATH_MAX + 1 ];
175
- FRESULT res = f_getcwd (buf , sizeof buf );
176
-
166
+ memcpy (buf , self -> str , self -> len );
167
+ FRESULT res = f_getcwd ( & self -> fatfs , buf + self -> len , sizeof ( buf ) - self -> len );
177
168
if (res != FR_OK ) {
178
169
mp_raise_OSError (fresult_to_errno_table [res ]);
179
170
}
180
-
171
+ // remove trailing / if in root dir, because we prepended the mount point
172
+ size_t l = strlen (buf );
173
+ if (res == FR_OK && buf [l - 1 ] == '/' ) {
174
+ buf [l - 1 ] = 0 ;
175
+ }
181
176
return mp_obj_new_str (buf , strlen (buf ), false);
182
177
}
183
178
STATIC MP_DEFINE_CONST_FUN_OBJ_1 (fat_vfs_getcwd_obj , fat_vfs_getcwd );
@@ -202,14 +197,10 @@ STATIC bool path_equal(const char *path, const char *path_canonical) {
202
197
/// \function stat(path)
203
198
/// Get the status of a file or directory.
204
199
STATIC mp_obj_t fat_vfs_stat (mp_obj_t vfs_in , mp_obj_t path_in ) {
205
- ( void ) vfs_in ;
200
+ mp_obj_fat_vfs_t * self = MP_OBJ_TO_PTR ( vfs_in ) ;
206
201
const char * path = mp_obj_str_get_str (path_in );
207
202
208
203
FILINFO fno ;
209
- #if _USE_LFN
210
- fno .lfname = NULL ;
211
- fno .lfsize = 0 ;
212
- #endif
213
204
FRESULT res ;
214
205
215
206
if (path_equal (path , "/" )) {
@@ -233,7 +224,7 @@ STATIC mp_obj_t fat_vfs_stat(mp_obj_t vfs_in, mp_obj_t path_in) {
233
224
}
234
225
if (res == FR_NO_PATH ) {
235
226
// stat normal file
236
- res = f_stat (path , & fno );
227
+ res = f_stat (& self -> fatfs , path , & fno );
237
228
}
238
229
if (res != FR_OK ) {
239
230
mp_raise_OSError (fresult_to_errno_table [res ]);
@@ -272,12 +263,12 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_stat_obj, fat_vfs_stat);
272
263
273
264
// Get the status of a VFS.
274
265
STATIC mp_obj_t fat_vfs_statvfs (mp_obj_t vfs_in , mp_obj_t path_in ) {
275
- ( void ) vfs_in ;
276
- const char * path = mp_obj_str_get_str ( path_in ) ;
266
+ mp_obj_fat_vfs_t * self = MP_OBJ_TO_PTR ( vfs_in ) ;
267
+ ( void ) path_in ;
277
268
278
- FATFS * fatfs ;
279
269
DWORD nclst ;
280
- FRESULT res = f_getfree (path , & nclst , & fatfs );
270
+ FATFS * fatfs = & self -> fatfs ;
271
+ FRESULT res = f_getfree (fatfs , & nclst );
281
272
if (FR_OK != res ) {
282
273
mp_raise_OSError (fresult_to_errno_table [res ]);
283
274
}
0 commit comments