Serenity Operating System
at master 177 lines 4.7 kB view raw
1/* 2 * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <Kernel/API/POSIX/fcntl.h> 8#include <Kernel/API/Syscall.h> 9#include <arpa/inet.h> 10#include <errno.h> 11#include <serenity.h> 12#include <string.h> 13#include <syscall.h> 14 15extern "C" { 16 17int disown(pid_t pid) 18{ 19 int rc = syscall(SC_disown, pid); 20 __RETURN_WITH_ERRNO(rc, rc, -1); 21} 22 23int profiling_enable(pid_t pid, uint64_t event_mask) 24{ 25 int rc = syscall(SC_profiling_enable, pid, &event_mask); 26 __RETURN_WITH_ERRNO(rc, rc, -1); 27} 28 29int profiling_disable(pid_t pid) 30{ 31 int rc = syscall(SC_profiling_disable, pid); 32 __RETURN_WITH_ERRNO(rc, rc, -1); 33} 34 35int profiling_free_buffer(pid_t pid) 36{ 37 int rc = syscall(SC_profiling_free_buffer, pid); 38 __RETURN_WITH_ERRNO(rc, rc, -1); 39} 40 41int futex(uint32_t* userspace_address, int futex_op, uint32_t value, const struct timespec* timeout, uint32_t* userspace_address2, uint32_t value3) 42{ 43 int rc; 44 switch (futex_op & FUTEX_CMD_MASK) { 45 case FUTEX_WAKE_OP: { 46 // These interpret timeout as a u32 value for val2 47 Syscall::SC_futex_params params { 48 .userspace_address = userspace_address, 49 .futex_op = futex_op, 50 .val = value, 51 .val2 = (FlatPtr)timeout, 52 .userspace_address2 = userspace_address2, 53 .val3 = value3 54 }; 55 rc = syscall(SC_futex, &params); 56 break; 57 } 58 default: { 59 Syscall::SC_futex_params params { 60 .userspace_address = userspace_address, 61 .futex_op = futex_op, 62 .val = value, 63 .timeout = timeout, 64 .userspace_address2 = userspace_address2, 65 .val3 = value3 66 }; 67 rc = syscall(SC_futex, &params); 68 break; 69 } 70 } 71 __RETURN_WITH_ERRNO(rc, rc, -1); 72} 73 74int purge(int mode) 75{ 76 int rc = syscall(SC_purge, mode); 77 __RETURN_WITH_ERRNO(rc, rc, -1); 78} 79 80int perf_event(int type, uintptr_t arg1, FlatPtr arg2) 81{ 82 int rc = syscall(SC_perf_event, type, arg1, arg2); 83 __RETURN_WITH_ERRNO(rc, rc, -1); 84} 85 86int perf_register_string(char const* string, size_t string_length) 87{ 88 int rc = syscall(SC_perf_register_string, string, string_length); 89 __RETURN_WITH_ERRNO(rc, rc, -1); 90} 91 92int get_stack_bounds(uintptr_t* user_stack_base, size_t* user_stack_size) 93{ 94 int rc = syscall(SC_get_stack_bounds, user_stack_base, user_stack_size); 95 __RETURN_WITH_ERRNO(rc, rc, -1); 96} 97 98int anon_create(size_t size, int options) 99{ 100 int rc = syscall(SC_anon_create, size, options); 101 __RETURN_WITH_ERRNO(rc, rc, -1); 102} 103 104int serenity_readlink(char const* path, size_t path_length, char* buffer, size_t buffer_size) 105{ 106 Syscall::SC_readlink_params small_params { 107 { path, path_length }, 108 { buffer, buffer_size }, 109 AT_FDCWD 110 }; 111 int rc = syscall(SC_readlink, &small_params); 112 __RETURN_WITH_ERRNO(rc, rc, -1); 113} 114 115int setkeymap(char const* name, u32 const* map, u32* const shift_map, u32 const* alt_map, u32 const* altgr_map, u32 const* shift_altgr_map) 116{ 117 Syscall::SC_setkeymap_params params { map, shift_map, alt_map, altgr_map, shift_altgr_map, { name, strlen(name) } }; 118 return syscall(SC_setkeymap, &params); 119} 120 121int getkeymap(char* name_buffer, size_t name_buffer_size, u32* map, u32* shift_map, u32* alt_map, u32* altgr_map, u32* shift_altgr_map) 122{ 123 Syscall::SC_getkeymap_params params { 124 map, 125 shift_map, 126 alt_map, 127 altgr_map, 128 shift_altgr_map, 129 { name_buffer, name_buffer_size } 130 }; 131 int rc = syscall(SC_getkeymap, &params); 132 __RETURN_WITH_ERRNO(rc, rc, -1); 133} 134 135u16 internet_checksum(void const* ptr, size_t count) 136{ 137 u32 checksum = 0; 138 auto* w = (u16 const*)ptr; 139 while (count > 1) { 140 checksum += ntohs(*w++); 141 if (checksum & 0x80000000) 142 checksum = (checksum & 0xffff) | (checksum >> 16); 143 count -= 2; 144 } 145 while (checksum >> 16) 146 checksum = (checksum & 0xffff) + (checksum >> 16); 147 return htons(~checksum); 148} 149 150int emuctl(uintptr_t command, uintptr_t arg0, uintptr_t arg1) 151{ 152 return syscall(SC_emuctl, command, arg0, arg1); 153} 154 155int serenity_open(char const* path, size_t path_length, int options, ...) 156{ 157 if (!path) { 158 errno = EFAULT; 159 return -1; 160 } 161 162 if (path_length > INT32_MAX) { 163 errno = EINVAL; 164 return -1; 165 } 166 167 va_list ap; 168 va_start(ap, options); 169 auto mode = (mode_t)va_arg(ap, unsigned); 170 va_end(ap); 171 172 Syscall::SC_open_params params { AT_FDCWD, { path, path_length }, options, mode }; 173 int rc = syscall(SC_open, &params); 174 175 __RETURN_WITH_ERRNO(rc, rc, -1); 176} 177}