From 7677592f4a87f1f0d9aca096f738d0f8ce874edd Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sat, 1 Jan 2022 17:25:16 +0000 Subject: [PATCH] git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15303 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/sb/common/dirent.h | 90 +++++++++++++++++++++++++++++++++++++++++++ os/sb/host/sbposix.c | 53 ++++++++++++++++++++++++- os/sb/host/sbposix.h | 1 + 3 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 os/sb/common/dirent.h diff --git a/os/sb/common/dirent.h b/os/sb/common/dirent.h new file mode 100644 index 000000000..a9c52798e --- /dev/null +++ b/os/sb/common/dirent.h @@ -0,0 +1,90 @@ +/* + ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014, + 2015,2016,2017,2018,2019,2020,2021,2022 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation version 3 of the License. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file sb/common/dirent.h + * @brief Replaces the default dirent.h file. + * + * @addtogroup ARM_SANDBOX_DIRENT + * @{ + */ + +#ifndef DIRENT_H +#define DIRENT_H + +#include +#include + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/** + * @name Structure dirent defined fields + * @{ + */ +#define _DIRENT_HAVE_D_RECLEN +#define _DIRENT_HAVE_D_TYPE +/** @} */ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +struct dirent { + ino_t d_ino; + unsigned short d_reclen; + unsigned char d_type; + char d_name[]; +}; + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +#define IFTODT(mode) (((mode) & 0170000) >> 12) +#define DTTOIF(dirtype) ((dirtype) << 12) + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +#endif /* DIRENT_H */ + +/** @} */ diff --git a/os/sb/host/sbposix.c b/os/sb/host/sbposix.c index 2894a59d6..3f2b3f531 100644 --- a/os/sb/host/sbposix.c +++ b/os/sb/host/sbposix.c @@ -25,6 +25,8 @@ * @{ */ +#include + #include "ch.h" #include "sb.h" @@ -198,7 +200,7 @@ int sb_posix_fstat(int fd, struct stat *statbuf) { ssize_t sb_posix_read(int fd, void *buf, size_t count) { sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p; - if (!sb_is_valid_write_range(sbp, (void *)buf, count)) { + if (!sb_is_valid_write_range(sbp, buf, count)) { return CH_RET_EFAULT; } @@ -216,7 +218,7 @@ ssize_t sb_posix_read(int fd, void *buf, size_t count) { ssize_t sb_posix_write(int fd, const void *buf, size_t count) { sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p; - if (!sb_is_valid_read_range(sbp, (void *)buf, count)) { + if (!sb_is_valid_read_range(sbp, buf, count)) { return CH_RET_EFAULT; } @@ -255,6 +257,53 @@ off_t sb_posix_lseek(int fd, off_t offset, int whence) { whence);; } +ssize_t sbPosixGetdents(int fd, void *buf, size_t count) { + sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p; + vfs_direntry_info_t *dip; + msg_t ret; + + if (!sb_is_valid_write_range(sbp, buf, count)) { + return (ssize_t)CH_RET_EFAULT; + } + + if (!is_existing_descriptor(&sbp->io, fd)) { + return (ssize_t)CH_RET_EBADF; + } + + if (!VFS_MODE_S_ISDIR(sbp->io.vfs_nodes[fd]->mode)) { + return (ssize_t)CH_RET_ENOTDIR; + } + + dip = (vfs_direntry_info_t *)(void *)vfs_buffer_take(); + + do { + size_t n; + struct dirent *dep = (struct dirent *)buf; + + ret = vfsReadDirectoryNext((vfs_directory_node_c *)sbp->io.vfs_nodes[fd], dip); + CH_BREAK_ON_ERROR(ret); + + n = sizeof (struct dirent) + strlen(dip->name) + (size_t)1; + if (count < n) { + ret = CH_RET_EINVAL; + break; + } + + /* Copying data from VFS structure to the Posix one.*/ + dep->d_ino = (ino_t)1; /* TODO */ + dep->d_reclen = n; + dep->d_type = IFTODT(sbp->io.vfs_nodes[fd]->mode); + strcpy(dep->d_name, dip->name); + + ret = (msg_t)n; + + } while (false); + + vfs_buffer_release((char *)dip); + + return (ssize_t)ret; +} + void sbPosixRegisterDescriptor(sb_class_t *sbp, int fd, vfs_node_c *np) { chDbgAssert(is_available_descriptor(&sbp->io, fd), "invalid file descriptor"); diff --git a/os/sb/host/sbposix.h b/os/sb/host/sbposix.h index 2a1260547..442591679 100644 --- a/os/sb/host/sbposix.h +++ b/os/sb/host/sbposix.h @@ -67,6 +67,7 @@ extern "C" { ssize_t sb_posix_read(int fd, void *buf, size_t count); 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); + ssize_t sbPosixGetdents(int fd, void *buf, size_t count); #if SB_CFG_ENABLE_VFS == TRUE void sbPosixRegisterDescriptor(sb_class_t *sbp, int fd, vfs_node_c *np); #endif