1*10465441SEvalZero /*
2*10465441SEvalZero * Copyright (c) 2006-2018, RT-Thread Development Team
3*10465441SEvalZero *
4*10465441SEvalZero * SPDX-License-Identifier: Apache-2.0
5*10465441SEvalZero *
6*10465441SEvalZero * Change Logs:
7*10465441SEvalZero * Date Author Notes
8*10465441SEvalZero */
9*10465441SEvalZero #include <reent.h>
10*10465441SEvalZero #include <sys/errno.h>
11*10465441SEvalZero #include <sys/time.h>
12*10465441SEvalZero #include <stdio.h>
13*10465441SEvalZero
14*10465441SEvalZero #include <rtthread.h>
15*10465441SEvalZero
16*10465441SEvalZero #ifdef RT_USING_DFS
17*10465441SEvalZero #include <dfs_posix.h>
18*10465441SEvalZero #endif
19*10465441SEvalZero
20*10465441SEvalZero #ifdef RT_USING_PTHREADS
21*10465441SEvalZero #include <pthread.h>
22*10465441SEvalZero #endif
23*10465441SEvalZero
24*10465441SEvalZero #ifdef RT_USING_MODULE
25*10465441SEvalZero #include <dlmodule.h>
26*10465441SEvalZero #endif
27*10465441SEvalZero
28*10465441SEvalZero /* Reentrant versions of system calls. */
29*10465441SEvalZero
30*10465441SEvalZero int
_close_r(struct _reent * ptr,int fd)31*10465441SEvalZero _close_r(struct _reent *ptr, int fd)
32*10465441SEvalZero {
33*10465441SEvalZero #ifndef RT_USING_DFS
34*10465441SEvalZero return 0;
35*10465441SEvalZero #else
36*10465441SEvalZero return close(fd);
37*10465441SEvalZero #endif
38*10465441SEvalZero }
39*10465441SEvalZero
40*10465441SEvalZero int
_execve_r(struct _reent * ptr,const char * name,char * const * argv,char * const * env)41*10465441SEvalZero _execve_r(struct _reent *ptr, const char * name, char *const *argv, char *const *env)
42*10465441SEvalZero {
43*10465441SEvalZero /* return "not supported" */
44*10465441SEvalZero ptr->_errno = ENOTSUP;
45*10465441SEvalZero return -1;
46*10465441SEvalZero }
47*10465441SEvalZero
48*10465441SEvalZero int
_fcntl_r(struct _reent * ptr,int fd,int cmd,int arg)49*10465441SEvalZero _fcntl_r(struct _reent *ptr, int fd, int cmd, int arg)
50*10465441SEvalZero {
51*10465441SEvalZero /* return "not supported" */
52*10465441SEvalZero ptr->_errno = ENOTSUP;
53*10465441SEvalZero return -1;
54*10465441SEvalZero }
55*10465441SEvalZero
56*10465441SEvalZero int
_fork_r(struct _reent * ptr)57*10465441SEvalZero _fork_r(struct _reent *ptr)
58*10465441SEvalZero {
59*10465441SEvalZero /* return "not supported" */
60*10465441SEvalZero ptr->_errno = ENOTSUP;
61*10465441SEvalZero return -1;
62*10465441SEvalZero }
63*10465441SEvalZero
64*10465441SEvalZero int
_fstat_r(struct _reent * ptr,int fd,struct stat * pstat)65*10465441SEvalZero _fstat_r(struct _reent *ptr, int fd, struct stat *pstat)
66*10465441SEvalZero {
67*10465441SEvalZero /* return "not supported" */
68*10465441SEvalZero ptr->_errno = ENOTSUP;
69*10465441SEvalZero return -1;
70*10465441SEvalZero }
71*10465441SEvalZero
72*10465441SEvalZero int
_getpid_r(struct _reent * ptr)73*10465441SEvalZero _getpid_r(struct _reent *ptr)
74*10465441SEvalZero {
75*10465441SEvalZero return 0;
76*10465441SEvalZero }
77*10465441SEvalZero
78*10465441SEvalZero int
_isatty_r(struct _reent * ptr,int fd)79*10465441SEvalZero _isatty_r(struct _reent *ptr, int fd)
80*10465441SEvalZero {
81*10465441SEvalZero if (fd >=0 && fd < 3) return 1;
82*10465441SEvalZero
83*10465441SEvalZero /* return "not supported" */
84*10465441SEvalZero ptr->_errno = ENOTSUP;
85*10465441SEvalZero return -1;
86*10465441SEvalZero }
87*10465441SEvalZero
88*10465441SEvalZero int
_kill_r(struct _reent * ptr,int pid,int sig)89*10465441SEvalZero _kill_r(struct _reent *ptr, int pid, int sig)
90*10465441SEvalZero {
91*10465441SEvalZero /* return "not supported" */
92*10465441SEvalZero ptr->_errno = ENOTSUP;
93*10465441SEvalZero return -1;
94*10465441SEvalZero }
95*10465441SEvalZero
96*10465441SEvalZero int
_link_r(struct _reent * ptr,const char * old,const char * new)97*10465441SEvalZero _link_r(struct _reent *ptr, const char *old, const char *new)
98*10465441SEvalZero {
99*10465441SEvalZero /* return "not supported" */
100*10465441SEvalZero ptr->_errno = ENOTSUP;
101*10465441SEvalZero return -1;
102*10465441SEvalZero }
103*10465441SEvalZero
104*10465441SEvalZero _off_t
_lseek_r(struct _reent * ptr,int fd,_off_t pos,int whence)105*10465441SEvalZero _lseek_r(struct _reent *ptr, int fd, _off_t pos, int whence)
106*10465441SEvalZero {
107*10465441SEvalZero #ifndef RT_USING_DFS
108*10465441SEvalZero return 0;
109*10465441SEvalZero #else
110*10465441SEvalZero _off_t rc;
111*10465441SEvalZero
112*10465441SEvalZero rc = lseek(fd, pos, whence);
113*10465441SEvalZero return rc;
114*10465441SEvalZero #endif
115*10465441SEvalZero }
116*10465441SEvalZero
117*10465441SEvalZero int
_mkdir_r(struct _reent * ptr,const char * name,int mode)118*10465441SEvalZero _mkdir_r(struct _reent *ptr, const char *name, int mode)
119*10465441SEvalZero {
120*10465441SEvalZero #ifndef RT_USING_DFS
121*10465441SEvalZero return 0;
122*10465441SEvalZero #else
123*10465441SEvalZero int rc;
124*10465441SEvalZero
125*10465441SEvalZero rc = mkdir(name, mode);
126*10465441SEvalZero return rc;
127*10465441SEvalZero #endif
128*10465441SEvalZero }
129*10465441SEvalZero
130*10465441SEvalZero int
_open_r(struct _reent * ptr,const char * file,int flags,int mode)131*10465441SEvalZero _open_r(struct _reent *ptr, const char *file, int flags, int mode)
132*10465441SEvalZero {
133*10465441SEvalZero #ifndef RT_USING_DFS
134*10465441SEvalZero return 0;
135*10465441SEvalZero #else
136*10465441SEvalZero int rc;
137*10465441SEvalZero
138*10465441SEvalZero rc = open(file, flags, mode);
139*10465441SEvalZero return rc;
140*10465441SEvalZero #endif
141*10465441SEvalZero }
142*10465441SEvalZero
143*10465441SEvalZero _ssize_t
_read_r(struct _reent * ptr,int fd,void * buf,size_t nbytes)144*10465441SEvalZero _read_r(struct _reent *ptr, int fd, void *buf, size_t nbytes)
145*10465441SEvalZero {
146*10465441SEvalZero #ifndef RT_USING_DFS
147*10465441SEvalZero return 0;
148*10465441SEvalZero #else
149*10465441SEvalZero _ssize_t rc;
150*10465441SEvalZero
151*10465441SEvalZero rc = read(fd, buf, nbytes);
152*10465441SEvalZero return rc;
153*10465441SEvalZero #endif
154*10465441SEvalZero }
155*10465441SEvalZero
156*10465441SEvalZero int
_rename_r(struct _reent * ptr,const char * old,const char * new)157*10465441SEvalZero _rename_r(struct _reent *ptr, const char *old, const char *new)
158*10465441SEvalZero {
159*10465441SEvalZero #ifndef RT_USING_DFS
160*10465441SEvalZero return 0;
161*10465441SEvalZero #else
162*10465441SEvalZero int rc;
163*10465441SEvalZero
164*10465441SEvalZero rc = rename(old, new);
165*10465441SEvalZero return rc;
166*10465441SEvalZero #endif
167*10465441SEvalZero }
168*10465441SEvalZero
169*10465441SEvalZero void *
_sbrk_r(struct _reent * ptr,ptrdiff_t incr)170*10465441SEvalZero _sbrk_r(struct _reent *ptr, ptrdiff_t incr)
171*10465441SEvalZero {
172*10465441SEvalZero /* no use this routine to get memory */
173*10465441SEvalZero return RT_NULL;
174*10465441SEvalZero }
175*10465441SEvalZero
176*10465441SEvalZero int
_stat_r(struct _reent * ptr,const char * file,struct stat * pstat)177*10465441SEvalZero _stat_r(struct _reent *ptr, const char *file, struct stat *pstat)
178*10465441SEvalZero {
179*10465441SEvalZero #ifndef RT_USING_DFS
180*10465441SEvalZero return 0;
181*10465441SEvalZero #else
182*10465441SEvalZero int rc;
183*10465441SEvalZero
184*10465441SEvalZero rc = stat(file, pstat);
185*10465441SEvalZero return rc;
186*10465441SEvalZero #endif
187*10465441SEvalZero }
188*10465441SEvalZero
189*10465441SEvalZero _CLOCK_T_
_times_r(struct _reent * ptr,struct tms * ptms)190*10465441SEvalZero _times_r(struct _reent *ptr, struct tms *ptms)
191*10465441SEvalZero {
192*10465441SEvalZero /* return "not supported" */
193*10465441SEvalZero ptr->_errno = ENOTSUP;
194*10465441SEvalZero return -1;
195*10465441SEvalZero }
196*10465441SEvalZero
197*10465441SEvalZero int
_unlink_r(struct _reent * ptr,const char * file)198*10465441SEvalZero _unlink_r(struct _reent *ptr, const char *file)
199*10465441SEvalZero {
200*10465441SEvalZero #ifndef RT_USING_DFS
201*10465441SEvalZero return 0;
202*10465441SEvalZero #else
203*10465441SEvalZero int rc;
204*10465441SEvalZero
205*10465441SEvalZero rc = unlink(file);
206*10465441SEvalZero return rc;
207*10465441SEvalZero #endif
208*10465441SEvalZero }
209*10465441SEvalZero
210*10465441SEvalZero int
_wait_r(struct _reent * ptr,int * status)211*10465441SEvalZero _wait_r(struct _reent *ptr, int *status)
212*10465441SEvalZero {
213*10465441SEvalZero /* return "not supported" */
214*10465441SEvalZero ptr->_errno = ENOTSUP;
215*10465441SEvalZero return -1;
216*10465441SEvalZero }
217*10465441SEvalZero
218*10465441SEvalZero #ifdef RT_USING_DEVICE
219*10465441SEvalZero _ssize_t
_write_r(struct _reent * ptr,int fd,const void * buf,size_t nbytes)220*10465441SEvalZero _write_r(struct _reent *ptr, int fd, const void *buf, size_t nbytes)
221*10465441SEvalZero {
222*10465441SEvalZero #ifndef RT_USING_DFS
223*10465441SEvalZero if (fileno(stdout) == fd)
224*10465441SEvalZero {
225*10465441SEvalZero rt_device_t console;
226*10465441SEvalZero
227*10465441SEvalZero console = rt_console_get_device();
228*10465441SEvalZero if (console) return rt_device_write(console, -1, buf, nbytes);
229*10465441SEvalZero }
230*10465441SEvalZero
231*10465441SEvalZero return 0;
232*10465441SEvalZero
233*10465441SEvalZero #else
234*10465441SEvalZero _ssize_t rc;
235*10465441SEvalZero
236*10465441SEvalZero rc = write(fd, buf, nbytes);
237*10465441SEvalZero return rc;
238*10465441SEvalZero #endif
239*10465441SEvalZero }
240*10465441SEvalZero #endif
241*10465441SEvalZero
242*10465441SEvalZero #ifdef RT_USING_PTHREADS
243*10465441SEvalZero
244*10465441SEvalZero #include <clock_time.h>
245*10465441SEvalZero /* POSIX timer provides clock_gettime function */
246*10465441SEvalZero #include <time.h>
247*10465441SEvalZero int
_gettimeofday_r(struct _reent * ptr,struct timeval * __tp,void * __tzp)248*10465441SEvalZero _gettimeofday_r(struct _reent *ptr, struct timeval *__tp, void *__tzp)
249*10465441SEvalZero {
250*10465441SEvalZero struct timespec tp;
251*10465441SEvalZero
252*10465441SEvalZero if (clock_gettime(CLOCK_REALTIME, &tp) == 0)
253*10465441SEvalZero {
254*10465441SEvalZero if (__tp != RT_NULL)
255*10465441SEvalZero {
256*10465441SEvalZero __tp->tv_sec = tp.tv_sec;
257*10465441SEvalZero __tp->tv_usec = tp.tv_nsec / 1000UL;
258*10465441SEvalZero }
259*10465441SEvalZero
260*10465441SEvalZero return tp.tv_sec;
261*10465441SEvalZero }
262*10465441SEvalZero
263*10465441SEvalZero /* return "not supported" */
264*10465441SEvalZero ptr->_errno = ENOTSUP;
265*10465441SEvalZero return -1;
266*10465441SEvalZero }
267*10465441SEvalZero
268*10465441SEvalZero #else
269*10465441SEvalZero
270*10465441SEvalZero #define MILLISECOND_PER_SECOND 1000UL
271*10465441SEvalZero #define MICROSECOND_PER_SECOND 1000000UL
272*10465441SEvalZero #define NANOSECOND_PER_SECOND 1000000000UL
273*10465441SEvalZero
274*10465441SEvalZero #define MILLISECOND_PER_TICK (MILLISECOND_PER_SECOND / RT_TICK_PER_SECOND)
275*10465441SEvalZero #define MICROSECOND_PER_TICK (MICROSECOND_PER_SECOND / RT_TICK_PER_SECOND)
276*10465441SEvalZero #define NANOSECOND_PER_TICK (NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND)
277*10465441SEvalZero
278*10465441SEvalZero struct timeval _timevalue = {0};
279*10465441SEvalZero #ifdef RT_USING_DEVICE
libc_system_time_init(void)280*10465441SEvalZero static void libc_system_time_init(void)
281*10465441SEvalZero {
282*10465441SEvalZero time_t time;
283*10465441SEvalZero rt_tick_t tick;
284*10465441SEvalZero rt_device_t device;
285*10465441SEvalZero
286*10465441SEvalZero time = 0;
287*10465441SEvalZero device = rt_device_find("rtc");
288*10465441SEvalZero if (device != RT_NULL)
289*10465441SEvalZero {
290*10465441SEvalZero /* get realtime seconds */
291*10465441SEvalZero rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time);
292*10465441SEvalZero }
293*10465441SEvalZero
294*10465441SEvalZero /* get tick */
295*10465441SEvalZero tick = rt_tick_get();
296*10465441SEvalZero
297*10465441SEvalZero _timevalue.tv_usec = MICROSECOND_PER_SECOND - (tick%RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK;
298*10465441SEvalZero _timevalue.tv_sec = time - tick/RT_TICK_PER_SECOND - 1;
299*10465441SEvalZero }
300*10465441SEvalZero #endif
301*10465441SEvalZero
libc_get_time(struct timespec * time)302*10465441SEvalZero int libc_get_time(struct timespec *time)
303*10465441SEvalZero {
304*10465441SEvalZero rt_tick_t tick;
305*10465441SEvalZero static rt_bool_t inited = 0;
306*10465441SEvalZero
307*10465441SEvalZero RT_ASSERT(time != RT_NULL);
308*10465441SEvalZero
309*10465441SEvalZero /* initialize system time */
310*10465441SEvalZero if (inited == 0)
311*10465441SEvalZero {
312*10465441SEvalZero libc_system_time_init();
313*10465441SEvalZero inited = 1;
314*10465441SEvalZero }
315*10465441SEvalZero
316*10465441SEvalZero /* get tick */
317*10465441SEvalZero tick = rt_tick_get();
318*10465441SEvalZero
319*10465441SEvalZero time->tv_sec = _timevalue.tv_sec + tick / RT_TICK_PER_SECOND;
320*10465441SEvalZero time->tv_nsec = (_timevalue.tv_usec + (tick % RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK) * 1000;
321*10465441SEvalZero
322*10465441SEvalZero return 0;
323*10465441SEvalZero }
324*10465441SEvalZero
325*10465441SEvalZero int
_gettimeofday_r(struct _reent * ptr,struct timeval * __tp,void * __tzp)326*10465441SEvalZero _gettimeofday_r(struct _reent *ptr, struct timeval *__tp, void *__tzp)
327*10465441SEvalZero {
328*10465441SEvalZero struct timespec tp;
329*10465441SEvalZero
330*10465441SEvalZero if (libc_get_time(&tp) == 0)
331*10465441SEvalZero {
332*10465441SEvalZero if (__tp != RT_NULL)
333*10465441SEvalZero {
334*10465441SEvalZero __tp->tv_sec = tp.tv_sec;
335*10465441SEvalZero __tp->tv_usec = tp.tv_nsec / 1000UL;
336*10465441SEvalZero }
337*10465441SEvalZero
338*10465441SEvalZero return tp.tv_sec;
339*10465441SEvalZero }
340*10465441SEvalZero
341*10465441SEvalZero /* return "not supported" */
342*10465441SEvalZero ptr->_errno = ENOTSUP;
343*10465441SEvalZero return -1;
344*10465441SEvalZero }
345*10465441SEvalZero #endif
346*10465441SEvalZero
347*10465441SEvalZero /* Memory routine */
348*10465441SEvalZero void *
_malloc_r(struct _reent * ptr,size_t size)349*10465441SEvalZero _malloc_r (struct _reent *ptr, size_t size)
350*10465441SEvalZero {
351*10465441SEvalZero void* result;
352*10465441SEvalZero
353*10465441SEvalZero result = (void*)rt_malloc (size);
354*10465441SEvalZero if (result == RT_NULL)
355*10465441SEvalZero {
356*10465441SEvalZero ptr->_errno = ENOMEM;
357*10465441SEvalZero }
358*10465441SEvalZero
359*10465441SEvalZero return result;
360*10465441SEvalZero }
361*10465441SEvalZero
362*10465441SEvalZero void *
_realloc_r(struct _reent * ptr,void * old,size_t newlen)363*10465441SEvalZero _realloc_r (struct _reent *ptr, void *old, size_t newlen)
364*10465441SEvalZero {
365*10465441SEvalZero void* result;
366*10465441SEvalZero
367*10465441SEvalZero result = (void*)rt_realloc (old, newlen);
368*10465441SEvalZero if (result == RT_NULL)
369*10465441SEvalZero {
370*10465441SEvalZero ptr->_errno = ENOMEM;
371*10465441SEvalZero }
372*10465441SEvalZero
373*10465441SEvalZero return result;
374*10465441SEvalZero }
375*10465441SEvalZero
_calloc_r(struct _reent * ptr,size_t size,size_t len)376*10465441SEvalZero void *_calloc_r (struct _reent *ptr, size_t size, size_t len)
377*10465441SEvalZero {
378*10465441SEvalZero void* result;
379*10465441SEvalZero
380*10465441SEvalZero result = (void*)rt_calloc (size, len);
381*10465441SEvalZero if (result == RT_NULL)
382*10465441SEvalZero {
383*10465441SEvalZero ptr->_errno = ENOMEM;
384*10465441SEvalZero }
385*10465441SEvalZero
386*10465441SEvalZero return result;
387*10465441SEvalZero }
388*10465441SEvalZero
389*10465441SEvalZero void
_free_r(struct _reent * ptr,void * addr)390*10465441SEvalZero _free_r (struct _reent *ptr, void *addr)
391*10465441SEvalZero {
392*10465441SEvalZero rt_free (addr);
393*10465441SEvalZero }
394*10465441SEvalZero
395*10465441SEvalZero void
exit(int status)396*10465441SEvalZero exit (int status)
397*10465441SEvalZero {
398*10465441SEvalZero #ifdef RT_USING_MODULE
399*10465441SEvalZero if (dlmodule_self())
400*10465441SEvalZero {
401*10465441SEvalZero dlmodule_exit(status);
402*10465441SEvalZero }
403*10465441SEvalZero #endif
404*10465441SEvalZero
405*10465441SEvalZero rt_kprintf("thread:%s exit with %d\n", rt_thread_self()->name, status);
406*10465441SEvalZero RT_ASSERT(0);
407*10465441SEvalZero
408*10465441SEvalZero while (1);
409*10465441SEvalZero }
410*10465441SEvalZero
411*10465441SEvalZero void
_system(const char * s)412*10465441SEvalZero _system(const char *s)
413*10465441SEvalZero {
414*10465441SEvalZero /* not support this call */
415*10465441SEvalZero return;
416*10465441SEvalZero }
417*10465441SEvalZero
__libc_init_array(void)418*10465441SEvalZero void __libc_init_array(void)
419*10465441SEvalZero {
420*10465441SEvalZero /* we not use __libc init_aray to initialize C++ objects */
421*10465441SEvalZero }
422*10465441SEvalZero
abort(void)423*10465441SEvalZero void abort(void)
424*10465441SEvalZero {
425*10465441SEvalZero if (rt_thread_self())
426*10465441SEvalZero {
427*10465441SEvalZero rt_thread_t self = rt_thread_self();
428*10465441SEvalZero
429*10465441SEvalZero rt_kprintf("thread:%-8.*s abort!\n", RT_NAME_MAX, self->name);
430*10465441SEvalZero rt_thread_suspend(self);
431*10465441SEvalZero
432*10465441SEvalZero rt_schedule();
433*10465441SEvalZero }
434*10465441SEvalZero
435*10465441SEvalZero while (1);
436*10465441SEvalZero }
437