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