SB-VFS integration working in the demo.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15280 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2021-12-29 16:00:10 +00:00
parent aac3849aa4
commit 6751fc38ee
9 changed files with 380 additions and 203 deletions

View File

@ -22,8 +22,42 @@
#include "rt_test_root.h"
#include "oslib_test_root.h"
#include "nullstreams.h"
#include "startup_defs.h"
/*===========================================================================*/
/* VFS-related. */
/*===========================================================================*/
#if VFS_CFG_ENABLE_DRV_FATFS == TRUE
/* VFS FatFS driver object representing the root directory.*/
static vfs_fatfs_driver_c root_driver;
#endif
/* VFS overlay driver object representing the root directory.*/
static vfs_overlay_driver_c root_overlay_driver;
/* VFS streams driver object representing the /dev directory.*/
static vfs_streams_driver_c dev_driver;
/* VFS API will use this object as implicit root, defining this
symbol is expected.*/
vfs_driver_c *vfs_root = (vfs_driver_c *)&root_overlay_driver;
static NullStream nullstream;
/* Stream to be exposed under /dev as files.*/
static const drv_streams_element_t streams[] = {
{"VSD1", (BaseSequentialStream *)&LPSD1},
{"null", (BaseSequentialStream *)&nullstream},
{NULL, NULL}
};
/*===========================================================================*/
/* SB-related. */
/*===========================================================================*/
/* Sandbox 1 configuration.*/
static const sb_config_t sb_config1 = {
.code_region = 0U,
@ -52,9 +86,6 @@ static const sb_config_t sb_config1 = {
MPU_RASR_ENABLE
}
},
.stdin_stream = (SandboxStream *)&LPSD1,
.stdout_stream = (SandboxStream *)&LPSD1,
.stderr_stream = (SandboxStream *)&LPSD1
};
/* Sandbox 2 configuration.*/
@ -85,16 +116,17 @@ static const sb_config_t sb_config2 = {
MPU_RASR_ENABLE
}
},
.stdin_stream = (SandboxStream *)&LPSD1,
.stdout_stream = (SandboxStream *)&LPSD1,
.stderr_stream = (SandboxStream *)&LPSD1
};
/* Sandbox objects.*/
sb_class_t sbx1, sbx2;
static THD_WORKING_AREA(waUnprivileged1, 256);
static THD_WORKING_AREA(waUnprivileged2, 256);
static THD_WORKING_AREA(waUnprivileged1, 512);
static THD_WORKING_AREA(waUnprivileged2, 512);
/*===========================================================================*/
/* Main and generic code. */
/*===========================================================================*/
/*
* Green LED blinker thread, times are in milliseconds.
@ -118,6 +150,8 @@ int main(void) {
unsigned i = 1U;
thread_t *utp1, *utp2;
event_listener_t el1;
vfs_file_node_c *fnp;
msg_t ret;
/*
* System initializations.
@ -125,29 +159,61 @@ int main(void) {
* and performs the board-specific initializations.
* - Kernel initialization, the main() function becomes a thread and the
* RTOS is active.
* - Virtual File System initialization.
* - SandBox manager initialization.
*/
halInit();
chSysInit();
vfsInit();
sbHostInit();
/*
* Listening to sandbox events.
*/
chEvtRegister(&sb.termination_es, &el1, (eventid_t)0);
/*
* Activates the Serial driver using the default configuration.
* Starting a serial port for I/O, initializing other streams too.
*/
sdStart(&LPSD1, NULL);
nullObjectInit(&nullstream);
/*
* Creates the blinker thread.
* Creating a blinker thread.
*/
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO+10, Thread1, NULL);
/*
* Initializing an overlay VFS object as a root, no overlaid driver,
* registering a streams VFS driver on the VFS overlay root as "/dev".
*/
drvOverlayObjectInit(&root_overlay_driver, NULL, NULL);
ret = drvOverlayRegisterDriver(&root_overlay_driver,
drvStreamsObjectInit(&dev_driver, &streams[0]),
"dev");
if (CH_RET_IS_ERROR(ret)) {
chSysHalt("VFS");
}
/*
* Sandbox objects initialization.
*/
sbObjectInit(&sbx1, &sb_config1);
sbObjectInit(&sbx2, &sb_config2);
/*
* Associating standard input, output and error to sandboxes. Both sandboxes
* use the same serial port in this setup.
*/
ret = vfsOpenFile("/dev/VSD1", 0, &fnp);
if (CH_RET_IS_ERROR(ret)) {
chSysHalt("VFS");
}
sbPosixRegisterFileDescriptor(&sbx1, STDIN_FILENO, (vfs_file_node_c *)roAddRef(fnp));
sbPosixRegisterFileDescriptor(&sbx1, STDOUT_FILENO, (vfs_file_node_c *)roAddRef(fnp));
sbPosixRegisterFileDescriptor(&sbx1, STDERR_FILENO, (vfs_file_node_c *)roAddRef(fnp));
sbPosixRegisterFileDescriptor(&sbx2, STDIN_FILENO, (vfs_file_node_c *)roAddRef(fnp));
sbPosixRegisterFileDescriptor(&sbx2, STDOUT_FILENO, (vfs_file_node_c *)roAddRef(fnp));
sbPosixRegisterFileDescriptor(&sbx2, STDERR_FILENO, (vfs_file_node_c *)roAddRef(fnp));
vfsCloseFile(fnp);
/* Starting sandboxed thread 1.*/
utp1 = sbStartThread(&sbx1, &sb_config1, "sbx1",
utp1 = sbStartThread(&sbx1, "sbx1",
waUnprivileged1, sizeof (waUnprivileged1),
NORMALPRIO - 1);
if (utp1 == NULL) {
@ -155,7 +221,7 @@ int main(void) {
}
/* Starting sandboxed thread 2.*/
utp2 = sbStartThread(&sbx2, &sb_config2, "sbx2",
utp2 = sbStartThread(&sbx2, "sbx2",
waUnprivileged2, sizeof (waUnprivileged2),
NORMALPRIO - 1);
if (utp1 == NULL) {
@ -163,7 +229,12 @@ int main(void) {
}
/*
* Normal main() thread activity, in this demo it monitos the user button
* Listening to sandbox events.
*/
chEvtRegister(&sb.termination_es, &el1, (eventid_t)0);
/*
* Normal main() thread activity, in this demo it monitors the user button
* and checks for sandboxes state.
*/
while (true) {
@ -199,4 +270,3 @@ int main(void) {
i++;
}
}

View File

@ -22,8 +22,42 @@
#include "rt_test_root.h"
#include "oslib_test_root.h"
#include "nullstreams.h"
#include "startup_defs.h"
/*===========================================================================*/
/* VFS-related. */
/*===========================================================================*/
#if VFS_CFG_ENABLE_DRV_FATFS == TRUE
/* VFS FatFS driver object representing the root directory.*/
static vfs_fatfs_driver_c root_driver;
#endif
/* VFS overlay driver object representing the root directory.*/
static vfs_overlay_driver_c root_overlay_driver;
/* VFS streams driver object representing the /dev directory.*/
static vfs_streams_driver_c dev_driver;
/* VFS API will use this object as implicit root, defining this
symbol is expected.*/
vfs_driver_c *vfs_root = (vfs_driver_c *)&root_overlay_driver;
static NullStream nullstream;
/* Stream to be exposed under /dev as files.*/
static const drv_streams_element_t streams[] = {
{"VSD1", (BaseSequentialStream *)&LPSD1},
{"null", (BaseSequentialStream *)&nullstream},
{NULL, NULL}
};
/*===========================================================================*/
/* SB-related. */
/*===========================================================================*/
/* Sandbox 1 configuration.*/
static const sb_config_t sb_config1 = {
.code_region = 0U,
@ -38,9 +72,7 @@ static const sb_config_t sb_config1 = {
.writeable = true
}
},
.stdin_stream = (SandboxStream *)&LPSD1,
.stdout_stream = (SandboxStream *)&LPSD1,
.stderr_stream = (SandboxStream *)&LPSD1
.vfs_driver = (vfs_driver_c *)&root_overlay_driver
};
/* Sandbox 2 configuration.*/
@ -57,16 +89,18 @@ static const sb_config_t sb_config2 = {
.writeable = true
}
},
.stdin_stream = (SandboxStream *)&LPSD1,
.stdout_stream = (SandboxStream *)&LPSD1,
.stderr_stream = (SandboxStream *)&LPSD1
.vfs_driver = (vfs_driver_c *)&root_overlay_driver
};
/* Sandbox objects.*/
sb_class_t sbx1, sbx2;
static THD_WORKING_AREA(waUnprivileged1, 256);
static THD_WORKING_AREA(waUnprivileged2, 256);
static THD_WORKING_AREA(waUnprivileged1, 512);
static THD_WORKING_AREA(waUnprivileged2, 512);
/*===========================================================================*/
/* Main and generic code. */
/*===========================================================================*/
/*
* Green LED blinker thread, times are in milliseconds.
@ -90,6 +124,8 @@ int main(void) {
unsigned i = 1U;
thread_t *utp1, *utp2;
event_listener_t el1;
vfs_file_node_c *fnp;
msg_t ret;
/*
* System initializations.
@ -97,27 +133,59 @@ int main(void) {
* and performs the board-specific initializations.
* - Kernel initialization, the main() function becomes a thread and the
* RTOS is active.
* - Virtual File System initialization.
* - SandBox manager initialization.
*/
halInit();
chSysInit();
vfsInit();
sbHostInit();
/*
* Listening to sandbox events.
*/
chEvtRegister(&sb.termination_es, &el1, (eventid_t)0);
/*
* Activates the Serial driver using the default configuration.
* Starting a serial port for I/O, initializing other streams too.
*/
sdStart(&LPSD1, NULL);
nullObjectInit(&nullstream);
/*
* Creates the blinker thread.
* Creating a blinker thread.
*/
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO+10, Thread1, NULL);
/*
* Initializing an overlay VFS object as a root, no overlaid driver,
* registering a streams VFS driver on the VFS overlay root as "/dev".
*/
drvOverlayObjectInit(&root_overlay_driver, NULL, NULL);
ret = drvOverlayRegisterDriver(&root_overlay_driver,
drvStreamsObjectInit(&dev_driver, &streams[0]),
"dev");
if (CH_RET_IS_ERROR(ret)) {
chSysHalt("VFS");
}
/*
* Sandbox objects initialization.
*/
sbObjectInit(&sbx1, &sb_config1);
sbObjectInit(&sbx2, &sb_config2);
/*
* Associating standard input, output and error to sandboxes. Both sandboxes
* use the same serial port in this setup.
*/
ret = vfsOpenFile("/dev/VSD1", 0, &fnp);
if (CH_RET_IS_ERROR(ret)) {
chSysHalt("VFS");
}
sbPosixRegisterFileDescriptor(&sbx1, STDIN_FILENO, (vfs_file_node_c *)roAddRef(fnp));
sbPosixRegisterFileDescriptor(&sbx1, STDOUT_FILENO, (vfs_file_node_c *)roAddRef(fnp));
sbPosixRegisterFileDescriptor(&sbx1, STDERR_FILENO, (vfs_file_node_c *)roAddRef(fnp));
sbPosixRegisterFileDescriptor(&sbx2, STDIN_FILENO, (vfs_file_node_c *)roAddRef(fnp));
sbPosixRegisterFileDescriptor(&sbx2, STDOUT_FILENO, (vfs_file_node_c *)roAddRef(fnp));
sbPosixRegisterFileDescriptor(&sbx2, STDERR_FILENO, (vfs_file_node_c *)roAddRef(fnp));
vfsCloseFile(fnp);
/*
* Creating **static** boxes using MPU.
* Note: The two regions cover both sandbox 1 and 2, there is no
@ -137,7 +205,7 @@ int main(void) {
MPU_RASR_ENABLE);
/* Starting sandboxed thread 1.*/
utp1 = sbStartThread(&sbx1, &sb_config1, "sbx1",
utp1 = sbStartThread(&sbx1, "sbx1",
waUnprivileged1, sizeof (waUnprivileged1),
NORMALPRIO - 1);
if (utp1 == NULL) {
@ -145,7 +213,7 @@ int main(void) {
}
/* Starting sandboxed thread 2.*/
utp2 = sbStartThread(&sbx2, &sb_config2, "sbx2",
utp2 = sbStartThread(&sbx2, "sbx2",
waUnprivileged2, sizeof (waUnprivileged2),
NORMALPRIO - 1);
if (utp1 == NULL) {
@ -153,7 +221,12 @@ int main(void) {
}
/*
* Normal main() thread activity, in this demo it monitos the user button
* Listening to sandbox events.
*/
chEvtRegister(&sb.termination_es, &el1, (eventid_t)0);
/*
* Normal main() thread activity, in this demo it monitors the user button
* and checks for sandboxes state.
*/
while (true) {
@ -189,4 +262,3 @@ int main(void) {
i++;
}
}

View File

@ -153,24 +153,26 @@ static inline void __referenced_object_release_impl(void *ip) {
/**
* @brief New reference creation.
*
* @param[in] rop A reference to the object.
* @param[in] ip A reference to the object.
* @return A new reference to the object.
*/
CC_FORCE_INLINE
static inline referenced_object_c *roAddRef(referenced_object_c *rop) {
static inline referenced_object_c *roAddRef(void *ip) {
referenced_object_c *objp = (referenced_object_c *)ip;
return (referenced_object_c *)rop->vmt->addref((void *)rop);
return objp->vmt->addref(ip);
}
/**
* @brief Reference release.
*
* @param[in] rop A reference to the object.
* @param[in] ip A reference to the object.
*/
CC_FORCE_INLINE
static inline void roRelease(referenced_object_c *rop) {
static inline void roRelease(void *ip) {
referenced_object_c *objp = (referenced_object_c *)ip;
return rop->vmt->release((void *)rop);
return objp->vmt->release(ip);
}
#endif /* OOP_REFERENCED_OBJECT_H */

View File

@ -28,6 +28,10 @@
#ifndef SB_H
#define SB_H
#include "hal.h"
#include "vfs.h"
#include "errcodes.h"
/*===========================================================================*/
/* Module constants. */
/*===========================================================================*/
@ -146,6 +150,138 @@
/* Module data structures and types. */
/*===========================================================================*/
/**
* @brief Type of a sandbox manager global structure.
*/
typedef struct {
#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
/**
* @brief Event source for sandbox termination.
*/
event_source_t termination_es;
#endif
} sb_t;
/**
* @brief Type of a sandbox memory region.
*/
typedef struct {
/**
* @brief Associated memory area.
*/
memory_area_t area;
/**
* @brief Writable memory range.
*/
bool writeable;
} sb_memory_region_t;
#if (SB_CFG_ENABLE_VFS == TRUE) || defined(__DOXYGEN__)
/**
* @brief Type of a sandbox I/O structure.
*/
typedef struct {
/**
* @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
/**
* @brief Type of a sandbox configuration structure.
*/
typedef struct {
/**
* @brief Memory region for code.
* @note It is used to locate the startup header.
*/
uint32_t code_region;
/**
* @brief Memory region for data and stack.
* @note It is used for initial PSP placement.
*/
uint32_t data_region;
/**
* @brief SandBox regions.
* @note The following memory regions are used only for pointers
* validation, not for MPU setup.
*/
sb_memory_region_t regions[SB_CFG_NUM_REGIONS];
#if (PORT_SWITCHED_REGIONS_NUMBER == SB_CFG_NUM_REGIONS) || defined(__DOXYGEN__)
/**
* @brief MPU regions initialization values.
* @note Regions initialization values must be chosen to be
* consistent with the values in the "regions" field.
*/
mpureg_t mpuregs[SB_CFG_NUM_REGIONS];
#endif
#if (SB_CFG_ENABLE_VFS == TRUE) || defined(__DOXYGEN__)
/**
* @brief VFS driver associated to the sandbox as root.
*/
vfs_driver_c *vfs_driver;
#else
/**
* @brief Sandbox STDIN stream.
* @note Set this to @p NULL if standard I/O is not needed.
* @note By design you can use HAL streams here, you need to use
* a cast however.
*/
SandboxStream *stdin_stream;
/**
* @brief Sandbox STDOUT stream.
* @note Set this to @p NULL if standard I/O is not needed.
* @note By design you can use HAL streams here, you need to use
* a cast however.
*/
SandboxStream *stdout_stream;
/**
* @brief Sandbox STDERR stream.
* @note Set this to @p NULL if standard I/O is not needed.
* @note By design you can use HAL streams here, you need to use
* a cast however.
*/
SandboxStream *stderr_stream;
#endif
} sb_config_t;
/**
* @brief Type of a sandbox object.
*/
typedef struct {
/**
* @brief Pointer to the sandbox configuration data.
*/
const sb_config_t *config;
/**
* @brief Thread running in the sandbox.
*/
thread_t *tp;
#if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__)
/**
* @brief Thread sending a message to the sandbox.
*/
thread_t *msg_tp;
#endif
#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
/**
* @brief Sandbox events source.
*/
event_source_t es;
#endif
#if (SB_CFG_ENABLE_VFS == TRUE) || defined(__DOXYGEN__)
/**
* @brief VFS bindings for Posix API.
*/
sb_ioblock_t io;
#endif
} sb_class_t;
/*===========================================================================*/
/* Module macros. */
/*===========================================================================*/
@ -166,9 +302,6 @@ extern "C" {
/* Module inline functions. */
/*===========================================================================*/
#include "hal.h"
#include "errcodes.h"
#include "sbsysc.h"
#include "sbposix.h"
#include "sbapi.h"

View File

@ -100,12 +100,13 @@ bool sb_is_valid_string_range(sb_class_t *sbcp, const char *s, size_t n) {
* @brief Sandbox object initialization.
*
* @param[out] sbcp pointer to the sandbox object
* @param[in] config pointer to the sandbox configuration
*
* @init
*/
void sbObjectInit(sb_class_t *sbcp) {
void sbObjectInit(sb_class_t *sbcp, const sb_config_t *config) {
sbcp->config = NULL;
sbcp->config = config;
sbcp->tp = NULL;
#if CH_CFG_USE_MESSAGES == TRUE
sbcp->msg_tp = NULL;
@ -118,16 +119,20 @@ void sbObjectInit(sb_class_t *sbcp) {
/**
* @brief Starts a sandboxed thread.
*
* @param[out] sbcp pointer to the sandbox object
* @param[in] config pointer to the sandbox configuration
* @param[in] sbcp 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
* @param[in] prio the priority level for the new thread
* @return The thread pointer.
* @retval NULL if the sandbox thread creation failed.
*/
thread_t *sbStartThread(sb_class_t *sbcp, const sb_config_t *config,
const char *name, void *wsp, size_t size,
thread_t *sbStartThread(sb_class_t *sbcp, const char *name,
void *wsp, size_t size,
tprio_t prio) {
thread_t *utp;
const sb_header_t *sbhp;
const sb_config_t *config = sbcp->config;
/* Header location.*/
sbhp = (const sb_header_t *)(void *)config->regions[config->code_region].area.base;
@ -142,9 +147,6 @@ thread_t *sbStartThread(sb_class_t *sbcp, const sb_config_t *config,
return NULL;
}
/* Linking configuration information.*/
sbcp->config = config;
unprivileged_thread_descriptor_t utd = {
.name = name,
.wbase = (stkalign_t *)wsp,
@ -166,12 +168,6 @@ thread_t *sbStartThread(sb_class_t *sbcp, const sb_config_t *config,
/* For messages exchange.*/
sbcp->tp = utp;
#if CH_CFG_USE_MESSAGES == TRUE
sbcp->msg_tp = NULL;
#endif
#if CH_CFG_USE_EVENTS == TRUE
chEvtObjectInit(&sbcp->es);
#endif
return utp;
}

View File

@ -52,115 +52,6 @@
/* Module data structures and types. */
/*===========================================================================*/
/**
* @brief Type of a sandbox manager global structure.
*/
typedef struct {
#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
/**
* @brief Event source for sandbox termination.
*/
event_source_t termination_es;
#endif
} sb_t;
/**
* @brief Type of a sandbox memory region.
*/
typedef struct {
/**
* @brief Associated memory area.
*/
memory_area_t area;
/**
* @brief Writable memory range.
*/
bool writeable;
} sb_memory_region_t;
/**
* @brief Type of a sandbox configuration structure.
*/
typedef struct {
/**
* @brief Memory region for code.
* @note It is used to locate the startup header.
*/
uint32_t code_region;
/**
* @brief Memory region for data and stack.
* @note It is used for initial PSP placement.
*/
uint32_t data_region;
/**
* @brief SandBox regions.
* @note The following memory regions are used only for pointers
* validation, not for MPU setup.
*/
sb_memory_region_t regions[SB_CFG_NUM_REGIONS];
#if (PORT_SWITCHED_REGIONS_NUMBER == SB_CFG_NUM_REGIONS) || defined(__DOXYGEN__)
/**
* @brief MPU regions initialization values.
* @note Regions initialization values must be chosen to be
* consistent with the values in the "regions" field.
*/
mpureg_t mpuregs[SB_CFG_NUM_REGIONS];
#endif
/**
* @brief Sandbox STDIN stream.
* @note Set this to @p NULL if standard I/O is not needed.
* @note By design you can use HAL streams here, you need to use
* a cast however.
*/
SandboxStream *stdin_stream;
/**
* @brief Sandbox STDOUT stream.
* @note Set this to @p NULL if standard I/O is not needed.
* @note By design you can use HAL streams here, you need to use
* a cast however.
*/
SandboxStream *stdout_stream;
/**
* @brief Sandbox STDERR stream.
* @note Set this to @p NULL if standard I/O is not needed.
* @note By design you can use HAL streams here, you need to use
* a cast however.
*/
SandboxStream *stderr_stream;
} sb_config_t;
/**
* @brief Type of a sandbox object.
*/
typedef struct {
/**
* @brief Pointer to the sandbox configuration data.
*/
const sb_config_t *config;
/**
* @brief Thread running in the sandbox.
*/
thread_t *tp;
#if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__)
/**
* @brief Thread sending a message to the sandbox.
*/
thread_t *msg_tp;
#endif
#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
/**
* @brief Sandbox events source.
*/
event_source_t es;
#endif
#if (SB_CFG_ENABLE_VFS == TRUE) || defined(__DOXYGEN__)
/**
* @brief VFS bindings for Posix API.
*/
sb_ioblock_t io;
#endif
} sb_class_t;
/**
* @brief Type of a sandbox binary image header.
*/
@ -200,10 +91,9 @@ extern "C" {
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_string_range(sb_class_t *sbcp, const char *s, size_t n);
void sbObjectInit(sb_class_t *sbcp);
void sbStart(sb_class_t *sbcp, const sb_config_t *config);
thread_t *sbStartThread(sb_class_t *sbcp, const sb_config_t *config,
const char *name, void *wsp, size_t size,
void sbObjectInit(sb_class_t *sbcp, const sb_config_t *config);
thread_t *sbStartThread(sb_class_t *sbcp, const char *name,
void *wsp, size_t size,
tprio_t prio);
msg_t sbSendMessageTimeout(sb_class_t *sbcp,
msg_t msg,

View File

@ -48,6 +48,7 @@
/* Module local functions. */
/*===========================================================================*/
#if (SB_CFG_ENABLE_VFS == TRUE) || defined(__DOXYGEN__)
static msg_t create_descriptor(sb_ioblock_t *iop,
vfs_node_c *np,
uint8_t attributes) {
@ -69,6 +70,7 @@ static bool is_valid_descriptor(sb_ioblock_t *iop, int fd) {
return (fd >= 0) && (fd < SB_CFG_FD_NUM) && (iop->vfs_nodes[fd] != NULL);
}
#endif
/*===========================================================================*/
/* Module exported functions. */
@ -85,7 +87,8 @@ int sb_posix_open(const char *path, int flags) {
}
do {
ret = vfsDrvOpenFile(sbp->io.vfs_driver, path, (unsigned)flags, &fnp);
ret = vfsDrvOpenFile(sbp->config->vfs_driver, path,
(unsigned)flags, &fnp);
CH_BREAK_ON_ERROR(ret);
ret = create_descriptor(&sbp->io, (vfs_node_c *)fnp, 0);
@ -122,7 +125,7 @@ int sb_posix_close(int fd) {
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)) {
if (!sb_is_valid_write_range(sbp, (void *)buf, count)) {
return CH_RET_EFAULT;
}
@ -140,7 +143,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_write_range(sbp, (void *)buf, count)) {
if (!sb_is_valid_read_range(sbp, (void *)buf, count)) {
return CH_RET_EFAULT;
}
@ -168,6 +171,18 @@ off_t sb_posix_lseek(int fd, off_t offset, int whence) {
return CH_RET_EBADF;
}
void sbPosixRegisterFileDescriptor(sb_class_t *sbp,
int fd,
vfs_file_node_c *fnp) {
chDbgAssert(is_valid_descriptor(&sbp->io, fd) &&
sbp->io.vfs_nodes[fd] == NULL,
"invalid file descriptor");
sbp->io.vfs_nodes[fd] = (vfs_node_c *)fnp;
sbp->io.attributes[fd] = 0;
}
#else /* Fallbacks for when there is no VFS.*/
uint32_t sb_posix_open(const char *pathname, uint32_t flags) {

View File

@ -48,26 +48,6 @@
/* 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. */
/*===========================================================================*/
@ -84,6 +64,11 @@ 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);
#if SB_CFG_ENABLE_VFS == TRUE
void sbPosixRegisterFileDescriptor(sb_class_t *sbp,
int fd,
vfs_file_node_c *fnp);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -23,9 +23,23 @@
#include <sys/stat.h>
#include <sys/types.h>
#include "errcodes.h"
#include "sbuser.h"
#define MAKERR(e) (-(int)(e))
__attribute__((used))
int _open_r(struct _reent *r, const char *p, int oflag, int mode) {
uint32_t err;
(void)mode;
err = sbFileOpen(p, oflag);
if (CH_RET_IS_ERROR(err)) {
__errno_r(r) = CH_DECODE_ERROR(err);
return -1;
}
return err;
}
__attribute__((used))
int _close_r(struct _reent *r, int file) {
@ -33,7 +47,7 @@ int _close_r(struct _reent *r, int file) {
err = sbFileClose((uint32_t)file);
if (CH_RET_IS_ERROR(err)) {
__errno_r(r) = MAKERR(err);
__errno_r(r) = CH_DECODE_ERROR(err);
return -1;
}
@ -46,7 +60,7 @@ int _write_r(struct _reent *r, int file, char * ptr, int len) {
err = sbFileWrite((uint32_t)file, (const uint8_t *)ptr, (size_t)len);
if (CH_RET_IS_ERROR(err)) {
__errno_r(r) = MAKERR(err);
__errno_r(r) = CH_DECODE_ERROR(err);
return -1;
}
@ -59,7 +73,7 @@ int _read_r(struct _reent *r, int file, char * ptr, int len) {
err = sbFileRead((uint32_t)file, (uint8_t *)ptr, (size_t)len);
if (CH_RET_IS_ERROR(err)) {
__errno_r(r) = MAKERR(err);
__errno_r(r) = CH_DECODE_ERROR(err);
return -1;
}
@ -72,7 +86,7 @@ int _lseek_r(struct _reent *r, int file, int ptr, int dir) {
err = sbFileSeek((uint32_t)file, (uint32_t)ptr, (uint32_t)dir);
if (CH_RET_IS_ERROR(err)) {
__errno_r(r) = MAKERR(err);
__errno_r(r) = CH_DECODE_ERROR(err);
return -1;
}