35
35
#include "lib/fatfs/diskio.h"
36
36
#include "extmod/vfs_fat_file.h"
37
37
#include "extmod/fsusermount.h"
38
+ #include "timeutils.h"
38
39
39
40
#define mp_obj_fat_vfs_t fs_user_mount_t
40
41
@@ -152,6 +153,94 @@ STATIC mp_obj_t fat_vfs_getcwd(mp_obj_t vfs_in) {
152
153
}
153
154
STATIC MP_DEFINE_CONST_FUN_OBJ_1 (fat_vfs_getcwd_obj , fat_vfs_getcwd );
154
155
156
+ // Checks for path equality, ignoring trailing slashes:
157
+ // path_equal(/, /) -> true
158
+ // second argument must be in canonical form (meaning no trailing slash, unless it's just /)
159
+ STATIC bool path_equal (const char * path , const char * path_canonical ) {
160
+ while (* path_canonical != '\0' && * path == * path_canonical ) {
161
+ ++ path ;
162
+ ++ path_canonical ;
163
+ }
164
+ if (* path_canonical != '\0' ) {
165
+ return false;
166
+ }
167
+ while (* path == '/' ) {
168
+ ++ path ;
169
+ }
170
+ return * path == '\0' ;
171
+ }
172
+
173
+ /// \function stat(path)
174
+ /// Get the status of a file or directory.
175
+ STATIC mp_obj_t fat_vfs_stat (mp_obj_t vfs_in , mp_obj_t path_in ) {
176
+ const char * path = mp_obj_str_get_str (path_in );
177
+
178
+ FILINFO fno ;
179
+ #if _USE_LFN
180
+ fno .lfname = NULL ;
181
+ fno .lfsize = 0 ;
182
+ #endif
183
+ FRESULT res ;
184
+
185
+ if (path_equal (path , "/" )) {
186
+ // stat root directory
187
+ fno .fsize = 0 ;
188
+ fno .fdate = 0 ;
189
+ fno .ftime = 0 ;
190
+ fno .fattrib = AM_DIR ;
191
+ } else {
192
+ res = FR_NO_PATH ;
193
+ for (size_t i = 0 ; i < MP_ARRAY_SIZE (MP_STATE_PORT (fs_user_mount )); ++ i ) {
194
+ fs_user_mount_t * vfs = MP_STATE_PORT (fs_user_mount )[i ];
195
+ if (vfs != NULL && path_equal (path , vfs -> str )) {
196
+ // stat mounted device directory
197
+ fno .fsize = 0 ;
198
+ fno .fdate = 0 ;
199
+ fno .ftime = 0 ;
200
+ fno .fattrib = AM_DIR ;
201
+ res = FR_OK ;
202
+ }
203
+ }
204
+ if (res == FR_NO_PATH ) {
205
+ // stat normal file
206
+ res = f_stat (path , & fno );
207
+ }
208
+ if (res != FR_OK ) {
209
+ nlr_raise (mp_obj_new_exception_arg1 (& mp_type_OSError ,
210
+ MP_OBJ_NEW_SMALL_INT (fresult_to_errno_table [res ])));
211
+ }
212
+ }
213
+
214
+ mp_obj_tuple_t * t = MP_OBJ_TO_PTR (mp_obj_new_tuple (10 , NULL ));
215
+ mp_int_t mode = 0 ;
216
+ if (fno .fattrib & AM_DIR ) {
217
+ mode |= 0x4000 ; // stat.S_IFDIR
218
+ } else {
219
+ mode |= 0x8000 ; // stat.S_IFREG
220
+ }
221
+ mp_int_t seconds = timeutils_seconds_since_2000 (
222
+ 1980 + ((fno .fdate >> 9 ) & 0x7f ),
223
+ (fno .fdate >> 5 ) & 0x0f ,
224
+ fno .fdate & 0x1f ,
225
+ (fno .ftime >> 11 ) & 0x1f ,
226
+ (fno .ftime >> 5 ) & 0x3f ,
227
+ 2 * (fno .ftime & 0x1f )
228
+ );
229
+ t -> items [0 ] = MP_OBJ_NEW_SMALL_INT (mode ); // st_mode
230
+ t -> items [1 ] = MP_OBJ_NEW_SMALL_INT (0 ); // st_ino
231
+ t -> items [2 ] = MP_OBJ_NEW_SMALL_INT (0 ); // st_dev
232
+ t -> items [3 ] = MP_OBJ_NEW_SMALL_INT (0 ); // st_nlink
233
+ t -> items [4 ] = MP_OBJ_NEW_SMALL_INT (0 ); // st_uid
234
+ t -> items [5 ] = MP_OBJ_NEW_SMALL_INT (0 ); // st_gid
235
+ t -> items [6 ] = MP_OBJ_NEW_SMALL_INT (fno .fsize ); // st_size
236
+ t -> items [7 ] = MP_OBJ_NEW_SMALL_INT (seconds ); // st_atime
237
+ t -> items [8 ] = MP_OBJ_NEW_SMALL_INT (seconds ); // st_mtime
238
+ t -> items [9 ] = MP_OBJ_NEW_SMALL_INT (seconds ); // st_ctime
239
+
240
+ return MP_OBJ_FROM_PTR (t );
241
+ }
242
+ STATIC MP_DEFINE_CONST_FUN_OBJ_2 (fat_vfs_stat_obj , fat_vfs_stat );
243
+
155
244
STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table [] = {
156
245
{ MP_ROM_QSTR (MP_QSTR_mkfs ), MP_ROM_PTR (& fat_vfs_mkfs_obj ) },
157
246
{ MP_ROM_QSTR (MP_QSTR_open ), MP_ROM_PTR (& fat_vfs_open_obj ) },
@@ -161,6 +250,7 @@ STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = {
161
250
{ MP_ROM_QSTR (MP_QSTR_getcwd ), MP_ROM_PTR (& fat_vfs_getcwd_obj ) },
162
251
{ MP_ROM_QSTR (MP_QSTR_remove ), MP_ROM_PTR (& fat_vfs_remove_obj ) },
163
252
{ MP_ROM_QSTR (MP_QSTR_rename ), MP_ROM_PTR (& fat_vfs_rename_obj ) },
253
+ { MP_ROM_QSTR (MP_QSTR_stat ), MP_ROM_PTR (& fat_vfs_stat_obj ) },
164
254
};
165
255
STATIC MP_DEFINE_CONST_DICT (fat_vfs_locals_dict , fat_vfs_locals_dict_table );
166
256
0 commit comments