1 /*
2  * Copyright (c) 2015, 2021 Intel Corporation.
3  * Copyright (c) 2021 Synopsys.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <stdio.h>
9 #include <zephyr/sys/libc-hooks.h>
10 #include <zephyr/syscall_handler.h>
11 #include <string.h>
12 #include <zephyr/sys/errno_private.h>
13 #include <unistd.h>
14 #include <errno.h>
15 
16 #ifndef STDIN_FILENO
17   #define STDIN_FILENO    0
18 #endif
19 
20 #ifndef STDOUT_FILENO
21   #define STDOUT_FILENO   1
22 #endif
23 
24 #ifndef STDERR_FILENO
25   #define STDERR_FILENO   2
26 #endif
27 
_stdout_hook_default(int c)28 static int _stdout_hook_default(int c)
29 {
30 	ARG_UNUSED(c);
31 
32 	return EOF;
33 }
34 
35 static int (*_stdout_hook)(int) = _stdout_hook_default;
36 
__stdout_hook_install(int (* hook)(int))37 void __stdout_hook_install(int (*hook)(int))
38 {
39 	_stdout_hook = hook;
40 }
41 
z_impl_zephyr_write_stdout(const void * buffer,int nbytes)42 int z_impl_zephyr_write_stdout(const void *buffer, int nbytes)
43 {
44 	const char *buf = buffer;
45 	int i;
46 
47 	for (i = 0; i < nbytes; i++) {
48 		if (*(buf + i) == '\n') {
49 			_stdout_hook('\r');
50 		}
51 		_stdout_hook(*(buf + i));
52 	}
53 	return nbytes;
54 }
55 
56 #ifdef CONFIG_USERSPACE
z_vrfy_zephyr_write_stdout(const void * buf,int nbytes)57 static inline int z_vrfy_zephyr_write_stdout(const void *buf, int nbytes)
58 {
59 	Z_OOPS(Z_SYSCALL_MEMORY_READ(buf, nbytes));
60 	return z_impl_zephyr_write_stdout(buf, nbytes);
61 }
62 #include <syscalls/zephyr_write_stdout_mrsh.c>
63 #endif
64 
65 #ifndef CONFIG_POSIX_API
_write(int fd,const char * buf,unsigned int nbytes)66 int _write(int fd, const char *buf, unsigned int nbytes)
67 {
68 	ARG_UNUSED(fd);
69 
70 	return zephyr_write_stdout(buf, nbytes);
71 }
72 #endif
73 
74 /*
75  * It's require to implement _isatty to have STDIN/STDOUT/STDERR buffered
76  * properly.
77  */
_isatty(int file)78 int _isatty(int file)
79 {
80 	if (file == STDIN_FILENO || file == STDOUT_FILENO || file == STDERR_FILENO) {
81 		return 1;
82 	}
83 
84 	return 0;
85 }
86 
___errno(void)87 int *___errno(void)
88 {
89 	return z_errno();
90 }
91 
_exit(int status)92 __weak void _exit(int status)
93 {
94 	while (1) {
95 	}
96 }
97