diff --git a/pkg/fatfs/fatfs_vfs/fatfs_vfs.c b/pkg/fatfs/fatfs_vfs/fatfs_vfs.c index ac77fb23e4..842ebdae69 100644 --- a/pkg/fatfs/fatfs_vfs/fatfs_vfs.c +++ b/pkg/fatfs/fatfs_vfs/fatfs_vfs.c @@ -445,6 +445,7 @@ static const vfs_file_system_ops_t fatfs_fs_ops = { .unlink = _unlink, .mkdir = _mkdir, .rmdir = _rmdir, + .stat = vfs_sysop_stat_from_fstat, }; static const vfs_file_ops_t fatfs_file_ops = { diff --git a/sys/include/vfs.h b/sys/include/vfs.h index babd3d4710..e0a96b0036 100644 --- a/sys/include/vfs.h +++ b/sys/include/vfs.h @@ -969,6 +969,20 @@ const vfs_mount_t *vfs_iterate_mounts(const vfs_mount_t *cur); */ const vfs_file_t *vfs_file_get(int fd); +/** @brief Implementation of `stat` using `fstat` + * + * This helper can be used by file system drivers that do not have any more + * efficient implementation of `fs_op::stat` than opening the file and running + * `f_op::fstat` on it. + * + * It can be set as `fs_op::stat` by a file system driver, provided it + * implements `f_op::open` and `f_op::fstat` and `f_op::close`, and its `open` + * accepts `NULL` in the `abs_path` position. + */ +int vfs_sysop_stat_from_fstat(vfs_mount_t *mountp, + const char *restrict path, + struct stat *restrict buf); + #ifdef __cplusplus } #endif diff --git a/sys/vfs/vfs.c b/sys/vfs/vfs.c index 995709a4a8..e0db65ec68 100644 --- a/sys/vfs/vfs.c +++ b/sys/vfs/vfs.c @@ -1000,4 +1000,23 @@ static inline int _fd_is_valid(int fd) return 0; } +int vfs_sysop_stat_from_fstat(vfs_mount_t *mountp, const char *restrict path, struct stat *restrict buf) +{ + const vfs_file_ops_t * f_op = mountp->fs->f_op; + vfs_file_t opened = { + .mp = mountp, + /* As per definition of the `vfsfile_ops::open` field */ + .f_op = f_op, + .private_data = { .ptr = NULL }, + .pos = 0, + }; + int err = f_op->open(&opened, path, 0, 0, NULL); + if (err < 0) { + return err; + } + err = f_op->fstat(&opened, buf); + f_op->close(&opened); + return err; +} + /** @} */ diff --git a/tests/pkg_fatfs_vfs/main.c b/tests/pkg_fatfs_vfs/main.c index 907031236f..e69a67d9fa 100644 --- a/tests/pkg_fatfs_vfs/main.c +++ b/tests/pkg_fatfs_vfs/main.c @@ -318,6 +318,8 @@ static void test_fstat(void) vfs_write(fd, test_txt, sizeof(test_txt)) == sizeof(test_txt)); print_test_result("test_stat__close", vfs_close(fd) == 0); + print_test_result("test_stat__direct", vfs_stat(FULL_FNAME1, &stat_buf) == 0); + fd = vfs_open(FULL_FNAME1, O_RDONLY, 0); print_test_result("test_stat__open", fd >= 0); print_test_result("test_stat__stat", vfs_fstat(fd, &stat_buf) == 0);