Selaa lähdekoodia

Merge pull request #5268 from mysterywolf/SYSCALL

[libc]重新梳理read write桩函数实现
Bernard Xiong 3 vuotta sitten
vanhempi
commit
0bcab2892a

+ 2 - 1
components/libc/Kconfig

@@ -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

+ 32 - 4
components/libc/compilers/armlibc/mem_std.c

@@ -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

+ 38 - 31
components/libc/compilers/armlibc/syscalls.c

@@ -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)
-        {
-            LOG_W("Do not invoke standard input before initializing libc");
-            return 0;
-        }
-        size = write(STDOUT_FILENO, buf, len);
-        return len - size;
-#elif defined(RT_USING_CONSOLE)
-        if (rt_console_get_device())
+#ifdef RT_USING_CONSOLE
+        rt_device_t console;
+        console = rt_console_get_device();
+        if (console)
         {
-            rt_device_write(rt_console_get_device(), -1, buf, len);
+            rt_device_write(console, -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 */
+    }
 }
 
 /*

+ 7 - 1
components/libc/compilers/dlib/syscall_close.c

@@ -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 ||

+ 16 - 1
components/libc/compilers/dlib/syscall_lseek.c

@@ -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 ||

+ 33 - 5
components/libc/compilers/dlib/syscall_mem.c

@@ -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>
 
-#ifdef RT_USING_HEAP
-void *malloc(rt_size_t n)
+#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
     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
+}

+ 6 - 1
components/libc/compilers/dlib/syscall_open.c

@@ -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)

+ 21 - 5
components/libc/compilers/dlib/syscall_read.c

@@ -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 */

+ 10 - 4
components/libc/compilers/dlib/syscall_remove.c

@@ -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 */
 }

+ 25 - 16
components/libc/compilers/dlib/syscall_write.c

@@ -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 */
+    }
 }

+ 43 - 17
components/libc/compilers/gcc/newlib/syscalls.c

@@ -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() */