Serenity Operating System
at hosted 227 lines 5.6 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#ifdef __serenity__ 28#include <Kernel/Syscall.h> 29#endif 30#include <errno.h> 31#include <serenity.h> 32 33#ifdef __OpenBSD__ 34#include <AK/Assertions.h> 35#include <err.h> 36#include <limits.h> 37#include <sys/shm.h> 38#include <sys/mman.h> 39 40#define EMAXERRNO ELAST 41#endif 42 43extern "C" { 44 45#ifdef __serenity__ 46int module_load(const char* path, size_t path_length) 47{ 48 int rc = syscall(SC_module_load, path, path_length); 49 __RETURN_WITH_ERRNO(rc, rc, -1); 50} 51 52int module_unload(const char* name, size_t name_length) 53{ 54 int rc = syscall(SC_module_unload, name, name_length); 55 __RETURN_WITH_ERRNO(rc, rc, -1); 56} 57 58int profiling_enable(pid_t pid) 59{ 60 int rc = syscall(SC_profiling_enable, pid); 61 __RETURN_WITH_ERRNO(rc, rc, -1); 62} 63 64int profiling_disable(pid_t pid) 65{ 66 int rc = syscall(SC_profiling_disable, pid); 67 __RETURN_WITH_ERRNO(rc, rc, -1); 68} 69 70int set_thread_boost(int tid, int amount) 71{ 72 int rc = syscall(SC_set_thread_boost, tid, amount); 73 __RETURN_WITH_ERRNO(rc, rc, -1); 74} 75 76int set_process_boost(int tid, int amount) 77{ 78 int rc = syscall(SC_set_process_boost, tid, amount); 79 __RETURN_WITH_ERRNO(rc, rc, -1); 80} 81 82int futex(int32_t* userspace_address, int futex_op, int32_t value, const struct timespec* timeout) 83{ 84 Syscall::SC_futex_params params { userspace_address, futex_op, value, timeout }; 85 int rc = syscall(SC_futex, &params); 86 __RETURN_WITH_ERRNO(rc, rc, -1); 87} 88 89int purge(int mode) 90{ 91 int rc = syscall(SC_purge, mode); 92 __RETURN_WITH_ERRNO(rc, rc, -1); 93} 94 95#else 96 97int module_load(const char* path, size_t path_length) 98{ 99 (void)path; 100 (void)path_length; 101 return -ENOTSUP; 102} 103 104int module_unload(const char* name, size_t name_length) 105{ 106 (void)name; 107 (void)name_length; 108 return -ENOTSUP; 109} 110 111int profiling_enable(pid_t pid) 112{ 113 (void)pid; 114 return -ENOTSUP; 115} 116 117int profiling_disable(pid_t pid) 118{ 119 (void)pid; 120 return -ENOTSUP; 121} 122 123int set_process_boost(int tid, int amount) 124{ 125 /* TODO: use nice(3)? */ 126 (void)tid; 127 (void)amount; 128 return 0; 129} 130 131int shbuf_create(int size, void** buffer) 132{ 133 int key, id = -1; 134 135 for (key = 1; key < INT_MAX; key++) { 136 id = shmget(key, size, IPC_CREAT | IPC_EXCL | 0600); 137 if (id != -1) { 138 *buffer = shmat(id, 0, 0); 139 if (*buffer == (void *)-1) { 140 perror("shmat"); 141 ASSERT_NOT_REACHED(); 142 } 143 warnx("%d: shbuf_create = shm key %d, id %d", getpid(), key, id); 144 break; 145 } 146 } 147 148 if (id == -1) { 149 perror("shmget: exhausted"); 150 ASSERT_NOT_REACHED(); 151 } 152 153 return key; 154} 155 156int shbuf_allow_pid(int shbuf_id, pid_t peer_pid) 157{ 158 // XXX: non-serenity doesn't support this, but processes expect to be able 159 // to read once this is called 160 warnx("%d: %s(%d, %d) not implemented, allowing all", getpid(), __func__, 161 shbuf_id, peer_pid); 162 shbuf_allow_all(shbuf_id); 163 return 0; 164} 165 166int shbuf_allow_all(int shbuf_id) 167{ 168 struct shmid_ds ds; 169 int id = shmget(shbuf_id, 0, 0); 170 if (id == -1) 171 return -1; 172 if (shmctl(id, IPC_STAT, &ds) == -1) 173 return -1; 174 ds.shm_perm.mode = 0666; 175 return shmctl(id, IPC_SET, &ds); 176} 177 178void* shbuf_get(int shbuf_id, __attribute__((unused)) size_t *size) 179{ 180 int id = shmget(shbuf_id, 0, 0); 181 if (id == -1) { 182 warn("%d: shbuf_get(%d) failed", getpid(), shbuf_id); 183 errno = -id; 184 return (void*)-1; 185 } 186 void *j = shmat(id, 0, 0); 187 if (j == (void *)-1) 188 warn("%d: shmget(%d) = %d, but shmat failed", getpid(), shbuf_id, id); 189 return j; 190} 191 192int shbuf_release(int shbuf_id) 193{ 194 int id = shmget(shbuf_id, 0, 0); 195 if (id == -1) 196 return -1; 197 return shmctl(id, IPC_RMID, NULL); 198} 199 200int shbuf_get_size(int shbuf_id) 201{ 202 struct shmid_ds ds; 203 int id = shmget(shbuf_id, 0, 0); 204 if (id == -1) 205 return -1; 206 if (shmctl(id, IPC_STAT, &ds) == -1) 207 return 0; 208 return ds.shm_segsz; 209} 210 211int shbuf_seal(int shbuf_id) 212{ 213 struct shmid_ds ds; 214 int id = shmget(shbuf_id, 0, 0); 215 if (id == -1) 216 return -1; 217 if (shmctl(id, IPC_STAT, &ds) == -1) 218 return -1; 219 ds.shm_perm.mode &= 0755; // remove group/world write 220 return shmctl(id, IPC_SET, &ds); 221} 222 223 224#endif 225 226 227}