syscalls.c 5.5 KB

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