diff options
Diffstat (limited to 'lib/mlibc/options/posix/generic/sys-mman-stubs.cpp')
-rw-r--r-- | lib/mlibc/options/posix/generic/sys-mman-stubs.cpp | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/lib/mlibc/options/posix/generic/sys-mman-stubs.cpp b/lib/mlibc/options/posix/generic/sys-mman-stubs.cpp new file mode 100644 index 0000000..9383976 --- /dev/null +++ b/lib/mlibc/options/posix/generic/sys-mman-stubs.cpp @@ -0,0 +1,177 @@ + +#include <errno.h> +#include <limits.h> +#include <pthread.h> +#include <unistd.h> +#include <sys/mman.h> +#include <bits/ensure.h> + +#include <mlibc/debug.hpp> +#include <mlibc/posix-sysdeps.hpp> + +int mprotect(void *pointer, size_t size, int prot) { + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_vm_protect, -1); + if(int e = mlibc::sys_vm_protect(pointer, size, prot); e) { + errno = e; + return -1; + } + return 0; +} + +int mlock(const void *addr, size_t len) { + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_mlock, -1); + if(int e = mlibc::sys_mlock(addr, len); e) { + errno = e; + return -1; + } + return 0; +} + +int mlockall(int flags) { + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_mlockall, -1); + if(int e = mlibc::sys_mlockall(flags); e) { + errno = e; + return -1; + } + return 0; +} + +int munlock(const void *addr, size_t len) { + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_munlock, -1); + if(int e = mlibc::sys_munlock(addr, len); e) { + errno = e; + return -1; + } + return 0; +} + +int munlockall(void) { + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_munlockall, -1); + if(int e = mlibc::sys_munlockall(); e) { + errno = e; + return -1; + } + return 0; +} + + +int posix_madvise(void *, size_t, int) { + mlibc::infoLogger() << "\e[31m" "mlibc: posix_madvise() fails unconditionally" "\e[39m" + << frg::endlog; + return ENOSYS; +} + +int msync(void *addr, size_t length, int flags) { + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_msync, -1); + if(int e = mlibc::sys_msync(addr, length, flags); e) { + errno = e; + return -1; + } + return 0; +} + +void *mremap(void *pointer, size_t size, size_t new_size, int flags, ...) { + __ensure(flags == MREMAP_MAYMOVE); + + void *window; + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_vm_remap, (void *)-1); + if(int e = mlibc::sys_vm_remap(pointer, size, new_size, &window); e) { + errno = e; + return (void *)-1; + } + return window; +} + +int remap_file_pages(void *, size_t, int, size_t, int) { + __ensure(!"Not implemented"); + __builtin_unreachable(); +} + +void *mmap(void *hint, size_t size, int prot, int flags, int fd, off_t offset) { + void *window; + if(int e = mlibc::sys_vm_map(hint, size, prot, flags, fd, offset, &window); e) { + errno = e; + return (void *)-1; + } + return window; +} + +int munmap(void *pointer, size_t size) { + if(int e = mlibc::sys_vm_unmap(pointer, size); e) { + errno = e; + return -1; + } + return 0; +} + +// The implementation of shm_open and shm_unlink is taken from musl. +namespace { + char *shm_mapname(const char *name, char *buf) { + char *p; + while(*name == '/') + name++; + if(*(p = strchrnul(name, '/')) || p == name || + (p - name <= 2 && name[0] == '.' && p[-1] == '.')) { + errno = EINVAL; + return 0; + } + if(p - name > NAME_MAX) { + errno = ENAMETOOLONG; + return 0; + } + memcpy(buf, "/dev/shm/", 9); + memcpy(buf + 9, name, p - name + 1); + return buf; + } +} + +int shm_open(const char *name, int flags, mode_t mode) { + int cs; + char buf[NAME_MAX + 10]; + if(!(name = shm_mapname(name, buf))) + return -1; + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); + int fd = open(name, flags | O_NOFOLLOW | O_CLOEXEC | O_NONBLOCK, mode); + pthread_setcancelstate(cs, 0); + return fd; +} + +int shm_unlink(const char *name) { + char buf[NAME_MAX + 10]; + if(!(name = shm_mapname(name, buf))) + return -1; + return unlink(name); +} + +#if __MLIBC_LINUX_OPTION +int memfd_create(const char *name, unsigned int flags) { + int ret = -1; + + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_memfd_create, -1); + if(int e = mlibc::sys_memfd_create(name, flags, &ret)) { + errno = e; + return -1; + } + + return ret; +} + +int madvise(void *addr, size_t length, int advice) { + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_madvise, -1); + if(int e = mlibc::sys_madvise(addr, length, advice)) { + errno = e; + return -1; + } + + return 0; +} + +int mincore(void *addr, size_t length, unsigned char *vec) { + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_munlockall, -1); + if(int e = mlibc::sys_mincore(addr, length, vec); e) { + errno = e; + return -1; + } + return 0; +} +#endif /* __MLIBC_LINUX_OPTION */ |