summaryrefslogtreecommitdiff
path: root/extmod
diff options
context:
space:
mode:
Diffstat (limited to 'extmod')
-rw-r--r--extmod/vfs_fat.c16
-rw-r--r--extmod/vfs_lfsx.c25
-rw-r--r--extmod/vfs_posix.c19
3 files changed, 56 insertions, 4 deletions
diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c
index 27681ca77..7d8b51efe 100644
--- a/extmod/vfs_fat.c
+++ b/extmod/vfs_fat.c
@@ -28,6 +28,10 @@
#include "py/mpconfig.h"
#if MICROPY_VFS_FAT
+#if !MICROPY_ENABLE_FINALISER
+#error "MICROPY_VFS_FAT requires MICROPY_ENABLE_FINALISER"
+#endif
+
#if !MICROPY_VFS
#error "with MICROPY_VFS_FAT enabled, must also enable MICROPY_VFS"
#endif
@@ -118,6 +122,7 @@ STATIC MP_DEFINE_CONST_STATICMETHOD_OBJ(fat_vfs_mkfs_obj, MP_ROM_PTR(&fat_vfs_mk
typedef struct _mp_vfs_fat_ilistdir_it_t {
mp_obj_base_t base;
mp_fun_1_t iternext;
+ mp_fun_1_t finaliser;
bool is_str;
FF_DIR dir;
} mp_vfs_fat_ilistdir_it_t;
@@ -162,6 +167,13 @@ STATIC mp_obj_t mp_vfs_fat_ilistdir_it_iternext(mp_obj_t self_in) {
return MP_OBJ_STOP_ITERATION;
}
+STATIC mp_obj_t mp_vfs_fat_ilistdir_it_del(mp_obj_t self_in) {
+ mp_vfs_fat_ilistdir_it_t *self = MP_OBJ_TO_PTR(self_in);
+ // ignore result / error because we may be closing a second time.
+ f_closedir(&self->dir);
+ return mp_const_none;
+}
+
STATIC mp_obj_t fat_vfs_ilistdir_func(size_t n_args, const mp_obj_t *args) {
mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(args[0]);
bool is_str_type = true;
@@ -176,8 +188,10 @@ STATIC mp_obj_t fat_vfs_ilistdir_func(size_t n_args, const mp_obj_t *args) {
}
// Create a new iterator object to list the dir
- mp_vfs_fat_ilistdir_it_t *iter = mp_obj_malloc(mp_vfs_fat_ilistdir_it_t, &mp_type_polymorph_iter);
+ mp_vfs_fat_ilistdir_it_t *iter = m_new_obj_with_finaliser(mp_vfs_fat_ilistdir_it_t);
+ iter->base.type = &mp_type_polymorph_iter_with_finaliser;
iter->iternext = mp_vfs_fat_ilistdir_it_iternext;
+ iter->finaliser = mp_vfs_fat_ilistdir_it_del;
iter->is_str = is_str_type;
FRESULT res = f_opendir(&self->fatfs, &iter->dir, path);
if (res != FR_OK) {
diff --git a/extmod/vfs_lfsx.c b/extmod/vfs_lfsx.c
index dbd32338c..fbfeaa5cc 100644
--- a/extmod/vfs_lfsx.c
+++ b/extmod/vfs_lfsx.c
@@ -36,6 +36,10 @@
#include "extmod/vfs.h"
#include "shared/timeutils/timeutils.h"
+#if !MICROPY_ENABLE_FINALISER
+#error "MICROPY_VFS_LFS requires MICROPY_ENABLE_FINALISER"
+#endif
+
STATIC int MP_VFS_LFSx(dev_ioctl)(const struct LFSx_API (config) * c, int cmd, int arg, bool must_return_int) {
mp_obj_t ret = mp_vfs_blockdev_ioctl(c->context, cmd, arg);
int ret_i = 0;
@@ -155,6 +159,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(MP_VFS_LFSx(open_obj), MP_VFS_LFSx(file_open));
typedef struct MP_VFS_LFSx (_ilistdir_it_t) {
mp_obj_base_t base;
mp_fun_1_t iternext;
+ mp_fun_1_t finaliser;
bool is_str;
MP_OBJ_VFS_LFSx *vfs;
LFSx_API(dir_t) dir;
@@ -163,11 +168,16 @@ typedef struct MP_VFS_LFSx (_ilistdir_it_t) {
STATIC mp_obj_t MP_VFS_LFSx(ilistdir_it_iternext)(mp_obj_t self_in) {
MP_VFS_LFSx(ilistdir_it_t) * self = MP_OBJ_TO_PTR(self_in);
+ if (self->vfs == NULL) {
+ return MP_OBJ_STOP_ITERATION;
+ }
+
struct LFSx_API (info) info;
for (;;) {
int ret = LFSx_API(dir_read)(&self->vfs->lfs, &self->dir, &info);
if (ret == 0) {
LFSx_API(dir_close)(&self->vfs->lfs, &self->dir);
+ self->vfs = NULL;
return MP_OBJ_STOP_ITERATION;
}
if (!(info.name[0] == '.' && (info.name[1] == '\0'
@@ -190,6 +200,14 @@ STATIC mp_obj_t MP_VFS_LFSx(ilistdir_it_iternext)(mp_obj_t self_in) {
return MP_OBJ_FROM_PTR(t);
}
+STATIC mp_obj_t MP_VFS_LFSx(ilistdir_it_del)(mp_obj_t self_in) {
+ MP_VFS_LFSx(ilistdir_it_t) * self = MP_OBJ_TO_PTR(self_in);
+ if (self->vfs != NULL) {
+ LFSx_API(dir_close)(&self->vfs->lfs, &self->dir);
+ }
+ return mp_const_none;
+}
+
STATIC mp_obj_t MP_VFS_LFSx(ilistdir_func)(size_t n_args, const mp_obj_t *args) {
MP_OBJ_VFS_LFSx *self = MP_OBJ_TO_PTR(args[0]);
bool is_str_type = true;
@@ -203,14 +221,17 @@ STATIC mp_obj_t MP_VFS_LFSx(ilistdir_func)(size_t n_args, const mp_obj_t *args)
path = vstr_null_terminated_str(&self->cur_dir);
}
- MP_VFS_LFSx(ilistdir_it_t) * iter = mp_obj_malloc(MP_VFS_LFSx(ilistdir_it_t), &mp_type_polymorph_iter);
+ MP_VFS_LFSx(ilistdir_it_t) * iter = m_new_obj_with_finaliser(MP_VFS_LFSx(ilistdir_it_t));
+ iter->base.type = &mp_type_polymorph_iter_with_finaliser;
+
iter->iternext = MP_VFS_LFSx(ilistdir_it_iternext);
+ iter->finaliser = MP_VFS_LFSx(ilistdir_it_del);
iter->is_str = is_str_type;
- iter->vfs = self;
int ret = LFSx_API(dir_open)(&self->lfs, &iter->dir, path);
if (ret < 0) {
mp_raise_OSError(-ret);
}
+ iter->vfs = self;
return MP_OBJ_FROM_PTR(iter);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(MP_VFS_LFSx(ilistdir_obj), 1, 2, MP_VFS_LFSx(ilistdir_func));
diff --git a/extmod/vfs_posix.c b/extmod/vfs_posix.c
index 9b0036581..36b211b84 100644
--- a/extmod/vfs_posix.c
+++ b/extmod/vfs_posix.c
@@ -33,6 +33,10 @@
#if MICROPY_VFS_POSIX
+#if !MICROPY_ENABLE_FINALISER
+#error "MICROPY_VFS_POSIX requires MICROPY_ENABLE_FINALISER"
+#endif
+
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
@@ -162,6 +166,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(vfs_posix_getcwd_obj, vfs_posix_getcwd);
typedef struct _vfs_posix_ilistdir_it_t {
mp_obj_base_t base;
mp_fun_1_t iternext;
+ mp_fun_1_t finaliser;
bool is_str;
DIR *dir;
} vfs_posix_ilistdir_it_t;
@@ -226,10 +231,22 @@ STATIC mp_obj_t vfs_posix_ilistdir_it_iternext(mp_obj_t self_in) {
}
}
+STATIC mp_obj_t vfs_posix_ilistdir_it_del(mp_obj_t self_in) {
+ vfs_posix_ilistdir_it_t *self = MP_OBJ_TO_PTR(self_in);
+ if (self->dir != NULL) {
+ MP_THREAD_GIL_EXIT();
+ closedir(self->dir);
+ MP_THREAD_GIL_ENTER();
+ }
+ return mp_const_none;
+}
+
STATIC mp_obj_t vfs_posix_ilistdir(mp_obj_t self_in, mp_obj_t path_in) {
mp_obj_vfs_posix_t *self = MP_OBJ_TO_PTR(self_in);
- vfs_posix_ilistdir_it_t *iter = mp_obj_malloc(vfs_posix_ilistdir_it_t, &mp_type_polymorph_iter);
+ vfs_posix_ilistdir_it_t *iter = m_new_obj_with_finaliser(vfs_posix_ilistdir_it_t);
+ iter->base.type = &mp_type_polymorph_iter_with_finaliser;
iter->iternext = vfs_posix_ilistdir_it_iternext;
+ iter->finaliser = vfs_posix_ilistdir_it_del;
iter->is_str = mp_obj_get_type(path_in) == &mp_type_str;
const char *path = vfs_posix_get_path_str(self, path_in);
if (path[0] == '\0') {