34#define FD_TABLE_ENTRY_UNUSED (fd_table_t) { .permanent = false, .has_pending_close = false, .has_pending_select = false, .vfs_index = -1, .local_fd = -1 }
36#if !defined(STATIC_ASSERT)
37# define STATIC_ASSERT(EXPR, ...) extern char (*_do_assert(void)) [sizeof(char[1 - 2*!(EXPR)])]
40#define _lock_acquire(lock) xf_lock_lock(lock)
41#define _lock_release(lock) xf_lock_unlock(lock)
43#if !defined(xf_strncpy)
44# define xf_strncpy(dst, src, len) strncpy((dst), (src), (len))
49#if ((1 << (1 * 8)) >= XF_VFS_FDS_MAX)
50# define _LOCAL_FD_T_ uint8_t
52# define _LOCAL_FD_T_ uint16_t
79#if XF_VFS_SUPPORT_DIR_IS_ENABLE
82#if XF_VFS_SUPPORT_SELECT_IS_ENABLE
97 const char *base_path,
size_t len,
const xf_vfs_fs_ops_t *vfs,
int flags,
void *
ctx,
int *vfs_index);
105static const char *
const TAG =
"xf_vfs";
158 XF_LOGE(
TAG,
"XF_VFS_FLAG_STATIC is not supported for xf_vfs_t, use xf_vfs_register_fs instead");
185 XF_LOGD(
TAG,
"Invalid arguments: xf_vfs_register_fd_range(0x%x, 0x%x, %d, %d)", (
int)(uintptr_t)vfs,
186 (
int)(uintptr_t)
ctx, min_fd, max_fd);
195 for (
int i = min_fd; i < max_fd; ++i) {
199 for (
int j = min_fd; j < i; ++j) {
205 XF_LOGD(
TAG,
"xf_vfs_register_fd_range cannot set fd %d (used by other VFS)", i);
214 XF_LOGW(
TAG,
"xf_vfs_register_fd_range is successful for range <%d; %d) and VFS ID %d", min_fd, max_fd, index);
222 if (vfs_id == NULL) {
232 if (vfs_id == NULL) {
247 s_vfs[vfs_id] = NULL;
269 const size_t base_path_len =
xf_strlen(base_path);
295 if (vfs_id < 0 || vfs_id >=
s_vfs_count || fd == NULL) {
296 XF_LOGD(
TAG,
"Invalid arguments for xf_vfs_register_fd_with_local_fd(%d, %d, %d, 0x%p)",
297 vfs_id, local_fd, permanent, fd);
319 XF_LOGD(
TAG,
"xf_vfs_register_fd_with_local_fd(%d, %d, %d, 0x%p) finished with %s",
330 XF_LOGD(
TAG,
"Invalid arguments for xf_vfs_unregister_fd(%d, %d)", vfs_id, fd);
350 xf_log_printf(
"------------------------------------------------------\n");
351 xf_log_printf(
"<VFS Path Prefix>-<FD seen by App>-<FD seen by driver>\n");
352 xf_log_printf(
"------------------------------------------------------\n");
369 xf_log_printf(
"------------------------------------------------------\n");
370 xf_log_printf(
"<index>:<VFS Path Prefix> -> <VFS entry ptr>\n");
371 xf_log_printf(
"------------------------------------------------------\n");
390 const size_t base_path_len =
xf_strlen(base_path);
425 if (len < vfs->path_prefix_len ||
466#define CHECK_AND_CALL(ret, r, pvfs, func, ...) \
467 if (pvfs->vfs->func == NULL) { \
471 if (pvfs->flags & XF_VFS_FLAG_CONTEXT_PTR) { \
472 ret = (*pvfs->vfs->func ## _p)(pvfs->ctx, __VA_ARGS__); \
474 ret = (*pvfs->vfs->func)(__VA_ARGS__); \
477#define CHECK_AND_CALL_SUBCOMPONENT(ret, r, pvfs, component, func, ...) \
478 if (pvfs->vfs->component == NULL || pvfs->vfs->component->func == NULL) { \
482 if (pvfs->flags & XF_VFS_FLAG_CONTEXT_PTR) { \
483 ret = (*pvfs->vfs->component->func ## _p)(pvfs->ctx, __VA_ARGS__); \
485 ret = (*pvfs->vfs->component->func)(__VA_ARGS__); \
488#define CHECK_AND_CALLV(r, pvfs, func, ...) \
489 if (pvfs->vfs->func == NULL) { \
493 if (pvfs->flags & XF_VFS_FLAG_CONTEXT_PTR) { \
494 (*pvfs->vfs->func ## _p)(pvfs->ctx, __VA_ARGS__); \
496 (*pvfs->vfs->func)(__VA_ARGS__); \
499#define CHECK_AND_CALL_SUBCOMPONENTV(r, pvfs, component, func, ...) \
500 if (pvfs->vfs->component == NULL || pvfs->vfs->component->func == NULL) { \
504 if (pvfs->flags & XF_VFS_FLAG_CONTEXT_PTR) { \
505 (*pvfs->vfs->component->func ## _p)(pvfs->ctx, __VA_ARGS__); \
507 (*pvfs->vfs->component->func)(__VA_ARGS__); \
510#define CHECK_AND_CALLP(ret, r, pvfs, func, ...) \
511 if (pvfs->vfs->func == NULL) { \
515 if (pvfs->flags & XF_VFS_FLAG_CONTEXT_PTR) { \
516 ret = (*pvfs->vfs->func ## _p)(pvfs->ctx, __VA_ARGS__); \
518 ret = (*pvfs->vfs->func)(__VA_ARGS__); \
521#define CHECK_AND_CALL_SUBCOMPONENTP(ret, r, pvfs, component, func, ...) \
522 if (pvfs->vfs->component == NULL || pvfs->vfs->component->func == NULL) { \
526 if (pvfs->flags & XF_VFS_FLAG_CONTEXT_PTR) { \
527 ret = (*pvfs->vfs->component->func ## _p)(pvfs->ctx, __VA_ARGS__); \
529 ret = (*pvfs->vfs->component->func)(__VA_ARGS__); \
532#define CHECK_VFS_READONLY_FLAG(flags) \
533 if (flags & XF_VFS_FLAG_READONLY_FS) { \
556 if (fd_within_vfs >= 0) {
581 if (vfs == NULL || local_fd < 0) {
594 if (vfs == NULL || local_fd < 0) {
607 if (vfs == NULL || local_fd < 0) {
620 if (vfs == NULL || local_fd < 0) {
633 if (vfs == NULL || local_fd < 0) {
646 if (vfs == NULL || local_fd < 0) {
669 if (vfs == NULL || local_fd < 0) {
682 if (vfs == NULL || local_fd < 0) {
695 if (vfs == NULL || local_fd < 0) {
711 if (vfs == NULL || local_fd < 0) {
720#if XF_VFS_SUPPORT_DIR_IS_ENABLE
797 if (vfs != vfs_dst) {
955 if (vfs == NULL || local_fd < 0) {
969#if XF_VFS_SUPPORT_SELECT_IS_ENABLE
973 for (
int i = 0; i < end_index; ++i) {
999 for (
int i = 0; i < size; ++i) {
1006 XF_LOGD(
TAG,
"FD %d in readfds was set from VFS ID %d", fd, i);
1011 XF_LOGD(
TAG,
"FD %d in writefds was set from VFS ID %d", fd, i);
1016 XF_LOGD(
TAG,
"FD %d in errorfds was set from VFS ID %d", fd, i);
1030 if (fds_name && fds) {
1046 XF_LOGD(
TAG,
"xf_vfs_select starts with nfds = %d", nfds);
1066 if (vfs_fds_triple == NULL) {
1079 for (
int fd = 0; fd < nfds; ++fd) {
1089 if (vfs_index < 0) {
1094 if (!socket_select) {
1112 XF_LOGD(
TAG,
"removing %d from readfds and adding as local FD %d to xf_fd_set of VFS ID %d", fd, local_fd, vfs_index);
1118 XF_LOGD(
TAG,
"removing %d from writefds and adding as local FD %d to xf_fd_set of VFS ID %d", fd, local_fd, vfs_index);
1124 XF_LOGD(
TAG,
"removing %d from errorfds and adding as local FD %d to xf_fd_set of VFS ID %d", fd, local_fd, vfs_index);
1132 if (!socket_select) {
1140 if (sel_sem.
sem == NULL) {
1143 XF_LOGD(
TAG,
"cannot create select semaphore");
1148 void **driver_args =
xf_malloc(vfs_count *
sizeof(
void *));
1150 if (driver_args == NULL) {
1153 XF_LOGD(
TAG,
"calloc is unsuccessful for driver args");
1156 xf_memset(driver_args, 0, vfs_count *
sizeof(
void *));
1158 for (
size_t i = 0; i < vfs_count; ++i) {
1163 XF_LOGD(
TAG,
"start_select function callback for this vfs (s_vfs[%d]) is not defined", vfs->
offset);
1173 XF_LOGD(
TAG,
"calling start_select for VFS ID %d with the following local FDs", i);
1197 if (socket_select) {
1198 XF_LOGD(
TAG,
"calling socket_select with the following FDs");
1202 ret = socket_select(nfds, readfds, writefds, errorfds, timeout);
1203 XF_LOGD(
TAG,
"socket_select returned %d and the FDs are the following", ret);
1220 uint32_t timeout_ms = (timeout->
tv_sec * 1000) + (timeout->
tv_usec / 1000);
1229 XF_LOGD(
TAG,
"timeout is %" PRIu32
"ms", timeout_ms);
1231 XF_LOGD(
TAG,
"waiting without calling socket_select");
1243 }
else if (socket_select) {
1254 for (
int fd = 0; fd < nfds; ++fd) {
1263 XF_LOGD(
TAG,
"xf_vfs_select returns %d", ret);
1272 if (
sem.is_sem_local) {
1295 if (
sem.is_sem_local) {
1326 if (
s_vfs[i] == NULL) {
1337#if XF_VFS_SUPPORT_DIR_IS_ENABLE
1341#if XF_VFS_SUPPORT_SELECT_IS_ENABLE
1350 if (entry == NULL) {
1364#if XF_VFS_SUPPORT_DIR_IS_ENABLE
1366 if (proxy.
dir != NULL) {
1378 .mkdir = vfs->
mkdir,
1379 .rmdir = vfs->
rmdir,
1383 .utime = vfs->
utime,
1390#if XF_VFS_SUPPORT_SELECT_IS_ENABLE
1392 if (proxy.
select != NULL) {
1408 .lseek = vfs->
lseek,
1410 .pread = vfs->
pread,
1413 .close = vfs->
close,
1414 .fstat = vfs->
fstat,
1415 .fcntl = vfs->
fcntl,
1416 .ioctl = vfs->
ioctl,
1417 .fsync = vfs->
fsync,
1418#if XF_VFS_SUPPORT_DIR_IS_ENABLE
1421#if XF_VFS_SUPPORT_SELECT_IS_ENABLE
1439#if XF_VFS_SUPPORT_DIR_IS_ENABLE
1442#if XF_VFS_SUPPORT_SELECT_IS_ENABLE
1451#if XF_VFS_SUPPORT_DIR_IS_ENABLE
1452 if (orig->
dir != NULL) {
1454 if (proxy.
dir == NULL) {
1461#if XF_VFS_SUPPORT_SELECT_IS_ENABLE
1462 if (orig->
select != NULL) {
1464 if (proxy.
select == NULL) {
1474 .lseek = orig->
lseek,
1476 .pread = orig->
pread,
1479 .close = orig->
close,
1480 .fstat = orig->
fstat,
1481 .fcntl = orig->
fcntl,
1482 .ioctl = orig->
ioctl,
1483 .fsync = orig->
fsync,
1484#if XF_VFS_SUPPORT_DIR_IS_ENABLE
1487#if XF_VFS_SUPPORT_SELECT_IS_ENABLE
1520#if XF_VFS_SUPPORT_DIR_IS_ENABLE
1521 const bool skip_dir =
1522 vfs->
stat == NULL &&
1523 vfs->
link == NULL &&
1532 vfs->
mkdir == NULL &&
1533 vfs->
rmdir == NULL &&
1541 if (proxy.
dir == NULL) {
1547#if XF_VFS_SUPPORT_SELECT_IS_ENABLE
1548 const bool skip_select =
1558 if (proxy.
select == NULL) {
1579 void *
ctx,
int *vfs_index)
1592 if (len >= 2 && ((base_path[0] !=
'/') || (base_path[len - 1] ==
'/'))) {
1602 if (
s_vfs[index] != NULL) {
1611 if (entry == NULL) {
1615 s_vfs[index] = entry;
1625 entry->
flags = flags;
1663 XF_CHECK(cmp_res != 0, NULL,
TAG,
"path prefix does not match");
uint32_t xf_osal_kernel_ms_to_ticks(uint32_t ms)
将 ms 数转为滴答数.
xf_osal_semaphore_t xf_osal_semaphore_create(uint32_t max_count, uint32_t initial_count, const xf_osal_semaphore_attr_t *attr)
创建并初始化信号量对象。
xf_err_t xf_osal_semaphore_release(xf_osal_semaphore_t semaphore)
释放信号量令牌直至初始最大计数。
xf_err_t xf_osal_semaphore_delete(xf_osal_semaphore_t semaphore)
删除信号量对象。
xf_err_t xf_osal_semaphore_acquire(xf_osal_semaphore_t semaphore, uint32_t timeout)
获取信号量令牌,如果没有可用令牌则超时。
#define XF_OSAL_WAIT_FOREVER
#define XF_CHECK(condition, retval, tag, format,...)
xfusion 检查宏(条件 成立 时则输出日志后返回)。
int32_t xf_err_t
整形错误类型。 错误码具体值见 xf_err_code_t.
const char * xf_err_to_name(xf_err_t code)
返回 xf_err_code_t 错误代码对应的错误信息字符串。
xf_err_t xf_lock_init(xf_lock_t *p_lock)
初始化锁.
#define xf_strcmp(dest, src)
#define xf_strncmp(dest, src, n)
#define xf_memset(ptr, value, size)
#define xf_memcmp(dest, src, n)
#define xf_memcpy(dest, src, n)
void xf_vfs_dump_registered_paths(void)
Dump all registered FSs to the provided FILE*
int xf_vfs_unlink(const char *path)
int xf_vfs_mkdir(const char *name, xf_vfs_mode_t mode)
xf_err_t xf_vfs_register_fd(xf_vfs_id_t vfs_id, int *fd)
long xf_vfs_telldir(xf_vfs_dir_t *pdir)
xf_err_t xf_vfs_unregister_with_id(xf_vfs_id_t vfs_id)
xf_vfs_dir_t * xf_vfs_opendir(const char *name)
xf_err_t xf_vfs_register(const char *base_path, const xf_vfs_t *vfs, void *ctx)
int xf_vfs_ioctl(int fd, int cmd,...)
int xf_vfs_access(const char *path, int amode)
xf_vfs_dirent_t * xf_vfs_readdir(xf_vfs_dir_t *pdir)
int xf_vfs_ftruncate(int fd, xf_vfs_off_t length)
int xf_vfs_closedir(xf_vfs_dir_t *pdir)
int xf_vfs_readdir_r(xf_vfs_dir_t *pdir, xf_vfs_dirent_t *entry, xf_vfs_dirent_t **out_dirent)
int xf_vfs_fstat(int fd, xf_vfs_stat_t *st)
void xf_vfs_dump_fds(void)
Dump the existing VFS FDs data to FILE* fp
xf_err_t xf_vfs_unregister(const char *base_path)
xf_err_t xf_vfs_unregister_fs(const char *base_path)
void xf_vfs_select_triggered_isr(xf_vfs_select_sem_t sem, int *woken)
Notification from a VFS driver about a read/write/error condition (ISR version)
xf_err_t xf_vfs_register_fs_with_id(const xf_vfs_fs_ops_t *vfs, int flags, void *ctx, xf_vfs_id_t *vfs_id)
#define XF_VFS_PATH_PREFIX_LEN_IGNORED
xf_err_t xf_vfs_register_with_id(const xf_vfs_t *vfs, void *ctx, xf_vfs_id_t *vfs_id)
xf_err_t xf_vfs_register_fd_with_local_fd(xf_vfs_id_t vfs_id, int local_fd, bool permanent, int *fd)
#define XF_VFS_FLAG_READONLY_FS
xf_vfs_ssize_t xf_vfs_pread(int fd, void *dst, size_t size, xf_vfs_off_t offset)
Implements the VFS layer of POSIX pread()
xf_vfs_ssize_t xf_vfs_pwrite(int fd, const void *src, size_t size, xf_vfs_off_t offset)
Implements the VFS layer of POSIX pwrite()
xf_err_t xf_vfs_unregister_fs_with_id(xf_vfs_id_t vfs_id)
xf_err_t xf_vfs_register_fd_range(const xf_vfs_t *vfs, void *ctx, int min_fd, int max_fd)
int xf_vfs_open(const char *path, int flags, int mode)
int xf_vfs_rename(const char *src, const char *dst)
int xf_vfs_rmdir(const char *name)
int xf_vfs_link(const char *n1, const char *n2)
void xf_vfs_select_triggered(xf_vfs_select_sem_t sem)
Notification from a VFS driver about a read/write/error condition
xf_err_t xf_vfs_unregister_fd(xf_vfs_id_t vfs_id, int fd)
int xf_vfs_truncate(const char *path, xf_vfs_off_t length)
int xf_vfs_utime(const char *path, const xf_vfs_utimbuf_t *times)
int xf_vfs_fcntl_r(int fd, int cmd, int arg)
xf_err_t xf_vfs_register_fs(const char *base_path, const xf_vfs_fs_ops_t *vfs, int flags, void *ctx)
void xf_vfs_seekdir(xf_vfs_dir_t *pdir, long loc)
xf_vfs_ssize_t xf_vfs_read(int fd, void *dst, size_t size)
void xf_vfs_rewinddir(xf_vfs_dir_t *pdir)
xf_vfs_off_t xf_vfs_lseek(int fd, xf_vfs_off_t size, int mode)
int xf_vfs_select(int nfds, xf_fd_set *readfds, xf_fd_set *writefds, xf_fd_set *errorfds, xf_vfs_timeval_t *timeout)
Synchronous I/O multiplexing which implements the functionality of POSIX select() for VFS
#define XF_VFS_FLAG_STATIC
xf_vfs_ssize_t xf_vfs_write(int fd, const void *data, size_t size)
static xf_osal_semaphore_t sem
const xf_vfs_fs_ops_t * vfs
char path_prefix[XF_VFS_PATH_MAX]
xf_vfs_select_ops_t * select
Struct containing function pointers to directory related functionality.
const xf_vfs_stat_op_t stat
Opaque directory structure
Directory entry structure
Main struct of the minified vfs API, containing basic function pointers as well as pointers to the ot...
const xf_vfs_ioctl_op_t ioctl
const xf_vfs_pread_op_t pread
const xf_vfs_select_ops_t *const select
const xf_vfs_dir_ops_t *const dir
const xf_vfs_pwrite_op_t pwrite
const xf_vfs_read_op_t read
const xf_vfs_write_op_t write
const xf_vfs_fcntl_op_t fcntl
const xf_vfs_fstat_op_t fstat
const xf_vfs_fsync_op_t fsync
const xf_vfs_lseek_op_t lseek
const xf_vfs_close_op_t close
const xf_vfs_open_op_t open
Struct containing function pointers to select related functionality.
const xf_vfs_get_socket_select_semaphore_op_t get_socket_select_semaphore
const xf_vfs_end_select_op_t end_select
const xf_vfs_stop_socket_select_op_t stop_socket_select
const xf_vfs_stop_socket_select_isr_op_t stop_socket_select_isr
const xf_vfs_socket_select_op_t socket_select
const xf_vfs_start_select_op_t start_select
VFS semaphore type for select()
xf_err_t(* start_select)(int nfds, xf_fd_set *readfds, xf_fd_set *writefds, xf_fd_set *exceptfds, xf_vfs_select_sem_t sem, void **end_select_args)
xf_vfs_dirent_t *(* readdir)(xf_vfs_dir_t *pdir)
xf_vfs_ssize_t(* pwrite)(int fd, const void *src, size_t size, xf_vfs_off_t offset)
void(* stop_socket_select)(void *sem)
int(* truncate)(const char *path, xf_vfs_off_t length)
int(* stat)(const char *path, xf_vfs_stat_t *st)
int(* access)(const char *path, int amode)
void(* seekdir)(xf_vfs_dir_t *pdir, long offset)
xf_vfs_ssize_t(* write)(int fd, const void *data, size_t size)
int(* rename)(const char *src, const char *dst)
void *(* get_socket_select_semaphore)(void)
int(* rmdir)(const char *name)
int(* utime)(const char *path, const xf_vfs_utimbuf_t *times)
xf_err_t(* end_select)(void *end_select_args)
xf_vfs_ssize_t(* read)(int fd, void *dst, size_t size)
xf_vfs_dir_t *(* opendir)(const char *name)
int(* fcntl)(int fd, int cmd, int arg)
int(* readdir_r)(xf_vfs_dir_t *pdir, xf_vfs_dirent_t *entry, xf_vfs_dirent_t **out_dirent)
xf_vfs_off_t(* lseek)(int fd, xf_vfs_off_t size, int mode)
xf_vfs_ssize_t(* pread)(int fd, void *dst, size_t size, xf_vfs_off_t offset)
int(* link)(const char *n1, const char *n2)
void(* stop_socket_select_isr)(void *sem, int *woken)
int(* socket_select)(int nfds, xf_fd_set *readfds, xf_fd_set *writefds, xf_fd_set *errorfds, xf_vfs_timeval_t *timeout)
int(* fstat)(int fd, xf_vfs_stat_t *st)
long(* telldir)(xf_vfs_dir_t *pdir)
int(* ftruncate)(int fd, xf_vfs_off_t length)
int(* closedir)(xf_vfs_dir_t *pdir)
int(* open)(const char *path, int flags, int mode)
int(* ioctl)(int fd, int cmd, va_list args)
int(* unlink)(const char *path)
int(* mkdir)(const char *name, xf_vfs_mode_t mode)
xf_vfs_suseconds_t tv_usec
aos_utimbuf 结构描述了文件系统 inode 的 最后访问时间和最后修改时间。
int ioctl(int fd, unsigned long request,...)
size_t read(int fd, void *buf, size_t count)
size_t write(int fd, const void *buf, size_t count)
int open(const char *pathname, int flags)
#define XF_LOGE(tag, format,...)
#define XF_LOGW(tag, format,...)
#define XF_LOGD(tag, format,...)
#define xf_log_printf(format,...)
static bool fd_valid(int fd)
static void xf_vfs_free_entry(xf_vfs_entry_t *entry)
static void call_end_selects(int end_index, const fds_triple_t *vfs_fds_triple, void **driver_args)
#define _lock_release(lock)
static size_t s_vfs_count
#define CHECK_AND_CALL(ret, r, pvfs, func,...)
const xf_vfs_entry_t * xf_vfs_get_vfs_for_index(int index)
static const char * translate_path(const xf_vfs_entry_t *vfs, const char *src_path)
static void xf_vfs_log_fd_set(const char *fds_name, const xf_fd_set *fds)
static int get_local_fd(const xf_vfs_entry_t *vfs, int fd)
static xf_err_t xf_vfs_make_fs_ops(const xf_vfs_t *vfs, xf_vfs_fs_ops_t **min)
static int set_global_fd_sets(const fds_triple_t *vfs_fds_triple, int size, xf_fd_set *readfds, xf_fd_set *writefds, xf_fd_set *errorfds)
static const char *const TAG
static void xf_vfs_free_fs_ops(xf_vfs_fs_ops_t *vfs)
static xf_vfs_fs_ops_t * xf_vfs_duplicate_fs_ops(const xf_vfs_fs_ops_t *orig)
#define CHECK_VFS_READONLY_FLAG(flags)
xf_err_t xf_vfs_register_common(const char *base_path, size_t len, const xf_vfs_t *vfs, void *ctx, int *vfs_index)
static const xf_vfs_entry_t * get_vfs_for_fd(int fd)
static xf_lock_t s_fd_table_lock
static xf_err_t xf_vfs_register_fs_common(const char *base_path, size_t len, const xf_vfs_fs_ops_t *vfs, int flags, void *ctx, int *vfs_index)
#define CHECK_AND_CALL_SUBCOMPONENTV(r, pvfs, component, func,...)
#define CHECK_AND_CALL_SUBCOMPONENTP(ret, r, pvfs, component, func,...)
static fd_table_t s_fd_table[XF_VFS_FDS_MAX]
static xf_vfs_ssize_t xf_get_free_index(void)
static bool xf_vfs_safe_fd_isset(int fd, const xf_fd_set *fds)
#define STATIC_ASSERT(EXPR,...)
#define CHECK_AND_CALL_SUBCOMPONENT(ret, r, pvfs, component, func,...)
static xf_vfs_fs_ops_t * xf_minify_vfs(const xf_vfs_t *const vfs, vfs_component_proxy_t proxy)
const xf_vfs_entry_t * xf_vfs_get_vfs_for_path(const char *path)
#define FD_TABLE_ENTRY_UNUSED
#define xf_strncpy(dst, src, len)
static void free_proxy_members(vfs_component_proxy_t *proxy)
static xf_vfs_entry_t * s_vfs[XF_VFS_MAX_COUNT]
#define _lock_acquire(lock)
xf_err_t xf_vfs_set_readonly_flag(const char *base_path)
#define XF_FD_ISSET(n, p)
unsigned long xf_vfs_mode_t
signed int xf_vfs_ssize_t