2022-10-21 10:17:49 +08:00
|
|
|
#include <errno.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include "vlibc_stdio.h"
|
|
|
|
|
|
|
|
#ifndef vlibc_malloc
|
|
|
|
#define vlibc_malloc malloc
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef vlibc_free
|
|
|
|
#define vlibc_free free
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define _VLIBC_IO_HAVE_WRITE ((unsigned char)(0x04))
|
|
|
|
#define _VLIBC_IO_HAVE_READ ((unsigned char)(0x08))
|
|
|
|
|
|
|
|
#define _VLIBC_ABUF_ENABLE ((unsigned char)(0x01))
|
|
|
|
#define _VLIBC_ABUF_DISABLE ((unsigned char)(0x00))
|
|
|
|
|
|
|
|
#define _VLIBC_TYPEIS_IO ((int)(0x01))
|
|
|
|
#define _VLIBC_TYPEIS_FILE ((int)(0x02))
|
|
|
|
|
|
|
|
#define vlibc_file(_stream) ((vlibc_file_t *)(_stream))
|
|
|
|
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
int FRESULT_to_errno[20] = {
|
|
|
|
0,
|
|
|
|
EIO,
|
|
|
|
EPIPE,
|
|
|
|
EIO,
|
|
|
|
ENOENT,
|
|
|
|
ENOENT,
|
|
|
|
ENOEXEC,
|
|
|
|
ENOSPC,
|
|
|
|
EACCES,
|
|
|
|
ENXIO,
|
|
|
|
EROFS,
|
|
|
|
ENXIO,
|
|
|
|
ENXIO,
|
|
|
|
EPERM,
|
|
|
|
EPERM,
|
|
|
|
EBUSY,
|
|
|
|
EACCES,
|
|
|
|
ENOMEM,
|
|
|
|
EMFILE,
|
|
|
|
EINVAL
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_DEBUG
|
2022-10-21 10:17:49 +08:00
|
|
|
#define CHECK_FILE(_stream, __ret) \
|
|
|
|
do { \
|
|
|
|
if ((void *)(_stream) == NULL) { \
|
|
|
|
errno = EINVAL; \
|
|
|
|
return __ret; \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
#else
|
|
|
|
#define CHECK_FILE(_stream, __ret) \
|
|
|
|
do { \
|
|
|
|
} while (0)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define IF_IO_DEV(_stream) \
|
|
|
|
if (((vlibc_file(_stream)->magic) & _VLIBC_MAGIC_MASK) == _VLIBC_IO_MAGIC_CODE)
|
|
|
|
|
|
|
|
#define IF_FILE(_stream) \
|
|
|
|
if (((vlibc_file(_stream)->magic) & _VLIBC_MAGIC_MASK) == _VLIBC_FILE_MAGIC_CODE)
|
|
|
|
|
|
|
|
vlibc_file_t *__vlibc_stdio_fileptrs[3] = { NULL, NULL, NULL };
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief
|
|
|
|
* @param stream
|
|
|
|
*/
|
|
|
|
void vlibc_clearerr(VLIBC_FILE *stream)
|
|
|
|
{
|
|
|
|
CHECK_FILE(stream, /*!< no return */);
|
|
|
|
CHECK_FILE(stream->file, /*!< no return */);
|
|
|
|
|
|
|
|
IF_IO_DEV(stream)
|
|
|
|
{
|
|
|
|
stream->io->err = 0;
|
|
|
|
}
|
|
|
|
else IF_FILE(stream)
|
|
|
|
{
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
f_error(stream->file) = 0;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief
|
|
|
|
* @param stream
|
|
|
|
* @return int
|
|
|
|
*/
|
|
|
|
int vlibc_feof(VLIBC_FILE *stream)
|
|
|
|
{
|
|
|
|
CHECK_FILE(stream, EOF);
|
|
|
|
CHECK_FILE(stream->file, EOF);
|
|
|
|
|
|
|
|
IF_IO_DEV(stream)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else IF_FILE(stream)
|
|
|
|
{
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
return f_eof(stream->file);
|
|
|
|
#else
|
|
|
|
errno = EIO;
|
|
|
|
return EOF;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
errno = EBADF;
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief
|
|
|
|
* @param stream
|
|
|
|
* @return int
|
|
|
|
*/
|
|
|
|
int vlibc_ferror(VLIBC_FILE *stream)
|
|
|
|
{
|
|
|
|
CHECK_FILE(stream, EOF);
|
|
|
|
CHECK_FILE(stream->file, EOF);
|
|
|
|
|
|
|
|
IF_IO_DEV(stream)
|
|
|
|
{
|
|
|
|
return stream->io->err;
|
|
|
|
}
|
|
|
|
else IF_FILE(stream)
|
|
|
|
{
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
int fresult;
|
|
|
|
|
|
|
|
fresult = f_error(stream->file);
|
|
|
|
|
|
|
|
return (fresult == FR_OK) ? 0 : EOF;
|
|
|
|
#else
|
|
|
|
errno = EIO;
|
|
|
|
return EOF;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
errno = EBADF;
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int __get_mode_vlibc_fopen(const char *mode, unsigned char *iomode, unsigned char *openmode)
|
|
|
|
{
|
|
|
|
/*!< get file and io open mode */
|
|
|
|
switch (*mode) {
|
|
|
|
case 'r':
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
*openmode = FA_READ;
|
|
|
|
#endif
|
|
|
|
*iomode = _VLIBC_IO_READ;
|
|
|
|
break;
|
|
|
|
case 'w':
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
*openmode = FA_CREATE_ALWAYS | FA_WRITE;
|
|
|
|
#endif
|
|
|
|
*iomode = _VLIBC_IO_WRITE;
|
|
|
|
break;
|
|
|
|
case 'a':
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
*openmode = FA_OPEN_APPEND | FA_WRITE;
|
|
|
|
#endif
|
|
|
|
*iomode = _VLIBC_IO_WRITE;
|
|
|
|
break;
|
|
|
|
case 'x':
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
*openmode = FA_CREATE_NEW | FA_WRITE;
|
|
|
|
#endif
|
|
|
|
*iomode = _VLIBC_IO_WRITE;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
errno = EINVAL;
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 1; i < 7; ++i) {
|
|
|
|
switch (*++mode) {
|
|
|
|
case '\0':
|
|
|
|
break;
|
|
|
|
case '+':
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
*openmode |= (FA_WRITE | FA_READ);
|
|
|
|
#endif
|
|
|
|
*iomode |= (_VLIBC_IO_WRITE | _VLIBC_IO_READ);
|
|
|
|
continue;
|
|
|
|
case 'b':
|
|
|
|
continue;
|
|
|
|
default:
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int __check_type_vlibc_fopen(const char *name, unsigned char iomode)
|
|
|
|
{
|
|
|
|
/*!< check type */
|
|
|
|
switch (*name) {
|
|
|
|
case '>':
|
|
|
|
case '<': {
|
|
|
|
unsigned char count = 1;
|
|
|
|
for (int i = 0; i < VLIBC_FILENAME_MAX; i++) {
|
|
|
|
switch (*name++) {
|
|
|
|
case '\0':
|
|
|
|
if ((0 < count) && (count <= _VLIBC_IONAME_MAX)) {
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
errno = ENOEXEC;
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!< output io device */
|
|
|
|
case '<':
|
|
|
|
if (iomode & _VLIBC_IO_READ) {
|
|
|
|
errno = EINVAL;
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((0 < count) && (count <= _VLIBC_IONAME_MAX)) {
|
|
|
|
count = 0;
|
|
|
|
/*!< have a output io device */
|
|
|
|
iomode |= _VLIBC_IO_HAVE_WRITE;
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
errno = ENOEXEC;
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!< input io device */
|
|
|
|
case '>':
|
|
|
|
if (iomode & _VLIBC_IO_WRITE) {
|
|
|
|
errno = EINVAL;
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (iomode & _VLIBC_IO_HAVE_READ) {
|
|
|
|
/*!< only can have one input io device */
|
|
|
|
errno = EINVAL;
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((0 < count) && (count <= _VLIBC_IONAME_MAX)) {
|
|
|
|
count = 0;
|
|
|
|
/*!< have a input io device */
|
|
|
|
iomode |= _VLIBC_IO_HAVE_READ;
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
errno = ENOEXEC;
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
count++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (iomode & (_VLIBC_IO_HAVE_READ | _VLIBC_IO_HAVE_WRITE)) {
|
|
|
|
return _VLIBC_TYPEIS_IO;
|
|
|
|
}
|
|
|
|
|
|
|
|
return _VLIBC_TYPEIS_FILE;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
return _VLIBC_TYPEIS_FILE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static VLIBC_FILE *__io_vlibc_open(VLIBC_FILE *fnew, const char *name, unsigned char iomode)
|
|
|
|
{
|
|
|
|
int result = 0;
|
|
|
|
char namebuf[_VLIBC_IONAME_MAX + 2];
|
|
|
|
char *nameend = NULL;
|
|
|
|
char nofree = 0;
|
|
|
|
|
|
|
|
if (fnew == NULL) {
|
|
|
|
fnew = (VLIBC_FILE *)vlibc_malloc(sizeof(VLIBC_FILE));
|
|
|
|
if (fnew == NULL) {
|
|
|
|
errno = ENOMEM;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
nofree = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
fnew->io = (void *)vlibc_malloc(sizeof(struct __vlibc_io));
|
|
|
|
if (fnew == NULL) {
|
|
|
|
errno = ENOMEM;
|
|
|
|
if (nofree == 0) {
|
|
|
|
vlibc_free(fnew);
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
fnew->io->bg = (void *)vlibc_malloc(VLIBC_BUFSIZ);
|
|
|
|
if (fnew->io->bg == NULL) {
|
|
|
|
vlibc_free(fnew->io);
|
|
|
|
errno = ENOMEM;
|
|
|
|
if (nofree == 0) {
|
|
|
|
vlibc_free(fnew);
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
fnew->magic = _VLIBC_IO_MAGIC_CODE;
|
|
|
|
|
|
|
|
fnew->io->dev = 0;
|
|
|
|
fnew->io->flag = (iomode & (_VLIBC_IO_WRITE | _VLIBC_IO_READ));
|
|
|
|
fnew->io->vbuf = _IOLBF;
|
|
|
|
fnew->io->abuf = _VLIBC_ABUF_ENABLE;
|
|
|
|
fnew->io->err = 0;
|
|
|
|
|
|
|
|
fnew->io->wp = fnew->io->bg;
|
|
|
|
fnew->io->rp = fnew->io->bg;
|
|
|
|
fnew->io->ed = fnew->io->bg + VLIBC_BUFSIZ;
|
|
|
|
|
|
|
|
/*!< init io device */
|
|
|
|
for (int i = 0; i < VLIBC_FILENAME_MAX; i++) {
|
|
|
|
switch (*name) {
|
|
|
|
case '\0':
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '<':
|
|
|
|
case '>': {
|
|
|
|
for (; i < VLIBC_FILENAME_MAX; i++) {
|
|
|
|
switch (*name++) {
|
|
|
|
case '\0':
|
|
|
|
name--;
|
|
|
|
break;
|
|
|
|
case '>':
|
|
|
|
case '<':
|
|
|
|
strncpy(namebuf, name, _VLIBC_IONAME_MAX + 1);
|
|
|
|
nameend = strchr(namebuf, '<');
|
|
|
|
if (nameend != NULL) {
|
|
|
|
*nameend = '\0';
|
|
|
|
} else {
|
|
|
|
nameend = strchr(namebuf, '>');
|
|
|
|
if (nameend != NULL) {
|
|
|
|
*nameend = '\0';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
result = __vlibc_io_init(namebuf, iomode & (_VLIBC_IO_READ | _VLIBC_IO_WRITE));
|
|
|
|
fnew->io->dev = result;
|
|
|
|
if (result == 0) {
|
|
|
|
vlibc_free(fnew->io->bg);
|
|
|
|
vlibc_free(fnew->io);
|
|
|
|
fnew->magic = 0;
|
|
|
|
if (nofree == 0) {
|
|
|
|
vlibc_free(fnew);
|
|
|
|
}
|
|
|
|
errno = ENOENT;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
name++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return fnew;
|
|
|
|
}
|
|
|
|
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
static VLIBC_FILE *__file_vlibc_open(VLIBC_FILE *fnew, const char *name, unsigned char openmode)
|
|
|
|
{
|
|
|
|
int fresult;
|
|
|
|
char nofree = 0;
|
|
|
|
|
|
|
|
if (fnew == NULL) {
|
|
|
|
fnew = (VLIBC_FILE *)vlibc_malloc(sizeof(VLIBC_FILE));
|
|
|
|
if (fnew == NULL) {
|
|
|
|
errno = ENOMEM;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
nofree = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
fnew->file = (FIL *)vlibc_malloc(sizeof(FIL));
|
|
|
|
if (fnew->file == NULL) {
|
|
|
|
if (nofree == 0) {
|
|
|
|
vlibc_free(fnew);
|
|
|
|
}
|
|
|
|
errno = ENOMEM;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
fnew->magic = _VLIBC_FILE_MAGIC_CODE;
|
|
|
|
|
|
|
|
fresult = f_open(fnew->file, name, openmode);
|
|
|
|
|
|
|
|
if (fresult != FR_OK) {
|
|
|
|
if (fresult <= FR_INVALID_PARAMETER) {
|
|
|
|
errno = FRESULT_to_errno[fresult];
|
|
|
|
}
|
|
|
|
|
|
|
|
vlibc_free(fnew->file);
|
|
|
|
fnew->magic = 0;
|
|
|
|
if (nofree == 0) {
|
|
|
|
vlibc_free(fnew);
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return fnew;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
static VLIBC_FILE *__file_vlibc_open(VLIBC_FILE *fnew, const char *name, unsigned char openmode)
|
|
|
|
{
|
|
|
|
errno = EIO;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static int __io_vlibc_close(VLIBC_FILE *stream)
|
|
|
|
{
|
|
|
|
int result;
|
|
|
|
|
|
|
|
if (stream->io->abuf == _VLIBC_ABUF_ENABLE) {
|
|
|
|
if (stream->io->bg == NULL) {
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
result = __vlibc_io_deinit(stream->io);
|
|
|
|
if (result != stream->io->dev) {
|
|
|
|
errno = EINVAL;
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (stream->io->abuf == _VLIBC_ABUF_ENABLE) {
|
|
|
|
vlibc_free(stream->io->bg);
|
|
|
|
}
|
|
|
|
|
|
|
|
vlibc_free(stream->io);
|
|
|
|
stream->magic = 0;
|
|
|
|
stream->io = NULL;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
static int __file_vlibc_close(VLIBC_FILE *stream)
|
|
|
|
{
|
|
|
|
int fresult;
|
|
|
|
|
|
|
|
fresult = f_close(stream->file);
|
|
|
|
if (fresult != FR_OK) {
|
|
|
|
if (fresult <= FR_INVALID_PARAMETER) {
|
|
|
|
errno = FRESULT_to_errno[fresult];
|
|
|
|
}
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
|
|
|
|
vlibc_free(stream->file);
|
|
|
|
stream->magic = 0;
|
|
|
|
stream->io = NULL;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
static int __file_vlibc_close(VLIBC_FILE *stream)
|
|
|
|
{
|
|
|
|
errno = EIO;
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief
|
|
|
|
* @param filename
|
|
|
|
* @param mode
|
|
|
|
* @return VLIBC_FILE*
|
|
|
|
*/
|
|
|
|
VLIBC_FILE *vlibc_fopen(const char *filename, const char *mode)
|
|
|
|
{
|
|
|
|
CHECK_FILE(filename, NULL);
|
|
|
|
CHECK_FILE(mode, NULL);
|
|
|
|
|
|
|
|
unsigned char iomode = 0;
|
|
|
|
unsigned char openmode = 0;
|
|
|
|
|
|
|
|
if (__get_mode_vlibc_fopen(mode, &iomode, &openmode)) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (__check_type_vlibc_fopen(filename, iomode)) {
|
|
|
|
case EOF:
|
|
|
|
return NULL;
|
|
|
|
case _VLIBC_TYPEIS_IO:
|
|
|
|
return __io_vlibc_open(NULL, filename, iomode);
|
|
|
|
case _VLIBC_TYPEIS_FILE:
|
|
|
|
return __file_vlibc_open(NULL, filename, openmode);
|
|
|
|
default:
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief 重定向输入输出流.
|
|
|
|
* fclose 之后的文件指针无法再 freopen.
|
|
|
|
* freopen 会关闭原先的流, 并按照 <filename> 和 <mode> 直接在原先的流上重建实体.
|
|
|
|
* freopen 会将两个流合并为一个流, 可以多次执行将多个流合并,
|
|
|
|
* 只需要一次 fclose 就可以关闭所有合并的流
|
|
|
|
* @param filename
|
|
|
|
* @param mode
|
|
|
|
* @param stream
|
|
|
|
* @return VLIBC_FILE*
|
|
|
|
*/
|
|
|
|
VLIBC_FILE *vlibc_freopen(const char *filename, const char *mode, VLIBC_FILE *stream)
|
|
|
|
{
|
|
|
|
CHECK_FILE(filename, NULL);
|
|
|
|
CHECK_FILE(mode, NULL);
|
|
|
|
CHECK_FILE(stream, NULL);
|
|
|
|
CHECK_FILE(stream->file, NULL);
|
|
|
|
|
|
|
|
VLIBC_FILE *fnew = NULL;
|
|
|
|
|
|
|
|
unsigned char iomode = 0;
|
|
|
|
unsigned char openmode = 0;
|
|
|
|
|
|
|
|
if (__get_mode_vlibc_fopen(mode, &iomode, &openmode)) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (__check_type_vlibc_fopen(filename, iomode)) {
|
|
|
|
case EOF:
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
case _VLIBC_TYPEIS_IO:
|
|
|
|
IF_IO_DEV(stream)
|
|
|
|
{
|
|
|
|
if (__io_vlibc_close(stream)) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
fnew = __io_vlibc_open(stream, filename, iomode);
|
|
|
|
if (fnew == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return fnew;
|
|
|
|
}
|
|
|
|
else IF_FILE(stream)
|
|
|
|
{
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
if (__file_vlibc_close(stream)) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
fnew = __io_vlibc_open(stream, filename, iomode);
|
|
|
|
if (fnew == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return fnew;
|
|
|
|
#else
|
|
|
|
return NULL;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
errno = EBADF;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
case _VLIBC_TYPEIS_FILE:
|
|
|
|
IF_IO_DEV(stream)
|
|
|
|
{
|
|
|
|
if (__io_vlibc_close(stream)) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
fnew = __file_vlibc_open(stream, filename, openmode);
|
|
|
|
if (fnew == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return fnew;
|
|
|
|
}
|
|
|
|
else IF_FILE(stream)
|
|
|
|
{
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
if (__file_vlibc_close(stream)) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
fnew = __file_vlibc_open(stream, filename, openmode);
|
|
|
|
if (fnew == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return fnew;
|
|
|
|
#else
|
|
|
|
return NULL;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
errno = EBADF;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief
|
|
|
|
* @param stream
|
|
|
|
* @return int
|
|
|
|
*/
|
|
|
|
int vlibc_fclose(VLIBC_FILE *stream)
|
|
|
|
{
|
|
|
|
CHECK_FILE(stream, EOF);
|
|
|
|
CHECK_FILE(stream->file, EOF);
|
|
|
|
|
|
|
|
IF_IO_DEV(stream)
|
|
|
|
{
|
|
|
|
if (vlibc_fflush(stream)) {
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (__io_vlibc_close(stream)) {
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
|
|
|
|
vlibc_free(stream);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else IF_FILE(stream)
|
|
|
|
{
|
|
|
|
if (vlibc_fflush(stream)) {
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (__file_vlibc_close(stream)) {
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
|
|
|
|
vlibc_free(stream);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
errno = EBADF;
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief
|
|
|
|
* @param ptr
|
|
|
|
* @param size
|
|
|
|
* @param nmemb
|
|
|
|
* @param stream
|
|
|
|
* @return size_t
|
|
|
|
*/
|
|
|
|
size_t vlibc_fread(void *ptr, size_t size, size_t nmemb, VLIBC_FILE *stream)
|
|
|
|
{
|
|
|
|
CHECK_FILE(ptr, 0);
|
|
|
|
CHECK_FILE(size, 0);
|
|
|
|
CHECK_FILE(nmemb, 0);
|
|
|
|
CHECK_FILE(stream, 0);
|
|
|
|
|
|
|
|
IF_IO_DEV(stream)
|
|
|
|
{
|
|
|
|
size_t bytes = size * nmemb;
|
|
|
|
char *bg = stream->io->bg;
|
|
|
|
char *wp = stream->io->wp;
|
|
|
|
char *rp = stream->io->rp;
|
|
|
|
char *ed = stream->io->ed;
|
|
|
|
|
|
|
|
do {
|
|
|
|
if (rp == wp) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rp == ed) {
|
|
|
|
rp = bg;
|
|
|
|
}
|
|
|
|
|
|
|
|
*(char *)ptr++ = *rp++;
|
|
|
|
} while (--bytes);
|
|
|
|
|
|
|
|
return size * nmemb - bytes;
|
|
|
|
}
|
|
|
|
else IF_FILE(stream)
|
|
|
|
{
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
int fresult;
|
|
|
|
size_t bytes;
|
|
|
|
fresult = f_read(stream->file, ptr, size * nmemb, &bytes);
|
|
|
|
if (fresult != FR_OK) {
|
|
|
|
if (fresult <= FR_INVALID_PARAMETER) {
|
|
|
|
errno = FRESULT_to_errno[fresult];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return bytes;
|
|
|
|
#else
|
|
|
|
return 0;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
errno = EBADF;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief
|
|
|
|
* @param ptr
|
|
|
|
* @param size
|
|
|
|
* @param nmemb
|
|
|
|
* @param stream
|
|
|
|
* @return size_t
|
|
|
|
*/
|
|
|
|
size_t vlibc_fwrite(const void *ptr, size_t size, size_t nmemb, VLIBC_FILE *stream)
|
|
|
|
{
|
|
|
|
CHECK_FILE(ptr, 0);
|
|
|
|
CHECK_FILE(size, 0);
|
|
|
|
CHECK_FILE(nmemb, 0);
|
|
|
|
CHECK_FILE(stream, 0);
|
|
|
|
|
|
|
|
IF_IO_DEV(stream)
|
|
|
|
{
|
|
|
|
switch (stream->io->vbuf) {
|
|
|
|
case _IOFBF: {
|
|
|
|
size_t ret;
|
|
|
|
size_t bytes = size * nmemb;
|
|
|
|
char *bg = stream->io->bg;
|
|
|
|
char *wp = stream->io->wp;
|
|
|
|
char *ed = stream->io->ed;
|
|
|
|
|
|
|
|
do {
|
|
|
|
if (wp == ed) {
|
|
|
|
ret = __vlibc_io_mem2dev(stream->io, bg, ed - bg);
|
|
|
|
if (ret == 0) {
|
|
|
|
stream->io->wp = wp;
|
|
|
|
errno = EINVAL;
|
|
|
|
return size * nmemb - bytes;
|
|
|
|
}
|
|
|
|
wp = bg;
|
|
|
|
}
|
|
|
|
|
|
|
|
*wp++ = *(char *)ptr++;
|
|
|
|
} while (--bytes);
|
|
|
|
|
|
|
|
if (wp == ed) {
|
|
|
|
ret = __vlibc_io_mem2dev(stream->io, bg, ed - bg);
|
|
|
|
if (ret == 0) {
|
|
|
|
stream->io->wp = wp;
|
|
|
|
errno = EINVAL;
|
|
|
|
return size * nmemb - bytes;
|
|
|
|
}
|
|
|
|
wp = bg;
|
|
|
|
}
|
|
|
|
|
|
|
|
stream->io->wp = wp;
|
|
|
|
return size * nmemb - bytes;
|
|
|
|
}
|
|
|
|
case _IOLBF: {
|
|
|
|
size_t ret;
|
|
|
|
size_t bytes = size * nmemb;
|
|
|
|
char *bg = stream->io->bg;
|
|
|
|
char *wp = stream->io->wp;
|
|
|
|
char *ed = stream->io->ed;
|
|
|
|
|
|
|
|
do {
|
|
|
|
if (wp == ed) {
|
|
|
|
ret = __vlibc_io_mem2dev(stream->io, bg, ed - bg);
|
|
|
|
if (ret == 0) {
|
|
|
|
stream->io->wp = wp;
|
|
|
|
errno = EINVAL;
|
|
|
|
return size * nmemb - bytes;
|
|
|
|
}
|
|
|
|
wp = bg;
|
|
|
|
}
|
|
|
|
|
|
|
|
*wp = *(char *)ptr++;
|
|
|
|
|
|
|
|
if (*wp == '\n') {
|
|
|
|
wp++;
|
|
|
|
--bytes;
|
|
|
|
ret = __vlibc_io_mem2dev(stream->io, bg, wp - bg);
|
|
|
|
if (ret == 0) {
|
|
|
|
stream->io->wp = wp;
|
|
|
|
errno = EINVAL;
|
|
|
|
return size * nmemb - bytes;
|
|
|
|
}
|
|
|
|
|
|
|
|
wp = bg;
|
|
|
|
} else {
|
|
|
|
wp++;
|
|
|
|
--bytes;
|
|
|
|
}
|
|
|
|
} while (bytes);
|
|
|
|
|
|
|
|
stream->io->wp = wp;
|
|
|
|
|
|
|
|
return size * nmemb - bytes;
|
|
|
|
}
|
|
|
|
case _IONBF: {
|
|
|
|
size_t bytes;
|
|
|
|
bytes = __vlibc_io_mem2dev(stream->io, ptr, size * nmemb);
|
|
|
|
if (bytes == 0) {
|
|
|
|
errno = EINVAL;
|
|
|
|
}
|
|
|
|
return bytes;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
errno = EINVAL;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else IF_FILE(stream)
|
|
|
|
{
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
int fresult;
|
|
|
|
size_t bytes;
|
|
|
|
fresult = f_write(stream->file, ptr, size * nmemb, &bytes);
|
|
|
|
if (fresult != FR_OK) {
|
|
|
|
if (fresult <= FR_INVALID_PARAMETER) {
|
|
|
|
errno = FRESULT_to_errno[fresult];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return bytes;
|
|
|
|
#else
|
|
|
|
errno = EIO;
|
|
|
|
return 0;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
errno = EBADF;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief
|
|
|
|
* @param stream
|
|
|
|
* @return int
|
|
|
|
*/
|
|
|
|
int vlibc_fflush(VLIBC_FILE *stream)
|
|
|
|
{
|
|
|
|
CHECK_FILE(stream, EOF);
|
|
|
|
CHECK_FILE(stream->file, EOF);
|
|
|
|
|
|
|
|
IF_IO_DEV(stream)
|
|
|
|
{
|
|
|
|
switch (stream->io->vbuf) {
|
|
|
|
case _IOFBF:
|
|
|
|
case _IOLBF: {
|
|
|
|
size_t ret;
|
|
|
|
ret = (size_t)(stream->io->wp - stream->io->bg);
|
|
|
|
if (ret > 0) {
|
|
|
|
ret = __vlibc_io_mem2dev(stream->io, stream->io->bg, ret);
|
|
|
|
if (ret == 0) {
|
|
|
|
errno = EINVAL;
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
stream->io->wp = stream->io->bg;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case _IONBF:
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
default:
|
|
|
|
errno = EINVAL;
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else IF_FILE(stream)
|
|
|
|
{
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
int fresult;
|
|
|
|
fresult = f_sync(stream->file);
|
|
|
|
if (fresult != FR_OK) {
|
|
|
|
if (fresult <= FR_INVALID_PARAMETER) {
|
|
|
|
errno = FRESULT_to_errno[fresult];
|
|
|
|
}
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
#else
|
|
|
|
errno = EIO;
|
|
|
|
return EOF;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
errno = EBADF;
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief
|
|
|
|
* @param stream
|
|
|
|
* @param offset
|
|
|
|
* @param whence
|
|
|
|
* @return int
|
|
|
|
*/
|
|
|
|
int vlibc_fseek(VLIBC_FILE *stream, long offset, int whence)
|
|
|
|
{
|
|
|
|
CHECK_FILE(stream, EOF);
|
|
|
|
CHECK_FILE(stream->file, EOF);
|
|
|
|
|
|
|
|
IF_IO_DEV(stream)
|
|
|
|
{
|
|
|
|
errno = ESPIPE;
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
else IF_FILE(stream)
|
|
|
|
{
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
int fresult;
|
|
|
|
long long temp;
|
|
|
|
|
|
|
|
switch (whence) {
|
|
|
|
case SEEK_SET:
|
|
|
|
fresult = f_lseek(stream->file, offset);
|
|
|
|
if (fresult != FR_OK) {
|
|
|
|
if (fresult <= FR_INVALID_PARAMETER) {
|
|
|
|
errno = FRESULT_to_errno[fresult];
|
|
|
|
}
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case SEEK_CUR:
|
|
|
|
temp = (long)stream->file->fptr;
|
|
|
|
temp += offset;
|
|
|
|
if (temp > 0xffffffff) {
|
|
|
|
errno = ESPIPE;
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
|
|
|
|
fresult = f_lseek(stream->file, temp);
|
|
|
|
if (fresult != FR_OK) {
|
|
|
|
if (fresult <= FR_INVALID_PARAMETER) {
|
|
|
|
errno = FRESULT_to_errno[fresult];
|
|
|
|
}
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case SEEK_END:
|
|
|
|
temp = (long)stream->file->obj.objsize;
|
|
|
|
temp -= offset;
|
|
|
|
if (temp <= 0) {
|
|
|
|
temp = 0;
|
|
|
|
}
|
|
|
|
fresult = f_lseek(stream->file, temp);
|
|
|
|
if (fresult != FR_OK) {
|
|
|
|
if (fresult <= FR_INVALID_PARAMETER) {
|
|
|
|
errno = FRESULT_to_errno[fresult];
|
|
|
|
}
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
default:
|
|
|
|
errno = EINVAL;
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
errno = EIO;
|
|
|
|
return EOF;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
errno = EBADF;
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief
|
|
|
|
* @param stream
|
|
|
|
* @return long
|
|
|
|
*/
|
|
|
|
long vlibc_ftell(VLIBC_FILE *stream)
|
|
|
|
{
|
|
|
|
CHECK_FILE(stream, EOF);
|
|
|
|
CHECK_FILE(stream->file, EOF);
|
|
|
|
|
|
|
|
IF_IO_DEV(stream)
|
|
|
|
{
|
|
|
|
errno = ESPIPE;
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
else IF_FILE(stream)
|
|
|
|
{
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
return (long)f_tell(stream->file);
|
|
|
|
#else
|
|
|
|
errno = EIO;
|
|
|
|
return EOF;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
errno = EBADF;
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief
|
|
|
|
* @param filename
|
|
|
|
* @return int
|
|
|
|
*/
|
|
|
|
int vlibc_remove(const char *filename)
|
|
|
|
{
|
|
|
|
CHECK_FILE(filename, EOF);
|
|
|
|
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
int fresult;
|
|
|
|
FILINFO finfo;
|
|
|
|
|
|
|
|
fresult = f_stat(filename, &finfo);
|
|
|
|
if (fresult != FR_OK) {
|
|
|
|
if (fresult <= FR_INVALID_PARAMETER) {
|
|
|
|
errno = FRESULT_to_errno[fresult];
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fresult = f_unlink(filename);
|
|
|
|
if (fresult != FR_OK) {
|
|
|
|
if (fresult <= FR_INVALID_PARAMETER) {
|
|
|
|
errno = FRESULT_to_errno[fresult];
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
#else
|
|
|
|
errno = ENOENT;
|
|
|
|
return EOF;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief
|
|
|
|
* @param old_filename
|
|
|
|
* @param new_filename
|
|
|
|
* @return int
|
|
|
|
*/
|
|
|
|
int vlibc_rename(const char *old_filename, const char *new_filename)
|
|
|
|
{
|
|
|
|
CHECK_FILE(old_filename, EOF);
|
|
|
|
CHECK_FILE(new_filename, EOF);
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
int fresult;
|
|
|
|
|
|
|
|
fresult = f_rename(old_filename, new_filename);
|
|
|
|
if (fresult != FR_OK) {
|
|
|
|
if (fresult <= FR_INVALID_PARAMETER) {
|
|
|
|
errno = FRESULT_to_errno[fresult];
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
#else
|
|
|
|
errno = ENOENT;
|
|
|
|
return EOF;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief
|
|
|
|
* @param stream
|
|
|
|
*/
|
|
|
|
void vlibc_rewind(VLIBC_FILE *stream)
|
|
|
|
{
|
|
|
|
CHECK_FILE(stream, /*!< no return */);
|
|
|
|
CHECK_FILE(stream->file, /*!< no return */);
|
|
|
|
|
|
|
|
IF_IO_DEV(stream)
|
|
|
|
{
|
|
|
|
errno = ESPIPE;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else IF_FILE(stream)
|
|
|
|
{
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
int fresult;
|
|
|
|
fresult = f_lseek(stream->file, 0);
|
|
|
|
if (fresult != FR_OK) {
|
|
|
|
if (fresult <= FR_INVALID_PARAMETER) {
|
|
|
|
errno = FRESULT_to_errno[fresult];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
errno = EIO;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
errno = EBADF;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief
|
|
|
|
* @param stream
|
|
|
|
* @param buffer
|
|
|
|
*/
|
|
|
|
void vlibc_setbuf(VLIBC_FILE *stream, char *buffer)
|
|
|
|
{
|
|
|
|
CHECK_FILE(stream, /*!< no return */);
|
|
|
|
|
|
|
|
IF_IO_DEV(stream)
|
|
|
|
{
|
|
|
|
if (stream->io->abuf == _VLIBC_ABUF_ENABLE) {
|
|
|
|
if (stream->io->bg == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
vlibc_free(stream->io->bg);
|
|
|
|
stream->io->abuf = _VLIBC_ABUF_DISABLE;
|
|
|
|
}
|
|
|
|
|
|
|
|
stream->io->bg = buffer;
|
|
|
|
stream->io->wp = buffer;
|
|
|
|
stream->io->rp = buffer;
|
|
|
|
|
|
|
|
if (buffer == NULL) {
|
|
|
|
stream->io->ed = buffer;
|
|
|
|
} else {
|
|
|
|
stream->io->ed = buffer + VLIBC_BUFSIZ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else IF_FILE(stream)
|
|
|
|
{
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
return;
|
|
|
|
#else
|
|
|
|
errno = EIO;
|
|
|
|
return;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
errno = EBADF;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief
|
|
|
|
* @param stream
|
|
|
|
* @param buffer
|
|
|
|
* @param mode
|
|
|
|
* @param size
|
|
|
|
* @return int
|
|
|
|
*/
|
|
|
|
int vlibc_setvbuf(VLIBC_FILE *stream, char *buffer, int mode, size_t size)
|
|
|
|
{
|
|
|
|
CHECK_FILE(stream, EOF);
|
|
|
|
|
|
|
|
IF_IO_DEV(stream)
|
|
|
|
{
|
|
|
|
switch (mode) {
|
|
|
|
case _IOFBF:
|
|
|
|
case _IOLBF:
|
|
|
|
vlibc_setbuf(stream, buffer);
|
|
|
|
if (buffer != NULL) {
|
|
|
|
stream->io->ed = buffer + size;
|
|
|
|
}
|
|
|
|
stream->io->vbuf = mode;
|
|
|
|
break;
|
|
|
|
case _IONBF:
|
|
|
|
vlibc_setbuf(stream, NULL);
|
|
|
|
stream->io->vbuf = mode;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else IF_FILE(stream)
|
|
|
|
{
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
return EOF;
|
|
|
|
#else
|
|
|
|
errno = EIO;
|
|
|
|
return EOF;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
errno = EBADF;
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
VLIBC_FILE *vlibc_tmpfile(void)
|
|
|
|
{
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
return NULL;
|
|
|
|
#else
|
|
|
|
return NULL;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
char *vlibc_tmpnam(char *str)
|
|
|
|
{
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
return NULL;
|
|
|
|
#else
|
|
|
|
return NULL;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
int vlibc_fscanf(VLIBC_FILE *stream, const char *format, ...)
|
|
|
|
{
|
|
|
|
CHECK_FILE(stream, EOF);
|
|
|
|
CHECK_FILE(format, EOF);
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
return EOF;
|
|
|
|
#else
|
|
|
|
return EOF;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
int vlibc_scanf(const char *format, ...)
|
|
|
|
{
|
|
|
|
CHECK_FILE(format, EOF);
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
return EOF;
|
|
|
|
#else
|
|
|
|
return EOF;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
int vlibc_sscanf(const char *str, const char *format, ...)
|
|
|
|
{
|
|
|
|
CHECK_FILE(str, EOF);
|
|
|
|
CHECK_FILE(format, EOF);
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
return EOF;
|
|
|
|
#else
|
|
|
|
return EOF;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
int vlibc_vfscanf(VLIBC_FILE *stream, const char *format, va_list arg)
|
|
|
|
{
|
|
|
|
CHECK_FILE(stream, EOF);
|
|
|
|
CHECK_FILE(format, EOF);
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
return EOF;
|
|
|
|
#else
|
|
|
|
return EOF;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
int vlibc_vscanf(const char *format, va_list arg)
|
|
|
|
{
|
|
|
|
CHECK_FILE(format, EOF);
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
return EOF;
|
|
|
|
#else
|
|
|
|
return EOF;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
int vlibc_vsscanf(const char *str, const char *format, va_list arg)
|
|
|
|
{
|
|
|
|
CHECK_FILE(str, EOF);
|
|
|
|
CHECK_FILE(format, EOF);
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
return EOF;
|
|
|
|
#else
|
|
|
|
return EOF;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
int vlibc_fgetc(VLIBC_FILE *stream)
|
|
|
|
{
|
|
|
|
CHECK_FILE(stream, EOF);
|
|
|
|
IF_IO_DEV(stream)
|
|
|
|
{
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
else IF_FILE(stream)
|
|
|
|
{
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
int fresult;
|
|
|
|
int ch;
|
|
|
|
size_t bytes;
|
|
|
|
fresult = f_read(stream->file, &ch, 1, &bytes);
|
|
|
|
if (fresult != FR_OK) {
|
|
|
|
if (fresult <= FR_INVALID_PARAMETER) {
|
|
|
|
errno = FRESULT_to_errno[fresult];
|
|
|
|
}
|
|
|
|
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
if (bytes != 1) {
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ch;
|
|
|
|
#else
|
|
|
|
|
|
|
|
return EOF;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
char *vlibc_fgets(char *str, int size, VLIBC_FILE *stream)
|
|
|
|
{
|
|
|
|
CHECK_FILE(str, NULL);
|
|
|
|
CHECK_FILE(stream, NULL);
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
return NULL;
|
|
|
|
#else
|
|
|
|
return NULL;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
int vlibc_fputc(int chr, VLIBC_FILE *stream)
|
|
|
|
{
|
|
|
|
CHECK_FILE(stream, EOF);
|
|
|
|
|
|
|
|
IF_IO_DEV(stream)
|
|
|
|
{
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
else IF_FILE(stream)
|
|
|
|
{
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
int fresult;
|
|
|
|
size_t bytes;
|
|
|
|
fresult = f_write(stream->file, &chr, 1, &bytes);
|
|
|
|
if (fresult != FR_OK) {
|
|
|
|
if (fresult <= FR_INVALID_PARAMETER) {
|
|
|
|
errno = FRESULT_to_errno[fresult];
|
|
|
|
}
|
|
|
|
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
if (bytes != 1) {
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
#else
|
|
|
|
|
|
|
|
return EOF;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int vlibc_fputs(const char *str, VLIBC_FILE *stream)
|
|
|
|
{
|
|
|
|
return vlibc_fprintf(stream, str);
|
|
|
|
}
|
|
|
|
|
|
|
|
int vlibc_getc(VLIBC_FILE *stream)
|
|
|
|
{
|
|
|
|
CHECK_FILE(stream, EOF);
|
|
|
|
IF_IO_DEV(stream)
|
|
|
|
{
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
else IF_FILE(stream)
|
|
|
|
{
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
int fresult;
|
|
|
|
int ch;
|
|
|
|
size_t bytes;
|
|
|
|
fresult = f_read(stream->file, &ch, 1, &bytes);
|
|
|
|
if (fresult != FR_OK) {
|
|
|
|
if (fresult <= FR_INVALID_PARAMETER) {
|
|
|
|
errno = FRESULT_to_errno[fresult];
|
|
|
|
}
|
|
|
|
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
if (bytes != 1) {
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ch;
|
|
|
|
#else
|
|
|
|
|
|
|
|
return EOF;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int vlibc_getchar(void)
|
|
|
|
{
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
return EOF;
|
|
|
|
#else
|
|
|
|
return EOF;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
char *vlibc_gets(char *str)
|
|
|
|
{
|
|
|
|
CHECK_FILE(str, NULL);
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
return NULL;
|
|
|
|
#else
|
|
|
|
return NULL;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
int vlibc_putc(int chr, VLIBC_FILE *stream)
|
|
|
|
{
|
|
|
|
CHECK_FILE(stream, EOF);
|
|
|
|
|
|
|
|
IF_IO_DEV(stream)
|
|
|
|
{
|
|
|
|
size_t size;
|
|
|
|
size = vlibc_fwrite(&chr, 1, 1, stream);
|
|
|
|
if (size == 1) {
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else IF_FILE(stream)
|
|
|
|
{
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
int fresult;
|
|
|
|
size_t bytes;
|
|
|
|
fresult = f_write(stream->file, &chr, 1, &bytes);
|
|
|
|
if (fresult != FR_OK) {
|
|
|
|
if (fresult <= FR_INVALID_PARAMETER) {
|
|
|
|
errno = FRESULT_to_errno[fresult];
|
|
|
|
}
|
|
|
|
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
if (bytes != 1) {
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
#else
|
|
|
|
|
|
|
|
return EOF;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int vlibc_putchar(int chr)
|
|
|
|
{
|
|
|
|
IF_IO_DEV(vlibc_stdout)
|
|
|
|
{
|
|
|
|
size_t size;
|
|
|
|
size = vlibc_fwrite(&chr, 1, 1, vlibc_stdout);
|
|
|
|
if (size == 1) {
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else IF_FILE(vlibc_stdout)
|
|
|
|
{
|
2022-10-29 16:12:43 +08:00
|
|
|
#ifdef CONFIG_VLIBC_FATFS
|
2022-10-21 10:17:49 +08:00
|
|
|
int fresult;
|
|
|
|
size_t bytes;
|
|
|
|
fresult = f_write(vlibc_stdout->file, &chr, 1, &bytes);
|
|
|
|
if (fresult != FR_OK) {
|
|
|
|
if (fresult <= FR_INVALID_PARAMETER) {
|
|
|
|
errno = FRESULT_to_errno[fresult];
|
|
|
|
}
|
|
|
|
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
if (bytes != 1) {
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
#else
|
|
|
|
|
|
|
|
return EOF;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int vlibc_puts(const char *str)
|
|
|
|
{
|
|
|
|
return vlibc_printf(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
void vlibc_perror(const char *str)
|
|
|
|
{
|
|
|
|
CHECK_FILE(str, /*!< no return */);
|
|
|
|
}
|