MOS Source Code
Loading...
Searching...
No Matches
ksyscall.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2
4#include "mos/ipc/ipc_io.hpp"
5#include "mos/ipc/memfd.hpp"
6#include "mos/ipc/pipe.hpp"
7#include "mos/misc/power.hpp"
8#include "mos/mm/dma.hpp"
10
11#include <bits/posix/iovec.h>
12#include <errno.h>
13#include <fcntl.h>
16#include <mos/io/io.hpp>
17#include <mos/locks/futex.hpp>
18#include <mos/mm/mmap.hpp>
21#include <mos/syscall/decl.h>
22#include <mos/syscall/number.h>
23#include <mos/syslog/printk.hpp>
24#include <mos/tasks/elf.hpp>
25#include <mos/tasks/process.hpp>
28#include <mos/tasks/thread.hpp>
29#include <mos/types.hpp>
30#include <mos_stdlib.hpp>
31#include <mos_string.hpp>
32#include <sys/poll.h>
33
34#define DEFINE_SYSCALL(ret, name) \
35 MOS_STATIC_ASSERT(SYSCALL_DEFINED(name)); \
36 ret define_syscall(name)
37
38// taken from mlibc
39constexpr static int days_from_civil(int y, unsigned m, unsigned d) noexcept
40{
41 y -= m <= 2;
42 const int era = (y >= 0 ? y : y - 399) / 400;
43 const unsigned yoe = static_cast<unsigned>(y - era * 400); // [0, 399]
44 const unsigned doy = (153 * (m > 2 ? m - 3 : m + 9) + 2) / 5 + d - 1; // [0, 365]
45 const unsigned doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; // [0, 146096]
46 return era * 146097 + static_cast<int>(doe) - 719468;
47}
48
49DEFINE_SYSCALL(void, poweroff)(bool reboot, u32 magic)
50{
51#define POWEROFF_MAGIC MOS_FOURCC('G', 'B', 'y', 'e')
52 if (magic != POWEROFF_MAGIC)
53 {
54 mos_warn("poweroff syscall called with wrong magic number (0x%x)", magic);
55 return;
56 }
57
58 if (!reboot)
59 {
60 pr_info("Meow, see ya~ :3");
62 }
63 else
64 {
65 mos_warn("reboot is not implemented yet");
66 }
67}
68
69DEFINE_SYSCALL(fd_t, vfs_openat)(fd_t dirfd, const char *path, u64 flags)
70{
71 if (path == NULL)
72 return -1;
73
74 auto f = vfs_openat(dirfd, path, (open_flags) flags);
75 if (f.isErr())
76 return f.getErr();
78}
79
80DEFINE_SYSCALL(long, vfs_fstatat)(fd_t fd, const char *path, file_stat_t *stat_buf, u64 flags)
81{
82 return vfs_fstatat(fd, path, stat_buf, (fstatat_flags) flags);
83}
84
85DEFINE_SYSCALL(size_t, io_read)(fd_t fd, void *buf, size_t count)
86{
87 if (buf == NULL)
88 return -EFAULT;
89
91 if (!io)
92 return -EBADF;
93
94 return io->read(buf, count);
95}
96
97DEFINE_SYSCALL(size_t, io_write)(fd_t fd, const void *buf, size_t count)
98{
99 if (buf == NULL)
100 {
101 pr_warn("io_write called with invalid arguments (fd=%d, buf=%p, count=%zd)", fd, buf, count);
102 return -EFAULT;
103 }
104
106 if (!io)
107 {
108 pr_warn("io_write called with invalid fd %d", fd);
109 return -EBADF;
110 }
111
112 return io->write(buf, count);
113}
114
116{
118 return true;
119}
120
121DEFINE_SYSCALL([[noreturn]] void, exit)(u32 exit_code)
122{
123 // only use the lower 8 bits
124 exit_code &= 0xff;
125 process_exit(std::move(current_process), exit_code, 0);
126 __builtin_unreachable();
127}
128
130{
131 spinlock_acquire(&current_thread->state_lock);
132 reschedule();
133}
134
136{
137 const auto parent = current_process;
138 const auto child = process_do_fork(parent);
139 if (unlikely(!child))
140 return -1;
141 return child->pid; // return 0 for child, pid for parent
142}
143
145{
146 return current_process->pid;
147}
148
150{
151 return current_process->parent->pid;
152}
153
154DEFINE_SYSCALL(pid_t, spawn)(const char *path, const char *const argv[], const char *const envp[])
155{
156 const stdio_t stdio = current_stdio();
157
159 for (size_t i = 0; argv[i] != NULL; i++)
160 argv_vec.push_back(argv[i]);
161
163 for (size_t i = 0; envp[i] != NULL; i++)
164 envp_vec.push_back(envp[i]);
165
166 const auto process = elf_create_process(path, current_process, argv_vec, envp_vec, &stdio);
167
168 if (!process)
169 return -1;
170
171 return process->pid;
172}
173
174DEFINE_SYSCALL(tid_t, create_thread)(const char *name, thread_entry_t entry, void *arg, size_t stack_size, void *stack)
175{
176 const auto opt_thread = thread_new(current_process, THREAD_MODE_USER, name, stack_size, stack);
177 if (opt_thread.isErr())
178 return -1;
179
180 const auto thread = opt_thread.get();
181
182 platform_context_setup_child_thread(thread, entry, arg);
183 thread_complete_init(thread);
184 scheduler_add_thread(thread);
185 return thread->tid;
186}
187
189{
190 return current_thread->tid;
191}
192
193DEFINE_SYSCALL([[noreturn]] void, thread_exit)(void)
194{
195 thread_exit(std::move(current_thread));
196 __builtin_unreachable();
197}
198
200{
201 return thread_wait_for_tid(tid);
202}
203
205{
206 return futex_wait(futex, val);
207}
208
209DEFINE_SYSCALL(bool, futex_wake)(futex_word_t *futex, size_t count)
210{
211 return futex_wake(futex, count);
212}
213
214DEFINE_SYSCALL(fd_t, ipc_create)(const char *name, size_t max_pending_connections)
215{
216 auto io = ipc_create(name, max_pending_connections);
217 if (io.isErr())
218 return io.getErr();
220}
221
223{
224 IO *server = process_get_fd(current_process, listen_fd);
225 if (server == NULL)
226 return -1;
227
228 auto client_io = ipc_accept(server);
229 if (client_io.isErr())
230 return client_io.getErr();
231
232 return process_attach_ref_fd(current_process, client_io.get(), FD_FLAGS_NONE);
233}
234
235DEFINE_SYSCALL(fd_t, ipc_connect)(const char *server, size_t buffer_size)
236{
237 auto io = ipc_connect(server, buffer_size);
238 if (io.isErr())
239 return io.getErr();
241}
242
243DEFINE_SYSCALL(u64, arch_syscall)(u64 syscall, u64 arg1, u64 arg2, u64 arg3, u64 arg4)
244{
245 return platform_arch_syscall(syscall, arg1, arg2, arg3, arg4);
246}
247
248DEFINE_SYSCALL(long, vfs_mount)(const char *device, const char *mountpoint, const char *fs_type, const char *options)
249{
250 return vfs_mount(device, mountpoint, fs_type, options).getErr();
251}
252
253DEFINE_SYSCALL(ssize_t, vfs_readlinkat)(fd_t dirfd, const char *path, char *buf, size_t buflen)
254{
255 return vfs_readlinkat(dirfd, path, buf, buflen);
256}
257
258DEFINE_SYSCALL(long, vfs_unlinkat)(fd_t dirfd, const char *path)
259{
260 return vfs_unlinkat(dirfd, path);
261}
262
263DEFINE_SYSCALL(long, vfs_symlink)(const char *target, const char *linkpath)
264{
265 return vfs_symlink(target, linkpath);
266}
267
268DEFINE_SYSCALL(long, vfs_mkdir)(const char *path)
269{
270 return vfs_mkdir(path).getErr();
271}
272
273DEFINE_SYSCALL(size_t, vfs_list_dir)(fd_t fd, char *buffer, size_t buffer_size)
274{
276 if (io == NULL)
277 return false;
278 return vfs_list_dir(io, buffer, buffer_size);
279}
280
281DEFINE_SYSCALL(long, fd_manipulate)(fd_t fd, u64 op, void *arg)
282{
283 fd_type *fdt = &current_process->files[fd];
284 if (fdt->io == NULL)
285 return -EBADF;
286
287 switch (op)
288 {
289 case F_DUPFD:
290 {
292 return fd2;
293 }
294 case F_DUPFD_CLOEXEC:
295 {
297 return fd2;
298 }
299 case F_GETFD:
300 {
301 return fdt->flags;
302 }
303 case F_SETFD:
304 {
305 // test if arg is a valid flag
306 const FDFlags flags = (FDFlag) (u64) arg;
307 if (flags.test_inverse(FD_FLAGS_CLOEXEC))
308 return -EINVAL;
309 fdt->flags = flags;
310 return 0;
311 }
312 case F_GETFL:
313 case F_SETFL:
314 {
315 return -ENOSYS; // not implemented
316 }
317 case F_GETLK:
318 case F_SETLK:
319 case F_SETLKW:
320 {
321 return -ENOSYS; // not implemented
322 }
323 case F_GETOWN:
324 case F_SETOWN:
325 case F_GETOWN_EX:
326 case F_SETOWN_EX:
327 case F_GETSIG:
328 case F_SETSIG:
329 case F_GETOWNER_UIDS:
330 case F_ADD_SEALS:
331 case F_GET_SEALS:
332 {
333 return -ENOSYS; // not implemented
334 }
335 }
336
337 return -EINVAL;
338}
339
340DEFINE_SYSCALL(void *, mmap_anonymous)(ptr_t hint_addr, size_t size, mem_perm_t perm, u64 flags)
341{
342 const VMFlags vmflags = VM_USER | (VMFlag) perm; // VMFlags shares the same values as mem_perm_t
343 const size_t n_pages = ALIGN_UP_TO_PAGE(size) / MOS_PAGE_SIZE;
344
345 ptr_t result = mmap_anonymous(current_mm, hint_addr, (mmap_flags_t) flags, vmflags, n_pages);
346 return (void *) result;
347}
348
349DEFINE_SYSCALL(void *, mmap_file)(ptr_t hint_addr, size_t size, mem_perm_t perm, u64 mmap_flags, fd_t fd, off_t offset)
350{
351 const VMFlags vmflags = VM_USER | (VMFlag) perm; // VMFlags shares the same values as mem_perm_t
352 const size_t n_pages = ALIGN_UP_TO_PAGE(size) / MOS_PAGE_SIZE;
353
355 if (io == NULL)
356 return NULL;
357
358 ptr_t result = mmap_file(current_mm, hint_addr, (mmap_flags_t) mmap_flags, vmflags, n_pages, io, offset);
359 return (void *) result;
360}
361
363{
364 return process_wait_for_pid(pid, exit_code, flags);
365}
366
367DEFINE_SYSCALL(bool, munmap)(void *addr, size_t size)
368{
369 return munmap((ptr_t) addr, size);
370}
371
372DEFINE_SYSCALL(long, vfs_chdirat)(fd_t dirfd, const char *path)
373{
374 return vfs_chdirat(dirfd, path);
375}
376
378{
379 return vfs_getcwd(buf, size);
380}
381
383{
385 if (io == NULL)
386 return -1;
387 return io->seek(offset, whence);
388}
389
391{
393 if (io == NULL)
394 return -1;
395 return io->tell();
396}
397
399{
401}
402
404{
405 const auto process = process_get(pid);
406 if (!process)
407 return -ESRCH;
408 return signal_send_to_process(*process, sig);
409}
410
412{
413 Thread *thread = thread_get(tid);
414 if (!thread)
415 return -ESRCH;
416 return signal_send_to_thread(thread, sig);
417}
418
419DEFINE_SYSCALL([[noreturn]] void, signal_return)(void *sp)
420{
422}
423
424DEFINE_SYSCALL(bool, vm_protect)(void *addr, size_t size, mem_perm_t perm)
425{
426 return vm_protect(current_mm, (ptr_t) addr, size, (VMFlag) perm);
427}
428
429DEFINE_SYSCALL(int, io_poll)(struct pollfd *fds, nfds_t nfds, int timeout)
430{
431 if (timeout == 0) // poll with timeout 0 is just a check
432 return 0;
433
434 if (!fds || nfds == 0)
435 return -1;
436
437 for (nfds_t i = 0; i < nfds; i++)
438 {
439 if (fds[i].fd < 0)
440 fds[i].revents = 0;
441 pr_info2("io_poll: fd=%d, events=%d", fds[i].fd, fds[i].events);
442 }
443
444 pr_emerg("io_poll is not implemented yet\n");
445 signal_send_to_thread(current_thread, SIGKILL); // unimplemented
446 return 0;
447}
448
449#ifndef FD_CLR
450#define FD_CLR(__fd, __set) (__set->fds_bits[__fd / 8] &= ~(1 << (__fd % 8)))
451#endif
452
453#ifndef FD_ISSET
454#define FD_ISSET(__fd, __set) (__set->fds_bits[__fd / 8] & (1 << (__fd % 8)))
455#endif
456
457#ifndef FD_SET
458#define FD_SET(__fd, __set) (__set->fds_bits[__fd / 8] |= 1 << (__fd % 8))
459#endif
460
461#ifndef FD_ZERO
462#define FD_ZERO(__set) memset(__set->fds_bits, 0, sizeof(fd_set))
463#endif
464
465DEFINE_SYSCALL(int, io_pselect)(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask)
466{
467 MOS_UNUSED(timeout);
468 MOS_UNUSED(sigmask);
469
470 for (int i = 0; i < nfds; i++)
471 {
472 if (readfds && FD_ISSET(i, readfds))
473 {
474 // pr_info2("io_pselect: fd=%d, read", i);
475 }
476 if (writefds && FD_ISSET(i, writefds))
477 {
478 // pr_info2("io_pselect: fd=%d, write", i);
479 }
480 if (exceptfds && FD_ISSET(i, exceptfds))
481 {
482 // pr_info2("io_pselect: fd=%d, except", i);
483 }
484 }
485
486 return 1; // stub
487}
488
489DEFINE_SYSCALL(long, execveat)(fd_t dirfd, const char *path, const char *const argv[], const char *const envp[], u64 flags)
490{
491 return process_do_execveat(dirfd, path, argv, envp, flags);
492}
493
495{
496 timer_msleep(ms);
497 return 0;
498}
499
501{
503 if (io == NULL)
504 return -EBADF; // fd is not a valid file descriptor
505 return process_attach_ref_fd(current_process, io->ref(), current_process->files[fd].flags);
506}
507
509{
510 fd_type *old = &current_process->files[oldfd];
511 if (old->io == NULL)
512 return -EBADF; // oldfd is not a valid file descriptor
513
514 if (oldfd == newfd)
515 return newfd;
516
518
519 current_process->files[newfd].io = old->io->ref();
520 current_process->files[newfd].flags = old->flags;
521 return newfd;
522}
523
524DEFINE_SYSCALL(bool, dmabuf_alloc)(size_t n_pages, ptr_t *phys, ptr_t *virt)
525{
526 pfn_t pfn = dmabuf_allocate(n_pages, virt);
527 *phys = pfn * MOS_PAGE_SIZE;
528 return !IS_ERR_VALUE(pfn);
529}
530
532{
533 return dmabuf_free(vaddr, paddr);
534}
535
536DEFINE_SYSCALL(bool, dmabuf_share)(void *buffer, size_t size, ptr_t *phyaddr)
537{
539
540 if (IS_ERR_VALUE(pfn))
541 return false;
542
543 *phyaddr = pfn * MOS_PAGE_SIZE;
544 return true;
545}
546
547DEFINE_SYSCALL(bool, dmabuf_unshare)(ptr_t phys, size_t size, void *buf)
548{
549 return dmabuf_unshare(phys, size, buf);
550}
551
552DEFINE_SYSCALL(long, pipe)(fd_t *reader, fd_t *writer, u64 flags)
553{
554 auto pipe = pipe_create(MOS_PAGE_SIZE * 4);
555 if (pipe.isErr())
556 return pipe.getErr();
557
558 auto pipeio = pipeio_create(pipe.get());
559 *reader = process_attach_ref_fd(current_process, &pipeio->io_r, (FDFlag) flags);
560 *writer = process_attach_ref_fd(current_process, &pipeio->io_w, (FDFlag) flags);
561 return 0;
562}
563
564DEFINE_SYSCALL(ssize_t, io_readv)(fd_t fd, const struct iovec *iov, int iovcnt)
565{
566 if (fd < 0)
567 return -EBADF;
568
569 if (iov == NULL)
570 return -EFAULT;
571
573 if (!io)
574 return -EBADF;
575
576 for (int i = 0; i < iovcnt; i++)
577 {
578 if (iov[i].iov_base == NULL)
579 return -EFAULT;
580 }
581
582 ssize_t bytes_read = 0;
583
584 for (int i = 0; i < iovcnt; i++)
585 {
586 size_t ret = io->read(iov[i].iov_base, iov[i].iov_len);
587 if (IS_ERR_VALUE(ret))
588 return ret;
589
590 bytes_read += ret;
591
592 if (ret != iov[i].iov_len)
593 break; // short read, leave
594 }
595
596 return bytes_read;
597}
598
599DEFINE_SYSCALL(long, vfs_unmount)(const char *path)
600{
601 return vfs_unmount(path);
602}
603
604DEFINE_SYSCALL(long, clock_gettimeofday)(struct timespec *ts)
605{
606#ifdef __x86_64__
607 timeval_t tv;
609 if (tv.day == 0)
610 return -ENOTSUP;
611
612 const auto days = days_from_civil(tv.year, tv.month, tv.day);
613 ts->tv_sec = (days * 86400) + (tv.hour * 60 * 60) + (tv.minute * 60) + tv.second;
614 ts->tv_nsec = 0;
615#elifdef __riscv
616 constexpr auto NSEC_PER_SEC = 1'000'000'000;
617 u64 timestamp = 0;
618 platform_get_unix_timestamp(&timestamp);
619 ts->tv_sec = timestamp / NSEC_PER_SEC;
620 ts->tv_nsec = timestamp % NSEC_PER_SEC;
621#endif
622 return 0;
623}
624
625DEFINE_SYSCALL(long, thread_setname)(tid_t tid, const char *name)
626{
627 Thread *thread = thread_get(tid);
628 if (!thread)
629 return -ESRCH;
630
631 thread->name = name;
632 return true;
633}
634
635DEFINE_SYSCALL(ssize_t, thread_getname)(tid_t tid, char *buf, size_t buflen)
636{
637 Thread *thread = thread_get(tid);
638
639 if (!thread)
640 return -ESRCH;
641
642 char *end = strncpy(buf, thread->name.data(), buflen);
643 return end - buf;
644}
645
646DEFINE_SYSCALL(long, vfs_fchmodat)(fd_t dirfd, const char *path, int mode, u64 flags)
647{
648 return vfs_fchmodat(dirfd, path, mode, flags);
649}
650
651DEFINE_SYSCALL(long, io_pread)(fd_t fd, void *buf, size_t count, off_t offset)
652{
653 if (fd < 0)
654 return -EBADF;
655
656 if (buf == NULL)
657 return -EFAULT;
658
660 if (!io)
661 return -EBADF;
662
663 return io->pread(buf, count, offset);
664}
665
667{
668 auto io = memfd_create(name);
669 if (io.isErr())
670 return io.getErr();
671
672 return process_attach_ref_fd(current_process, io.get(), (FDFlag) flags);
673}
674
675DEFINE_SYSCALL(long, signal_mask_op)(int how, const sigset_t *set, sigset_t *oldset)
676{
677 if (oldset)
678 *oldset = current_thread->signal_info.mask;
679
680 if (set)
681 {
682 switch (how)
683 {
684 case SIG_SETMASK: current_thread->signal_info.mask = *set; break;
685 case SIG_BLOCK:
686 {
687 char *ptr = (char *) set;
688 char *mask = (char *) &current_thread->signal_info.mask;
689 for (size_t i = 0; i < sizeof(sigset_t); i++)
690 mask[i] |= ptr[i];
691 break;
692 }
693 case SIG_UNBLOCK:
694 {
695 char *ptr = (char *) set;
696 char *mask = (char *) &current_thread->signal_info.mask;
697 for (size_t i = 0; i < sizeof(sigset_t); i++)
698 mask[i] &= ~ptr[i];
699 break;
700 }
701 default: return -EINVAL;
702 }
703 }
704
705 return 0;
706}
707
708DEFINE_SYSCALL(long, vfs_fsync)(fd_t fd, bool data_only)
709{
711 if (!io)
712 return -EBADF;
713
714 if (io->io_type != IO_FILE)
715 return -EBADF;
716
717 return vfs_fsync(io, data_only, 0, (off_t) -1);
718}
719
720DEFINE_SYSCALL(long, vfs_rmdir)(const char *path)
721{
722 return vfs_rmdir(path).getErr();
723}
#define mos_warn(fmt,...)
Definition assert.hpp:22
#define MOS_PAGE_SIZE
Definition autoconf.h:6
const Char * data() const
Definition string.hpp:254
auto push_back(const TItem &value) noexcept
Definition vector.hpp:143
bool dmabuf_free(ptr_t vaddr, ptr_t paddr)
Definition ksyscall.cpp:531
pfn_t dmabuf_share(void *buffer, size_t size)
Definition dma.cpp:52
bool dmabuf_unshare(ptr_t phys, size_t size, void *virt)
Definition ksyscall.cpp:547
pfn_t dmabuf_allocate(size_t n_pages, ptr_t *pages)
Allocate DMA pages.
Definition dma.cpp:24
Process * elf_create_process(mos::string_view path, Process *parent, const mos::vector< mos::string > &argv, const mos::vector< mos::string > &envp, const stdio_t *ios)
Definition elf.cpp:384
fstatat_flags
Definition fs_types.h:40
FDFlag
Definition fs_types.h:47
@ FD_FLAGS_CLOEXEC
Definition fs_types.h:49
@ FD_FLAGS_NONE
Definition fs_types.h:48
open_flags
Definition fs_types.h:26
long signal_send_to_process(Process *target, signal_t signal)
Send a signal to a process, an arbitrary thread will be chosen to receive the signal.
Definition signal.cpp:122
long signal_send_to_thread(Thread *target, signal_t signal)
Send a signal to a thread.
Definition signal.cpp:88
MOSAPI char * strncpy(char *__restrict dest, const char *__restrict src, size_t n)
MOSAPI void(1, 2) fatal_abort(const char *fmt
@ THREAD_MODE_USER
long vfs_chdirat(fd_t dirfd, const char *path)
Change the current working directory.
Definition vfs.cpp:787
long vfs_symlink(const char *path, const char *target)
Create a symbolic link.
Definition vfs.cpp:658
long vfs_unmount(const char *path)
Unmount a filesystem at a given path.
Definition vfs.cpp:543
PtrResult< void > vfs_mount(const char *device, const char *path, const char *fs, const char *options)
Mount a filesystem at a given existing path.
Definition vfs.cpp:464
long vfs_fstatat(fd_t fd, const char *path, file_stat_t *__restrict statbuf, FStatAtFlags flags)
Stat a file.
Definition vfs.cpp:596
ssize_t vfs_getcwd(char *buf, size_t size)
Get the current working directory.
Definition vfs.cpp:806
PtrResult< FsBaseFile > vfs_openat(int fd, mos::string_view path, OpenFlags flags)
Open a file at a given path.
Definition vfs.cpp:585
long vfs_unlinkat(fd_t dirfd, const char *path)
Remove the name of a file, and possibly the file itself.
Definition vfs.cpp:846
PtrResult< void > vfs_mkdir(const char *path)
Create a directory.
Definition vfs.cpp:679
long vfs_fsync(IO *io, bool sync_metadata, off_t start, off_t end)
Synchronize a file with the filesystem.
Definition vfs.cpp:876
PtrResult< void > vfs_rmdir(const char *path)
Definition vfs.cpp:708
long vfs_fchmodat(fd_t fd, const char *path, int perm, int flags)
Change the permissions of a file.
Definition vfs.cpp:829
size_t vfs_readlinkat(fd_t dirfd, const char *path, char *buf, size_t size)
Read a symbolic link.
Definition vfs.cpp:632
size_t vfs_list_dir(IO *io, void *user_buf, size_t user_size)
Get the content of a directory.
Definition vfs.cpp:735
@ IO_FILE
Definition io.hpp:20
io_seek_whence_t
Definition io_types.h:6
PtrResult< IO > ipc_accept(IO *server)
Accept a new connection on an IPC server.
Definition ipc_io.cpp:109
PtrResult< IO > ipc_connect(const char *name, size_t buffer_size)
Connect to an IPC servers.
Definition ipc_io.cpp:126
PtrResult< IO > ipc_create(const char *name, size_t max_pending_connections)
Create a new IPC server.
Definition ipc_io.cpp:92
bool define_syscall vm_protect(void *addr, size_t size, mem_perm_t perm)
Definition ksyscall.cpp:424
void *define_syscall mmap_anonymous(ptr_t hint_addr, size_t size, mem_perm_t perm, u64 flags)
Definition ksyscall.cpp:340
long define_syscall vfs_fsync(fd_t fd, bool data_only)
Definition ksyscall.cpp:708
static constexpr int days_from_civil(int y, unsigned m, unsigned d) noexcept
Definition ksyscall.cpp:39
fd_t define_syscall memfd_create(const char *name, u64 flags)
Definition ksyscall.cpp:666
ssize_t define_syscall thread_getname(tid_t tid, char *buf, size_t buflen)
Definition ksyscall.cpp:635
bool define_syscall signal_register(signal_t sig, const sigaction_t *action)
Definition ksyscall.cpp:398
long define_syscall vfs_fstatat(fd_t fd, const char *path, file_stat_t *stat_buf, u64 flags)
Definition ksyscall.cpp:80
#define FD_ISSET(__fd, __set)
Definition ksyscall.cpp:454
fd_t define_syscall io_dup(fd_t fd)
Definition ksyscall.cpp:500
off_t define_syscall io_seek(fd_t fd, off_t offset, io_seek_whence_t whence)
Definition ksyscall.cpp:382
fd_t define_syscall ipc_accept(fd_t listen_fd)
Definition ksyscall.cpp:222
fd_t define_syscall io_dup2(fd_t oldfd, fd_t newfd)
Definition ksyscall.cpp:508
long define_syscall clock_msleep(u64 ms)
Definition ksyscall.cpp:494
long define_syscall signal_thread(tid_t tid, signal_t sig)
Definition ksyscall.cpp:411
long define_syscall signal_process(pid_t pid, signal_t sig)
Definition ksyscall.cpp:403
off_t define_syscall io_tell(fd_t fd)
Definition ksyscall.cpp:390
pid_t define_syscall wait_for_process(pid_t pid, u32 *exit_code, u64 flags)
Definition ksyscall.cpp:362
void define_syscall thread_exit(void)
Definition ksyscall.cpp:193
void define_syscall poweroff(bool reboot, u32 magic)
Definition ksyscall.cpp:49
pid_t define_syscall get_parent_pid(void)
Definition ksyscall.cpp:149
long define_syscall fd_manipulate(fd_t fd, u64 op, void *arg)
Definition ksyscall.cpp:281
int define_syscall io_pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask)
Definition ksyscall.cpp:465
#define POWEROFF_MAGIC
bool define_syscall munmap(void *addr, size_t size)
Definition ksyscall.cpp:367
fd_t define_syscall ipc_connect(const char *server, size_t buffer_size)
Connect to an IPC servers.
Definition ksyscall.cpp:235
bool define_syscall dmabuf_free(ptr_t vaddr, ptr_t paddr)
Definition ksyscall.cpp:531
void define_syscall exit(u32 exit_code)
Definition ksyscall.cpp:121
void define_syscall yield_cpu(void)
Definition ksyscall.cpp:129
bool define_syscall wait_for_thread(tid_t tid)
Definition ksyscall.cpp:199
long define_syscall vfs_fchmodat(fd_t dirfd, const char *path, int mode, u64 flags)
Definition ksyscall.cpp:646
long define_syscall io_pread(fd_t fd, void *buf, size_t count, off_t offset)
Definition ksyscall.cpp:651
long define_syscall signal_mask_op(int how, const sigset_t *set, sigset_t *oldset)
Definition ksyscall.cpp:675
size_t define_syscall vfs_list_dir(fd_t fd, char *buffer, size_t buffer_size)
Definition ksyscall.cpp:273
size_t define_syscall io_read(fd_t fd, void *buf, size_t count)
Definition ksyscall.cpp:85
ssize_t define_syscall io_readv(fd_t fd, const struct iovec *iov, int iovcnt)
Definition ksyscall.cpp:564
bool define_syscall dmabuf_alloc(size_t n_pages, ptr_t *phys, ptr_t *virt)
Definition ksyscall.cpp:524
bool define_syscall dmabuf_unshare(ptr_t phys, size_t size, void *buf)
Definition ksyscall.cpp:547
fd_t define_syscall vfs_openat(fd_t dirfd, const char *path, u64 flags)
Definition ksyscall.cpp:69
pid_t define_syscall get_pid(void)
Definition ksyscall.cpp:144
u64 define_syscall arch_syscall(u64 syscall, u64 arg1, u64 arg2, u64 arg3, u64 arg4)
Definition ksyscall.cpp:243
pid_t define_syscall spawn(const char *path, const char *const argv[], const char *const envp[])
Definition ksyscall.cpp:154
int define_syscall io_poll(struct pollfd *fds, nfds_t nfds, int timeout)
Definition ksyscall.cpp:429
tid_t define_syscall get_tid(void)
Definition ksyscall.cpp:188
fd_t define_syscall ipc_create(const char *name, size_t max_pending_connections)
Create a new IPC server.
Definition ksyscall.cpp:214
tid_t define_syscall create_thread(const char *name, thread_entry_t entry, void *arg, size_t stack_size, void *stack)
Definition ksyscall.cpp:174
void define_syscall signal_return(void *sp)
Definition ksyscall.cpp:419
long define_syscall execveat(fd_t dirfd, const char *path, const char *const argv[], const char *const envp[], u64 flags)
Definition ksyscall.cpp:489
void *define_syscall mmap_file(ptr_t hint_addr, size_t size, mem_perm_t perm, u64 mmap_flags, fd_t fd, off_t offset)
Definition ksyscall.cpp:349
#define DEFINE_SYSCALL(ret, name)
Definition ksyscall.cpp:34
size_t define_syscall io_write(fd_t fd, const void *buf, size_t count)
Definition ksyscall.cpp:97
bool define_syscall dmabuf_share(void *buffer, size_t size, ptr_t *phyaddr)
Definition ksyscall.cpp:536
long define_syscall thread_setname(tid_t tid, const char *name)
Definition ksyscall.cpp:625
long define_syscall pipe(fd_t *reader, fd_t *writer, u64 flags)
Definition ksyscall.cpp:552
long define_syscall clock_gettimeofday(struct timespec *ts)
Definition ksyscall.cpp:604
bool define_syscall io_close(fd_t fd)
Definition ksyscall.cpp:115
pid_t define_syscall fork(void)
Definition ksyscall.cpp:135
PtrResult< IO > memfd_create(const char *name)
Definition memfd.cpp:40
mem_perm_t
Definition mm_types.h:7
mmap_flags_t
Definition mm_types.h:15
VMFlag
Definition mm_types.hpp:11
@ VM_USER
Definition mm_types.hpp:17
bool munmap(ptr_t addr, size_t size)
Unmap a page from the current process's address space.
Definition mmap.cpp:108
ptr_t mmap_file(MMContext *ctx, ptr_t hint_addr, MMapFlags flags, VMFlags VMFlags, size_t n_pages, IO *io, off_t offset)
Map a file into the current process's address space.
Definition mmap.cpp:71
ptr_t mmap_anonymous(MMContext *ctx, ptr_t hint_addr, MMapFlags flags, VMFlags VMFlags, size_t n_pages)
Map a page into the current process's address space.
Definition mmap.cpp:54
bool vm_protect(MMContext *mmctx, ptr_t addr, size_t size, VMFlags perm)
Change the permissions of a mapping.
Definition mmap.cpp:141
#define ALIGN_UP_TO_PAGE(addr)
Definition mos_global.h:76
#define MOS_UNUSED(x)
Definition mos_global.h:65
#define IS_ERR_VALUE(x)
Definition mos_global.h:137
#define unlikely(x)
Definition mos_global.h:40
#define futex_wake(futex, val)
Definition mutex.cpp:10
#define futex_wait(futex, val)
Definition mutex.cpp:9
#define NULL
Definition pb_syshdr.h:46
PtrResult< pipe_t > pipe_create(size_t bufsize)
Definition pipe.cpp:165
pipeio_t * pipeio_create(pipe_t *pipe)
Definition pipe.cpp:213
#define current_thread
Definition platform.hpp:33
#define current_mm
Definition platform.hpp:35
#define current_process
Definition platform.hpp:34
void power_shutdown(void)
Shutdown the system.
Definition power.cpp:30
#define pr_info2(fmt,...)
Definition printk.hpp:36
#define pr_warn(fmt,...)
Definition printk.hpp:38
#define pr_emerg(fmt,...)
Definition printk.hpp:39
#define pr_info(fmt,...)
Definition printk.hpp:35
void process_exit(Process *&&proc, u8 exit_code, signal_t signal)
Definition process.cpp:289
pid_t process_wait_for_pid(pid_t pid, u32 *exit_code, u32 flags)
Definition process.cpp:221
long process_do_execveat(fd_t dirfd, const char *path, const char *const argv[], const char *const envp[], int flags)
Definition execve.cpp:19
IO * process_get_fd(Process *process, fd_t fd)
Definition process.cpp:198
Process * process_do_fork(Process *process)
Definition fork.cpp:24
should_inline stdio_t current_stdio(void)
Definition process.hpp:25
bool process_register_signal_handler(Process *process, signal_t sig, const sigaction_t *sigaction)
Definition process.cpp:388
std::optional< Process * > process_get(pid_t pid)
Definition process.cpp:166
fd_t process_attach_ref_fd(Process *process, IO *file, FDFlags flags)
Definition process.cpp:177
bool process_detach_fd(Process *process, fd_t fd)
Definition process.cpp:206
void platform_get_time(timeval_t *tv)
u64 platform_arch_syscall(u64 syscall, u64 arg1, u64 arg2, u64 arg3, u64 arg4)
void platform_restore_from_signal_handler(void *sp)
void platform_context_setup_child_thread(Thread *thread, thread_entry_t entry, void *arg)
void platform_get_unix_timestamp(u64 *timestamp)
void reschedule(void)
reschedule.
Definition schedule.cpp:106
void scheduler_add_thread(Thread *thread)
Add a thread to the scheduler, so that it can be scheduled.
Definition schedule.cpp:77
mos::shared_ptr< T > ptr
void(* thread_entry_t)(void *arg)
Definition signal_types.h:8
int signal_t
size_t size
Definition slab.cpp:32
const char * name
Definition slab.cpp:33
#define spinlock_acquire(lock)
Definition spinlock.hpp:64
Definition io.hpp:39
virtual size_t pread(void *buf, size_t count, off_t offset) final
Definition io.cpp:69
virtual size_t read(void *buf, size_t count) final
Definition io.cpp:50
IO * ref()
Definition io.hpp:57
const io_type_t io_type
Definition io.hpp:41
virtual off_t tell() final
Definition io.cpp:136
virtual off_t seek(off_t, io_seek_whence_t) final
Definition io.cpp:117
virtual size_t write(const void *buf, size_t count) final
Definition io.cpp:98
mos::string name
FDFlags flags
A wrapper type for the standard I/O streams.
Definition process.hpp:17
#define f(_fmt)
Definition syslog.hpp:160
static char buffer[2048]
Thread * thread_get(tid_t id)
Definition thread.cpp:174
void thread_exit(Thread *&&t)
Definition thread.cpp:210
bool thread_wait_for_tid(tid_t tid)
Definition thread.cpp:189
PtrResult< Thread > thread_new(Process *owner, thread_mode mode, mos::string_view name, size_t stack_size, void *stack)
Definition thread.cpp:77
Thread * thread_complete_init(Thread *thread)
Definition thread.cpp:165
long timer_msleep(u64 ms)
Definition timer.cpp:39
unsigned int u32
Definition types.h:17
s32 futex_word_t
Definition types.h:95
unsigned long long pfn_t
Definition types.h:37
ssize_t off_t
Definition types.h:80
s32 fd_t
Definition types.h:77
s32 tid_t
Definition types.h:75
s32 pid_t
Definition types.h:74
unsigned long ptr_t
Definition types.h:21
unsigned long long u64
Definition types.h:19
signed long ssize_t
Definition types.h:79