xref: /nrf52832-nimble/rt-thread/components/libc/compilers/armlibc/stubs.c (revision 104654410c56c573564690304ae786df310c91fc)
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  * 2012-11-23     Yihui        The first version
9*10465441SEvalZero  * 2013-11-24     aozima       fixed _sys_read()/_sys_write() issues.
10*10465441SEvalZero  * 2014-08-03     bernard      If using msh, use system() implementation
11*10465441SEvalZero  *                             in msh.
12*10465441SEvalZero  */
13*10465441SEvalZero 
14*10465441SEvalZero #include <string.h>
15*10465441SEvalZero #include <rt_sys.h>
16*10465441SEvalZero 
17*10465441SEvalZero #include "rtthread.h"
18*10465441SEvalZero #include "libc.h"
19*10465441SEvalZero 
20*10465441SEvalZero #ifdef RT_USING_DFS
21*10465441SEvalZero #include "dfs_posix.h"
22*10465441SEvalZero #endif
23*10465441SEvalZero 
24*10465441SEvalZero #ifdef __CLANG_ARM
25*10465441SEvalZero __asm(".global __use_no_semihosting\n\t");
26*10465441SEvalZero #else
27*10465441SEvalZero #pragma import(__use_no_semihosting_swi)
28*10465441SEvalZero #endif
29*10465441SEvalZero 
30*10465441SEvalZero /* Standard IO device handles. */
31*10465441SEvalZero #define STDIN       0
32*10465441SEvalZero #define STDOUT      1
33*10465441SEvalZero #define STDERR      2
34*10465441SEvalZero 
35*10465441SEvalZero /* Standard IO device name defines. */
36*10465441SEvalZero const char __stdin_name[]  = "STDIN";
37*10465441SEvalZero const char __stdout_name[] = "STDOUT";
38*10465441SEvalZero const char __stderr_name[] = "STDERR";
39*10465441SEvalZero 
40*10465441SEvalZero /**
41*10465441SEvalZero  * required by fopen() and freopen().
42*10465441SEvalZero  *
43*10465441SEvalZero  * @param name - file name with path.
44*10465441SEvalZero  * @param openmode - a bitmap hose bits mostly correspond directly to
45*10465441SEvalZero  *                     the ISO mode specification.
46*10465441SEvalZero  * @return  -1 if an error occurs.
47*10465441SEvalZero  */
_sys_open(const char * name,int openmode)48*10465441SEvalZero FILEHANDLE _sys_open(const char *name, int openmode)
49*10465441SEvalZero {
50*10465441SEvalZero #ifdef RT_USING_DFS
51*10465441SEvalZero     int fd;
52*10465441SEvalZero     int mode = O_RDONLY;
53*10465441SEvalZero #endif
54*10465441SEvalZero 
55*10465441SEvalZero     /* Register standard Input Output devices. */
56*10465441SEvalZero     if (strcmp(name, __stdin_name) == 0)
57*10465441SEvalZero         return (STDIN);
58*10465441SEvalZero     if (strcmp(name, __stdout_name) == 0)
59*10465441SEvalZero         return (STDOUT);
60*10465441SEvalZero     if (strcmp(name, __stderr_name) == 0)
61*10465441SEvalZero         return (STDERR);
62*10465441SEvalZero 
63*10465441SEvalZero #ifndef RT_USING_DFS
64*10465441SEvalZero     return -1;
65*10465441SEvalZero #else
66*10465441SEvalZero     /* Correct openmode from fopen to open */
67*10465441SEvalZero     if (openmode & OPEN_PLUS)
68*10465441SEvalZero     {
69*10465441SEvalZero         if (openmode & OPEN_W)
70*10465441SEvalZero         {
71*10465441SEvalZero             mode |= (O_RDWR | O_TRUNC | O_CREAT);
72*10465441SEvalZero         }
73*10465441SEvalZero         else if (openmode & OPEN_A)
74*10465441SEvalZero         {
75*10465441SEvalZero             mode |= (O_RDWR | O_APPEND | O_CREAT);
76*10465441SEvalZero         }
77*10465441SEvalZero         else
78*10465441SEvalZero             mode |= O_RDWR;
79*10465441SEvalZero     }
80*10465441SEvalZero     else
81*10465441SEvalZero     {
82*10465441SEvalZero         if (openmode & OPEN_W)
83*10465441SEvalZero         {
84*10465441SEvalZero             mode |= (O_WRONLY | O_TRUNC | O_CREAT);
85*10465441SEvalZero         }
86*10465441SEvalZero         else if (openmode & OPEN_A)
87*10465441SEvalZero         {
88*10465441SEvalZero             mode |= (O_WRONLY | O_APPEND | O_CREAT);
89*10465441SEvalZero         }
90*10465441SEvalZero     }
91*10465441SEvalZero 
92*10465441SEvalZero     fd = open(name, mode, 0);
93*10465441SEvalZero     if (fd < 0)
94*10465441SEvalZero         return -1;
95*10465441SEvalZero     else
96*10465441SEvalZero         return fd;
97*10465441SEvalZero #endif
98*10465441SEvalZero }
99*10465441SEvalZero 
_sys_close(FILEHANDLE fh)100*10465441SEvalZero int _sys_close(FILEHANDLE fh)
101*10465441SEvalZero {
102*10465441SEvalZero #ifndef RT_USING_DFS
103*10465441SEvalZero     return 0;
104*10465441SEvalZero #else
105*10465441SEvalZero     if (fh <= STDERR) return 0;
106*10465441SEvalZero 
107*10465441SEvalZero     return close(fh);
108*10465441SEvalZero #endif
109*10465441SEvalZero }
110*10465441SEvalZero 
111*10465441SEvalZero /*
112*10465441SEvalZero  * Read from a file. Can return:
113*10465441SEvalZero  *  - zero if the read was completely successful
114*10465441SEvalZero  *  - the number of bytes _not_ read, if the read was partially successful
115*10465441SEvalZero  *  - the number of bytes not read, plus the top bit set (0x80000000), if
116*10465441SEvalZero  *    the read was partially successful due to end of file
117*10465441SEvalZero  *  - -1 if some error other than EOF occurred
118*10465441SEvalZero  *
119*10465441SEvalZero  * It is also legal to signal EOF by returning no data but
120*10465441SEvalZero  * signalling no error (i.e. the top-bit-set mechanism need never
121*10465441SEvalZero  * be used).
122*10465441SEvalZero  *
123*10465441SEvalZero  * So if (for example) the user is trying to read 8 bytes at a time
124*10465441SEvalZero  * from a file in which only 5 remain, this routine can do three
125*10465441SEvalZero  * equally valid things:
126*10465441SEvalZero  *
127*10465441SEvalZero  *  - it can return 0x80000003 (3 bytes not read due to EOF)
128*10465441SEvalZero  *  - OR it can return 3 (3 bytes not read), and then return
129*10465441SEvalZero  *    0x80000008 (8 bytes not read due to EOF) on the next attempt
130*10465441SEvalZero  *  - OR it can return 3 (3 bytes not read), and then return
131*10465441SEvalZero  *    8 (8 bytes not read, meaning 0 read, meaning EOF) on the next
132*10465441SEvalZero  *    attempt
133*10465441SEvalZero  *
134*10465441SEvalZero  * `mode' exists for historical reasons and must be ignored.
135*10465441SEvalZero  */
_sys_read(FILEHANDLE fh,unsigned char * buf,unsigned len,int mode)136*10465441SEvalZero int _sys_read(FILEHANDLE fh, unsigned char *buf, unsigned len, int mode)
137*10465441SEvalZero {
138*10465441SEvalZero #ifdef RT_USING_DFS
139*10465441SEvalZero     int size;
140*10465441SEvalZero #endif
141*10465441SEvalZero 
142*10465441SEvalZero     if (fh == STDIN)
143*10465441SEvalZero     {
144*10465441SEvalZero #ifdef RT_USING_POSIX
145*10465441SEvalZero         size = libc_stdio_read(buf, len);
146*10465441SEvalZero         return len - size;
147*10465441SEvalZero #else
148*10465441SEvalZero         /* no stdin */
149*10465441SEvalZero         return -1;
150*10465441SEvalZero #endif
151*10465441SEvalZero     }
152*10465441SEvalZero 
153*10465441SEvalZero     if ((fh == STDOUT) || (fh == STDERR))
154*10465441SEvalZero         return -1;
155*10465441SEvalZero 
156*10465441SEvalZero #ifndef RT_USING_DFS
157*10465441SEvalZero     return 0;
158*10465441SEvalZero #else
159*10465441SEvalZero     size = read(fh, buf, len);
160*10465441SEvalZero     if (size >= 0)
161*10465441SEvalZero         return len - size;
162*10465441SEvalZero     else
163*10465441SEvalZero         return -1;
164*10465441SEvalZero #endif
165*10465441SEvalZero }
166*10465441SEvalZero 
167*10465441SEvalZero /*
168*10465441SEvalZero  * Write to a file. Returns 0 on success, negative on error, and
169*10465441SEvalZero  * the number of characters _not_ written on partial success.
170*10465441SEvalZero  * `mode' exists for historical reasons and must be ignored.
171*10465441SEvalZero  */
_sys_write(FILEHANDLE fh,const unsigned char * buf,unsigned len,int mode)172*10465441SEvalZero int _sys_write(FILEHANDLE fh, const unsigned char *buf, unsigned len, int mode)
173*10465441SEvalZero {
174*10465441SEvalZero #ifdef RT_USING_DFS
175*10465441SEvalZero     int size;
176*10465441SEvalZero #endif
177*10465441SEvalZero 
178*10465441SEvalZero     if ((fh == STDOUT) || (fh == STDERR))
179*10465441SEvalZero     {
180*10465441SEvalZero #if !defined(RT_USING_CONSOLE) || !defined(RT_USING_DEVICE)
181*10465441SEvalZero         return 0;
182*10465441SEvalZero #else
183*10465441SEvalZero #ifdef RT_USING_POSIX
184*10465441SEvalZero         size = libc_stdio_write(buf, len);
185*10465441SEvalZero         return len - size;
186*10465441SEvalZero #else
187*10465441SEvalZero         if (rt_console_get_device())
188*10465441SEvalZero         {
189*10465441SEvalZero             rt_device_write(rt_console_get_device(), -1, buf, len);
190*10465441SEvalZero             return 0;
191*10465441SEvalZero         }
192*10465441SEvalZero 
193*10465441SEvalZero         return -1;
194*10465441SEvalZero #endif
195*10465441SEvalZero #endif
196*10465441SEvalZero     }
197*10465441SEvalZero 
198*10465441SEvalZero     if (fh == STDIN) return -1;
199*10465441SEvalZero 
200*10465441SEvalZero #ifndef RT_USING_DFS
201*10465441SEvalZero     return 0;
202*10465441SEvalZero #else
203*10465441SEvalZero     size = write(fh, buf, len);
204*10465441SEvalZero     if (size >= 0)
205*10465441SEvalZero         return len - size;
206*10465441SEvalZero     else
207*10465441SEvalZero         return -1;
208*10465441SEvalZero #endif
209*10465441SEvalZero }
210*10465441SEvalZero 
211*10465441SEvalZero /*
212*10465441SEvalZero  * Move the file position to a given offset from the file start.
213*10465441SEvalZero  * Returns >=0 on success, <0 on failure.
214*10465441SEvalZero  */
_sys_seek(FILEHANDLE fh,long pos)215*10465441SEvalZero int _sys_seek(FILEHANDLE fh, long pos)
216*10465441SEvalZero {
217*10465441SEvalZero     if (fh < STDERR)
218*10465441SEvalZero         return -1;
219*10465441SEvalZero 
220*10465441SEvalZero #ifndef RT_USING_DFS
221*10465441SEvalZero     return -1;
222*10465441SEvalZero #else
223*10465441SEvalZero 
224*10465441SEvalZero     /* position is relative to the start of file fh */
225*10465441SEvalZero     return lseek(fh, pos, 0);
226*10465441SEvalZero #endif
227*10465441SEvalZero }
228*10465441SEvalZero 
229*10465441SEvalZero /**
230*10465441SEvalZero  * used by tmpnam() or tmpfile()
231*10465441SEvalZero  */
_sys_tmpnam(char * name,int fileno,unsigned maxlength)232*10465441SEvalZero int _sys_tmpnam(char *name, int fileno, unsigned maxlength)
233*10465441SEvalZero {
234*10465441SEvalZero     return -1;
235*10465441SEvalZero }
236*10465441SEvalZero 
_sys_command_string(char * cmd,int len)237*10465441SEvalZero char *_sys_command_string(char *cmd, int len)
238*10465441SEvalZero {
239*10465441SEvalZero     /* no support */
240*10465441SEvalZero     return RT_NULL;
241*10465441SEvalZero }
242*10465441SEvalZero 
243*10465441SEvalZero /* This function writes a character to the console. */
_ttywrch(int ch)244*10465441SEvalZero void _ttywrch(int ch)
245*10465441SEvalZero {
246*10465441SEvalZero #ifdef RT_USING_CONSOLE
247*10465441SEvalZero     char c;
248*10465441SEvalZero 
249*10465441SEvalZero     c = (char)ch;
250*10465441SEvalZero     rt_kprintf(&c);
251*10465441SEvalZero #endif
252*10465441SEvalZero }
253*10465441SEvalZero 
_sys_exit(int return_code)254*10465441SEvalZero void _sys_exit(int return_code)
255*10465441SEvalZero {
256*10465441SEvalZero     /* TODO: perhaps exit the thread which is invoking this function */
257*10465441SEvalZero     while (1);
258*10465441SEvalZero }
259*10465441SEvalZero 
260*10465441SEvalZero /**
261*10465441SEvalZero  * return current length of file.
262*10465441SEvalZero  *
263*10465441SEvalZero  * @param fh - file handle
264*10465441SEvalZero  * @return file length, or -1 on failed
265*10465441SEvalZero  */
_sys_flen(FILEHANDLE fh)266*10465441SEvalZero long _sys_flen(FILEHANDLE fh)
267*10465441SEvalZero {
268*10465441SEvalZero     struct stat stat;
269*10465441SEvalZero 
270*10465441SEvalZero     if (fh < STDERR)
271*10465441SEvalZero         return -1;
272*10465441SEvalZero 
273*10465441SEvalZero #ifndef RT_USING_DFS
274*10465441SEvalZero     return -1;
275*10465441SEvalZero #else
276*10465441SEvalZero     fstat(fh, &stat);
277*10465441SEvalZero     return stat.st_size;
278*10465441SEvalZero #endif
279*10465441SEvalZero }
280*10465441SEvalZero 
_sys_istty(FILEHANDLE fh)281*10465441SEvalZero int _sys_istty(FILEHANDLE fh)
282*10465441SEvalZero {
283*10465441SEvalZero     if((STDIN <= fh) && (fh <= STDERR))
284*10465441SEvalZero         return 1;
285*10465441SEvalZero     else
286*10465441SEvalZero         return 0;
287*10465441SEvalZero }
288*10465441SEvalZero 
remove(const char * filename)289*10465441SEvalZero int remove(const char *filename)
290*10465441SEvalZero {
291*10465441SEvalZero #ifndef RT_USING_DFS
292*10465441SEvalZero     return -1;
293*10465441SEvalZero #else
294*10465441SEvalZero     return unlink(filename);
295*10465441SEvalZero #endif
296*10465441SEvalZero }
297*10465441SEvalZero 
298*10465441SEvalZero #if defined(RT_USING_FINSH) && defined(FINSH_USING_MSH) && defined(RT_USING_MODULE) && defined(RT_USING_DFS)
299*10465441SEvalZero /* use system(const char *string) implementation in the msh */
300*10465441SEvalZero #else
system(const char * string)301*10465441SEvalZero int system(const char *string)
302*10465441SEvalZero {
303*10465441SEvalZero     RT_ASSERT(0);
304*10465441SEvalZero     for (;;);
305*10465441SEvalZero }
306*10465441SEvalZero #endif
307*10465441SEvalZero 
308*10465441SEvalZero #ifdef __MICROLIB
309*10465441SEvalZero #include <stdio.h>
310*10465441SEvalZero 
fputc(int c,FILE * f)311*10465441SEvalZero int fputc(int c, FILE *f)
312*10465441SEvalZero {
313*10465441SEvalZero     char ch[2] = {0};
314*10465441SEvalZero 
315*10465441SEvalZero     ch[0] = c;
316*10465441SEvalZero     rt_kprintf(&ch[0]);
317*10465441SEvalZero     return 1;
318*10465441SEvalZero }
319*10465441SEvalZero 
fgetc(FILE * f)320*10465441SEvalZero int fgetc(FILE *f)
321*10465441SEvalZero {
322*10465441SEvalZero #ifdef RT_USING_POSIX
323*10465441SEvalZero     char ch;
324*10465441SEvalZero 
325*10465441SEvalZero     if (libc_stdio_read(&ch, 1) == 1)
326*10465441SEvalZero         return ch;
327*10465441SEvalZero #endif
328*10465441SEvalZero 
329*10465441SEvalZero     return -1;
330*10465441SEvalZero }
331*10465441SEvalZero #endif
332