Skip to content
This repository was archived by the owner on Sep 6, 2023. It is now read-only.

Commit ee009d7

Browse files
robert-hhPaul Sokolovsky
authored and
Paul Sokolovsky
committed
extmod/vfs_fat.c: Add vfs.stat().
The call to stat() returns a 10 element tuple consistent to the os.stat() call. At the moment, the only relevant information returned are file type and file size.
1 parent 7d4fd8b commit ee009d7

File tree

2 files changed

+92
-0
lines changed

2 files changed

+92
-0
lines changed

extmod/vfs_fat.c

+90
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "lib/fatfs/diskio.h"
3636
#include "extmod/vfs_fat_file.h"
3737
#include "extmod/fsusermount.h"
38+
#include "timeutils.h"
3839

3940
#define mp_obj_fat_vfs_t fs_user_mount_t
4041

@@ -152,6 +153,94 @@ STATIC mp_obj_t fat_vfs_getcwd(mp_obj_t vfs_in) {
152153
}
153154
STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_getcwd_obj, fat_vfs_getcwd);
154155

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+
155244
STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = {
156245
{ MP_ROM_QSTR(MP_QSTR_mkfs), MP_ROM_PTR(&fat_vfs_mkfs_obj) },
157246
{ 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[] = {
161250
{ MP_ROM_QSTR(MP_QSTR_getcwd), MP_ROM_PTR(&fat_vfs_getcwd_obj) },
162251
{ MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&fat_vfs_remove_obj) },
163252
{ 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) },
164254
};
165255
STATIC MP_DEFINE_CONST_DICT(fat_vfs_locals_dict, fat_vfs_locals_dict_table);
166256

unix/Makefile

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ include ../py/py.mk
1515

1616
INC += -I.
1717
INC += -I..
18+
INC += -I../lib/timeutils
1819
INC += -I$(BUILD)
1920

2021
# compiler settings
@@ -163,6 +164,7 @@ LIB_SRC_C = $(addprefix lib/,\
163164
utils/printf.c \
164165
fatfs/ff.c \
165166
fatfs/option/ccsbcs.c \
167+
timeutils/timeutils.c \
166168
)
167169

168170
OBJ = $(PY_O)

0 commit comments

Comments
 (0)