mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
feat(esp_libc): picolibc: add fopencookie implementation
This commit is contained in:
@@ -80,6 +80,7 @@ else()
|
||||
"src/picolibc/errno.c")
|
||||
if(CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY)
|
||||
list(APPEND srcs "src/picolibc/getreent.c")
|
||||
list(APPEND srcs "src/picolibc/fopencookie.c")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -40,6 +40,20 @@ FILE *funopen(const void *cookie,
|
||||
void flockfile(FILE *);
|
||||
void funlockfile(FILE *);
|
||||
FILE *open_memstream(char **, size_t *);
|
||||
|
||||
typedef ssize_t cookie_read_function_t(void *cookie, char *buf, size_t n);
|
||||
typedef ssize_t cookie_write_function_t(void *cookie, const char *buf, size_t n);
|
||||
typedef int cookie_seek_function_t(void *cookie, __off_t *off, int whence);
|
||||
typedef int cookie_close_function_t(void *cookie);
|
||||
typedef struct {
|
||||
/* These four struct member names are dictated by Linux; hopefully,
|
||||
they don't conflict with any macros. */
|
||||
cookie_read_function_t *read;
|
||||
cookie_write_function_t *write;
|
||||
cookie_seek_function_t *seek;
|
||||
cookie_close_function_t *close;
|
||||
} cookie_io_functions_t;
|
||||
FILE *fopencookie(void *cookie, const char *mode, cookie_io_functions_t functions);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "esp_compiler.h"
|
||||
|
||||
struct cookie_wrap {
|
||||
void *cookie;
|
||||
cookie_io_functions_t fn;
|
||||
};
|
||||
|
||||
static int fun_read(void *c, char *buf, int size)
|
||||
{
|
||||
struct cookie_wrap *w = c;
|
||||
return (int)w->fn.read(w->cookie, buf, (size_t)size);
|
||||
}
|
||||
|
||||
static int fun_write(void *c, const char *buf, int size)
|
||||
{
|
||||
struct cookie_wrap *w = c;
|
||||
return (int)w->fn.write(w->cookie, buf, (size_t)size);
|
||||
}
|
||||
|
||||
static off_t fun_seek(void *c, off_t off, int whence)
|
||||
{
|
||||
struct cookie_wrap *w = c;
|
||||
return w->fn.seek(w->cookie, &off, whence);
|
||||
}
|
||||
|
||||
static int fun_close(void *c)
|
||||
{
|
||||
struct cookie_wrap *w = c;
|
||||
int r = w->fn.close ? w->fn.close(w->cookie) : 0;
|
||||
free(w);
|
||||
return r;
|
||||
}
|
||||
|
||||
FILE *fopencookie(void *cookie, __attribute__((unused)) const char *mode,
|
||||
cookie_io_functions_t fn)
|
||||
{
|
||||
ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-malloc-leak")
|
||||
struct cookie_wrap *w = malloc(sizeof * w);
|
||||
if (!w) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
w->cookie = cookie;
|
||||
w->fn = fn;
|
||||
|
||||
FILE *fp = funopen(w,
|
||||
fn.read ? fun_read : NULL,
|
||||
fn.write ? fun_write : NULL,
|
||||
fn.seek ? fun_seek : NULL,
|
||||
fun_close);
|
||||
|
||||
if (!fp) {
|
||||
free(w);
|
||||
}
|
||||
return fp;
|
||||
ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-malloc-leak")
|
||||
}
|
||||
Reference in New Issue
Block a user