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.
This commit is contained in:
parent
7d4fd8b6db
commit
ee009d713a
|
@ -35,6 +35,7 @@
|
|||
#include "lib/fatfs/diskio.h"
|
||||
#include "extmod/vfs_fat_file.h"
|
||||
#include "extmod/fsusermount.h"
|
||||
#include "timeutils.h"
|
||||
|
||||
#define mp_obj_fat_vfs_t fs_user_mount_t
|
||||
|
||||
|
@ -152,6 +153,94 @@ STATIC mp_obj_t fat_vfs_getcwd(mp_obj_t vfs_in) {
|
|||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_getcwd_obj, fat_vfs_getcwd);
|
||||
|
||||
// Checks for path equality, ignoring trailing slashes:
|
||||
// path_equal(/, /) -> true
|
||||
// second argument must be in canonical form (meaning no trailing slash, unless it's just /)
|
||||
STATIC bool path_equal(const char *path, const char *path_canonical) {
|
||||
while (*path_canonical != '\0' && *path == *path_canonical) {
|
||||
++path;
|
||||
++path_canonical;
|
||||
}
|
||||
if (*path_canonical != '\0') {
|
||||
return false;
|
||||
}
|
||||
while (*path == '/') {
|
||||
++path;
|
||||
}
|
||||
return *path == '\0';
|
||||
}
|
||||
|
||||
/// \function stat(path)
|
||||
/// Get the status of a file or directory.
|
||||
STATIC mp_obj_t fat_vfs_stat(mp_obj_t vfs_in, mp_obj_t path_in) {
|
||||
const char *path = mp_obj_str_get_str(path_in);
|
||||
|
||||
FILINFO fno;
|
||||
#if _USE_LFN
|
||||
fno.lfname = NULL;
|
||||
fno.lfsize = 0;
|
||||
#endif
|
||||
FRESULT res;
|
||||
|
||||
if (path_equal(path, "/")) {
|
||||
// stat root directory
|
||||
fno.fsize = 0;
|
||||
fno.fdate = 0;
|
||||
fno.ftime = 0;
|
||||
fno.fattrib = AM_DIR;
|
||||
} else {
|
||||
res = FR_NO_PATH;
|
||||
for (size_t i = 0; i < MP_ARRAY_SIZE(MP_STATE_PORT(fs_user_mount)); ++i) {
|
||||
fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount)[i];
|
||||
if (vfs != NULL && path_equal(path, vfs->str)) {
|
||||
// stat mounted device directory
|
||||
fno.fsize = 0;
|
||||
fno.fdate = 0;
|
||||
fno.ftime = 0;
|
||||
fno.fattrib = AM_DIR;
|
||||
res = FR_OK;
|
||||
}
|
||||
}
|
||||
if (res == FR_NO_PATH) {
|
||||
// stat normal file
|
||||
res = f_stat(path, &fno);
|
||||
}
|
||||
if (res != FR_OK) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError,
|
||||
MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
|
||||
}
|
||||
}
|
||||
|
||||
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(10, NULL));
|
||||
mp_int_t mode = 0;
|
||||
if (fno.fattrib & AM_DIR) {
|
||||
mode |= 0x4000; // stat.S_IFDIR
|
||||
} else {
|
||||
mode |= 0x8000; // stat.S_IFREG
|
||||
}
|
||||
mp_int_t seconds = timeutils_seconds_since_2000(
|
||||
1980 + ((fno.fdate >> 9) & 0x7f),
|
||||
(fno.fdate >> 5) & 0x0f,
|
||||
fno.fdate & 0x1f,
|
||||
(fno.ftime >> 11) & 0x1f,
|
||||
(fno.ftime >> 5) & 0x3f,
|
||||
2 * (fno.ftime & 0x1f)
|
||||
);
|
||||
t->items[0] = MP_OBJ_NEW_SMALL_INT(mode); // st_mode
|
||||
t->items[1] = MP_OBJ_NEW_SMALL_INT(0); // st_ino
|
||||
t->items[2] = MP_OBJ_NEW_SMALL_INT(0); // st_dev
|
||||
t->items[3] = MP_OBJ_NEW_SMALL_INT(0); // st_nlink
|
||||
t->items[4] = MP_OBJ_NEW_SMALL_INT(0); // st_uid
|
||||
t->items[5] = MP_OBJ_NEW_SMALL_INT(0); // st_gid
|
||||
t->items[6] = MP_OBJ_NEW_SMALL_INT(fno.fsize); // st_size
|
||||
t->items[7] = MP_OBJ_NEW_SMALL_INT(seconds); // st_atime
|
||||
t->items[8] = MP_OBJ_NEW_SMALL_INT(seconds); // st_mtime
|
||||
t->items[9] = MP_OBJ_NEW_SMALL_INT(seconds); // st_ctime
|
||||
|
||||
return MP_OBJ_FROM_PTR(t);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_stat_obj, fat_vfs_stat);
|
||||
|
||||
STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_mkfs), MP_ROM_PTR(&fat_vfs_mkfs_obj) },
|
||||
{ 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[] = {
|
|||
{ MP_ROM_QSTR(MP_QSTR_getcwd), MP_ROM_PTR(&fat_vfs_getcwd_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&fat_vfs_remove_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&fat_vfs_rename_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&fat_vfs_stat_obj) },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(fat_vfs_locals_dict, fat_vfs_locals_dict_table);
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ include ../py/py.mk
|
|||
|
||||
INC += -I.
|
||||
INC += -I..
|
||||
INC += -I../lib/timeutils
|
||||
INC += -I$(BUILD)
|
||||
|
||||
# compiler settings
|
||||
|
@ -163,6 +164,7 @@ LIB_SRC_C = $(addprefix lib/,\
|
|||
utils/printf.c \
|
||||
fatfs/ff.c \
|
||||
fatfs/option/ccsbcs.c \
|
||||
timeutils/timeutils.c \
|
||||
)
|
||||
|
||||
OBJ = $(PY_O)
|
||||
|
|
Loading…
Reference in New Issue