syscalls.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include <stdbool.h>
  15. #include <stdlib.h>
  16. #include <stdarg.h>
  17. #include <sys/types.h>
  18. #include <unistd.h>
  19. #include <string.h>
  20. #include <errno.h>
  21. #include <reent.h>
  22. #include <sys/fcntl.h>
  23. #include "sdkconfig.h"
  24. #include "esp_rom_uart.h"
  25. static int syscall_not_implemented(struct _reent *r, ...)
  26. {
  27. __errno_r(r) = ENOSYS;
  28. return -1;
  29. }
  30. static int syscall_not_implemented_aborts(void)
  31. {
  32. abort();
  33. }
  34. ssize_t _write_r_console(struct _reent *r, int fd, const void * data, size_t size)
  35. {
  36. const char* cdata = (const char*) data;
  37. if (fd == STDOUT_FILENO || fd == STDERR_FILENO) {
  38. for (size_t i = 0; i < size; ++i) {
  39. esp_rom_uart_tx_one_char(cdata[i]);
  40. }
  41. return size;
  42. }
  43. __errno_r(r) = EBADF;
  44. return -1;
  45. }
  46. ssize_t _read_r_console(struct _reent *r, int fd, void * data, size_t size)
  47. {
  48. char* cdata = (char*) data;
  49. if (fd == STDIN_FILENO) {
  50. size_t received;
  51. for (received = 0; received < size; ++received) {
  52. int status = esp_rom_uart_rx_one_char((uint8_t*) &cdata[received]);
  53. if (status != 0) {
  54. break;
  55. }
  56. }
  57. return received;
  58. }
  59. __errno_r(r) = EBADF;
  60. return -1;
  61. }
  62. static ssize_t _fstat_r_console(struct _reent *r, int fd, struct stat * st)
  63. {
  64. if (fd == STDOUT_FILENO || fd == STDERR_FILENO) {
  65. memset(st, 0, sizeof(*st));
  66. /* This needs to be set so that stdout and stderr are line buffered. */
  67. st->st_mode = S_IFCHR;
  68. return 0;
  69. }
  70. __errno_r(r) = EBADF;
  71. return -1;
  72. }
  73. /* The following weak definitions of syscalls will be used unless
  74. * another definition is provided. That definition may come from
  75. * VFS, LWIP, or the application.
  76. */
  77. ssize_t _read_r(struct _reent *r, int fd, void * dst, size_t size)
  78. __attribute__((weak,alias("_read_r_console")));
  79. ssize_t _write_r(struct _reent *r, int fd, const void * data, size_t size)
  80. __attribute__((weak,alias("_write_r_console")));
  81. int _fstat_r (struct _reent *r, int fd, struct stat *st)
  82. __attribute__((weak,alias("_fstat_r_console")));
  83. /* The aliases below are to "syscall_not_implemented", which
  84. * doesn't have the same signature as the original function.
  85. * Disable type mismatch warnings for this reason.
  86. */
  87. #if defined(__GNUC__) && !defined(__clang__)
  88. #pragma GCC diagnostic push
  89. #pragma GCC diagnostic ignored "-Wattribute-alias"
  90. #endif
  91. int _open_r(struct _reent *r, const char * path, int flags, int mode)
  92. __attribute__((weak,alias("syscall_not_implemented")));
  93. int _close_r(struct _reent *r, int fd)
  94. __attribute__((weak,alias("syscall_not_implemented")));
  95. off_t _lseek_r(struct _reent *r, int fd, off_t size, int mode)
  96. __attribute__((weak,alias("syscall_not_implemented")));
  97. int _fcntl_r(struct _reent *r, int fd, int cmd, int arg)
  98. __attribute__((weak,alias("syscall_not_implemented")));
  99. int _stat_r(struct _reent *r, const char * path, struct stat * st)
  100. __attribute__((weak,alias("syscall_not_implemented")));
  101. int _link_r(struct _reent *r, const char* n1, const char* n2)
  102. __attribute__((weak,alias("syscall_not_implemented")));
  103. int _unlink_r(struct _reent *r, const char *path)
  104. __attribute__((weak,alias("syscall_not_implemented")));
  105. int _rename_r(struct _reent *r, const char *src, const char *dst)
  106. __attribute__((weak,alias("syscall_not_implemented")));
  107. int _isatty_r(struct _reent *r, int fd)
  108. __attribute__((weak,alias("syscall_not_implemented")));
  109. /* These functions are not expected to be overridden */
  110. int _system_r(struct _reent *r, const char *str)
  111. __attribute__((alias("syscall_not_implemented")));
  112. int raise(int sig)
  113. __attribute__((alias("syscall_not_implemented_aborts")));
  114. int _raise_r(struct _reent *r, int sig)
  115. __attribute__((alias("syscall_not_implemented_aborts")));
  116. void* _sbrk_r(struct _reent *r, ptrdiff_t sz)
  117. __attribute__((alias("syscall_not_implemented_aborts")));
  118. int _getpid_r(struct _reent *r)
  119. __attribute__((alias("syscall_not_implemented")));
  120. int _kill_r(struct _reent *r, int pid, int sig)
  121. __attribute__((alias("syscall_not_implemented")));
  122. void _exit(int __status)
  123. __attribute__((alias("syscall_not_implemented_aborts")));
  124. #if defined(__GNUC__) && !defined(__clang__)
  125. #pragma GCC diagnostic pop
  126. #endif
  127. /* Similar to syscall_not_implemented, but not taking struct _reent argument */
  128. int system(const char* str)
  129. {
  130. errno = ENOSYS;
  131. return -1;
  132. }
  133. /* Replaces newlib fcntl, which has been compiled without HAVE_FCNTL */
  134. int fcntl(int fd, int cmd, ...)
  135. {
  136. va_list args;
  137. va_start(args, cmd);
  138. int arg = va_arg(args, int);
  139. va_end(args);
  140. struct _reent* r = __getreent();
  141. return _fcntl_r(r, fd, cmd, arg);
  142. }
  143. /* No-op function, used to force linking this file,
  144. instead of the syscalls implementation from libgloss.
  145. */
  146. void newlib_include_syscalls_impl(void)
  147. {
  148. }