fix(vfs): add syscall argument validation in VFS layer

This commit is contained in:
sonika.rathi
2026-05-27 10:51:19 +02:00
parent 7b4a2c6d98
commit bc8e0ef153
4 changed files with 140 additions and 124 deletions

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -80,27 +80,27 @@ typedef struct {
esp_err_t esp_vfs_register_common(const char *base_path, size_t len, const esp_vfs_t *vfs, void *ctx, int *vfs_index);
/**
* Get vfs fd with given path.
* Resolve which registered VFS should handle the given absolute path.
*
* @param path file path prefix associated with the filesystem.
* @param path Zero-terminated absolute path. Must not be NULL when calling
* `strlen` internally; callers should reject NULL paths first
* (typically with `EINVAL`) before invoking this helper.
*
* @return Pointer to the `vfs_entry_t` corresponding to the given path, which cannot be NULL.
* @return Matching `vfs_entry_t`, or NULL if @p path is NULL or no VFS matches.
*/
const vfs_entry_t *get_vfs_for_path(const char *path);
/**
* Get vfs fd with given vfs index.
* Get VFS entry for a given VFS table index.
*
* @param index VFS index.
* @param index VFS index (as stored on FDs / DIR handles).
*
* @return Pointer to the `vfs_entry_t` corresponding to the given path, which cannot be NULL.
* @return Pointer to the `vfs_entry_t` for @p index, or NULL if invalid / unused.
*/
const vfs_entry_t *get_vfs_for_index(int index);
const char* translate_path(const vfs_entry_t* vfs, const char* src_path);
const vfs_entry_t* get_vfs_for_path(const char* path);
const vfs_entry_t *get_vfs_for_fd(int fd);
int register_fd(int vfs_index, int local_fd, bool permanent);

View File

@@ -5,6 +5,43 @@
*/
#pragma once
/*
* Early-return helpers for VFS syscalls (errno via reent).
* `r` must be a struct _reent * in scope, as for CHECK_AND_CALL macros.
*/
#define VFS_RETURN_ERR(r, err, ret) \
do { \
__errno_r(r) = (err); \
return (ret); \
} while (0)
#define VFS_RETURN_ON_NULL_PTR(r, ptr, err, ret) \
do { \
if ((ptr) == NULL) { \
VFS_RETURN_ERR(r, err, ret); \
} \
} while (0)
#define VFS_RETURN_ON_NULL_IOBUF(r, buf, size, ret) \
do { \
if ((size) != 0 && (buf) == NULL) { \
VFS_RETURN_ERR(r, EINVAL, ret); \
} \
} while (0)
#define VFS_RETURNV_ERR(r, err) \
do { \
__errno_r(r) = (err); \
return; \
} while (0)
#define VFS_RETURNV_ON_NULL_PTR(r, ptr, err) \
do { \
if ((ptr) == NULL) { \
VFS_RETURNV_ERR(r, err); \
} \
} while (0)
/*
* Using huge multi-line macros is never nice, but in this case
* the only alternative is to repeat this chunk of code (with different function names)
@@ -19,8 +56,7 @@
*/
#define CHECK_AND_CALL(ret, r, pvfs, func, ...) \
if (pvfs->vfs->func ## _p == NULL) { \
__errno_r(r) = ENOSYS; \
return -1; \
VFS_RETURN_ERR(r, ENOSYS, -1); \
} \
if (pvfs->flags & ESP_VFS_FLAG_CONTEXT_PTR) { \
ret = (*pvfs->vfs->func ## _p)(pvfs->ctx, __VA_ARGS__); \
@@ -30,8 +66,7 @@
#define CHECK_AND_CALL_SUBCOMPONENT(ret, r, pvfs, component, func, ...) \
if (pvfs->vfs->component == NULL || pvfs->vfs->component->func ## _p == NULL) { \
__errno_r(r) = ENOSYS; \
return -1; \
VFS_RETURN_ERR(r, ENOSYS, -1); \
} \
if (pvfs->flags & ESP_VFS_FLAG_CONTEXT_PTR) { \
ret = (*pvfs->vfs->component->func ## _p)(pvfs->ctx, __VA_ARGS__); \
@@ -41,8 +76,7 @@
#define CHECK_AND_CALLV(r, pvfs, func, ...) \
if (pvfs->vfs->func ## _p == NULL) { \
__errno_r(r) = ENOSYS; \
return; \
VFS_RETURNV_ERR(r, ENOSYS); \
} \
if (pvfs->flags & ESP_VFS_FLAG_CONTEXT_PTR) { \
(*pvfs->vfs->func ## _p)(pvfs->ctx, __VA_ARGS__); \
@@ -52,8 +86,7 @@
#define CHECK_AND_CALL_SUBCOMPONENTV(r, pvfs, component, func, ...) \
if (pvfs->vfs->component == NULL || pvfs->vfs->component->func ## _p == NULL) { \
__errno_r(r) = ENOSYS; \
return; \
VFS_RETURNV_ERR(r, ENOSYS); \
} \
if (pvfs->flags & ESP_VFS_FLAG_CONTEXT_PTR) { \
(*pvfs->vfs->component->func ## _p)(pvfs->ctx, __VA_ARGS__); \
@@ -63,8 +96,7 @@
#define CHECK_AND_CALLP(ret, r, pvfs, func, ...) \
if (pvfs->vfs->func ## _p == NULL) { \
__errno_r(r) = ENOSYS; \
return NULL; \
VFS_RETURN_ERR(r, ENOSYS, NULL); \
} \
if (pvfs->flags & ESP_VFS_FLAG_CONTEXT_PTR) { \
ret = (*pvfs->vfs->func ## _p)(pvfs->ctx, __VA_ARGS__); \
@@ -74,8 +106,7 @@
#define CHECK_AND_CALL_SUBCOMPONENTP(ret, r, pvfs, component, func, ...) \
if (pvfs->vfs->component == NULL || pvfs->vfs->component->func ## _p == NULL) { \
__errno_r(r) = ENOSYS; \
return NULL; \
VFS_RETURN_ERR(r, ENOSYS, NULL); \
} \
if (pvfs->flags & ESP_VFS_FLAG_CONTEXT_PTR) { \
ret = (*pvfs->vfs->component->func ## _p)(pvfs->ctx, __VA_ARGS__); \
@@ -85,6 +116,5 @@
#define CHECK_VFS_READONLY_FLAG(flags) \
if (flags & ESP_VFS_FLAG_READONLY_FS) { \
__errno_r(r) = EROFS; \
return -1; \
VFS_RETURN_ERR(r, EROFS, -1); \
}

View File

@@ -833,6 +833,9 @@ const char* translate_path(const vfs_entry_t* vfs, const char* src_path)
const vfs_entry_t* get_vfs_for_path(const char* path)
{
if (path == NULL) {
return NULL;
}
const vfs_entry_t* best_match = NULL;
ssize_t best_match_prefix_len = -1;
size_t len = strlen(path);

View File

@@ -31,17 +31,16 @@ static const char __attribute__((unused)) *TAG = "vfs_calls";
int esp_vfs_open(struct _reent *r, const char *path, int flags, int mode)
{
VFS_RETURN_ON_NULL_PTR(r, path, EINVAL, -1);
const vfs_entry_t *vfs = get_vfs_for_path(path);
if (vfs == NULL) {
__errno_r(r) = ENOENT;
return -1;
VFS_RETURN_ERR(r, ENOENT, -1);
}
int acc_mode = flags & O_ACCMODE;
int ro_filesystem = vfs->flags & ESP_VFS_FLAG_READONLY_FS;
if (acc_mode != O_RDONLY && ro_filesystem) {
__errno_r(r) = EROFS;
return -1;
VFS_RETURN_ERR(r, EROFS, -1);
}
const char *path_within_vfs = translate_path(vfs, path);
@@ -49,8 +48,7 @@ int esp_vfs_open(struct _reent *r, const char *path, int flags, int mode)
CHECK_AND_CALL(fd_within_vfs, r, vfs, open, path_within_vfs, flags, mode);
if (fd_within_vfs < 0) {
__errno_r(r) = errno;
return -1;
VFS_RETURN_ERR(r, errno, -1);
}
int fd = register_fd(vfs->offset, fd_within_vfs, false);
@@ -61,8 +59,7 @@ int esp_vfs_open(struct _reent *r, const char *path, int flags, int mode)
int ret;
CHECK_AND_CALL(ret, r, vfs, close, fd_within_vfs);
(void) ret; // remove "set but not used" warning
__errno_r(r) = ENFILE;
return -1;
VFS_RETURN_ERR(r, ENFILE, -1);
}
ssize_t esp_vfs_write(struct _reent *r, int fd, const void *data, size_t size)
@@ -70,9 +67,9 @@ ssize_t esp_vfs_write(struct _reent *r, int fd, const void *data, size_t size)
const vfs_entry_t *vfs = get_vfs_for_fd(fd);
const int local_fd = get_local_fd(vfs, fd);
if (vfs == NULL || local_fd < 0) {
__errno_r(r) = EBADF;
return -1;
VFS_RETURN_ERR(r, EBADF, -1);
}
VFS_RETURN_ON_NULL_IOBUF(r, data, size, -1);
ssize_t ret;
CHECK_AND_CALL(ret, r, vfs, write, local_fd, data, size);
return ret;
@@ -83,8 +80,7 @@ off_t esp_vfs_lseek(struct _reent *r, int fd, off_t size, int mode)
const vfs_entry_t *vfs = get_vfs_for_fd(fd);
const int local_fd = get_local_fd(vfs, fd);
if (vfs == NULL || local_fd < 0) {
__errno_r(r) = EBADF;
return -1;
VFS_RETURN_ERR(r, EBADF, -1);
}
off_t ret;
CHECK_AND_CALL(ret, r, vfs, lseek, local_fd, size, mode);
@@ -96,9 +92,9 @@ ssize_t esp_vfs_read(struct _reent *r, int fd, void *dst, size_t size)
const vfs_entry_t *vfs = get_vfs_for_fd(fd);
const int local_fd = get_local_fd(vfs, fd);
if (vfs == NULL || local_fd < 0) {
__errno_r(r) = EBADF;
return -1;
VFS_RETURN_ERR(r, EBADF, -1);
}
VFS_RETURN_ON_NULL_IOBUF(r, dst, size, -1);
ssize_t ret;
CHECK_AND_CALL(ret, r, vfs, read, local_fd, dst, size);
return ret;
@@ -110,9 +106,9 @@ ssize_t esp_vfs_pread(int fd, void *dst, size_t size, off_t offset)
const vfs_entry_t *vfs = get_vfs_for_fd(fd);
const int local_fd = get_local_fd(vfs, fd);
if (vfs == NULL || local_fd < 0) {
__errno_r(r) = EBADF;
return -1;
VFS_RETURN_ERR(r, EBADF, -1);
}
VFS_RETURN_ON_NULL_IOBUF(r, dst, size, -1);
ssize_t ret;
CHECK_AND_CALL(ret, r, vfs, pread, local_fd, dst, size, offset);
return ret;
@@ -124,9 +120,9 @@ ssize_t esp_vfs_pwrite(int fd, const void *src, size_t size, off_t offset)
const vfs_entry_t *vfs = get_vfs_for_fd(fd);
const int local_fd = get_local_fd(vfs, fd);
if (vfs == NULL || local_fd < 0) {
__errno_r(r) = EBADF;
return -1;
VFS_RETURN_ERR(r, EBADF, -1);
}
VFS_RETURN_ON_NULL_IOBUF(r, src, size, -1);
ssize_t ret;
CHECK_AND_CALL(ret, r, vfs, pwrite, local_fd, src, size, offset);
return ret;
@@ -137,8 +133,7 @@ int esp_vfs_close(struct _reent *r, int fd)
const vfs_entry_t *vfs = get_vfs_for_fd(fd);
const int local_fd = get_local_fd(vfs, fd);
if (vfs == NULL || local_fd < 0) {
__errno_r(r) = EBADF;
return -1;
VFS_RETURN_ERR(r, EBADF, -1);
}
int ret;
CHECK_AND_CALL(ret, r, vfs, close, local_fd);
@@ -153,9 +148,9 @@ int esp_vfs_fstat(struct _reent *r, int fd, struct stat *st)
const vfs_entry_t *vfs = get_vfs_for_fd(fd);
const int local_fd = get_local_fd(vfs, fd);
if (vfs == NULL || local_fd < 0) {
__errno_r(r) = EBADF;
return -1;
VFS_RETURN_ERR(r, EBADF, -1);
}
VFS_RETURN_ON_NULL_PTR(r, st, EINVAL, -1);
int ret;
CHECK_AND_CALL(ret, r, vfs, fstat, local_fd, st);
return ret;
@@ -166,8 +161,7 @@ int esp_vfs_fcntl_r(struct _reent *r, int fd, int cmd, int arg)
const vfs_entry_t *vfs = get_vfs_for_fd(fd);
const int local_fd = get_local_fd(vfs, fd);
if (vfs == NULL || local_fd < 0) {
__errno_r(r) = EBADF;
return -1;
VFS_RETURN_ERR(r, EBADF, -1);
}
int ret;
CHECK_AND_CALL(ret, r, vfs, fcntl, local_fd, cmd, arg);
@@ -180,13 +174,11 @@ int esp_vfs_ioctl(int fd, int cmd, ...)
const int local_fd = get_local_fd(vfs, fd);
struct _reent __attribute__((unused)) *r = __getreent();
if (vfs == NULL || local_fd < 0) {
__errno_r(r) = EBADF;
return -1;
VFS_RETURN_ERR(r, EBADF, -1);
}
if (vfs->vfs->ioctl == NULL) {
__errno_r(r) = ENOSYS;
return -1;
VFS_RETURN_ERR(r, ENOSYS, -1);
}
int ret;
@@ -209,8 +201,7 @@ int esp_vfs_fsync(int fd)
const int local_fd = get_local_fd(vfs, fd);
struct _reent __attribute__((unused)) *r = __getreent();
if (vfs == NULL || local_fd < 0) {
__errno_r(r) = EBADF;
return -1;
VFS_RETURN_ERR(r, EBADF, -1);
}
int ret;
CHECK_AND_CALL(ret, r, vfs, fsync, local_fd);
@@ -221,10 +212,11 @@ int esp_vfs_fsync(int fd)
int esp_vfs_stat(struct _reent *r, const char *path, struct stat *st)
{
VFS_RETURN_ON_NULL_PTR(r, path, EINVAL, -1);
VFS_RETURN_ON_NULL_PTR(r, st, EINVAL, -1);
const vfs_entry_t *vfs = get_vfs_for_path(path);
if (vfs == NULL) {
__errno_r(r) = ENOENT;
return -1;
VFS_RETURN_ERR(r, ENOENT, -1);
}
const char *path_within_vfs = translate_path(vfs, path);
int ret;
@@ -235,11 +227,11 @@ int esp_vfs_stat(struct _reent *r, const char *path, struct stat *st)
int esp_vfs_utime(const char *path, const struct utimbuf *times)
{
int ret;
const vfs_entry_t *vfs = get_vfs_for_path(path);
struct _reent __attribute__((unused)) *r = __getreent();
VFS_RETURN_ON_NULL_PTR(r, path, EINVAL, -1);
const vfs_entry_t *vfs = get_vfs_for_path(path);
if (vfs == NULL) {
__errno_r(r) = ENOENT;
return -1;
VFS_RETURN_ERR(r, ENOENT, -1);
}
const char *path_within_vfs = translate_path(vfs, path);
CHECK_AND_CALL_SUBCOMPONENT(ret, r, vfs, dir, utime, path_within_vfs, times);
@@ -248,15 +240,15 @@ int esp_vfs_utime(const char *path, const struct utimbuf *times)
int esp_vfs_link(struct _reent *r, const char *n1, const char *n2)
{
VFS_RETURN_ON_NULL_PTR(r, n1, EINVAL, -1);
VFS_RETURN_ON_NULL_PTR(r, n2, EINVAL, -1);
const vfs_entry_t *vfs = get_vfs_for_path(n1);
if (vfs == NULL) {
__errno_r(r) = ENOENT;
return -1;
VFS_RETURN_ERR(r, ENOENT, -1);
}
const vfs_entry_t *vfs2 = get_vfs_for_path(n2);
if (vfs != vfs2) {
__errno_r(r) = EXDEV;
return -1;
VFS_RETURN_ERR(r, EXDEV, -1);
}
CHECK_VFS_READONLY_FLAG(vfs2->flags);
@@ -270,10 +262,10 @@ int esp_vfs_link(struct _reent *r, const char *n1, const char *n2)
int esp_vfs_unlink(struct _reent *r, const char *path)
{
VFS_RETURN_ON_NULL_PTR(r, path, EINVAL, -1);
const vfs_entry_t *vfs = get_vfs_for_path(path);
if (vfs == NULL) {
__errno_r(r) = ENOENT;
return -1;
VFS_RETURN_ERR(r, ENOENT, -1);
}
CHECK_VFS_READONLY_FLAG(vfs->flags);
@@ -286,18 +278,18 @@ int esp_vfs_unlink(struct _reent *r, const char *path)
int esp_vfs_rename(struct _reent *r, const char *src, const char *dst)
{
VFS_RETURN_ON_NULL_PTR(r, src, EINVAL, -1);
VFS_RETURN_ON_NULL_PTR(r, dst, EINVAL, -1);
const vfs_entry_t *vfs = get_vfs_for_path(src);
if (vfs == NULL) {
__errno_r(r) = ENOENT;
return -1;
VFS_RETURN_ERR(r, ENOENT, -1);
}
CHECK_VFS_READONLY_FLAG(vfs->flags);
const vfs_entry_t *vfs_dst = get_vfs_for_path(dst);
if (vfs != vfs_dst) {
__errno_r(r) = EXDEV;
return -1;
VFS_RETURN_ERR(r, EXDEV, -1);
}
CHECK_VFS_READONLY_FLAG(vfs_dst->flags);
@@ -311,11 +303,11 @@ int esp_vfs_rename(struct _reent *r, const char *src, const char *dst)
DIR *esp_vfs_opendir(const char *name)
{
const vfs_entry_t *vfs = get_vfs_for_path(name);
struct _reent __attribute__((unused)) *r = __getreent();
VFS_RETURN_ON_NULL_PTR(r, name, EINVAL, NULL);
const vfs_entry_t *vfs = get_vfs_for_path(name);
if (vfs == NULL) {
__errno_r(r) = ENOENT;
return NULL;
VFS_RETURN_ERR(r, ENOENT, NULL);
}
const char *path_within_vfs = translate_path(vfs, name);
DIR *ret;
@@ -328,11 +320,11 @@ DIR *esp_vfs_opendir(const char *name)
struct dirent *esp_vfs_readdir(DIR *pdir)
{
const vfs_entry_t *vfs = get_vfs_for_index(pdir->dd_vfs_idx);
struct _reent __attribute__((unused)) *r = __getreent();
VFS_RETURN_ON_NULL_PTR(r, pdir, EBADF, NULL);
const vfs_entry_t *vfs = get_vfs_for_index(pdir->dd_vfs_idx);
if (vfs == NULL) {
__errno_r(r) = EBADF;
return NULL;
VFS_RETURN_ERR(r, EBADF, NULL);
}
struct dirent *ret;
CHECK_AND_CALL_SUBCOMPONENTP(ret, r, vfs, dir, readdir, pdir);
@@ -341,11 +333,13 @@ struct dirent *esp_vfs_readdir(DIR *pdir)
int esp_vfs_readdir_r(DIR *pdir, struct dirent *entry, struct dirent* *out_dirent)
{
const vfs_entry_t *vfs = get_vfs_for_index(pdir->dd_vfs_idx);
struct _reent __attribute__((unused)) *r = __getreent();
VFS_RETURN_ON_NULL_PTR(r, pdir, EINVAL, -1);
VFS_RETURN_ON_NULL_PTR(r, entry, EINVAL, -1);
VFS_RETURN_ON_NULL_PTR(r, out_dirent, EINVAL, -1);
const vfs_entry_t *vfs = get_vfs_for_index(pdir->dd_vfs_idx);
if (vfs == NULL) {
errno = EBADF;
return -1;
VFS_RETURN_ERR(r, EBADF, -1);
}
int ret;
CHECK_AND_CALL_SUBCOMPONENT(ret, r, vfs, dir, readdir_r, pdir, entry, out_dirent);
@@ -354,11 +348,11 @@ int esp_vfs_readdir_r(DIR *pdir, struct dirent *entry, struct dirent* *out_diren
long esp_vfs_telldir(DIR *pdir)
{
const vfs_entry_t *vfs = get_vfs_for_index(pdir->dd_vfs_idx);
struct _reent __attribute__((unused)) *r = __getreent();
VFS_RETURN_ON_NULL_PTR(r, pdir, EBADF, -1);
const vfs_entry_t *vfs = get_vfs_for_index(pdir->dd_vfs_idx);
if (vfs == NULL) {
errno = EBADF;
return -1;
VFS_RETURN_ERR(r, EBADF, -1);
}
long ret;
CHECK_AND_CALL_SUBCOMPONENT(ret, r, vfs, dir, telldir, pdir);
@@ -367,11 +361,11 @@ long esp_vfs_telldir(DIR *pdir)
void esp_vfs_seekdir(DIR *pdir, long loc)
{
const vfs_entry_t *vfs = get_vfs_for_index(pdir->dd_vfs_idx);
struct _reent __attribute__((unused)) *r = __getreent();
VFS_RETURNV_ON_NULL_PTR(r, pdir, EBADF);
const vfs_entry_t *vfs = get_vfs_for_index(pdir->dd_vfs_idx);
if (vfs == NULL) {
errno = EBADF;
return;
VFS_RETURNV_ERR(r, EBADF);
}
CHECK_AND_CALL_SUBCOMPONENTV(r, vfs, dir, seekdir, pdir, loc);
}
@@ -383,11 +377,11 @@ void esp_vfs_rewinddir(DIR *pdir)
int esp_vfs_closedir(DIR *pdir)
{
const vfs_entry_t *vfs = get_vfs_for_index(pdir->dd_vfs_idx);
struct _reent __attribute__((unused)) *r = __getreent();
VFS_RETURN_ON_NULL_PTR(r, pdir, EBADF, -1);
const vfs_entry_t *vfs = get_vfs_for_index(pdir->dd_vfs_idx);
if (vfs == NULL) {
errno = EBADF;
return -1;
VFS_RETURN_ERR(r, EBADF, -1);
}
int ret;
CHECK_AND_CALL_SUBCOMPONENT(ret, r, vfs, dir, closedir, pdir);
@@ -396,11 +390,11 @@ int esp_vfs_closedir(DIR *pdir)
int esp_vfs_mkdir(const char *name, mode_t mode)
{
const vfs_entry_t *vfs = get_vfs_for_path(name);
struct _reent __attribute__((unused)) *r = __getreent();
VFS_RETURN_ON_NULL_PTR(r, name, EINVAL, -1);
const vfs_entry_t *vfs = get_vfs_for_path(name);
if (vfs == NULL) {
__errno_r(r) = ENOENT;
return -1;
VFS_RETURN_ERR(r, ENOENT, -1);
}
CHECK_VFS_READONLY_FLAG(vfs->flags);
@@ -413,11 +407,11 @@ int esp_vfs_mkdir(const char *name, mode_t mode)
int esp_vfs_rmdir(const char *name)
{
const vfs_entry_t *vfs = get_vfs_for_path(name);
struct _reent __attribute__((unused)) *r = __getreent();
VFS_RETURN_ON_NULL_PTR(r, name, EINVAL, -1);
const vfs_entry_t *vfs = get_vfs_for_path(name);
if (vfs == NULL) {
__errno_r(r) = ENOENT;
return -1;
VFS_RETURN_ERR(r, ENOENT, -1);
}
CHECK_VFS_READONLY_FLAG(vfs->flags);
@@ -431,11 +425,11 @@ int esp_vfs_rmdir(const char *name)
int esp_vfs_access(const char *path, int amode)
{
int ret;
const vfs_entry_t *vfs = get_vfs_for_path(path);
struct _reent __attribute__((unused)) *r = __getreent();
VFS_RETURN_ON_NULL_PTR(r, path, EINVAL, -1);
const vfs_entry_t *vfs = get_vfs_for_path(path);
if (vfs == NULL) {
__errno_r(r) = ENOENT;
return -1;
VFS_RETURN_ERR(r, ENOENT, -1);
}
const char *path_within_vfs = translate_path(vfs, path);
CHECK_AND_CALL_SUBCOMPONENT(ret, r, vfs, dir, access, path_within_vfs, amode);
@@ -445,11 +439,11 @@ int esp_vfs_access(const char *path, int amode)
int esp_vfs_truncate(const char *path, off_t length)
{
int ret;
const vfs_entry_t *vfs = get_vfs_for_path(path);
struct _reent __attribute__((unused)) *r = __getreent();
VFS_RETURN_ON_NULL_PTR(r, path, EINVAL, -1);
const vfs_entry_t *vfs = get_vfs_for_path(path);
if (vfs == NULL) {
__errno_r(r) = ENOENT;
return -1;
VFS_RETURN_ERR(r, ENOENT, -1);
}
CHECK_VFS_READONLY_FLAG(vfs->flags);
@@ -465,8 +459,7 @@ int esp_vfs_ftruncate(int fd, off_t length)
int local_fd = get_local_fd(vfs, fd);
struct _reent __attribute__((unused)) *r = __getreent();
if (vfs == NULL || local_fd < 0) {
__errno_r(r) = EBADF;
return -1;
VFS_RETURN_ERR(r, EBADF, -1);
}
CHECK_VFS_READONLY_FLAG(vfs->flags);
@@ -561,8 +554,7 @@ int esp_vfs_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds
if (nfds > MAX_FDS || nfds < 0) {
ESP_LOGD(TAG, "incorrect nfds");
__errno_r(r) = EINVAL;
return -1;
VFS_RETURN_ERR(r, EINVAL, -1);
}
// Capture s_vfs_count to a local variable in case a new driver is registered or removed during this actual select()
@@ -571,9 +563,8 @@ int esp_vfs_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds
const size_t vfs_count = get_vfs_count();
fds_triple_t *vfs_fds_triple;
if ((vfs_fds_triple = heap_caps_calloc(vfs_count, sizeof(fds_triple_t), VFS_MALLOC_FLAGS)) == NULL) {
__errno_r(r) = ENOMEM;
ESP_LOGD(TAG, "calloc is unsuccessful");
return -1;
VFS_RETURN_ERR(r, ENOMEM, -1);
}
esp_vfs_select_sem_t sel_sem = {
@@ -637,9 +628,8 @@ int esp_vfs_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds
sel_sem.is_sem_local = true;
if ((sel_sem.sem = xSemaphoreCreateBinary()) == NULL) {
free(vfs_fds_triple);
__errno_r(r) = ENOMEM;
ESP_LOGD(TAG, "cannot create select semaphore");
return -1;
VFS_RETURN_ERR(r, ENOMEM, -1);
}
}
@@ -647,9 +637,8 @@ int esp_vfs_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds
if (driver_args == NULL) {
free(vfs_fds_triple);
__errno_r(r) = ENOMEM;
ESP_LOGD(TAG, "calloc is unsuccessful for driver args");
return -1;
VFS_RETURN_ERR(r, ENOMEM, -1);
}
for (size_t i = 0; i < vfs_count; ++i) {
@@ -685,9 +674,8 @@ int esp_vfs_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds
}
free(vfs_fds_triple);
free(driver_args);
__errno_r(r) = EINTR;
ESP_LOGD(TAG, "start_select failed: %s", esp_err_to_name(err));
return -1;
VFS_RETURN_ERR(r, EINTR, -1);
}
}
@@ -815,9 +803,9 @@ int tcgetattr(int fd, struct termios *p)
const int local_fd = get_local_fd(vfs, fd);
struct _reent __attribute__((unused)) *r = __getreent();
if (vfs == NULL || local_fd < 0) {
__errno_r(r) = EBADF;
return -1;
VFS_RETURN_ERR(r, EBADF, -1);
}
VFS_RETURN_ON_NULL_PTR(r, p, EINVAL, -1);
int ret;
CHECK_AND_CALL_SUBCOMPONENT(ret, r, vfs, termios, tcgetattr, local_fd, p);
return ret;
@@ -829,9 +817,9 @@ int tcsetattr(int fd, int optional_actions, const struct termios *p)
const int local_fd = get_local_fd(vfs, fd);
struct _reent __attribute__((unused)) *r = __getreent();
if (vfs == NULL || local_fd < 0) {
__errno_r(r) = EBADF;
return -1;
VFS_RETURN_ERR(r, EBADF, -1);
}
VFS_RETURN_ON_NULL_PTR(r, p, EINVAL, -1);
int ret;
CHECK_AND_CALL_SUBCOMPONENT(ret, r, vfs, termios, tcsetattr, local_fd, optional_actions, p);
return ret;
@@ -843,8 +831,7 @@ int tcdrain(int fd)
const int local_fd = get_local_fd(vfs, fd);
struct _reent __attribute__((unused)) *r = __getreent();
if (vfs == NULL || local_fd < 0) {
__errno_r(r) = EBADF;
return -1;
VFS_RETURN_ERR(r, EBADF, -1);
}
int ret;
CHECK_AND_CALL_SUBCOMPONENT(ret, r, vfs, termios, tcdrain, local_fd);
@@ -857,8 +844,7 @@ int tcflush(int fd, int select)
const int local_fd = get_local_fd(vfs, fd);
struct _reent __attribute__((unused)) *r = __getreent();
if (vfs == NULL || local_fd < 0) {
__errno_r(r) = EBADF;
return -1;
VFS_RETURN_ERR(r, EBADF, -1);
}
int ret;
CHECK_AND_CALL_SUBCOMPONENT(ret, r, vfs, termios, tcflush, local_fd, select);
@@ -871,8 +857,7 @@ int tcflow(int fd, int action)
const int local_fd = get_local_fd(vfs, fd);
struct _reent __attribute__((unused)) *r = __getreent();
if (vfs == NULL || local_fd < 0) {
__errno_r(r) = EBADF;
return -1;
VFS_RETURN_ERR(r, EBADF, -1);
}
int ret;
CHECK_AND_CALL_SUBCOMPONENT(ret, r, vfs, termios, tcflow, local_fd, action);
@@ -885,8 +870,7 @@ pid_t tcgetsid(int fd)
const int local_fd = get_local_fd(vfs, fd);
struct _reent __attribute__((unused)) *r = __getreent();
if (vfs == NULL || local_fd < 0) {
__errno_r(r) = EBADF;
return -1;
VFS_RETURN_ERR(r, EBADF, -1);
}
int ret;
CHECK_AND_CALL_SUBCOMPONENT(ret, r, vfs, termios, tcgetsid, local_fd);
@@ -899,8 +883,7 @@ int tcsendbreak(int fd, int duration)
const int local_fd = get_local_fd(vfs, fd);
struct _reent __attribute__((unused)) *r = __getreent();
if (vfs == NULL || local_fd < 0) {
__errno_r(r) = EBADF;
return -1;
VFS_RETURN_ERR(r, EBADF, -1);
}
int ret;
CHECK_AND_CALL_SUBCOMPONENT(ret, r, vfs, termios, tcsendbreak, local_fd, duration);