git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15274 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
4b9b255235
commit
c6015620db
|
@ -52,6 +52,7 @@
|
||||||
#define CH_RET_EBADF CH_ENCODE_ERROR(EBADF) /* Bad file number */
|
#define CH_RET_EBADF CH_ENCODE_ERROR(EBADF) /* Bad file number */
|
||||||
#define CH_RET_ENOMEM CH_ENCODE_ERROR(ENOMEM) /* Not enough space */
|
#define CH_RET_ENOMEM CH_ENCODE_ERROR(ENOMEM) /* Not enough space */
|
||||||
#define CH_RET_EACCES CH_ENCODE_ERROR(EACCES) /* Permission denied */
|
#define CH_RET_EACCES CH_ENCODE_ERROR(EACCES) /* Permission denied */
|
||||||
|
#define CH_RET_EFAULT CH_ENCODE_ERROR(EACCES) /* Bad address */
|
||||||
#define CH_RET_EEXIST CH_ENCODE_ERROR(EEXIST) /* File exists */
|
#define CH_RET_EEXIST CH_ENCODE_ERROR(EEXIST) /* File exists */
|
||||||
#define CH_RET_ENOTDIR CH_ENCODE_ERROR(ENOTDIR) /* Not a directory */
|
#define CH_RET_ENOTDIR CH_ENCODE_ERROR(ENOTDIR) /* Not a directory */
|
||||||
#define CH_RET_EISDIR CH_ENCODE_ERROR(EISDIR) /* Is a directory */
|
#define CH_RET_EISDIR CH_ENCODE_ERROR(EISDIR) /* Is a directory */
|
||||||
|
|
|
@ -73,6 +73,9 @@ typedef struct {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
#if CH_CFG_USE_MEMCHECKS == TRUE
|
#if CH_CFG_USE_MEMCHECKS == TRUE
|
||||||
|
bool chMemIsStringWithinX(const memory_area_t *map,
|
||||||
|
const char *s,
|
||||||
|
size_t n);
|
||||||
bool chMemIsAreaContainedX(const memory_area_t areas[],
|
bool chMemIsAreaContainedX(const memory_area_t areas[],
|
||||||
const void *base,
|
const void *base,
|
||||||
size_t size);
|
size_t size);
|
||||||
|
@ -93,10 +96,9 @@ extern "C" {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Memory area check.
|
* @brief Memory area check.
|
||||||
* @details Checks if specified area belongs to the specified area.
|
* @details Checks if specified area belongs to the specified memory area.
|
||||||
*
|
*
|
||||||
* @param[in] map pointer to an array of valid areas terminated with
|
* @param[in] map pointer to a @p memory_area_t structure
|
||||||
* a zero element
|
|
||||||
* @param[in] p pointer to the area to be checked
|
* @param[in] p pointer to the area to be checked
|
||||||
* @param[in] size size of the area to be checked
|
* @param[in] size size of the area to be checked
|
||||||
* @return The test result.
|
* @return The test result.
|
||||||
|
|
|
@ -76,6 +76,39 @@ CC_WEAK memory_area_t __ch_mem_readable_areas[] = {
|
||||||
/* Module exported functions. */
|
/* Module exported functions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief String check.
|
||||||
|
* @details Checks if specified string is entirely contained in the specified
|
||||||
|
* memory area.
|
||||||
|
*
|
||||||
|
* @param[in] map pointer to a @p memory_area_t structure
|
||||||
|
* @param[in] s pointer to the string to be checked
|
||||||
|
* @param[in] n maximum expected size of the string
|
||||||
|
* @return The test result.
|
||||||
|
* @retval false if the string is entirely contained within one of the
|
||||||
|
* specified areas.
|
||||||
|
* @retval true if the string check failed.
|
||||||
|
*
|
||||||
|
* @xclass
|
||||||
|
*/
|
||||||
|
bool chMemIsStringWithinX(const memory_area_t *map, const char *s, size_t n) {
|
||||||
|
const char *base = (const char *)map->base;
|
||||||
|
const char *end = (const char *)base + map->size;
|
||||||
|
|
||||||
|
if (s >= base) {
|
||||||
|
while ((s < end) && (n > 0U)) {
|
||||||
|
if (*s == '\0') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
s++;
|
||||||
|
n--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Memory area check.
|
* @brief Memory area check.
|
||||||
* @details Checks if specified area belongs to one of the specified areas.
|
* @details Checks if specified area belongs to one of the specified areas.
|
||||||
|
|
|
@ -1,97 +0,0 @@
|
||||||
/*
|
|
||||||
ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
|
|
||||||
2015,2016,2017,2018,2019,2020,2021 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file sb/common/sberr.h
|
|
||||||
* @brief ARMv7-M sandbox common macros and structures.
|
|
||||||
*
|
|
||||||
* @addtogroup ARM_SANDBOX_ERRORS
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SBERR_H
|
|
||||||
#define SBERR_H
|
|
||||||
|
|
||||||
/*===========================================================================*/
|
|
||||||
/* Module constants. */
|
|
||||||
/*===========================================================================*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @name Sandbox API error codes
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
#define SB_ERR_NOERROR 0U
|
|
||||||
#define SB_ERR_ENOENT ((uint32_t)(-2))
|
|
||||||
#define SB_ERR_EFAULT ((uint32_t)(-14))
|
|
||||||
#define SB_ERR_EBUSY ((uint32_t)(-16))
|
|
||||||
#define SB_ERR_EINVAL ((uint32_t)(-22))
|
|
||||||
#define SB_ERR_ESPIPE ((uint32_t)(-29))
|
|
||||||
#define SB_ERR_EBADFD ((uint32_t)(-81))
|
|
||||||
#define SB_ERR_ENOSYS ((uint32_t)(-88))
|
|
||||||
|
|
||||||
#define SB_ERR_ERRORMASK 0xFFFFFF00U
|
|
||||||
#define SB_ERR_ISERROR(x) (((uint32_t)(x) & SB_ERR_ERRORMASK) == SB_ERR_ERRORMASK)
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @name Posix-like function codes
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
#define SB_POSIX_OPEN 1
|
|
||||||
#define SB_POSIX_CLOSE 2
|
|
||||||
#define SB_POSIX_READ 3
|
|
||||||
#define SB_POSIX_WRITE 4
|
|
||||||
#define SB_POSIX_LSEEK 5
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/*===========================================================================*/
|
|
||||||
/* Module pre-compile time settings. */
|
|
||||||
/*===========================================================================*/
|
|
||||||
|
|
||||||
/*===========================================================================*/
|
|
||||||
/* Derived constants and error checks. */
|
|
||||||
/*===========================================================================*/
|
|
||||||
|
|
||||||
/*===========================================================================*/
|
|
||||||
/* Module data structures and types. */
|
|
||||||
/*===========================================================================*/
|
|
||||||
|
|
||||||
/*===========================================================================*/
|
|
||||||
/* Module macros. */
|
|
||||||
/*===========================================================================*/
|
|
||||||
|
|
||||||
/*===========================================================================*/
|
|
||||||
/* External declarations. */
|
|
||||||
/*===========================================================================*/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*===========================================================================*/
|
|
||||||
/* Module inline functions. */
|
|
||||||
/*===========================================================================*/
|
|
||||||
|
|
||||||
#endif /* SBERR_H */
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -94,6 +94,10 @@
|
||||||
#error "SB_CFG_ENABLE_VFS not defined in sbconf.h"
|
#error "SB_CFG_ENABLE_VFS not defined in sbconf.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(SB_CFG_FD_NUM) || defined(__DOXYGEN__)
|
||||||
|
#error "SB_CFG_FD_NUM not defined in sbconf.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* License checks.*/
|
/* License checks.*/
|
||||||
#if !defined(CH_CUSTOMER_LIC_SB) || !defined(CH_LICENSE_FEATURES)
|
#if !defined(CH_CUSTOMER_LIC_SB) || !defined(CH_LICENSE_FEATURES)
|
||||||
#error "malformed chlicense.h"
|
#error "malformed chlicense.h"
|
||||||
|
@ -162,10 +166,13 @@ extern "C" {
|
||||||
/* Module inline functions. */
|
/* Module inline functions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
#include "sberr.h"
|
#include "hal.h"
|
||||||
|
#include "errcodes.h"
|
||||||
|
|
||||||
|
#include "sbsysc.h"
|
||||||
#include "sbposix.h"
|
#include "sbposix.h"
|
||||||
#include "sbhost.h"
|
|
||||||
#include "sbapi.h"
|
#include "sbapi.h"
|
||||||
|
#include "sbhost.h"
|
||||||
|
|
||||||
#endif /* SBHOST_H */
|
#endif /* SBHOST_H */
|
||||||
|
|
||||||
|
|
|
@ -915,7 +915,7 @@ const port_syscall_t sb_syscalls[256] = {
|
||||||
|
|
||||||
static void sb_undef_handler(struct port_extctx *ectxp) {
|
static void sb_undef_handler(struct port_extctx *ectxp) {
|
||||||
|
|
||||||
ectxp->r0 = SB_ERR_ENOSYS;
|
ectxp->r0 = CH_RET_ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static thread_t *sb_msg_wait_timeout_s(sysinterval_t timeout) {
|
static thread_t *sb_msg_wait_timeout_s(sysinterval_t timeout) {
|
||||||
|
@ -979,7 +979,7 @@ void sb_api_stdio(struct port_extctx *ectxp) {
|
||||||
ectxp->r3);
|
ectxp->r3);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ectxp->r0 = SB_ERR_ENOSYS;
|
ectxp->r0 = CH_RET_ENOSYS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -994,7 +994,7 @@ void sb_api_exit(struct port_extctx *ectxp) {
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
|
|
||||||
/* Cannot get here.*/
|
/* Cannot get here.*/
|
||||||
ectxp->r0 = SB_ERR_ENOSYS;
|
ectxp->r0 = CH_RET_ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sb_api_get_systime(struct port_extctx *ectxp) {
|
void sb_api_get_systime(struct port_extctx *ectxp) {
|
||||||
|
@ -1014,14 +1014,14 @@ void sb_api_sleep(struct port_extctx *ectxp) {
|
||||||
chThdSleep(interval);
|
chThdSleep(interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
ectxp->r0 = SB_ERR_NOERROR;
|
ectxp->r0 = CH_RET_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sb_api_sleep_until_windowed(struct port_extctx *ectxp) {
|
void sb_api_sleep_until_windowed(struct port_extctx *ectxp) {
|
||||||
|
|
||||||
chThdSleepUntilWindowed((systime_t )ectxp->r0, (systime_t )ectxp->r1);
|
chThdSleepUntilWindowed((systime_t )ectxp->r0, (systime_t )ectxp->r1);
|
||||||
|
|
||||||
ectxp->r0 = SB_ERR_NOERROR;
|
ectxp->r0 = CH_RET_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sb_api_wait_message(struct port_extctx *ectxp) {
|
void sb_api_wait_message(struct port_extctx *ectxp) {
|
||||||
|
@ -1038,12 +1038,12 @@ void sb_api_wait_message(struct port_extctx *ectxp) {
|
||||||
thread_t *tp = sbcp->msg_tp;
|
thread_t *tp = sbcp->msg_tp;
|
||||||
sbcp->msg_tp = NULL;
|
sbcp->msg_tp = NULL;
|
||||||
chMsgReleaseS(tp, MSG_RESET);
|
chMsgReleaseS(tp, MSG_RESET);
|
||||||
ectxp->r0 = SB_ERR_EBUSY;
|
ectxp->r0 = MSG_RESET;
|
||||||
}
|
}
|
||||||
|
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
#else
|
#else
|
||||||
ectxp->r0 = SB_ERR_NOT_IMPLEMENTED;
|
ectxp->r0 = CH_RET_ENOSYS;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1057,15 +1057,15 @@ void sb_api_reply_message(struct port_extctx *ectxp) {
|
||||||
thread_t *tp = sbcp->msg_tp;
|
thread_t *tp = sbcp->msg_tp;
|
||||||
sbcp->msg_tp = NULL;
|
sbcp->msg_tp = NULL;
|
||||||
chMsgReleaseS(tp, (msg_t )ectxp->r0);
|
chMsgReleaseS(tp, (msg_t )ectxp->r0);
|
||||||
ectxp->r0 = SB_ERR_NOERROR;
|
ectxp->r0 = CH_RET_SUCCESS;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ectxp->r0 = SB_ERR_EBUSY;
|
ectxp->r0 = MSG_RESET;
|
||||||
}
|
}
|
||||||
|
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
#else
|
#else
|
||||||
ectxp->r0 = SB_ERR_NOT_IMPLEMENTED;
|
ectxp->r0 = CH_RET_ENOSYS;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1075,7 +1075,7 @@ void sb_api_wait_one_timeout(struct port_extctx *ectxp) {
|
||||||
ectxp->r0 = (uint32_t)chEvtWaitOneTimeout((eventmask_t )ectxp->r0,
|
ectxp->r0 = (uint32_t)chEvtWaitOneTimeout((eventmask_t )ectxp->r0,
|
||||||
(sysinterval_t )ectxp->r1);
|
(sysinterval_t )ectxp->r1);
|
||||||
#else
|
#else
|
||||||
ectxp->r0 = SB_ERR_NOT_IMPLEMENTED;
|
ectxp->r0 = CH_RET_ENOSYS;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1085,7 +1085,7 @@ void sb_api_wait_any_timeout(struct port_extctx *ectxp) {
|
||||||
ectxp->r0 = (uint32_t)chEvtWaitAnyTimeout((eventmask_t )ectxp->r0,
|
ectxp->r0 = (uint32_t)chEvtWaitAnyTimeout((eventmask_t )ectxp->r0,
|
||||||
(sysinterval_t )ectxp->r1);
|
(sysinterval_t )ectxp->r1);
|
||||||
#else
|
#else
|
||||||
ectxp->r0 = SB_ERR_NOT_IMPLEMENTED;
|
ectxp->r0 = CH_RET_ENOSYS;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1095,7 +1095,7 @@ void sb_api_wait_all_timeout(struct port_extctx *ectxp) {
|
||||||
ectxp->r0 = (uint32_t)chEvtWaitAllTimeout((eventmask_t )ectxp->r0,
|
ectxp->r0 = (uint32_t)chEvtWaitAllTimeout((eventmask_t )ectxp->r0,
|
||||||
(sysinterval_t )ectxp->r1);
|
(sysinterval_t )ectxp->r1);
|
||||||
#else
|
#else
|
||||||
ectxp->r0 = SB_ERR_NOT_IMPLEMENTED;
|
ectxp->r0 = CH_RET_ENOSYS;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1104,9 +1104,9 @@ void sb_api_broadcast_flags(struct port_extctx *ectxp) {
|
||||||
sb_class_t *sbcp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p;
|
sb_class_t *sbcp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p;
|
||||||
|
|
||||||
chEvtBroadcastFlags(&sbcp->es, (eventflags_t )ectxp->r0);
|
chEvtBroadcastFlags(&sbcp->es, (eventflags_t )ectxp->r0);
|
||||||
ectxp->r0 = SB_ERR_NOERROR;
|
ectxp->r0 = CH_RET_SUCCESS;
|
||||||
#else
|
#else
|
||||||
ectxp->r0 = SB_ERR_NOT_IMPLEMENTED;
|
ectxp->r0 = CH_RET_ENOSYS;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ 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];
|
const sb_memory_region_t *rp = &sbcp->config->regions[0];
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (chMemIsAreaContainedX(&rp->area, start, size)) {
|
if (chMemIsAreaWithinX(&rp->area, start, size)) {
|
||||||
return rp->writeable;
|
return rp->writeable;
|
||||||
}
|
}
|
||||||
rp++;
|
rp++;
|
||||||
|
@ -83,6 +83,19 @@ bool sb_is_valid_write_range(sb_class_t *sbcp, void *start, size_t size) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool sb_is_valid_string_range(sb_class_t *sbcp, const char *s, size_t n) {
|
||||||
|
const sb_memory_region_t *rp = &sbcp->config->regions[0];
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (chMemIsAreaWithinX(&rp->area, s, n)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
rp++;
|
||||||
|
} while (rp < &sbcp->config->regions[SB_CFG_NUM_REGIONS]);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sandbox object initialization.
|
* @brief Sandbox object initialization.
|
||||||
*
|
*
|
||||||
|
|
|
@ -28,9 +28,6 @@
|
||||||
#ifndef SBHOST_H
|
#ifndef SBHOST_H
|
||||||
#define SBHOST_H
|
#define SBHOST_H
|
||||||
|
|
||||||
#include "sberr.h"
|
|
||||||
#include "sbapi.h"
|
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Module constants. */
|
/* Module constants. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -151,8 +148,17 @@ typedef struct {
|
||||||
thread_t *msg_tp;
|
thread_t *msg_tp;
|
||||||
#endif
|
#endif
|
||||||
#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
|
#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief Sandbox events source.
|
||||||
|
*/
|
||||||
event_source_t es;
|
event_source_t es;
|
||||||
#endif
|
#endif
|
||||||
|
#if (SB_CFG_ENABLE_VFS == TRUE) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief VFS bindings for Posix API.
|
||||||
|
*/
|
||||||
|
sb_ioblock_t io;
|
||||||
|
#endif
|
||||||
} sb_class_t;
|
} sb_class_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -193,6 +199,7 @@ extern "C" {
|
||||||
void port_syscall(struct port_extctx *ctxp, uint32_t n);
|
void port_syscall(struct port_extctx *ctxp, uint32_t n);
|
||||||
bool sb_is_valid_read_range(sb_class_t *sbcp, const void *start, size_t size);
|
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);
|
bool sb_is_valid_write_range(sb_class_t *sbcp, void *start, size_t size);
|
||||||
|
bool sb_is_valid_string_range(sb_class_t *sbcp, const char *s, size_t n);
|
||||||
void sbObjectInit(sb_class_t *sbcp);
|
void sbObjectInit(sb_class_t *sbcp);
|
||||||
void sbStart(sb_class_t *sbcp, const sb_config_t *config);
|
void sbStart(sb_class_t *sbcp, const sb_config_t *config);
|
||||||
thread_t *sbStartThread(sb_class_t *sbcp, const sb_config_t *config,
|
thread_t *sbStartThread(sb_class_t *sbcp, const sb_config_t *config,
|
||||||
|
|
|
@ -48,10 +48,127 @@
|
||||||
/* Module local functions. */
|
/* Module local functions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
static msg_t create_descriptor(sb_ioblock_t *iop,
|
||||||
|
vfs_node_c *np,
|
||||||
|
uint8_t attributes) {
|
||||||
|
unsigned fd;
|
||||||
|
|
||||||
|
for (fd = 0U; fd < SB_CFG_FD_NUM; fd++) {
|
||||||
|
if (iop->vfs_nodes[fd] == NULL) {
|
||||||
|
iop->vfs_nodes[fd] = np;
|
||||||
|
iop->attributes[fd] = attributes;
|
||||||
|
|
||||||
|
return (msg_t)fd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return CH_RET_EMFILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_valid_descriptor(sb_ioblock_t *iop, int fd) {
|
||||||
|
|
||||||
|
return (fd >= 0) && (fd < SB_CFG_FD_NUM) && (iop->vfs_nodes[fd] != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Module exported functions. */
|
/* Module exported functions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#if (SB_CFG_ENABLE_VFS == TRUE) || defined(__DOXYGEN__)
|
||||||
|
int sb_posix_open(const char *path, int flags) {
|
||||||
|
sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p;
|
||||||
|
vfs_file_node_c *fnp = NULL;
|
||||||
|
msg_t ret;
|
||||||
|
|
||||||
|
if (!sb_is_valid_string_range(sbp, (void *)path, VFS_CFG_PATHLEN_MAX)) {
|
||||||
|
return CH_RET_EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
ret = vfsDrvOpenFile(sbp->io.vfs_driver, path, (unsigned)flags, &fnp);
|
||||||
|
CH_BREAK_ON_ERROR(ret);
|
||||||
|
|
||||||
|
ret = create_descriptor(&sbp->io, (vfs_node_c *)fnp, 0);
|
||||||
|
CH_BREAK_ON_ERROR(ret);
|
||||||
|
|
||||||
|
return (int)ret;
|
||||||
|
} while (true);
|
||||||
|
|
||||||
|
if (fnp != NULL) {
|
||||||
|
vfsCloseFile(fnp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int)ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sb_posix_close(int fd) {
|
||||||
|
sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p;
|
||||||
|
|
||||||
|
if (!is_valid_descriptor(&sbp->io, fd)) {
|
||||||
|
return CH_RET_EBADF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sbp->io.attributes[fd] == 0) {
|
||||||
|
vfsCloseFile((vfs_file_node_c *)sbp->io.vfs_nodes[fd]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
vfsCloseDirectory((vfs_directory_node_c *)sbp->io.vfs_nodes[fd]);
|
||||||
|
}
|
||||||
|
sbp->io.vfs_nodes[fd] = NULL;
|
||||||
|
|
||||||
|
return CH_RET_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
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_read_range(sbp, (void *)buf, count)) {
|
||||||
|
return CH_RET_EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_valid_descriptor(&sbp->io, fd)) {
|
||||||
|
return CH_RET_EBADF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sbp->io.attributes[fd] != 0) {
|
||||||
|
return CH_RET_EISDIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return vfsReadFile((vfs_file_node_c *)sbp->io.vfs_nodes[fd], buf, 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_write_range(sbp, (void *)buf, count)) {
|
||||||
|
return CH_RET_EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_valid_descriptor(&sbp->io, fd)) {
|
||||||
|
return CH_RET_EBADF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sbp->io.attributes[fd] != 0) {
|
||||||
|
return CH_RET_EISDIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return vfsWriteFile((vfs_file_node_c *)sbp->io.vfs_nodes[fd], buf, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t sb_posix_lseek(int fd, off_t offset, int whence) {
|
||||||
|
|
||||||
|
(void)offset;
|
||||||
|
(void)whence;
|
||||||
|
|
||||||
|
if ((fd == 0U) || (fd == 1U) || (fd == 2U)) {
|
||||||
|
|
||||||
|
return CH_RET_ESPIPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CH_RET_EBADF;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* Fallbacks for when there is no VFS.*/
|
||||||
uint32_t sb_posix_open(const char *pathname, uint32_t flags) {
|
uint32_t sb_posix_open(const char *pathname, uint32_t flags) {
|
||||||
|
|
||||||
(void)pathname;
|
(void)pathname;
|
||||||
|
@ -132,5 +249,6 @@ uint32_t sb_posix_lseek(uint32_t fd, uint32_t offset, uint32_t whence) {
|
||||||
|
|
||||||
return SB_ERR_EBADFD;
|
return SB_ERR_EBADFD;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
|
@ -28,6 +28,10 @@
|
||||||
#ifndef SBPOSIX_H
|
#ifndef SBPOSIX_H
|
||||||
#define SBPOSIX_H
|
#define SBPOSIX_H
|
||||||
|
|
||||||
|
#if (SB_CFG_ENABLE_VFS == TRUE) || defined(__DOXYGEN__)
|
||||||
|
#include "vfs.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Module constants. */
|
/* Module constants. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -44,6 +48,26 @@
|
||||||
/* Module data structures and types. */
|
/* Module data structures and types. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#if (SB_CFG_ENABLE_VFS == TRUE) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief Type of a sandbox I/O structure.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/**
|
||||||
|
* @brief VFS driver associated to the sandbox as root.
|
||||||
|
*/
|
||||||
|
vfs_driver_c *vfs_driver;
|
||||||
|
/**
|
||||||
|
* @brief VFS nodes associated to file descriptors.
|
||||||
|
*/
|
||||||
|
vfs_node_c *vfs_nodes[SB_CFG_FD_NUM];
|
||||||
|
/**
|
||||||
|
* @brief Extra attributes added to the VFS nodes.
|
||||||
|
*/
|
||||||
|
uint8_t attributes[SB_CFG_FD_NUM];
|
||||||
|
} sb_ioblock_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Module macros. */
|
/* Module macros. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -55,11 +79,11 @@
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
uint32_t sb_posix_open(const char *pathname, uint32_t flags);
|
int sb_posix_open(const char *path, int flags);
|
||||||
uint32_t sb_posix_close(uint32_t fd);
|
int sb_posix_close(int fd);
|
||||||
uint32_t sb_posix_read(uint32_t fd, uint8_t *buf, size_t count);
|
ssize_t sb_posix_read(int fd, void *buf, size_t count);
|
||||||
uint32_t sb_posix_write(uint32_t fd, const uint8_t *buf, size_t count);
|
ssize_t sb_posix_write(int fd, const void *buf, size_t count);
|
||||||
uint32_t sb_posix_lseek(uint32_t fd, uint32_t offset, uint32_t whence);
|
off_t sb_posix_lseek(int fd, off_t offset, int whence);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue