1 | // SPDX-License-Identifier: GPL-3.0-or-later |
2 | |
3 | #define __NO_START_FUNCTION |
4 | #include "mosapi.h" |
5 | |
6 | #include <fcntl.h> |
7 | #include <mos/syscall/number.h> |
8 | #include <mos/syscall/usermode.h> |
9 | #include <mos_stdio.h> |
10 | #include <mos_stdlib.h> |
11 | #include <mos_string.h> |
12 | #include <stdarg.h> |
13 | |
14 | struct _FILE |
15 | { |
16 | int fd; |
17 | }; |
18 | |
19 | static struct _FILE __stdin = { .fd = 0 }; |
20 | static struct _FILE __stdout = { .fd = 1 }; |
21 | static struct _FILE __stderr = { .fd = 2 }; |
22 | |
23 | FILE *stdin = &__stdin; |
24 | FILE *stdout = &__stdout; |
25 | FILE *stderr = &__stderr; |
26 | |
27 | typedef struct thread_start_args |
28 | { |
29 | thread_entry_t entry; |
30 | void *arg; |
31 | } thread_start_args_t; |
32 | |
33 | u64 __stack_chk_guard = 0xdeadbeefdeadbeef; |
34 | |
35 | [[noreturn]] void __stack_chk_fail(void) |
36 | { |
37 | puts(s: "stack smashing detected..." ); |
38 | syscall_exit(exit_code: -1); |
39 | __builtin_unreachable(); |
40 | } |
41 | |
42 | void __stack_chk_fail_local(void) |
43 | { |
44 | __stack_chk_fail(); |
45 | } |
46 | |
47 | void __printf(1, 2) fatal_abort(const char *fmt, ...) |
48 | { |
49 | va_list ap; |
50 | va_start(ap, fmt); |
51 | vdprintf(stderr->fd, format: fmt, ap); |
52 | va_end(ap); |
53 | abort(); |
54 | } |
55 | |
56 | [[noreturn]] void abort() |
57 | { |
58 | raise(SIGABRT); |
59 | syscall_exit(exit_code: -1); |
60 | } |
61 | |
62 | fd_t open(const char *path, open_flags flags) |
63 | { |
64 | if (path == NULL) |
65 | return -1; |
66 | |
67 | return openat(AT_FDCWD, path, flags); |
68 | } |
69 | |
70 | fd_t openat(fd_t fd, const char *path, open_flags flags) |
71 | { |
72 | return syscall_vfs_openat(dirfd: fd, file_path: path, flags); |
73 | } |
74 | |
75 | int raise(signal_t sig) |
76 | { |
77 | syscall_signal_thread(tid: syscall_get_tid(), signum: sig); |
78 | return 0; |
79 | } |
80 | |
81 | bool lstatat(int fd, const char *path, file_stat_t *buf) |
82 | { |
83 | return syscall_vfs_fstatat(dirfd: fd, file_path: path, stat_buf: buf, flags: FSTATAT_NOFOLLOW) == 0; |
84 | } |
85 | |
86 | bool chdir(const char *path) |
87 | { |
88 | return syscall_vfs_chdirat(AT_FDCWD, path) == 0; |
89 | } |
90 | |
91 | bool unlink(const char *path) |
92 | { |
93 | return syscall_vfs_unlinkat(AT_FDCWD, path) == 0; |
94 | } |
95 | |
96 | int printf(const char *fmt, ...) |
97 | { |
98 | va_list ap; |
99 | va_start(ap, fmt); |
100 | int size = vdprintf(stdout->fd, format: fmt, ap); |
101 | va_end(ap); |
102 | return size; |
103 | } |
104 | |
105 | int fprintf(FILE *stream, const char *fmt, ...) |
106 | { |
107 | va_list ap; |
108 | va_start(ap, fmt); |
109 | int size = vdprintf(fd: stream->fd, format: fmt, ap); |
110 | va_end(ap); |
111 | return size; |
112 | } |
113 | |
114 | int vdprintf(int fd, const char *fmt, va_list ap) |
115 | { |
116 | char buffer[256]; |
117 | int size = vsnprintf(buf: buffer, size: sizeof(buffer), format: fmt, args: ap); |
118 | syscall_io_write(fd, buffer, size); |
119 | return size; |
120 | } |
121 | |
122 | int putchar(int c) |
123 | { |
124 | char ch = c; |
125 | syscall_io_write(stdout->fd, buffer: &ch, size: 1); |
126 | return c; |
127 | } |
128 | |
129 | int puts(const char *s) |
130 | { |
131 | syscall_io_write(stdout->fd, buffer: s, size: strlen(str: s)); |
132 | return putchar(c: '\n'); |
133 | } |
134 | |
135 | int fputs(const char *restrict s, FILE *restrict file) |
136 | { |
137 | return syscall_io_write(fd: file->fd, buffer: s, size: strlen(str: s)); |
138 | } |
139 | |
140 | size_t fwrite(const void *__restrict ptr, size_t size, size_t nmemb, FILE *__restrict stream) |
141 | { |
142 | return syscall_io_write(fd: stream->fd, buffer: ptr, size: size * nmemb) / size; |
143 | } |
144 | |