mirror of
https://github.com/espressif/esp-idf
synced 2025-03-09 17:19:09 -04:00
feat(fatfs): add support for a few fcntl commands
This commit is contained in:
parent
7a214c1fab
commit
80d4c75b89
@ -39,7 +39,7 @@ typedef struct {
|
|||||||
FATFS fs; /* fatfs library FS structure */
|
FATFS fs; /* fatfs library FS structure */
|
||||||
char tmp_path_buf[FILENAME_MAX+3]; /* temporary buffer used to prepend drive name to the path */
|
char tmp_path_buf[FILENAME_MAX+3]; /* temporary buffer used to prepend drive name to the path */
|
||||||
char tmp_path_buf2[FILENAME_MAX+3]; /* as above; used in functions which take two path arguments */
|
char tmp_path_buf2[FILENAME_MAX+3]; /* as above; used in functions which take two path arguments */
|
||||||
bool *o_append; /* O_APPEND is stored here for each max_files entries (because O_APPEND is not compatible with FA_OPEN_APPEND) */
|
uint32_t *flags; /* file descriptor flags, array of max_files size */
|
||||||
#ifdef CONFIG_VFS_SUPPORT_DIR
|
#ifdef CONFIG_VFS_SUPPORT_DIR
|
||||||
char dir_path[FILENAME_MAX]; /* variable to store path of opened directory*/
|
char dir_path[FILENAME_MAX]; /* variable to store path of opened directory*/
|
||||||
struct cached_data cached_fileinfo;
|
struct cached_data cached_fileinfo;
|
||||||
@ -85,6 +85,7 @@ static int vfs_fat_open(void* ctx, const char * path, int flags, int mode);
|
|||||||
static int vfs_fat_close(void* ctx, int fd);
|
static int vfs_fat_close(void* ctx, int fd);
|
||||||
static int vfs_fat_fstat(void* ctx, int fd, struct stat * st);
|
static int vfs_fat_fstat(void* ctx, int fd, struct stat * st);
|
||||||
static int vfs_fat_fsync(void* ctx, int fd);
|
static int vfs_fat_fsync(void* ctx, int fd);
|
||||||
|
static int vfs_fat_fcntl(void* ctx, int fd, int cmd, int arg);
|
||||||
#ifdef CONFIG_VFS_SUPPORT_DIR
|
#ifdef CONFIG_VFS_SUPPORT_DIR
|
||||||
static int vfs_fat_stat(void* ctx, const char * path, struct stat * st);
|
static int vfs_fat_stat(void* ctx, const char * path, struct stat * st);
|
||||||
static int vfs_fat_link(void* ctx, const char* n1, const char* n2);
|
static int vfs_fat_link(void* ctx, const char* n1, const char* n2);
|
||||||
@ -170,6 +171,7 @@ static const esp_vfs_fs_ops_t s_vfs_fat = {
|
|||||||
.open_p = &vfs_fat_open,
|
.open_p = &vfs_fat_open,
|
||||||
.close_p = &vfs_fat_close,
|
.close_p = &vfs_fat_close,
|
||||||
.fstat_p = &vfs_fat_fstat,
|
.fstat_p = &vfs_fat_fstat,
|
||||||
|
.fcntl_p = &vfs_fat_fcntl,
|
||||||
.fsync_p = &vfs_fat_fsync,
|
.fsync_p = &vfs_fat_fsync,
|
||||||
#ifdef CONFIG_VFS_SUPPORT_DIR
|
#ifdef CONFIG_VFS_SUPPORT_DIR
|
||||||
.dir = &s_vfs_fat_dir,
|
.dir = &s_vfs_fat_dir,
|
||||||
@ -199,19 +201,19 @@ esp_err_t esp_vfs_fat_register_cfg(const esp_vfs_fat_conf_t* conf, FATFS** out_f
|
|||||||
return ESP_ERR_NO_MEM;
|
return ESP_ERR_NO_MEM;
|
||||||
}
|
}
|
||||||
memset(fat_ctx, 0, ctx_size);
|
memset(fat_ctx, 0, ctx_size);
|
||||||
fat_ctx->o_append = ff_memalloc(max_files * sizeof(bool));
|
fat_ctx->flags = ff_memalloc(max_files * sizeof(*fat_ctx->flags));
|
||||||
if (fat_ctx->o_append == NULL) {
|
if (fat_ctx->flags == NULL) {
|
||||||
free(fat_ctx);
|
free(fat_ctx);
|
||||||
return ESP_ERR_NO_MEM;
|
return ESP_ERR_NO_MEM;
|
||||||
}
|
}
|
||||||
memset(fat_ctx->o_append, 0, max_files * sizeof(bool));
|
memset(fat_ctx->flags, 0, max_files * sizeof(*fat_ctx->flags));
|
||||||
fat_ctx->max_files = max_files;
|
fat_ctx->max_files = max_files;
|
||||||
strlcpy(fat_ctx->fat_drive, conf->fat_drive, sizeof(fat_ctx->fat_drive) - 1);
|
strlcpy(fat_ctx->fat_drive, conf->fat_drive, sizeof(fat_ctx->fat_drive) - 1);
|
||||||
strlcpy(fat_ctx->base_path, conf->base_path, sizeof(fat_ctx->base_path) - 1);
|
strlcpy(fat_ctx->base_path, conf->base_path, sizeof(fat_ctx->base_path) - 1);
|
||||||
|
|
||||||
esp_err_t err = esp_vfs_register_fs(conf->base_path, &s_vfs_fat, ESP_VFS_FLAG_CONTEXT_PTR | ESP_VFS_FLAG_STATIC, fat_ctx);
|
esp_err_t err = esp_vfs_register_fs(conf->base_path, &s_vfs_fat, ESP_VFS_FLAG_CONTEXT_PTR | ESP_VFS_FLAG_STATIC, fat_ctx);
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
free(fat_ctx->o_append);
|
free(fat_ctx->flags);
|
||||||
free(fat_ctx);
|
free(fat_ctx);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -239,7 +241,7 @@ esp_err_t esp_vfs_fat_unregister_path(const char* base_path)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
_lock_close(&fat_ctx->lock);
|
_lock_close(&fat_ctx->lock);
|
||||||
free(fat_ctx->o_append);
|
free(fat_ctx->flags);
|
||||||
free(fat_ctx);
|
free(fat_ctx);
|
||||||
s_fat_ctxs[ctx] = NULL;
|
s_fat_ctxs[ctx] = NULL;
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
@ -427,7 +429,7 @@ static int vfs_fat_open(void* ctx, const char * path, int flags, int mode)
|
|||||||
// Other VFS drivers handles O_APPEND well (to the best of my knowledge),
|
// Other VFS drivers handles O_APPEND well (to the best of my knowledge),
|
||||||
// therefore this flag is stored here (at this VFS level) in order to save
|
// therefore this flag is stored here (at this VFS level) in order to save
|
||||||
// memory.
|
// memory.
|
||||||
fat_ctx->o_append[fd] = (flags & O_APPEND) == O_APPEND;
|
fat_ctx->flags[fd] = (flags & (O_APPEND | O_ACCMODE));
|
||||||
_lock_release(&fat_ctx->lock);
|
_lock_release(&fat_ctx->lock);
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
@ -438,7 +440,7 @@ static ssize_t vfs_fat_write(void* ctx, int fd, const void * data, size_t size)
|
|||||||
FIL* file = &fat_ctx->files[fd];
|
FIL* file = &fat_ctx->files[fd];
|
||||||
FRESULT res;
|
FRESULT res;
|
||||||
_lock_acquire(&fat_ctx->lock);
|
_lock_acquire(&fat_ctx->lock);
|
||||||
if (fat_ctx->o_append[fd]) {
|
if (fat_ctx->flags[fd] & O_APPEND) {
|
||||||
if ((res = f_lseek(file, f_size(file))) != FR_OK) {
|
if ((res = f_lseek(file, f_size(file))) != FR_OK) {
|
||||||
ESP_LOGD(TAG, "%s: fresult=%d", __func__, res);
|
ESP_LOGD(TAG, "%s: fresult=%d", __func__, res);
|
||||||
errno = fresult_to_errno(res);
|
errno = fresult_to_errno(res);
|
||||||
@ -672,6 +674,26 @@ static int vfs_fat_fstat(void* ctx, int fd, struct stat * st)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int vfs_fat_fcntl(void* ctx, int fd, int cmd, int arg)
|
||||||
|
{
|
||||||
|
vfs_fat_ctx_t* fat_ctx = (vfs_fat_ctx_t*) ctx;
|
||||||
|
switch (cmd) {
|
||||||
|
case F_GETFL:
|
||||||
|
return fat_ctx->flags[fd];
|
||||||
|
case F_SETFL:
|
||||||
|
fat_ctx->flags[fd] = arg;
|
||||||
|
return 0;
|
||||||
|
// no-ops:
|
||||||
|
case F_SETLK:
|
||||||
|
case F_SETLKW:
|
||||||
|
case F_GETLK:
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_VFS_SUPPORT_DIR
|
#ifdef CONFIG_VFS_SUPPORT_DIR
|
||||||
|
|
||||||
static inline mode_t get_stat_mode(bool is_dir)
|
static inline mode_t get_stat_mode(bool is_dir)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user