diff --git a/os/sb/host/sbposix.c b/os/sb/host/sbposix.c index 417d15144..89dadda25 100644 --- a/os/sb/host/sbposix.c +++ b/os/sb/host/sbposix.c @@ -161,7 +161,7 @@ ssize_t sb_posix_write(int fd, const void *buf, size_t count) { off_t sb_posix_lseek(int fd, off_t offset, int whence) { sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p; msg_t ret; - vfs_file_stat_t stat; + vfs_stat_t stat; if ((whence != SEEK_SET) || (whence == SEEK_CUR) || (whence != SEEK_END)) { return CH_RET_EINVAL; @@ -175,7 +175,7 @@ off_t sb_posix_lseek(int fd, off_t offset, int whence) { return CH_RET_EISDIR; } - ret = vfsGetFileStat((struct vfs_file_node *)sbp->io.vfs_nodes[fd], &stat); + ret = vfsGetStat(sbp->io.vfs_nodes[fd], &stat); CH_RETURN_ON_ERROR(ret); if (!VFS_MODE_S_ISREG(stat.mode)) { diff --git a/os/vfs/drivers/fatfs/drvfatfs.c b/os/vfs/drivers/fatfs/drvfatfs.c index 996073028..7abc84ddc 100644 --- a/os/vfs/drivers/fatfs/drvfatfs.c +++ b/os/vfs/drivers/fatfs/drvfatfs.c @@ -56,26 +56,29 @@ static msg_t drv_open_file(void *instance, vfs_file_node_c **vfnpp); static const struct vfs_fatfs_driver_vmt driver_vmt = { - .set_cwd = drv_set_cwd, - .get_cwd = drv_get_cwd, - .open_dir = drv_open_dir, - .open_file = drv_open_file + .set_cwd = drv_set_cwd, + .get_cwd = drv_get_cwd, + .open_dir = drv_open_dir, + .open_file = drv_open_file }; static void *node_dir_addref(void *instance); static void node_dir_release(void *instance); +static msg_t node_dir_stat(void *instance, vfs_stat_t *sp); static msg_t node_dir_first(void *instance, vfs_direntry_info_t *dip); static msg_t node_dir_next(void *instance, vfs_direntry_info_t *dip); static const struct vfs_fatfs_dir_node_vmt dir_node_vmt = { - .addref = node_dir_addref, - .release = node_dir_release, - .dir_first = node_dir_first, - .dir_next = node_dir_next + .addref = node_dir_addref, + .release = node_dir_release, + .node_stat = node_dir_stat, + .dir_first = node_dir_first, + .dir_next = node_dir_next }; static void *node_file_addref(void *instance); static void node_file_release(void *instance); +static msg_t node_file_stat(void *instance, vfs_stat_t *sp); static BaseSequentialStream *node_file_get_stream(void *instance); static ssize_t node_file_read(void *instance, uint8_t *buf, size_t n); static ssize_t node_file_write(void *instance, const uint8_t *buf, size_t n); @@ -83,17 +86,16 @@ static msg_t node_file_setpos(void *instance, vfs_offset_t offset, vfs_seekmode_t whence); static vfs_offset_t node_file_getpos(void *instance); -static msg_t node_file_getstat(void *instance, vfs_file_stat_t *fsp); static const struct vfs_fatfs_file_node_vmt file_node_vmt = { .addref = node_file_addref, .release = node_file_release, + .node_stat = node_file_stat, .file_get_stream = node_file_get_stream, .file_read = node_file_read, .file_write = node_file_write, .file_setpos = node_file_setpos, - .file_getpos = node_file_getpos, - .file_getstat = node_file_getstat + .file_getpos = node_file_getpos }; static size_t file_stream_write(void *instance, const uint8_t *bp, size_t n); @@ -282,12 +284,14 @@ static msg_t drv_open_dir(void *instance, ffdnp = chPoolAlloc(&vfs_fatfs_driver_static.dir_nodes_pool); if (ffdnp != NULL) { - /* Node object initialization.*/ - __referenced_object_objinit_impl(ffdnp, &dir_node_vmt); - ffdnp->driver = (vfs_driver_c *)drvp; - res = f_opendir(&ffdnp->dir, (TCHAR *)path); if (res == FR_OK) { + + /* Node object initialization.*/ + __referenced_object_objinit_impl(ffdnp, &dir_node_vmt); + ffdnp->driver = (vfs_driver_c *)drvp; + ffdnp->mode = translate_mode(ffdnp->dir.obj.attr); + *vdnpp = (vfs_directory_node_c *)ffdnp; err = CH_RET_SUCCESS; break; @@ -324,13 +328,15 @@ static msg_t drv_open_file(void *instance, fffnp = chPoolAlloc(&vfs_fatfs_driver_static.file_nodes_pool); if (fffnp != NULL) { - /* Node object initialization.*/ - __referenced_object_objinit_impl(fffnp, &file_node_vmt); - fffnp->driver = (vfs_driver_c *)drvp; - fffnp->stream.vmt = &file_stream_vmt; - res = f_open(&fffnp->file, (TCHAR *)path, mode); if (res == FR_OK) { + + /* Node object initialization.*/ + __referenced_object_objinit_impl(fffnp, &file_node_vmt); + fffnp->driver = (vfs_driver_c *)drvp; + fffnp->mode = translate_mode(fffnp->file.obj.attr); + fffnp->stream.vmt = &file_stream_vmt; + *vfnpp = (vfs_file_node_c *)fffnp; err = CH_RET_SUCCESS; break; @@ -361,6 +367,15 @@ static void node_dir_release(void *instance) { } } +static msg_t node_dir_stat(void *instance, vfs_stat_t *sp) { + vfs_fatfs_dir_node_c *ffdnp = (vfs_fatfs_dir_node_c *)instance; + + sp->mode = ffdnp->mode; + sp->size = (vfs_offset_t)0; + + return CH_RET_SUCCESS; +} + static msg_t node_dir_first(void *instance, vfs_direntry_info_t *dip) { vfs_fatfs_dir_node_c *ffdnp = (vfs_fatfs_dir_node_c *)instance; msg_t err; @@ -428,6 +443,15 @@ static void node_file_release(void *instance) { } } +static msg_t node_file_stat(void *instance, vfs_stat_t *sp) { + vfs_fatfs_file_node_c *fffnp = (vfs_fatfs_file_node_c *)instance; + + sp->mode = fffnp->mode; + sp->size = (vfs_offset_t)fffnp->file.obj.objsize; + + return CH_RET_SUCCESS; +} + static BaseSequentialStream *node_file_get_stream(void *instance) { vfs_fatfs_file_node_c *fffnp = (vfs_fatfs_file_node_c *)instance; @@ -553,15 +577,6 @@ static vfs_offset_t node_file_getpos(void *instance) { return (vfs_offset_t)f_tell(&fffnp->file); } -static msg_t node_file_getstat(void *instance, vfs_file_stat_t *fsp) { - vfs_fatfs_file_node_c *fffnp = (vfs_fatfs_file_node_c *)instance; - - fsp->mode = translate_mode(fffnp->file.obj.attr); - fsp->size = (vfs_offset_t)fffnp->file.obj.objsize; - - return CH_RET_SUCCESS; -} - static size_t file_stream_write(void *instance, const uint8_t *bp, size_t n) { vfs_fatfs_file_node_c *fffnp = objGetInstance(vfs_fatfs_file_node_c *, (BaseSequentialStream *)instance); diff --git a/os/vfs/drivers/streams/drvstreams.c b/os/vfs/drivers/streams/drvstreams.c index 269cd7ae4..efb9a23d1 100644 --- a/os/vfs/drivers/streams/drvstreams.c +++ b/os/vfs/drivers/streams/drvstreams.c @@ -56,26 +56,29 @@ static msg_t drv_open_file(void *instance, vfs_file_node_c **vfnpp); static const struct vfs_streams_driver_vmt driver_vmt = { - .set_cwd = drv_set_cwd, - .get_cwd = drv_get_cwd, - .open_dir = drv_open_dir, - .open_file = drv_open_file + .set_cwd = drv_set_cwd, + .get_cwd = drv_get_cwd, + .open_dir = drv_open_dir, + .open_file = drv_open_file }; static void *node_dir_addref(void *instance); static void node_dir_release(void *instance); +static msg_t node_dir_getstat(void *instance, vfs_stat_t *sp); static msg_t node_dir_first(void *instance, vfs_direntry_info_t *dip); static msg_t node_dir_next(void *instance, vfs_direntry_info_t *dip); static const struct vfs_streams_dir_node_vmt dir_node_vmt = { - .addref = node_dir_addref, - .release = node_dir_release, - .dir_first = node_dir_first, - .dir_next = node_dir_next + .addref = node_dir_addref, + .release = node_dir_release, + .node_stat = node_dir_getstat, + .dir_first = node_dir_first, + .dir_next = node_dir_next }; static void *node_file_addref(void *instance); static void node_file_release(void *instance); +static msg_t node_file_getstat(void *instance, vfs_stat_t *sp); static BaseSequentialStream *node_file_get_stream(void *instance); static ssize_t node_file_read(void *instance, uint8_t *buf, size_t n); static ssize_t node_file_write(void *instance, const uint8_t *buf, size_t n); @@ -83,17 +86,16 @@ static msg_t node_file_setpos(void *instance, vfs_offset_t offset, vfs_seekmode_t whence); static vfs_offset_t node_file_getpos(void *instance); -static msg_t node_file_getstat(void *instance, vfs_file_stat_t *fsp); static const struct vfs_streams_file_node_vmt file_node_vmt = { .addref = node_file_addref, .release = node_file_release, + .node_stat = node_file_getstat, .file_get_stream = node_file_get_stream, .file_read = node_file_read, .file_write = node_file_write, .file_setpos = node_file_setpos, - .file_getpos = node_file_getpos, - .file_getstat = node_file_getstat + .file_getpos = node_file_getpos }; /** @@ -167,8 +169,9 @@ static msg_t drv_open_dir(void *instance, /* Node object initialization.*/ __referenced_object_objinit_impl(sdnp, &dir_node_vmt); - sdnp->driver = (vfs_driver_c *)drvp; - sdnp->index = 0U; + sdnp->driver = (vfs_driver_c *)drvp; + sdnp->mode = VFS_MODE_S_IFDIR | VFS_MODE_S_IRUSR; + sdnp->index = 0U; *vdnpp = (vfs_directory_node_c *)sdnp; return CH_RET_SUCCESS; @@ -189,7 +192,7 @@ static msg_t drv_open_file(void *instance, const drv_streams_element_t *dsep; msg_t err; - (void)flags; + (void)flags; /* TODO handle invalid modes.*/ do { char fname[VFS_CFG_NAMELEN_MAX + 1]; @@ -213,8 +216,9 @@ static msg_t drv_open_file(void *instance, /* Node object initialization.*/ __referenced_object_objinit_impl(sfnp, &file_node_vmt); - sfnp->driver = (vfs_driver_c *)drvp; - sfnp->stream = dsep->stream; + sfnp->driver = (vfs_driver_c *)drvp; + sfnp->mode = VFS_MODE_S_IFIFO | VFS_MODE_S_IRUSR | VFS_MODE_S_IWUSR; + sfnp->stream = dsep->stream; *vfnpp = (vfs_file_node_c *)sfnp; return CH_RET_SUCCESS; @@ -248,6 +252,15 @@ static void node_dir_release(void *instance) { } } +static msg_t node_dir_getstat(void *instance, vfs_stat_t *sp) { + vfs_node_c *np = (vfs_node_c *)instance; + + sp->mode = np->mode; + sp->size = (vfs_offset_t)0; + + return CH_RET_SUCCESS; +} + static msg_t node_dir_first(void *instance, vfs_direntry_info_t *dip) { vfs_streams_dir_node_c *sdnp = (vfs_streams_dir_node_c *)instance; @@ -289,6 +302,15 @@ static void node_file_release(void *instance) { } } +static msg_t node_file_getstat(void *instance, vfs_stat_t *sp) { + vfs_node_c *np = (vfs_node_c *)instance; + + sp->mode = np->mode; + sp->size = (vfs_offset_t)0; + + return CH_RET_SUCCESS; +} + static BaseSequentialStream *node_file_get_stream(void *instance) { vfs_streams_file_node_c *sfnp = (vfs_streams_file_node_c *)instance; @@ -325,14 +347,6 @@ static vfs_offset_t node_file_getpos(void *instance) { return 0U; } -static msg_t node_file_getstat(void *instance, vfs_file_stat_t *fsp) { - - (void)instance; - (void)fsp; - - return CH_RET_ENOSYS; -} - /*===========================================================================*/ /* Module exported functions. */ /*===========================================================================*/ diff --git a/os/vfs/include/vfs.h b/os/vfs/include/vfs.h index 4ec7dfb64..f5e90608d 100644 --- a/os/vfs/include/vfs.h +++ b/os/vfs/include/vfs.h @@ -129,6 +129,7 @@ extern vfs_driver_c *vfs_root; extern "C" { #endif void vfsInit(void); + msg_t vfsGetStat(vfs_node_c *np, vfs_stat_t *sp); msg_t vfsChangeCurrentDirectory(const char *path); msg_t vfsGetCurrentDirectory(char *buf, size_t size); msg_t vfsOpenDirectory(const char *name, @@ -148,7 +149,6 @@ extern "C" { vfs_offset_t offset, vfs_seekmode_t whence); vfs_offset_t vfsGetFilePosition(vfs_file_node_c *vfnp); - msg_t vfsGetFileStat(vfs_file_node_c *vfnp, vfs_file_stat_t *fsp); BaseSequentialStream *vfsGetFileStream(vfs_file_node_c *vfnp); #ifdef __cplusplus } diff --git a/os/vfs/include/vfsnodes.h b/os/vfs/include/vfsnodes.h index f17291a1f..2d8701c77 100644 --- a/os/vfs/include/vfsnodes.h +++ b/os/vfs/include/vfsnodes.h @@ -114,7 +114,7 @@ typedef struct vfs_direntry_info { * @brief Type of a node information structure. * @todo Add time, permissions etc. */ -typedef struct vfs_file_stat { +typedef struct vfs_stat { /** * @brief Modes of the node. */ @@ -123,7 +123,7 @@ typedef struct vfs_file_stat { * @brief Size of the node. */ vfs_offset_t size; -} vfs_file_stat_t; +} vfs_stat_t; /** * @brief Type of a generic VFS node class. @@ -134,7 +134,8 @@ typedef struct vfs_node vfs_node_c; * @brief @p vfs_node_c specific methods. */ #define __vfs_node_methods \ - __referenced_object_methods + __referenced_object_methods \ + msg_t (*node_stat)(void *instance, vfs_stat_t *fsp); /** * @brief @p vfs_node_c specific data. @@ -142,7 +143,9 @@ typedef struct vfs_node vfs_node_c; #define __vfs_node_data \ __referenced_object_data \ /* Driver handling this node.*/ \ - vfs_driver_c *driver; + vfs_driver_c *driver; \ + /* Node mode information.*/ \ + vfs_mode_t mode; /** * @brief @p vfs_node_c virtual methods table. @@ -215,8 +218,7 @@ typedef struct vfs_file_node vfs_file_node_c; msg_t (*file_setpos)(void *instance, \ vfs_offset_t offset, \ vfs_seekmode_t whence); \ - vfs_offset_t (*file_getpos)(void *instance); \ - msg_t (*file_getstat)(void *instance, vfs_file_stat_t *fsp); + vfs_offset_t (*file_getpos)(void *instance); /** * @brief @p vfs_file_node_c specific data. diff --git a/os/vfs/src/vfs.c b/os/vfs/src/vfs.c index 316a24823..7c43ff6b5 100644 --- a/os/vfs/src/vfs.c +++ b/os/vfs/src/vfs.c @@ -74,6 +74,22 @@ void vfsInit(void) { #endif } +/** + * @brief Returns the current file size. + *. + * @param[in] np Pointer to the @p vfs_node_c object + * @param[out] sp Pointer to a @p vfs_stat_t structure. + * @return The operation result. + * + * @api + */ +msg_t vfsGetStat(vfs_node_c *np, vfs_stat_t *sp) { + + chDbgAssert(np->references > 0U, "zero count"); + + return np->vmt->node_stat((void *)np, sp); +} + /** * @brief Changes the current VFS directory. * @@ -271,22 +287,6 @@ vfs_offset_t vfsGetFilePosition(vfs_file_node_c *vfnp) { return vfnp->vmt->file_getpos((void *)vfnp); } -/** - * @brief Returns the current file size. - *. - * @param[in] vfnp Pointer to the @p vfs_file_node_c object - * @param[out] fsp Pointer to a @p vfs_file_stat_t structure. - * @return The operation result. - * - * @api - */ -msg_t vfsGetFileStat(vfs_file_node_c *vfnp, vfs_file_stat_t *fsp) { - - chDbgAssert(vfnp->references > 0U, "zero count"); - - return vfnp->vmt->file_getstat((void *)vfnp, fsp); -} - /** * @brief Returns the inner stream associated to the file. *