1 /*
2 * Copyright (c) 2006-2021, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2021-02-11 Meco Man remove _gettimeofday_r() and _times_r()
9 * 2021-02-13 Meco Man re-implement exit() and abort()
10 * 2021-02-21 Meco Man improve and beautify syscalls
11 * 2021-02-24 Meco Man fix bug of _isatty_r()
12 */
13
14 #include <reent.h>
15 #include <rtthread.h>
16 #include <stdio.h>
17 #include <string.h>
18 #include <stddef.h>
19 #include <fcntl.h>
20 #include <unistd.h>
21 #include <sys/errno.h>
22 #include <sys/stat.h>
23 #ifdef RT_USING_POSIX_STDIO
24 #include <posix/stdio.h>
25 #endif /* RT_USING_POSIX_STDIO */
26 #include <posix/stdlib.h>
27 #ifdef RT_USING_MODULE
28 #include <dlmodule.h>
29 #endif /* RT_USING_MODULE */
30 #include <compiler_private.h>
31 #define DBG_TAG "newlib.syscalls"
32 #define DBG_LVL DBG_INFO
33 #include <rtdbg.h>
34
35 #ifdef RT_USING_HEAP /* Memory routine */
_malloc_r(struct _reent * ptr,size_t size)36 void *_malloc_r(struct _reent *ptr, size_t size)
37 {
38 void* result;
39
40 result = (void*)rt_malloc(size);
41 if (result == RT_NULL)
42 {
43 ptr->_errno = ENOMEM;
44 }
45
46 return result;
47 }
48
_realloc_r(struct _reent * ptr,void * old,size_t newlen)49 void *_realloc_r(struct _reent *ptr, void *old, size_t newlen)
50 {
51 void* result;
52
53 result = (void*)rt_realloc(old, newlen);
54 if (result == RT_NULL)
55 {
56 ptr->_errno = ENOMEM;
57 }
58
59 return result;
60 }
61
_calloc_r(struct _reent * ptr,size_t size,size_t len)62 void *_calloc_r(struct _reent *ptr, size_t size, size_t len)
63 {
64 void* result;
65
66 result = (void*)rt_calloc(size, len);
67 if (result == RT_NULL)
68 {
69 ptr->_errno = ENOMEM;
70 }
71
72 return result;
73 }
74
_free_r(struct _reent * ptr,void * addr)75 void _free_r(struct _reent *ptr, void *addr)
76 {
77 rt_free(addr);
78 }
79
80 #else
_sbrk_r(struct _reent * ptr,ptrdiff_t incr)81 void *_sbrk_r(struct _reent *ptr, ptrdiff_t incr)
82 {
83 LOG_E("Please enable RT_USING_HEAP");
84 RT_ASSERT(0);
85 return RT_NULL;
86 }
87 #endif /*RT_USING_HEAP*/
88
__libc_init_array(void)89 void __libc_init_array(void)
90 {
91 /* we not use __libc init_aray to initialize C++ objects */
92 /* __libc_init_array is ARM code, not Thumb; it will cause a hardfault. */
93 }
94
95 /* Reentrant versions of system calls. */
96 #ifndef _REENT_ONLY
__errno(void)97 int *__errno(void)
98 {
99 return _rt_errno();
100 }
101 #endif
102
_getpid_r(struct _reent * ptr)103 int _getpid_r(struct _reent *ptr)
104 {
105 return 0;
106 }
107
_close_r(struct _reent * ptr,int fd)108 int _close_r(struct _reent *ptr, int fd)
109 {
110 #ifdef DFS_USING_POSIX
111 return close(fd);
112 #else
113 LOG_W("%s: %s", __func__, _WARNING_WITHOUT_FS);
114 ptr->_errno = ENOTSUP;
115 return -1;
116 #endif /* DFS_USING_POSIX */
117 }
118
_execve_r(struct _reent * ptr,const char * name,char * const * argv,char * const * env)119 int _execve_r(struct _reent *ptr, const char * name, char *const *argv, char *const *env)
120 {
121 ptr->_errno = ENOTSUP;
122 return -1;
123 }
124
_fcntl_r(struct _reent * ptr,int fd,int cmd,int arg)125 int _fcntl_r(struct _reent *ptr, int fd, int cmd, int arg)
126 {
127 ptr->_errno = ENOTSUP;
128 return -1;
129 }
130
_fork_r(struct _reent * ptr)131 int _fork_r(struct _reent *ptr)
132 {
133 ptr->_errno = ENOTSUP;
134 return -1;
135 }
136
_fstat_r(struct _reent * ptr,int fd,struct stat * pstat)137 int _fstat_r(struct _reent *ptr, int fd, struct stat *pstat)
138 {
139 ptr->_errno = ENOTSUP;
140 return -1;
141 }
142
_isatty_r(struct _reent * ptr,int fd)143 int _isatty_r(struct _reent *ptr, int fd)
144 {
145 if (fd >=0 && fd < 3)
146 {
147 return 1;
148 }
149 else
150 {
151 return 0;
152 }
153 }
154
_kill_r(struct _reent * ptr,int pid,int sig)155 int _kill_r(struct _reent *ptr, int pid, int sig)
156 {
157 ptr->_errno = ENOTSUP;
158 return -1;
159 }
160
_link_r(struct _reent * ptr,const char * old,const char * new)161 int _link_r(struct _reent *ptr, const char *old, const char *new)
162 {
163 ptr->_errno = ENOTSUP;
164 return -1;
165 }
166
_wait_r(struct _reent * ptr,int * status)167 int _wait_r(struct _reent *ptr, int *status)
168 {
169 ptr->_errno = ENOTSUP;
170 return -1;
171 }
172
umask(mode_t mask)173 mode_t umask(mode_t mask)
174 {
175 return 022;
176 }
177
flock(int fd,int operation)178 int flock(int fd, int operation)
179 {
180 return 0;
181 }
182
_lseek_r(struct _reent * ptr,int fd,_off_t pos,int whence)183 _off_t _lseek_r(struct _reent *ptr, int fd, _off_t pos, int whence)
184 {
185 #ifdef DFS_USING_POSIX
186 _off_t rc;
187 rc = lseek(fd, pos, whence);
188 return rc;
189 #else
190 LOG_W("%s: %s", __func__, _WARNING_WITHOUT_FS);
191 ptr->_errno = ENOTSUP;
192 return -1;
193 #endif /* DFS_USING_POSIX */
194 }
195
_mkdir_r(struct _reent * ptr,const char * name,int mode)196 int _mkdir_r(struct _reent *ptr, const char *name, int mode)
197 {
198 #ifdef DFS_USING_POSIX
199 int rc;
200 rc = mkdir(name, mode);
201 return rc;
202 #else
203 LOG_W("%s: %s", __func__, _WARNING_WITHOUT_FS);
204 ptr->_errno = ENOTSUP;
205 return -1;
206 #endif /* DFS_USING_POSIX */
207 }
208
_open_r(struct _reent * ptr,const char * file,int flags,int mode)209 int _open_r(struct _reent *ptr, const char *file, int flags, int mode)
210 {
211 #ifdef DFS_USING_POSIX
212 int rc;
213 rc = open(file, flags, mode);
214 return rc;
215 #else
216 LOG_W("%s: %s", __func__, _WARNING_WITHOUT_FS);
217 ptr->_errno = ENOTSUP;
218 return -1;
219 #endif /* DFS_USING_POSIX */
220 }
221
_read_r(struct _reent * ptr,int fd,void * buf,size_t nbytes)222 _ssize_t _read_r(struct _reent *ptr, int fd, void *buf, size_t nbytes)
223 {
224 #ifdef DFS_USING_POSIX
225 _ssize_t rc;
226 if (fd == STDIN_FILENO)
227 {
228 #ifdef RT_USING_POSIX_STDIO
229 if (rt_posix_stdio_get_console() < 0)
230 {
231 LOG_W("Do not invoke standard input before initializing Compiler");
232 return 0;
233 }
234 #else
235 LOG_W("%s: %s", __func__, _WARNING_WITHOUT_STDIO);
236 ptr->_errno = ENOTSUP;
237 return -1;
238 #endif /* RT_USING_POSIX_STDIO */
239 }
240 else if (fd == STDOUT_FILENO || fd == STDERR_FILENO)
241 {
242 ptr->_errno = ENOTSUP;
243 return -1;
244 }
245
246 rc = read(fd, buf, nbytes);
247 return rc;
248 #else
249 LOG_W("%s: %s", __func__, _WARNING_WITHOUT_FS);
250 ptr->_errno = ENOTSUP;
251 return -1;
252 #endif /* DFS_USING_POSIX */
253 }
254
_rename_r(struct _reent * ptr,const char * old,const char * new)255 int _rename_r(struct _reent *ptr, const char *old, const char *new)
256 {
257 #ifdef DFS_USING_POSIX
258 int rc;
259 rc = rename(old, new);
260 return rc;
261 #else
262 LOG_W("%s: %s", __func__, _WARNING_WITHOUT_FS);
263 ptr->_errno = ENOTSUP;
264 return -1;
265 #endif /* DFS_USING_POSIX */
266 }
267
_stat_r(struct _reent * ptr,const char * file,struct stat * pstat)268 int _stat_r(struct _reent *ptr, const char *file, struct stat *pstat)
269 {
270 #ifdef DFS_USING_POSIX
271 int rc;
272 rc = stat(file, pstat);
273 return rc;
274 #else
275 LOG_W("%s: %s", __func__, _WARNING_WITHOUT_FS);
276 ptr->_errno = ENOTSUP;
277 return -1;
278 #endif /* DFS_USING_POSIX */
279 }
280
_unlink_r(struct _reent * ptr,const char * file)281 int _unlink_r(struct _reent *ptr, const char *file)
282 {
283 #ifdef DFS_USING_POSIX
284 return unlink(file);
285 #else
286 LOG_W("%s: %s", __func__, _WARNING_WITHOUT_FS);
287 ptr->_errno = ENOTSUP;
288 return -1;
289 #endif /* DFS_USING_POSIX */
290 }
291
_write_r(struct _reent * ptr,int fd,const void * buf,size_t nbytes)292 _ssize_t _write_r(struct _reent *ptr, int fd, const void *buf, size_t nbytes)
293 {
294 #ifdef DFS_USING_POSIX
295 _ssize_t rc;
296 #endif /* DFS_USING_POSIX */
297
298 if (fd == STDOUT_FILENO || fd == STDERR_FILENO)
299 {
300 #if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
301 rt_device_t console;
302
303 console = rt_console_get_device();
304 if (console)
305 return rt_device_write(console, -1, buf, nbytes);
306 #else
307 ptr->_errno = ENOTSUP;
308 return -1;
309 #endif /* defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE) */
310 }
311 else if (fd == STDIN_FILENO)
312 {
313 ptr->_errno = ENOTSUP;
314 return -1;
315 }
316
317 #ifdef DFS_USING_POSIX
318 rc = write(fd, buf, nbytes);
319 return rc;
320 #else
321 LOG_W("%s: %s", __func__, _WARNING_WITHOUT_FS);
322 ptr->_errno = ENOTSUP;
323 return -1;
324 #endif /* DFS_USING_POSIX */
325 }
326
327 /* for exit() and abort() */
_exit(int status)328 __attribute__ ((noreturn)) void _exit (int status)
329 {
330 __rt_libc_exit(status);
331 while(1);
332 }
333
334 /*
335 These functions are implemented and replaced by the 'common/time.c' file
336 int _gettimeofday_r(struct _reent *ptr, struct timeval *__tp, void *__tzp);
337 _CLOCK_T_ _times_r(struct _reent *ptr, struct tms *ptms);
338 */
339