mirror of
https://github.com/espressif/esp-idf.git
synced 2025-11-18 10:31:09 +00:00
Merge branch 'feature/vfs_find_free_fd' into 'master'
Add "find file descriptor" API to be used by VFS drivers See merge request idf/esp-idf!2389
This commit is contained in:
@@ -57,6 +57,11 @@ extern "C" {
|
||||
*/
|
||||
#define ESP_VFS_FLAG_CONTEXT_PTR 1
|
||||
|
||||
/*
|
||||
* @brief VFS identificator used for esp_vfs_register_with_id()
|
||||
*/
|
||||
typedef int esp_vfs_id_t;
|
||||
|
||||
/**
|
||||
* @brief VFS definition structure
|
||||
*
|
||||
@@ -221,6 +226,24 @@ esp_err_t esp_vfs_register(const char* base_path, const esp_vfs_t* vfs, void* ct
|
||||
*/
|
||||
esp_err_t esp_vfs_register_fd_range(const esp_vfs_t *vfs, void *ctx, int min_fd, int max_fd);
|
||||
|
||||
/**
|
||||
* Special case function for registering a VFS that uses a method other than
|
||||
* open() to open new file descriptors. In comparison with
|
||||
* esp_vfs_register_fd_range, this function doesn't pre-registers an interval
|
||||
* of file descriptors. File descriptors can be registered later, by using
|
||||
* esp_vfs_register_fd.
|
||||
*
|
||||
* @param vfs Pointer to esp_vfs_t. Meaning is the same as for esp_vfs_register().
|
||||
* @param ctx Pointer to context structure. Meaning is the same as for esp_vfs_register().
|
||||
* @param vfs_id Here will be written the VFS ID which can be passed to
|
||||
* esp_vfs_register_fd for registering file descriptors.
|
||||
*
|
||||
* @return ESP_OK if successful, ESP_ERR_NO_MEM if too many VFSes are
|
||||
* registered, ESP_ERR_INVALID_ARG if the file descriptor boundaries
|
||||
* are incorrect.
|
||||
*/
|
||||
esp_err_t esp_vfs_register_with_id(const esp_vfs_t *vfs, void *ctx, esp_vfs_id_t *vfs_id);
|
||||
|
||||
/**
|
||||
* Unregister a virtual filesystem for given path prefix
|
||||
*
|
||||
@@ -230,6 +253,31 @@ esp_err_t esp_vfs_register_fd_range(const esp_vfs_t *vfs, void *ctx, int min_fd,
|
||||
*/
|
||||
esp_err_t esp_vfs_unregister(const char* base_path);
|
||||
|
||||
/**
|
||||
* Special function for registering another file descriptor for a VFS registered
|
||||
* by esp_vfs_register_with_id.
|
||||
*
|
||||
* @param vfs_id VFS identificator returned by esp_vfs_register_with_id.
|
||||
* @param fd The registered file descriptor will be written to this address.
|
||||
*
|
||||
* @return ESP_OK if the registration is successful,
|
||||
* ESP_ERR_NO_MEM if too many file descriptors are registered,
|
||||
* ESP_ERR_INVALID_ARG if the arguments are incorrect.
|
||||
*/
|
||||
esp_err_t esp_vfs_register_fd(esp_vfs_id_t vfs_id, int *fd);
|
||||
|
||||
/**
|
||||
* Special function for unregistering a file descriptor belonging to a VFS
|
||||
* registered by esp_vfs_register_with_id.
|
||||
*
|
||||
* @param vfs_id VFS identificator returned by esp_vfs_register_with_id.
|
||||
* @param fd File descriptor which should be unregistered.
|
||||
*
|
||||
* @return ESP_OK if the registration is successful,
|
||||
* ESP_ERR_INVALID_ARG if the arguments are incorrect.
|
||||
*/
|
||||
esp_err_t esp_vfs_unregister_fd(esp_vfs_id_t vfs_id, int fd);
|
||||
|
||||
/**
|
||||
* These functions are to be used in newlib syscall table. They will be called by
|
||||
* newlib when it needs to use any of the syscalls.
|
||||
|
||||
@@ -157,6 +157,16 @@ esp_err_t esp_vfs_register_fd_range(const esp_vfs_t *vfs, void *ctx, int min_fd,
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t esp_vfs_register_with_id(const esp_vfs_t *vfs, void *ctx, esp_vfs_id_t *vfs_id)
|
||||
{
|
||||
if (vfs_id == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*vfs_id = -1;
|
||||
return esp_vfs_register_common("", LEN_PATH_PREFIX_IGNORED, vfs, ctx, vfs_id);
|
||||
}
|
||||
|
||||
esp_err_t esp_vfs_unregister(const char* base_path)
|
||||
{
|
||||
for (size_t i = 0; i < s_vfs_count; ++i) {
|
||||
@@ -183,6 +193,48 @@ esp_err_t esp_vfs_unregister(const char* base_path)
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
esp_err_t esp_vfs_register_fd(esp_vfs_id_t vfs_id, int *fd)
|
||||
{
|
||||
if (vfs_id < 0 || vfs_id >= s_vfs_count || fd == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_err_t ret = ESP_ERR_NO_MEM;
|
||||
_lock_acquire(&s_fd_table_lock);
|
||||
for (int i = 0; i < MAX_FDS; ++i) {
|
||||
if (s_fd_table[i].vfs_index == -1) {
|
||||
s_fd_table[i].permanent = true;
|
||||
s_fd_table[i].vfs_index = vfs_id;
|
||||
s_fd_table[i].local_fd = i;
|
||||
*fd = i;
|
||||
ret = ESP_OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
_lock_release(&s_fd_table_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t esp_vfs_unregister_fd(esp_vfs_id_t vfs_id, int fd)
|
||||
{
|
||||
esp_err_t ret = ESP_ERR_INVALID_ARG;
|
||||
|
||||
if (vfs_id < 0 || vfs_id >= s_vfs_count || fd < 0 || fd >= MAX_FDS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
_lock_acquire(&s_fd_table_lock);
|
||||
fd_table_t *item = s_fd_table + fd;
|
||||
if (item->permanent == true && item->vfs_index == vfs_id && item->local_fd == fd) {
|
||||
*item = FD_TABLE_ENTRY_UNUSED;
|
||||
ret = ESP_OK;
|
||||
}
|
||||
_lock_release(&s_fd_table_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline const vfs_entry_t *get_vfs_for_index(int index)
|
||||
{
|
||||
if (index < 0 || index >= s_vfs_count) {
|
||||
|
||||
Reference in New Issue
Block a user