Merge pull request #5268 from mysterywolf/SYSCALL
[libc]重新梳理read write桩函数实现
This commit is contained in:
commit
0bcab2892a
|
@ -2,7 +2,8 @@ menu "POSIX layer and C standard library"
|
|||
|
||||
config RT_USING_LIBC
|
||||
bool "Enable libc APIs from toolchain"
|
||||
default y
|
||||
select RT_USING_HEAP
|
||||
default n
|
||||
|
||||
if RT_USING_LIBC
|
||||
config RT_LIBC_USING_TIME
|
||||
|
|
|
@ -4,40 +4,68 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* 2014-08-03 bernard Add file header.
|
||||
* Date Author Notes
|
||||
* 2014-08-03 bernard Add file header
|
||||
* 2021-11-13 Meco Man implement no-heap warning
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef RT_USING_HEAP
|
||||
#ifndef RT_USING_HEAP
|
||||
#define DBG_TAG "armlibc.mem"
|
||||
#define DBG_LVL DBG_INFO
|
||||
#include <rtdbg.h>
|
||||
|
||||
#define _NO_HEAP_ERROR() do{LOG_E("Please enable RT_USING_HEAP");\
|
||||
RT_ASSERT(0);\
|
||||
}while(0)
|
||||
#endif /* RT_USING_HEAP */
|
||||
|
||||
#ifdef __CC_ARM
|
||||
/* avoid the heap and heap-using library functions supplied by arm */
|
||||
#pragma import(__use_no_heap)
|
||||
#endif
|
||||
#endif /* __CC_ARM */
|
||||
|
||||
void *malloc(size_t n)
|
||||
{
|
||||
#ifdef RT_USING_HEAP
|
||||
return rt_malloc(n);
|
||||
#else
|
||||
_NO_HEAP_ERROR();
|
||||
return RT_NULL;
|
||||
#endif
|
||||
}
|
||||
RTM_EXPORT(malloc);
|
||||
|
||||
void *realloc(void *rmem, size_t newsize)
|
||||
{
|
||||
#ifdef RT_USING_HEAP
|
||||
return rt_realloc(rmem, newsize);
|
||||
#else
|
||||
_NO_HEAP_ERROR();
|
||||
return RT_NULL;
|
||||
#endif
|
||||
}
|
||||
RTM_EXPORT(realloc);
|
||||
|
||||
void *calloc(size_t nelem, size_t elsize)
|
||||
{
|
||||
#ifdef RT_USING_HEAP
|
||||
return rt_calloc(nelem, elsize);
|
||||
#else
|
||||
_NO_HEAP_ERROR();
|
||||
return RT_NULL;
|
||||
#endif
|
||||
}
|
||||
RTM_EXPORT(calloc);
|
||||
|
||||
void free(void *rmem)
|
||||
{
|
||||
#ifdef RT_USING_HEAP
|
||||
rt_free(rmem);
|
||||
#else
|
||||
_NO_HEAP_ERROR();
|
||||
#endif
|
||||
}
|
||||
RTM_EXPORT(free);
|
||||
#endif
|
||||
|
|
|
@ -144,38 +144,48 @@ int _sys_close(FILEHANDLE fh)
|
|||
*/
|
||||
int _sys_read(FILEHANDLE fh, unsigned char *buf, unsigned len, int mode)
|
||||
{
|
||||
#ifdef RT_USING_POSIX_STDIO
|
||||
#ifdef RT_USING_POSIX
|
||||
int size;
|
||||
|
||||
if (fh == STDIN)
|
||||
{
|
||||
#ifdef RT_USING_POSIX_STDIO
|
||||
if (libc_stdio_get_console() < 0)
|
||||
{
|
||||
LOG_W("Do not invoke standard output before initializing libc");
|
||||
return 0;
|
||||
return 0; /* error, but keep going */
|
||||
}
|
||||
size = read(STDIN_FILENO, buf, len);
|
||||
return len - size;
|
||||
return 0; /* success */
|
||||
#else
|
||||
return 0; /* error */
|
||||
#endif
|
||||
}
|
||||
else if ((fh == STDOUT) || (fh == STDERR))
|
||||
else if (fh == STDOUT || fh == STDERR)
|
||||
{
|
||||
return 0; /* error */
|
||||
}
|
||||
|
||||
size = read(fh, buf, len);
|
||||
if (size >= 0)
|
||||
return len - size;
|
||||
else
|
||||
return 0; /* error */
|
||||
{
|
||||
size = read(fh, buf, len);
|
||||
if (size >= 0)
|
||||
return len - size; /* success */
|
||||
else
|
||||
return 0; /* error */
|
||||
}
|
||||
#else
|
||||
return 0; /* error */
|
||||
#endif /* RT_USING_POSIX_STDIO */
|
||||
#endif /* RT_USING_POSIX */
|
||||
}
|
||||
|
||||
/*
|
||||
* Write to a file. Returns 0 on success, negative on error, and
|
||||
* the number of characters _not_ written on partial success.
|
||||
* `mode' exists for historical reasons and must be ignored.
|
||||
* The return value is either:
|
||||
* A positive number representing the number of characters not written
|
||||
* (so any nonzero return value denotes a failure of some sort).
|
||||
* A negative number indicating an error.
|
||||
*/
|
||||
int _sys_write(FILEHANDLE fh, const unsigned char *buf, unsigned len, int mode)
|
||||
{
|
||||
|
@ -183,39 +193,36 @@ int _sys_write(FILEHANDLE fh, const unsigned char *buf, unsigned len, int mode)
|
|||
int size;
|
||||
#endif /* RT_USING_POSIX */
|
||||
|
||||
if ((fh == STDOUT) || (fh == STDERR))
|
||||
if (fh == STDOUT || fh == STDERR)
|
||||
{
|
||||
#ifdef RT_USING_POSIX_STDIO
|
||||
if (libc_stdio_get_console() < 0)
|
||||
#ifdef RT_USING_CONSOLE
|
||||
rt_device_t console;
|
||||
console = rt_console_get_device();
|
||||
if (console)
|
||||
{
|
||||
LOG_W("Do not invoke standard input before initializing libc");
|
||||
return 0;
|
||||
rt_device_write(console, -1, buf, len);
|
||||
}
|
||||
size = write(STDOUT_FILENO, buf, len);
|
||||
return len - size;
|
||||
#elif defined(RT_USING_CONSOLE)
|
||||
if (rt_console_get_device())
|
||||
{
|
||||
rt_device_write(rt_console_get_device(), -1, buf, len);
|
||||
}
|
||||
|
||||
return 0; /* success */
|
||||
#else
|
||||
return 0; /* error */
|
||||
#endif /* RT_USING_POSIX_STDIO */
|
||||
#endif /* RT_USING_CONSOLE */
|
||||
}
|
||||
else if (fh == STDIN)
|
||||
{
|
||||
return 0; /* error */
|
||||
}
|
||||
|
||||
#ifdef RT_USING_POSIX
|
||||
size = write(fh, buf, len);
|
||||
if (size >= 0)
|
||||
return len - size;
|
||||
else
|
||||
return 0; /* error */
|
||||
{
|
||||
#ifdef RT_USING_POSIX
|
||||
size = write(fh, buf, len);
|
||||
if (size >= 0)
|
||||
return 0; /* success */
|
||||
else
|
||||
return 0; /* error */
|
||||
#else
|
||||
return 0;
|
||||
return 0; /* error */
|
||||
#endif /* RT_USING_POSIX */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -8,10 +8,16 @@
|
|||
* 2015-01-28 Bernard first version
|
||||
*/
|
||||
#include <rtthread.h>
|
||||
#include <yfuns.h>
|
||||
#include <LowLevelIOInterface.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/*
|
||||
* The "__close" function should close the file corresponding to
|
||||
* "handle". It should return 0 on success and nonzero on failure.
|
||||
*/
|
||||
|
||||
#pragma module_name = "?__close"
|
||||
|
||||
int __close(int handle)
|
||||
{
|
||||
if (handle == _LLIO_STDOUT ||
|
||||
|
|
|
@ -8,10 +8,25 @@
|
|||
* 2015-01-28 Bernard first version
|
||||
*/
|
||||
#include <rtthread.h>
|
||||
#include <yfuns.h>
|
||||
#include <LowLevelIOInterface.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/*
|
||||
* The "__lseek" function makes the next file operation (__read or
|
||||
* __write) act on a new location. The parameter "whence" specifies
|
||||
* how the "offset" parameter should be interpreted according to the
|
||||
* following table:
|
||||
*
|
||||
* 0 (=SEEK_SET) - Goto location "offset".
|
||||
* 1 (=SEEK_CUR) - Go "offset" bytes from the current location.
|
||||
* 2 (=SEEK_END) - Go to "offset" bytes from the end.
|
||||
*
|
||||
* This function should return the current file position, or -1 on
|
||||
* failure.
|
||||
*/
|
||||
|
||||
#pragma module_name = "?__lseek"
|
||||
|
||||
long __lseek(int handle, long offset, int whence)
|
||||
{
|
||||
if (handle == _LLIO_STDOUT ||
|
||||
|
|
|
@ -6,27 +6,55 @@
|
|||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2015-01-28 Bernard first version
|
||||
* 2021-11-13 Meco Man implement no-heap warning
|
||||
*/
|
||||
#include <rtthread.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifndef RT_USING_HEAP
|
||||
#define DBG_TAG "dlib.syscall_mem"
|
||||
#define DBG_LVL DBG_INFO
|
||||
#include <rtdbg.h>
|
||||
#define _NO_HEAP_ERROR() do{LOG_E("Please enable RT_USING_HEAP");\
|
||||
RT_ASSERT(0);\
|
||||
}while(0)
|
||||
#endif /* RT_USING_HEAP */
|
||||
|
||||
void *malloc(size_t n)
|
||||
{
|
||||
#ifdef RT_USING_HEAP
|
||||
void *malloc(rt_size_t n)
|
||||
{
|
||||
return rt_malloc(n);
|
||||
#else
|
||||
_NO_HEAP_ERROR();
|
||||
return RT_NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void *realloc(void *rmem, rt_size_t newsize)
|
||||
void *realloc(void *rmem, size_t newsize)
|
||||
{
|
||||
#ifdef RT_USING_HEAP
|
||||
return rt_realloc(rmem, newsize);
|
||||
#else
|
||||
_NO_HEAP_ERROR();
|
||||
return RT_NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void *calloc(rt_size_t nelem, rt_size_t elsize)
|
||||
void *calloc(size_t nelem, size_t elsize)
|
||||
{
|
||||
#ifdef RT_USING_HEAP
|
||||
return rt_calloc(nelem, elsize);
|
||||
#else
|
||||
_NO_HEAP_ERROR();
|
||||
return RT_NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void free(void *rmem)
|
||||
{
|
||||
#ifdef RT_USING_HEAP
|
||||
rt_free(rmem);
|
||||
}
|
||||
#else
|
||||
_NO_HEAP_ERROR();
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -9,9 +9,14 @@
|
|||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <yfuns.h>
|
||||
#include <LowLevelIOInterface.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
/*
|
||||
* The "__open" function opens the file named "filename" as specified
|
||||
* by "mode".
|
||||
*/
|
||||
|
||||
#pragma module_name = "?__open"
|
||||
|
||||
int __open(const char *filename, int mode)
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <yfuns.h>
|
||||
#include <LowLevelIOInterface.h>
|
||||
#include <unistd.h>
|
||||
#ifdef RT_USING_POSIX_STDIO
|
||||
#include "libc.h"
|
||||
|
@ -19,20 +19,36 @@
|
|||
#define DBG_LVL DBG_INFO
|
||||
#include <rtdbg.h>
|
||||
|
||||
/*
|
||||
* The "__read" function reads a number of bytes, at most "size" into
|
||||
* the memory area pointed to by "buffer". It returns the number of
|
||||
* bytes read, 0 at the end of the file, or _LLIO_ERROR if failure
|
||||
* occurs.
|
||||
*
|
||||
* The template implementation below assumes that the application
|
||||
* provides the function "MyLowLevelGetchar". It should return a
|
||||
* character value, or -1 on failure.
|
||||
*/
|
||||
|
||||
#pragma module_name = "?__read"
|
||||
|
||||
size_t __read(int handle, unsigned char *buf, size_t len)
|
||||
{
|
||||
#ifdef RT_USING_POSIX_STDIO
|
||||
#ifdef RT_USING_POSIX
|
||||
int size;
|
||||
|
||||
if (handle == _LLIO_STDIN)
|
||||
{
|
||||
#ifdef RT_USING_POSIX_STDIO
|
||||
if (libc_stdio_get_console() < 0)
|
||||
{
|
||||
LOG_W("Do not invoke standard input before initializing libc");
|
||||
return 0;
|
||||
return 0; /* error, but keep going */
|
||||
}
|
||||
return read(STDIN_FILENO, buf, len);
|
||||
return read(STDIN_FILENO, buf, len); /* return the length of the data read */
|
||||
#else
|
||||
return _LLIO_ERROR;
|
||||
#endif /* RT_USING_POSIX_STDIO */
|
||||
}
|
||||
else if ((handle == _LLIO_STDOUT) || (handle == _LLIO_STDERR))
|
||||
{
|
||||
|
@ -40,7 +56,7 @@ size_t __read(int handle, unsigned char *buf, size_t len)
|
|||
}
|
||||
|
||||
size = read(handle, buf, len);
|
||||
return size;
|
||||
return size; /* return the length of the data read */
|
||||
#else
|
||||
return _LLIO_ERROR;
|
||||
#endif /* RT_USING_POSIX */
|
||||
|
|
|
@ -8,15 +8,21 @@
|
|||
* 2015-01-28 Bernard first version
|
||||
*/
|
||||
#include <rtthread.h>
|
||||
#include <yfuns.h>
|
||||
#include <LowLevelIOInterface.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/*
|
||||
* The "remove" function should remove the file named "filename". It
|
||||
* should return 0 on success and nonzero on failure.
|
||||
*/
|
||||
|
||||
#pragma module_name = "?remove"
|
||||
int remove(const char *val)
|
||||
|
||||
int remove(const char *filename)
|
||||
{
|
||||
#ifdef RT_USING_POSIX
|
||||
return unlink(val);
|
||||
return unlink(filename);
|
||||
#else
|
||||
return -1;
|
||||
return _LLIO_ERROR;
|
||||
#endif /* RT_USING_POSIX */
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <yfuns.h>
|
||||
#include <LowLevelIOInterface.h>
|
||||
#include <unistd.h>
|
||||
#ifdef RT_USING_POSIX_STDIO
|
||||
#include "libc.h"
|
||||
|
@ -19,6 +19,20 @@
|
|||
#define DBG_LVL DBG_INFO
|
||||
#include <rtdbg.h>
|
||||
|
||||
/*
|
||||
* The "__write" function should output "size" number of bytes from
|
||||
* "buffer" in some application-specific way. It should return the
|
||||
* number of characters written, or _LLIO_ERROR on failure.
|
||||
*
|
||||
* If "buffer" is zero then __write should perform flushing of
|
||||
* internal buffers, if any. In this case "handle" can be -1 to
|
||||
* indicate that all handles should be flushed.
|
||||
*
|
||||
* The template implementation below assumes that the application
|
||||
* provides the function "MyLowLevelPutchar". It should return the
|
||||
* character written, or -1 on failure.
|
||||
*/
|
||||
|
||||
#pragma module_name = "?__write"
|
||||
|
||||
size_t __write(int handle, const unsigned char *buf, size_t len)
|
||||
|
@ -29,36 +43,31 @@ size_t __write(int handle, const unsigned char *buf, size_t len)
|
|||
|
||||
if ((handle == _LLIO_STDOUT) || (handle == _LLIO_STDERR))
|
||||
{
|
||||
#ifdef RT_USING_POSIX_STDIO
|
||||
if (libc_stdio_get_console() < 0)
|
||||
{
|
||||
LOG_W("Do not invoke standard output before initializing libc");
|
||||
return 0;
|
||||
}
|
||||
return write(STDOUT_FILENO, (void*)buf, len);
|
||||
#elif defined(RT_USING_CONSOLE)
|
||||
#ifdef RT_USING_CONSOLE
|
||||
rt_device_t console_device;
|
||||
|
||||
console_device = rt_console_get_device();
|
||||
if (console_device != 0)
|
||||
if (console_device)
|
||||
{
|
||||
rt_device_write(console_device, 0, buf, len);
|
||||
}
|
||||
|
||||
return len;
|
||||
return len; /* return the length of the data written */
|
||||
#else
|
||||
return _LLIO_ERROR;
|
||||
#endif /* RT_USING_POSIX */
|
||||
#endif /* RT_USING_CONSOLE */
|
||||
}
|
||||
else if (handle == _LLIO_STDIN)
|
||||
{
|
||||
return _LLIO_ERROR;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
#ifdef RT_USING_POSIX
|
||||
size = write(handle, buf, len);
|
||||
return size;
|
||||
size = write(handle, buf, len);
|
||||
return size; /* return the length of the data written */
|
||||
#else
|
||||
return _LLIO_ERROR;
|
||||
return _LLIO_ERROR;
|
||||
#endif /* RT_USING_POSIX */
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ void _free_r (struct _reent *ptr, void *addr)
|
|||
void *
|
||||
_sbrk_r(struct _reent *ptr, ptrdiff_t incr)
|
||||
{
|
||||
LOG_E("Please enable RT_USING_HEAP or RT_USING_LIBC");
|
||||
LOG_E("Please enable RT_USING_HEAP");
|
||||
RT_ASSERT(0);
|
||||
return RT_NULL;
|
||||
}
|
||||
|
@ -109,7 +109,12 @@ int _getpid_r(struct _reent *ptr)
|
|||
|
||||
int _close_r(struct _reent *ptr, int fd)
|
||||
{
|
||||
#ifdef RT_USING_POSIX
|
||||
return close(fd);
|
||||
#else
|
||||
ptr->_errno = ENOTSUP;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int _execve_r(struct _reent *ptr, const char * name, char *const *argv, char *const *env)
|
||||
|
@ -216,13 +221,27 @@ int _open_r(struct _reent *ptr, const char *file, int flags, int mode)
|
|||
|
||||
_ssize_t _read_r(struct _reent *ptr, int fd, void *buf, size_t nbytes)
|
||||
{
|
||||
#ifdef RT_USING_POSIX_STDIO
|
||||
#ifdef RT_USING_POSIX
|
||||
_ssize_t rc;
|
||||
if (libc_stdio_get_console() < 0 && fd == STDIN_FILENO)
|
||||
if (fd == STDIN_FILENO)
|
||||
{
|
||||
LOG_W("Do not invoke standard input before initializing libc");
|
||||
return 0;
|
||||
#ifdef RT_USING_POSIX_STDIO
|
||||
if (libc_stdio_get_console() < 0)
|
||||
{
|
||||
LOG_W("Do not invoke standard input before initializing libc");
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
ptr->_errno = ENOTSUP;
|
||||
return -1;
|
||||
#endif /* RT_USING_POSIX_STDIO */
|
||||
}
|
||||
else if (fd == STDOUT_FILENO || fd == STDERR_FILENO)
|
||||
{
|
||||
ptr->_errno = ENOTSUP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = read(fd, buf, nbytes);
|
||||
return rc;
|
||||
#else
|
||||
|
@ -271,27 +290,34 @@ _ssize_t _write_r(struct _reent *ptr, int fd, const void *buf, size_t nbytes)
|
|||
{
|
||||
#ifdef RT_USING_POSIX
|
||||
_ssize_t rc;
|
||||
#ifdef RT_USING_POSIX_STDIO
|
||||
if (libc_stdio_get_console() < 0 && fd == STDOUT_FILENO)
|
||||
{
|
||||
LOG_W("Do not invoke standard output before initializing libc");
|
||||
return 0;
|
||||
}
|
||||
#endif /* RT_USING_POSIX_STDIO */
|
||||
rc = write(fd, buf, nbytes);
|
||||
return rc;
|
||||
#elif defined(RT_USING_CONSOLE)
|
||||
if (STDOUT_FILENO == fd)
|
||||
#endif /* RT_USING_POSIX */
|
||||
|
||||
if (fd == STDOUT_FILENO || fd == STDERR_FILENO)
|
||||
{
|
||||
#ifdef RT_USING_CONSOLE
|
||||
rt_device_t console;
|
||||
|
||||
console = rt_console_get_device();
|
||||
if (console)
|
||||
return rt_device_write(console, -1, buf, nbytes);
|
||||
#else
|
||||
ptr->_errno = ENOTSUP;
|
||||
return -1;
|
||||
#endif /* RT_USING_CONSOLE */
|
||||
}
|
||||
#endif /* RT_USING_POSIX */
|
||||
else if (fd == STDIN_FILENO)
|
||||
{
|
||||
ptr->_errno = ENOTSUP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef RT_USING_POSIX
|
||||
rc = write(fd, buf, nbytes);
|
||||
return rc;
|
||||
#else
|
||||
ptr->_errno = ENOTSUP;
|
||||
return -1;
|
||||
#endif /* RT_USING_POSIX */
|
||||
}
|
||||
|
||||
/* for exit() and abort() */
|
||||
|
|
Loading…
Reference in New Issue