diff --git a/demos/STM32/RT-STM32L4R9-DISCOVERY-RAM_SB_HOST_DYNAMIC/Makefile b/demos/STM32/RT-STM32L4R9-DISCOVERY-RAM_SB_HOST_DYNAMIC/Makefile index 22d328552..a085f610f 100644 --- a/demos/STM32/RT-STM32L4R9-DISCOVERY-RAM_SB_HOST_DYNAMIC/Makefile +++ b/demos/STM32/RT-STM32L4R9-DISCOVERY-RAM_SB_HOST_DYNAMIC/Makefile @@ -55,7 +55,7 @@ endif # Stack size to be allocated to the Cortex-M process stack. This stack is # the stack used by the main() thread. ifeq ($(USE_PROCESS_STACKSIZE),) - USE_PROCESS_STACKSIZE = 0x400 + USE_PROCESS_STACKSIZE = 0x800 endif # Stack size to the allocated to the Cortex-M main/exceptions stack. This diff --git a/demos/STM32/RT-STM32L4R9-DISCOVERY-RAM_SB_HOST_DYNAMIC/main.c b/demos/STM32/RT-STM32L4R9-DISCOVERY-RAM_SB_HOST_DYNAMIC/main.c index b33302753..3b6ab7761 100644 --- a/demos/STM32/RT-STM32L4R9-DISCOVERY-RAM_SB_HOST_DYNAMIC/main.c +++ b/demos/STM32/RT-STM32L4R9-DISCOVERY-RAM_SB_HOST_DYNAMIC/main.c @@ -107,7 +107,7 @@ static const char *sbx1_envp[] = { NULL }; -static THD_WORKING_AREA(waUnprivileged1, 1024); +static THD_WORKING_AREA(waUnprivileged1, 2048); /*===========================================================================*/ /* Main and generic code. */ @@ -245,9 +245,9 @@ int main(void) { if (CH_RET_IS_ERROR(ret)) { chSysHalt("VFS"); } - sbPosixRegisterDescriptor(&sbx1, STDIN_FILENO, (vfs_node_c *)roAddRef(np)); - sbPosixRegisterDescriptor(&sbx1, STDOUT_FILENO, (vfs_node_c *)roAddRef(np)); - sbPosixRegisterDescriptor(&sbx1, STDERR_FILENO, (vfs_node_c *)roAddRef(np)); + sbRegisterDescriptor(&sbx1, STDIN_FILENO, (vfs_node_c *)roAddRef(np)); + sbRegisterDescriptor(&sbx1, STDOUT_FILENO, (vfs_node_c *)roAddRef(np)); + sbRegisterDescriptor(&sbx1, STDERR_FILENO, (vfs_node_c *)roAddRef(np)); vfsClose(np); #if 0 @@ -259,9 +259,9 @@ int main(void) { if (CH_RET_IS_ERROR(ret)) { chSysHalt("VFS"); } - sbPosixRegisterDescriptor(&sbx2, STDIN_FILENO, (vfs_node_c *)roAddRef(np)); - sbPosixRegisterDescriptor(&sbx2, STDOUT_FILENO, (vfs_node_c *)roAddRef(np)); - sbPosixRegisterDescriptor(&sbx2, STDERR_FILENO, (vfs_node_c *)roAddRef(np)); + sbRegisterDescriptor(&sbx2, STDIN_FILENO, (vfs_node_c *)roAddRef(np)); + sbRegisterDescriptor(&sbx2, STDOUT_FILENO, (vfs_node_c *)roAddRef(np)); + sbRegisterDescriptor(&sbx2, STDERR_FILENO, (vfs_node_c *)roAddRef(np)); vfsClose(np); #endif @@ -299,29 +299,15 @@ int main(void) { if (palReadLine(LINE_BUTTON)) { if (!sbIsThreadRunningX(&sbx1)) { - /* Loading sandbox code.*/ - ret = sbElfLoadFile((vfs_driver_c *)&sb1_root_overlay_driver, - "/bin/msh.elf", - &sbx1.config->regions[0].area); + /* Running the sandbox.*/ + ret = sbExec(&sbx1, "/bin/msh.elf", + waUnprivileged1, sizeof (waUnprivileged1), NORMALPRIO - 1, + sbx1_argv, sbx1_envp); if (CH_RET_IS_ERROR(ret)) { - chSysHalt("ELF"); - } - - /* Starting sandboxed thread 1.*/ - if (sbStartThread(&sbx1, "sbx1", - waUnprivileged1, sizeof (waUnprivileged1), NORMALPRIO - 1, - sbx1_argv, sbx1_envp) == NULL) { - chSysHalt("sbx1 failed"); + chprintf((BaseSequentialStream *)&SD2, "SBX1 launch failed (%08lx)\r\n", ret); + chThdSleepMilliseconds(1000); } } -#if 0 - static uint8_t loadbuf[1024]; - static memory_area_t ma = {loadbuf, sizeof (loadbuf)}; - ret = sbElfLoadFile((vfs_driver_c *)&sb1_root_overlay_driver, "/bin/app.elf", &ma); - if (CH_RET_IS_ERROR(ret)) { - chSysHalt("ELF"); - } -#endif } } } diff --git a/os/sb/host/sbhost.c b/os/sb/host/sbhost.c index 8b67bea61..c33ea62e6 100644 --- a/os/sb/host/sbhost.c +++ b/os/sb/host/sbhost.c @@ -105,34 +105,34 @@ void sb_strv_copy(const char *sp[], void *dp, int n) { *(vp + n) = NULL; } -bool sb_is_valid_read_range(sb_class_t *sbcp, const void *start, size_t size) { - const sb_memory_region_t *rp = &sbcp->config->regions[0]; +bool sb_is_valid_read_range(sb_class_t *sbp, const void *start, size_t size) { + const sb_memory_region_t *rp = &sbp->config->regions[0]; do { if (rp->used && chMemIsSpaceWithinX(&rp->area, start, size)) { return true; } rp++; - } while (rp < &sbcp->config->regions[SB_CFG_NUM_REGIONS]); + } while (rp < &sbp->config->regions[SB_CFG_NUM_REGIONS]); return false; } -bool sb_is_valid_write_range(sb_class_t *sbcp, void *start, size_t size) { - const sb_memory_region_t *rp = &sbcp->config->regions[0]; +bool sb_is_valid_write_range(sb_class_t *sbp, void *start, size_t size) { + const sb_memory_region_t *rp = &sbp->config->regions[0]; do { if (rp->used && chMemIsSpaceWithinX(&rp->area, start, size)) { return rp->writeable; } rp++; - } while (rp < &sbcp->config->regions[SB_CFG_NUM_REGIONS]); + } while (rp < &sbp->config->regions[SB_CFG_NUM_REGIONS]); return false; } -size_t sb_check_string(sb_class_t *sbcp, const char *s, size_t max) { - const sb_memory_region_t *rp = &sbcp->config->regions[0]; +size_t sb_check_string(sb_class_t *sbp, const char *s, size_t max) { + const sb_memory_region_t *rp = &sbp->config->regions[0]; do { if (rp->used) { @@ -142,13 +142,13 @@ size_t sb_check_string(sb_class_t *sbcp, const char *s, size_t max) { } } rp++; - } while (rp < &sbcp->config->regions[SB_CFG_NUM_REGIONS]); + } while (rp < &sbp->config->regions[SB_CFG_NUM_REGIONS]); return (size_t)0; } -size_t sb_check_pointers_array(sb_class_t *sbcp, const void *pp[], size_t max) { - const sb_memory_region_t *rp = &sbcp->config->regions[0]; +size_t sb_check_pointers_array(sb_class_t *sbp, const void *pp[], size_t max) { + const sb_memory_region_t *rp = &sbp->config->regions[0]; do { if (rp->used) { @@ -158,21 +158,21 @@ size_t sb_check_pointers_array(sb_class_t *sbcp, const void *pp[], size_t max) { } } rp++; - } while (rp < &sbcp->config->regions[SB_CFG_NUM_REGIONS]); + } while (rp < &sbp->config->regions[SB_CFG_NUM_REGIONS]); return (size_t)0; } -size_t sb_check_strings_array(sb_class_t *sbcp, const char *pp[], size_t max) { +size_t sb_check_strings_array(sb_class_t *sbp, const char *pp[], size_t max) { const char *s; size_t n; - n = sb_check_pointers_array(sbcp, (const void **)pp, max); + n = sb_check_pointers_array(sbp, (const void **)pp, max); if (n > (size_t)0) { while ((s = *pp++) != NULL) { size_t sn; - sn = sb_check_string(sbcp, s, max - n); + sn = sb_check_string(sbp, s, max - n); if (sn == (size_t)0) { return (size_t)0; } @@ -187,27 +187,27 @@ size_t sb_check_strings_array(sb_class_t *sbcp, const char *pp[], size_t max) { /** * @brief Sandbox object initialization. * - * @param[out] sbcp pointer to the sandbox object + * @param[out] sbp pointer to the sandbox object * @param[in] config pointer to the sandbox configuration * * @init */ -void sbObjectInit(sb_class_t *sbcp, const sb_config_t *config) { +void sbObjectInit(sb_class_t *sbp, const sb_config_t *config) { - sbcp->config = config; - sbcp->tp = NULL; + sbp->config = config; + sbp->tp = NULL; #if CH_CFG_USE_MESSAGES == TRUE - sbcp->msg_tp = NULL; + sbp->msg_tp = NULL; #endif #if CH_CFG_USE_EVENTS == TRUE - chEvtObjectInit(&sbcp->es); + chEvtObjectInit(&sbp->es); #endif } /** * @brief Starts a sandboxed thread. * - * @param[in] sbcp pointer to a @p sb_class_t structure + * @param[in] sbp pointer to a @p sb_class_t structure * @param[in] name name to be assigned to the thread * @param[out] wsp pointer to a working area dedicated to the thread stack * @param[in] size size of the working area @@ -217,12 +217,12 @@ void sbObjectInit(sb_class_t *sbcp, const sb_config_t *config) { * @return The thread pointer. * @retval NULL if the sandbox thread creation failed. */ -thread_t *sbStartThread(sb_class_t *sbcp, const char *name, +thread_t *sbStartThread(sb_class_t *sbp, const char *name, void *wsp, size_t size, tprio_t prio, const char *argv[], const char *envp[]) { thread_t *utp; const sb_header_t *sbhp; - const sb_config_t *config = sbcp->config; + const sb_config_t *config = sbp->config; void *usp, *uargv, *uenvp; size_t envsize, argsize, parsize; int uargc, uenvc; @@ -290,7 +290,7 @@ thread_t *sbStartThread(sb_class_t *sbcp, const char *name, .prio = prio, .u_pc = sbhp->hdr_entry, .u_psp = (uint32_t)usp, - .arg = (void *)sbcp + .arg = (void *)sbp }; #if PORT_SWITCHED_REGIONS_NUMBER > 0 for (unsigned i = 0U; i < PORT_SWITCHED_REGIONS_NUMBER; i++) { @@ -301,7 +301,7 @@ thread_t *sbStartThread(sb_class_t *sbcp, const char *name, utp = chThdCreateUnprivileged(&utd); /* For messages exchange.*/ - sbcp->tp = utp; + sbp->tp = utp; return utp; } @@ -309,20 +309,149 @@ thread_t *sbStartThread(sb_class_t *sbcp, const char *name, /** * @brief Verifies if the sandbox thread is running. * - * @param[in] sbcp pointer to a @p sb_class_t structure + * @param[in] sbp pointer to a @p sb_class_t structure * @return The thread status. * * @api */ -bool sbIsThreadRunningX(sb_class_t *sbcp) { +bool sbIsThreadRunningX(sb_class_t *sbp) { - if (sbcp->tp == NULL) { + if (sbp->tp == NULL) { return false; } - return !chThdTerminatedX(sbcp->tp); + return !chThdTerminatedX(sbp->tp); } +#if (SB_CFG_ENABLE_VFS == TRUE) || defined(__DOXYGEN__) +/** + * @brief Execute an elf file within a sandbox. + * @note The file is loaded into region zero of the sandbox which is + * assumed to be used for both code and data, extra regions are + * not touched by this function. + * + * @param[in] sbp pointer to a @p sb_class_t structure + * @param[in] pathname file to be executed + * @param[in] argv arguments to be passed to the sandbox + * @param[in] envp environment variables to be passed to the sandbox + * @return The operation result. + * + * @api + */ +msg_t sbExec(sb_class_t *sbp, const char *pathname, + void *wsp, size_t size, tprio_t prio, + const char *argv[], const char *envp[]) { + const sb_config_t *config = sbp->config; + memory_area_t ma = config->regions[0].area; + const sb_header_t *sbhp; + msg_t ret; + void *usp, *uargv, *uenvp; + size_t envsize, argsize, parsize; + int uargc, uenvc; + + /* Setting up an initial stack for the sandbox.*/ + usp = (void *)(config->regions[0].area.base + config->regions[0].area.size); + + /* Allocating space for environment variables.*/ + envsize = sb_strv_getsize(envp, &uenvc); + PUSHSPACE(usp, envsize); + uenvp = usp; + + /* Allocating space for arguments.*/ + argsize = sb_strv_getsize(argv, &uargc); + PUSHSPACE(usp, argsize); + uargv = usp; + + /* Allocating space for parameters.*/ + if (MEM_IS_ALIGNED(usp, PORT_STACK_ALIGN)) { + parsize = sizeof (int) + sizeof (const char **) + sizeof (const char **) + sizeof (int); + } + else { + parsize = sizeof (const char **) + sizeof (const char **) + sizeof (int); + } + PUSHSPACE(usp, parsize); + + /* Checking stack allocation.*/ + if (!chMemIsSpaceWithinX(&config->regions[0].area, + usp, envsize + argsize + parsize)) { + return CH_RET_ENOMEM; + } + + /* Adjusting the size of the memory area object, we don't want the loaded + elf file to overwrite the initialized stack.*/ + ma.size -= envsize + argsize + parsize; + + /* Initializing stack.*/ + sb_strv_copy(envp, uenvp, uenvc); + sb_strv_copy(argv, uargv, uargc); + *((uint32_t *)usp + 2) = (uint32_t)uenvp; + *((uint32_t *)usp + 1) = (uint32_t)uargv; + *((uint32_t *)usp + 0) = (uint32_t)uargc; + + /* Loading sandbox code into the specified memory area.*/ + ret = sbElfLoadFile(config->vfs_driver, pathname, &ma); + CH_RETURN_ON_ERROR(ret); + + /* Header location.*/ + sbhp = (const sb_header_t *)(void *)ma.base; + + /* Checking header magic numbers.*/ + if ((sbhp->hdr_magic1 != SB_MAGIC1) || (sbhp->hdr_magic2 != SB_MAGIC2)) { + return CH_RET_ENOEXEC; + } + + /* Checking header size.*/ + if (sbhp->hdr_size != sizeof (sb_header_t)) { + return CH_RET_ENOEXEC; + } + + /* Checking header entry point.*/ + if (!chMemIsSpaceWithinX(&ma, (const void *)sbhp->hdr_entry, (size_t)2)) { + return CH_RET_EFAULT; + } + + /* Everything OK, starting the unprivileged thread inside the sandbox.*/ + unprivileged_thread_descriptor_t utd = { + .name = pathname, + .wbase = (stkalign_t *)wsp, + .wend = (stkalign_t *)wsp + (size / sizeof (stkalign_t)), + .prio = prio, + .u_pc = sbhp->hdr_entry, + .u_psp = (uint32_t)usp, + .arg = (void *)sbp + }; +#if PORT_SWITCHED_REGIONS_NUMBER > 0 + for (unsigned i = 0U; i < PORT_SWITCHED_REGIONS_NUMBER; i++) { + utd.regions[i] = config->mpuregs[i]; + } +#endif + + sbp->tp = chThdCreateUnprivileged(&utd); + + if (sbp->tp == NULL) { + return CH_RET_ENOMEM; + } + + return CH_RET_SUCCESS; +} + +/** + * @brief Registers a file descriptor on a sandbox. + * + * @param[in] sbp pointer to a @p sb_class_t structure + * @param[in] fd file descriptor to be assigned + * @param[in] np VFS node to be registered on the file descriptor + * + * @api + */ +void sbRegisterDescriptor(sb_class_t *sbp, int fd, vfs_node_c *np) { + + chDbgAssert(sb_is_available_descriptor(&sbp->io, fd), "invalid file descriptor"); + + sbp->io.vfs_nodes[fd] = np; +} +#endif + #if (CH_CFG_USE_WAITEXIT == TRUE) || defined(__DOXYGEN__) /** * @brief Blocks the execution of the invoking thread until the specified @@ -330,21 +459,21 @@ bool sbIsThreadRunningX(sb_class_t *sbcp) { * @pre The configuration option @p CH_CFG_USE_WAITEXIT must be enabled in * order to use this function. * - * @param[in] sbcp pointer to a @p sb_class_t structure + * @param[in] sbp pointer to a @p sb_class_t structure * @return The exit code from the terminated sandbox thread. * @retval MSG_RESET Sandbox thread not started. * * @api */ -msg_t sbWaitThread(sb_class_t *sbcp) { +msg_t sbWaitThread(sb_class_t *sbp) { msg_t msg; - if (sbcp->tp == NULL) { + if (sbp->tp == NULL) { return MSG_RESET; } - msg = chThdWait(sbcp->tp); - sbcp->tp = NULL; + msg = chThdWait(sbp->tp); + sbp->tp = NULL; return msg; } @@ -354,7 +483,7 @@ msg_t sbWaitThread(sb_class_t *sbcp) { /** * @brief Sends a message to a sandboxed thread. * - * @param[in] sbcp pointer to the sandbox object + * @param[in] sbp pointer to the sandbox object * @param[in] msg message to be sent * @param[in] timeout the number of ticks before the operation timeouts, * the following special values are allowed: @@ -367,28 +496,28 @@ msg_t sbWaitThread(sb_class_t *sbcp) { * * @api */ -msg_t sbSendMessageTimeout(sb_class_t *sbcp, +msg_t sbSendMessageTimeout(sb_class_t *sbp, msg_t msg, sysinterval_t timeout) { thread_t *ctp = __sch_get_currthread(); - chDbgCheck(sbcp != NULL); + chDbgCheck(sbp != NULL); chSysLock(); /* Sending the message.*/ ctp->u.sentmsg = msg; - __ch_msg_insert(&sbcp->tp->msgqueue, ctp); - if (sbcp->tp->state == CH_STATE_WTMSG) { - (void) chSchReadyI(sbcp->tp); + __ch_msg_insert(&sbp->tp->msgqueue, ctp); + if (sbp->tp->state == CH_STATE_WTMSG) { + (void) chSchReadyI(sbp->tp); } msg = chSchGoSleepTimeoutS(CH_STATE_SNDMSGQ, timeout); /* If a timeout occurred while the boxed thread already received the message then this thread needs to "unregister" as sender, the boxed error will get SB_ERR_EBUSY when/if trying to reply.*/ - if ((msg == MSG_TIMEOUT) && (sbcp->msg_tp == ctp)) { - sbcp->msg_tp = NULL; + if ((msg == MSG_TIMEOUT) && (sbp->msg_tp == ctp)) { + sbp->msg_tp = NULL; } chSysUnlock(); diff --git a/os/sb/host/sbhost.h b/os/sb/host/sbhost.h index ecbfb238c..66753a566 100644 --- a/os/sb/host/sbhost.h +++ b/os/sb/host/sbhost.h @@ -93,21 +93,28 @@ extern "C" { #endif void port_syscall(struct port_extctx *ctxp, uint32_t n); size_t sb_strv_getsize(const char *v[], int *np); - bool sb_is_valid_read_range(sb_class_t *sbcp, const void *start, size_t size); - bool sb_is_valid_write_range(sb_class_t *sbcp, void *start, size_t size); - size_t sb_check_string(sb_class_t *sbcp, const char *s, size_t max); - size_t sb_check_pointers_array(sb_class_t *sbcp, const void *pp[], size_t max); - size_t sb_check_strings_array(sb_class_t *sbcp, const char *pp[], size_t max); - void sbObjectInit(sb_class_t *sbcp, const sb_config_t *config); - thread_t *sbStartThread(sb_class_t *sbcp, const char *name, + void sb_strv_copy(const char *sp[], void *dp, int n); + bool sb_is_valid_read_range(sb_class_t *sbp, const void *start, size_t size); + bool sb_is_valid_write_range(sb_class_t *sbp, void *start, size_t size); + size_t sb_check_string(sb_class_t *sbp, const char *s, size_t max); + size_t sb_check_pointers_array(sb_class_t *sbp, const void *pp[], size_t max); + size_t sb_check_strings_array(sb_class_t *sbp, const char *pp[], size_t max); + void sbObjectInit(sb_class_t *sbp, const sb_config_t *config); + thread_t *sbStartThread(sb_class_t *sbp, const char *name, void *wsp, size_t size, tprio_t prio, const char *argv[], const char *envp[]); - bool sbIsThreadRunningX(sb_class_t *sbcp); + bool sbIsThreadRunningX(sb_class_t *sbp); +#if SB_CFG_ENABLE_VFS == TRUE + msg_t sbExec(sb_class_t *sbp, const char *pathname, + void *wsp, size_t size, tprio_t prio, + const char *argv[], const char *envp[]); + void sbRegisterDescriptor(sb_class_t *sbp, int fd, vfs_node_c *np); +#endif #if CH_CFG_USE_WAITEXIT == TRUE - msg_t sbWaitThread(sb_class_t *sbcp); + msg_t sbWaitThread(sb_class_t *sbp); #endif #if CH_CFG_USE_MESSAGES == TRUE - msg_t sbSendMessageTimeout(sb_class_t *sbcp, + msg_t sbSendMessageTimeout(sb_class_t *sbp, msg_t msg, sysinterval_t timeout); #endif @@ -135,7 +142,7 @@ static inline void sbHostInit(void) { /** * @brief Sends a message to a sandboxed thread. * - * @param[in] sbcp pointer to the sandbox object + * @param[in] sbp pointer to the sandbox object * @param[in] msg message to be sent * @return The returned message. * @retval MSG_RESET if the exchange aborted, sandboxed thread API usage @@ -143,9 +150,9 @@ static inline void sbHostInit(void) { * * @api */ -static inline msg_t sbSendMessage(sb_class_t *sbcp, msg_t msg) { +static inline msg_t sbSendMessage(sb_class_t *sbp, msg_t msg) { - return sbSendMessageTimeout(sbcp, msg, TIME_INFINITE); + return sbSendMessageTimeout(sbp, msg, TIME_INFINITE); } #endif /* CH_CFG_USE_MESSAGES == TRUE */ @@ -153,40 +160,40 @@ static inline msg_t sbSendMessage(sb_class_t *sbcp, msg_t msg) { /** * @brief Adds a set of event flags directly to the specified sandbox. * - * @param[in] sbcp pointer to the sandbox object + * @param[in] sbp pointer to the sandbox object * @param[in] events the events set to be ORed * * @iclass */ -static inline void sbEvtSignalI(sb_class_t *sbcp, eventmask_t events) { +static inline void sbEvtSignalI(sb_class_t *sbp, eventmask_t events) { - chEvtSignalI(sbcp->tp, events); + chEvtSignalI(sbp->tp, events); } /** * @brief Adds a set of event flags directly to the specified sandbox. * - * @param[in] sbcp pointer to the sandbox object + * @param[in] sbp pointer to the sandbox object * @param[in] events the events set to be ORed * * @api */ -static inline void sbEvtSignal(sb_class_t *sbcp, eventmask_t events) { +static inline void sbEvtSignal(sb_class_t *sbp, eventmask_t events) { - chEvtSignal(sbcp->tp, events); + chEvtSignal(sbp->tp, events); } /** * @brief Returns the sandbox event source object. * - * @param[in] sbcp pointer to the sandbox object + * @param[in] sbp pointer to the sandbox object * @return The pointer to the event source object. * * @xclass */ -static inline event_source_t *sbGetEventSourceX(sb_class_t *sbcp) { +static inline event_source_t *sbGetEventSourceX(sb_class_t *sbp) { - return &sbcp->es; + return &sbp->es; } #endif /* CH_CFG_USE_EVENTS == TRUE */ diff --git a/os/sb/host/sbposix.c b/os/sb/host/sbposix.c index a15d00f6f..e08235849 100644 --- a/os/sb/host/sbposix.c +++ b/os/sb/host/sbposix.c @@ -65,22 +65,7 @@ static msg_t create_descriptor(sb_ioblock_t *iop, return CH_RET_EMFILE; } - -static bool is_valid_descriptor(int fd) { - - return (fd >= 0) && (fd < SB_CFG_FD_NUM); -} - -static bool is_available_descriptor(sb_ioblock_t *iop, int fd) { - - return (fd >= 0) && (fd < SB_CFG_FD_NUM) && (iop->vfs_nodes[fd] == NULL); -} - -static bool is_existing_descriptor(sb_ioblock_t *iop, int fd) { - - return (fd >= 0) && (fd < SB_CFG_FD_NUM) && (iop->vfs_nodes[fd] != NULL); -} -#endif +#endif /* SB_CFG_ENABLE_VFS == TRUE */ /*===========================================================================*/ /* Module exported functions. */ @@ -116,7 +101,7 @@ int sb_posix_open(const char *path, int flags) { int sb_posix_close(int fd) { sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p; - if (!is_existing_descriptor(&sbp->io, fd)) { + if (!sb_is_existing_descriptor(&sbp->io, fd)) { return CH_RET_EBADF; } @@ -131,7 +116,7 @@ int sb_posix_dup(int fd) { vfs_node_c *np; msg_t ret; - if (!is_existing_descriptor(&sbp->io, fd)) { + if (!sb_is_existing_descriptor(&sbp->io, fd)) { return CH_RET_EBADF; } @@ -152,11 +137,11 @@ int sb_posix_dup(int fd) { int sb_posix_dup2(int oldfd, int newfd) { sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p; - if (!is_existing_descriptor(&sbp->io, oldfd)) { + if (!sb_is_existing_descriptor(&sbp->io, oldfd)) { return CH_RET_EBADF; } - if (!is_valid_descriptor(oldfd)) { + if (!sb_is_valid_descriptor(oldfd)) { return CH_RET_EBADF; } @@ -182,7 +167,7 @@ int sb_posix_fstat(int fd, struct stat *statbuf) { return CH_RET_EFAULT; } - if (!is_existing_descriptor(&sbp->io, fd)) { + if (!sb_is_existing_descriptor(&sbp->io, fd)) { return CH_RET_EBADF; } @@ -204,7 +189,7 @@ ssize_t sb_posix_read(int fd, void *buf, size_t count) { return CH_RET_EFAULT; } - if (!is_existing_descriptor(&sbp->io, fd)) { + if (!sb_is_existing_descriptor(&sbp->io, fd)) { return CH_RET_EBADF; } @@ -222,7 +207,7 @@ ssize_t sb_posix_write(int fd, const void *buf, size_t count) { return CH_RET_EFAULT; } - if (!is_existing_descriptor(&sbp->io, fd)) { + if (!sb_is_existing_descriptor(&sbp->io, fd)) { return CH_RET_EBADF; } @@ -240,7 +225,7 @@ off_t sb_posix_lseek(int fd, off_t offset, int whence) { return CH_RET_EINVAL; } - if (!is_existing_descriptor(&sbp->io, fd)) { + if (!sb_is_existing_descriptor(&sbp->io, fd)) { return CH_RET_EBADF; } @@ -266,7 +251,7 @@ ssize_t sb_posix_getdents(int fd, void *buf, size_t count) { return (ssize_t)CH_RET_EFAULT; } - if (!is_existing_descriptor(&sbp->io, fd)) { + if (!sb_is_existing_descriptor(&sbp->io, fd)) { return (ssize_t)CH_RET_EBADF; } @@ -307,13 +292,6 @@ ssize_t sb_posix_getdents(int fd, void *buf, size_t count) { 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"); - - sbp->io.vfs_nodes[fd] = np; -} - #else /* Fallbacks for when there is no VFS.*/ uint32_t sb_posix_open(const char *pathname, uint32_t flags) { diff --git a/os/sb/host/sbposix.h b/os/sb/host/sbposix.h index 09169e8fd..4917cc829 100644 --- a/os/sb/host/sbposix.h +++ b/os/sb/host/sbposix.h @@ -68,9 +68,6 @@ extern "C" { 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 sb_posix_getdents(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 #ifdef __cplusplus } #endif @@ -79,6 +76,21 @@ extern "C" { /* Module inline functions. */ /*===========================================================================*/ +static inline bool sb_is_valid_descriptor(int fd) { + + return (fd >= 0) && (fd < SB_CFG_FD_NUM); +} + +static inline bool sb_is_available_descriptor(sb_ioblock_t *iop, int fd) { + + return (fd >= 0) && (fd < SB_CFG_FD_NUM) && (iop->vfs_nodes[fd] == NULL); +} + +static inline bool sb_is_existing_descriptor(sb_ioblock_t *iop, int fd) { + + return (fd >= 0) && (fd < SB_CFG_FD_NUM) && (iop->vfs_nodes[fd] != NULL); +} + #endif /* SBPOSIX_H */ /** @} */