11#include <bits/posix/iovec.h>
34#define DEFINE_SYSCALL(ret, name) \
35 MOS_STATIC_ASSERT(SYSCALL_DEFINED(name)); \
36 ret define_syscall(name)
42 const int era = (y >= 0 ? y : y - 399) / 400;
43 const unsigned yoe =
static_cast<unsigned>(y - era * 400);
44 const unsigned doy = (153 * (m > 2 ? m - 3 : m + 9) + 2) / 5 + d - 1;
45 const unsigned doe = yoe * 365 + yoe / 4 - yoe / 100 + doy;
46 return era * 146097 +
static_cast<int>(doe) - 719468;
51#define POWEROFF_MAGIC MOS_FOURCC('G', 'B', 'y', 'e')
54 mos_warn(
"poweroff syscall called with wrong magic number (0x%x)", magic);
65 mos_warn(
"reboot is not implemented yet");
94 return io->
read(buf, count);
101 pr_warn(
"io_write called with invalid arguments (fd=%d, buf=%p, count=%zd)", fd, buf, count);
108 pr_warn(
"io_write called with invalid fd %d", fd);
112 return io->
write(buf, count);
126 __builtin_unreachable();
159 for (
size_t i = 0; argv[i] !=
NULL; i++)
163 for (
size_t i = 0; envp[i] !=
NULL; i++)
177 if (opt_thread.isErr())
180 const auto thread = opt_thread.get();
196 __builtin_unreachable();
229 if (client_io.isErr())
230 return client_io.getErr();
250 return vfs_mount(device, mountpoint, fs_type, options).getErr();
294 case F_DUPFD_CLOEXEC:
306 const FDFlags flags = (
FDFlag) (
u64) arg;
329 case F_GETOWNER_UIDS:
346 return (
void *) result;
359 return (
void *) result;
387 return io->
seek(offset, whence);
434 if (!fds || nfds == 0)
437 for (nfds_t i = 0; i < nfds; i++)
441 pr_info2(
"io_poll: fd=%d, events=%d", fds[i].fd, fds[i].events);
444 pr_emerg(
"io_poll is not implemented yet\n");
450#define FD_CLR(__fd, __set) (__set->fds_bits[__fd / 8] &= ~(1 << (__fd % 8)))
454#define FD_ISSET(__fd, __set) (__set->fds_bits[__fd / 8] & (1 << (__fd % 8)))
458#define FD_SET(__fd, __set) (__set->fds_bits[__fd / 8] |= 1 << (__fd % 8))
462#define FD_ZERO(__set) memset(__set->fds_bits, 0, sizeof(fd_set))
465DEFINE_SYSCALL(
int,
io_pselect)(
int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
const struct timespec *timeout,
const sigset_t *sigmask)
470 for (
int i = 0; i < nfds; i++)
472 if (readfds &&
FD_ISSET(i, readfds))
476 if (writefds &&
FD_ISSET(i, writefds))
480 if (exceptfds &&
FD_ISSET(i, exceptfds))
556 return pipe.getErr();
576 for (
int i = 0; i < iovcnt; i++)
578 if (iov[i].iov_base ==
NULL)
584 for (
int i = 0; i < iovcnt; i++)
586 size_t ret = io->
read(iov[i].iov_base, iov[i].iov_len);
592 if (ret != iov[i].iov_len)
613 ts->tv_sec = (days * 86400) + (tv.
hour * 60 * 60) + (tv.
minute * 60) + tv.
second;
616 constexpr auto NSEC_PER_SEC = 1'000'000'000;
619 ts->tv_sec = timestamp / NSEC_PER_SEC;
620 ts->tv_nsec = timestamp % NSEC_PER_SEC;
663 return io->
pread(buf, count, offset);
687 char *
ptr = (
char *) set;
689 for (
size_t i = 0; i <
sizeof(sigset_t); i++)
695 char *
ptr = (
char *) set;
697 for (
size_t i = 0; i <
sizeof(sigset_t); i++)
701 default:
return -EINVAL;
#define mos_warn(fmt,...)
const Char * data() const
auto push_back(const TItem &value) noexcept
bool dmabuf_free(ptr_t vaddr, ptr_t paddr)
pfn_t dmabuf_share(void *buffer, size_t size)
bool dmabuf_unshare(ptr_t phys, size_t size, void *virt)
pfn_t dmabuf_allocate(size_t n_pages, ptr_t *pages)
Allocate DMA pages.
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)
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.
long signal_send_to_thread(Thread *target, signal_t signal)
Send a signal to a thread.
MOSAPI char * strncpy(char *__restrict dest, const char *__restrict src, size_t n)
MOSAPI void(1, 2) fatal_abort(const char *fmt
long vfs_chdirat(fd_t dirfd, const char *path)
Change the current working directory.
long vfs_symlink(const char *path, const char *target)
Create a symbolic link.
long vfs_unmount(const char *path)
Unmount a filesystem at a given path.
PtrResult< void > vfs_mount(const char *device, const char *path, const char *fs, const char *options)
Mount a filesystem at a given existing path.
long vfs_fstatat(fd_t fd, const char *path, file_stat_t *__restrict statbuf, FStatAtFlags flags)
Stat a file.
ssize_t vfs_getcwd(char *buf, size_t size)
Get the current working directory.
PtrResult< FsBaseFile > vfs_openat(int fd, mos::string_view path, OpenFlags flags)
Open a file at a given path.
long vfs_unlinkat(fd_t dirfd, const char *path)
Remove the name of a file, and possibly the file itself.
PtrResult< void > vfs_mkdir(const char *path)
Create a directory.
long vfs_fsync(IO *io, bool sync_metadata, off_t start, off_t end)
Synchronize a file with the filesystem.
PtrResult< void > vfs_rmdir(const char *path)
long vfs_fchmodat(fd_t fd, const char *path, int perm, int flags)
Change the permissions of a file.
size_t vfs_readlinkat(fd_t dirfd, const char *path, char *buf, size_t size)
Read a symbolic link.
size_t vfs_list_dir(IO *io, void *user_buf, size_t user_size)
Get the content of a directory.
PtrResult< IO > ipc_accept(IO *server)
Accept a new connection on an IPC server.
PtrResult< IO > ipc_connect(const char *name, size_t buffer_size)
Connect to an IPC servers.
PtrResult< IO > ipc_create(const char *name, size_t max_pending_connections)
Create a new IPC server.
bool define_syscall vm_protect(void *addr, size_t size, mem_perm_t perm)
void *define_syscall mmap_anonymous(ptr_t hint_addr, size_t size, mem_perm_t perm, u64 flags)
long define_syscall vfs_fsync(fd_t fd, bool data_only)
static constexpr int days_from_civil(int y, unsigned m, unsigned d) noexcept
fd_t define_syscall memfd_create(const char *name, u64 flags)
ssize_t define_syscall thread_getname(tid_t tid, char *buf, size_t buflen)
bool define_syscall signal_register(signal_t sig, const sigaction_t *action)
long define_syscall vfs_fstatat(fd_t fd, const char *path, file_stat_t *stat_buf, u64 flags)
#define FD_ISSET(__fd, __set)
fd_t define_syscall io_dup(fd_t fd)
off_t define_syscall io_seek(fd_t fd, off_t offset, io_seek_whence_t whence)
fd_t define_syscall ipc_accept(fd_t listen_fd)
fd_t define_syscall io_dup2(fd_t oldfd, fd_t newfd)
long define_syscall clock_msleep(u64 ms)
long define_syscall signal_thread(tid_t tid, signal_t sig)
long define_syscall signal_process(pid_t pid, signal_t sig)
off_t define_syscall io_tell(fd_t fd)
pid_t define_syscall wait_for_process(pid_t pid, u32 *exit_code, u64 flags)
void define_syscall thread_exit(void)
void define_syscall poweroff(bool reboot, u32 magic)
pid_t define_syscall get_parent_pid(void)
long define_syscall fd_manipulate(fd_t fd, u64 op, void *arg)
int define_syscall io_pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask)
bool define_syscall munmap(void *addr, size_t size)
fd_t define_syscall ipc_connect(const char *server, size_t buffer_size)
Connect to an IPC servers.
bool define_syscall dmabuf_free(ptr_t vaddr, ptr_t paddr)
void define_syscall exit(u32 exit_code)
void define_syscall yield_cpu(void)
bool define_syscall wait_for_thread(tid_t tid)
long define_syscall vfs_fchmodat(fd_t dirfd, const char *path, int mode, u64 flags)
long define_syscall io_pread(fd_t fd, void *buf, size_t count, off_t offset)
long define_syscall signal_mask_op(int how, const sigset_t *set, sigset_t *oldset)
size_t define_syscall vfs_list_dir(fd_t fd, char *buffer, size_t buffer_size)
size_t define_syscall io_read(fd_t fd, void *buf, size_t count)
ssize_t define_syscall io_readv(fd_t fd, const struct iovec *iov, int iovcnt)
bool define_syscall dmabuf_alloc(size_t n_pages, ptr_t *phys, ptr_t *virt)
bool define_syscall dmabuf_unshare(ptr_t phys, size_t size, void *buf)
fd_t define_syscall vfs_openat(fd_t dirfd, const char *path, u64 flags)
pid_t define_syscall get_pid(void)
u64 define_syscall arch_syscall(u64 syscall, u64 arg1, u64 arg2, u64 arg3, u64 arg4)
pid_t define_syscall spawn(const char *path, const char *const argv[], const char *const envp[])
int define_syscall io_poll(struct pollfd *fds, nfds_t nfds, int timeout)
tid_t define_syscall get_tid(void)
fd_t define_syscall ipc_create(const char *name, size_t max_pending_connections)
Create a new IPC server.
tid_t define_syscall create_thread(const char *name, thread_entry_t entry, void *arg, size_t stack_size, void *stack)
void define_syscall signal_return(void *sp)
long define_syscall execveat(fd_t dirfd, const char *path, const char *const argv[], const char *const envp[], u64 flags)
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)
#define DEFINE_SYSCALL(ret, name)
size_t define_syscall io_write(fd_t fd, const void *buf, size_t count)
bool define_syscall dmabuf_share(void *buffer, size_t size, ptr_t *phyaddr)
long define_syscall thread_setname(tid_t tid, const char *name)
long define_syscall pipe(fd_t *reader, fd_t *writer, u64 flags)
long define_syscall clock_gettimeofday(struct timespec *ts)
bool define_syscall io_close(fd_t fd)
pid_t define_syscall fork(void)
PtrResult< IO > memfd_create(const char *name)
bool munmap(ptr_t addr, size_t size)
Unmap a page from the current process's address space.
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.
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.
bool vm_protect(MMContext *mmctx, ptr_t addr, size_t size, VMFlags perm)
Change the permissions of a mapping.
#define ALIGN_UP_TO_PAGE(addr)
#define futex_wake(futex, val)
#define futex_wait(futex, val)
PtrResult< pipe_t > pipe_create(size_t bufsize)
pipeio_t * pipeio_create(pipe_t *pipe)
void power_shutdown(void)
Shutdown the system.
#define pr_info2(fmt,...)
#define pr_emerg(fmt,...)
void process_exit(Process *&&proc, u8 exit_code, signal_t signal)
pid_t process_wait_for_pid(pid_t pid, u32 *exit_code, u32 flags)
long process_do_execveat(fd_t dirfd, const char *path, const char *const argv[], const char *const envp[], int flags)
IO * process_get_fd(Process *process, fd_t fd)
Process * process_do_fork(Process *process)
should_inline stdio_t current_stdio(void)
bool process_register_signal_handler(Process *process, signal_t sig, const sigaction_t *sigaction)
std::optional< Process * > process_get(pid_t pid)
fd_t process_attach_ref_fd(Process *process, IO *file, FDFlags flags)
bool process_detach_fd(Process *process, fd_t fd)
void reschedule(void)
reschedule.
void scheduler_add_thread(Thread *thread)
Add a thread to the scheduler, so that it can be scheduled.
void(* thread_entry_t)(void *arg)
#define spinlock_acquire(lock)
virtual size_t pread(void *buf, size_t count, off_t offset) final
virtual size_t read(void *buf, size_t count) final
virtual off_t tell() final
virtual off_t seek(off_t, io_seek_whence_t) final
virtual size_t write(const void *buf, size_t count) final
A wrapper type for the standard I/O streams.
Thread * thread_get(tid_t id)
void thread_exit(Thread *&&t)
bool thread_wait_for_tid(tid_t tid)
PtrResult< Thread > thread_new(Process *owner, thread_mode mode, mos::string_view name, size_t stack_size, void *stack)
Thread * thread_complete_init(Thread *thread)
long timer_msleep(u64 ms)