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
14struct _FILE
15{
16 int fd;
17};
18
19static struct _FILE __stdin = { .fd = 0 };
20static struct _FILE __stdout = { .fd = 1 };
21static struct _FILE __stderr = { .fd = 2 };
22
23FILE *stdin = &__stdin;
24FILE *stdout = &__stdout;
25FILE *stderr = &__stderr;
26
27typedef struct thread_start_args
28{
29 thread_entry_t entry;
30 void *arg;
31} thread_start_args_t;
32
33u64 __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
42void __stack_chk_fail_local(void)
43{
44 __stack_chk_fail();
45}
46
47void __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
62fd_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
70fd_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
75int raise(signal_t sig)
76{
77 syscall_signal_thread(tid: syscall_get_tid(), signum: sig);
78 return 0;
79}
80
81bool 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
86bool chdir(const char *path)
87{
88 return syscall_vfs_chdirat(AT_FDCWD, path) == 0;
89}
90
91bool unlink(const char *path)
92{
93 return syscall_vfs_unlinkat(AT_FDCWD, path) == 0;
94}
95
96int 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
105int 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
114int 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
122int putchar(int c)
123{
124 char ch = c;
125 syscall_io_write(stdout->fd, buffer: &ch, size: 1);
126 return c;
127}
128
129int puts(const char *s)
130{
131 syscall_io_write(stdout->fd, buffer: s, size: strlen(str: s));
132 return putchar(c: '\n');
133}
134
135int 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
140size_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