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