aboutsummaryrefslogtreecommitdiff
path: root/lib/mlibc/options/posix/generic/posix_stdlib.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mlibc/options/posix/generic/posix_stdlib.cpp')
-rw-r--r--lib/mlibc/options/posix/generic/posix_stdlib.cpp513
1 files changed, 0 insertions, 513 deletions
diff --git a/lib/mlibc/options/posix/generic/posix_stdlib.cpp b/lib/mlibc/options/posix/generic/posix_stdlib.cpp
deleted file mode 100644
index 4010998..0000000
--- a/lib/mlibc/options/posix/generic/posix_stdlib.cpp
+++ /dev/null
@@ -1,513 +0,0 @@
-
-#include <abi-bits/fcntl.h>
-#include <bits/ensure.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-
-#include <frg/small_vector.hpp>
-#include <mlibc/allocator.hpp>
-#include <mlibc/debug.hpp>
-#include <mlibc/posix-sysdeps.hpp>
-#include <mlibc/rtdl-config.hpp>
-
-namespace {
- constexpr bool debugPathResolution = false;
-}
-
-// Borrowed from musl
-static uint32_t init[] = {
-0x00000000,0x5851f42d,0xc0b18ccf,0xcbb5f646,
-0xc7033129,0x30705b04,0x20fd5db4,0x9a8b7f78,
-0x502959d8,0xab894868,0x6c0356a7,0x88cdb7ff,
-0xb477d43f,0x70a3a52b,0xa8e4baf1,0xfd8341fc,
-0x8ae16fd9,0x742d2f7a,0x0d1f0796,0x76035e09,
-0x40f7702c,0x6fa72ca5,0xaaa84157,0x58a0df74,
-0xc74a0364,0xae533cc4,0x04185faf,0x6de3b115,
-0x0cab8628,0xf043bfa4,0x398150e9,0x37521657};
-
-static int n = 31;
-static int i = 3;
-static int j = 0;
-static uint32_t *x = init + 1;
-
-
-static uint32_t lcg31(uint32_t x) {
- return (1103515245 * x + 12345) & 0x7fffffff;
-}
-
-static uint64_t lcg64(uint64_t x) {
- return 6364136223846793005ull * x + 1;
-}
-
-static void *savestate(void) {
- x[-1] = (n << 16) | (i << 8) | j;
- return x - 1;
-}
-
-static void loadstate(uint32_t *state) {
- x = state + 1;
- n = x[-1] >> 16;
- i = (x[-1] >> 8) & 0xff;
- j = x[-1] & 0xff;
-}
-
-long random(void) {
- long k;
-
- if(n == 0) {
- k = x[0] = lcg31(x[0]);
- return k;
- }
- x[i] += x[j];
- k = x[i] >> 1;
- if(++i == n)
- i = 0;
- if(++j == n)
- j = 0;
-
- return k;
-}
-
-double drand48(void) {
- __ensure(!"Not implemented");
- __builtin_unreachable();
-}
-
-void srand48(long int) {
- __ensure(!"Not implemented");
- __builtin_unreachable();
-}
-
-// Borrowed from musl
-void srandom(unsigned int seed) {
- int k;
- uint64_t s = seed;
-
- if(n == 0) {
- x[0] = s;
- return;
- }
- i = n == 31 || n == 7 ? 3 : 1;
- j = 0;
- for(k = 0; k < n; k++) {
- s = lcg64(s);
- x[k] = s >> 32;
- }
- // Make sure x contains at least one odd number
- x[0] |= 1;
-}
-
-char *initstate(unsigned int seed, char *state, size_t size) {
- void *old;
-
- if(size < 8)
- return 0;
- old = savestate();
- if(size < 32)
- n = 0;
- else if(size < 64)
- n = 7;
- else if(size < 128)
- n = 15;
- else if(size < 256)
- n = 31;
- else
- n = 63;
- x = (uint32_t *)state + 1;
- srandom(seed);
- savestate();
- return (char *)old;
-}
-
-char *setstate(char *state) {
- void *old;
-
- old = savestate();
- loadstate((uint32_t *)state);
- return (char *)old;
-}
-
-// ----------------------------------------------------------------------------
-// Path handling.
-// ----------------------------------------------------------------------------
-
-
-int mkostemps(char *pattern, int suffixlen, int flags) {
- auto n = strlen(pattern);
- if(n < (6 + static_cast<size_t>(suffixlen))) {
- errno = EINVAL;
- return -1;
- }
-
- flags &= ~O_WRONLY;
-
- for(size_t i = 0; i < 6; i++) {
- if(pattern[n - (6 + suffixlen) + i] == 'X')
- continue;
- errno = EINVAL;
- return -1;
- }
-
- // TODO: Do an exponential search.
- for(size_t i = 0; i < 999999; i++) {
- char sfx = pattern[n - suffixlen];
- __ensure(sprintf(pattern + (n - (6 + suffixlen)), "%06zu", i) == 6);
- pattern[n - suffixlen] = sfx;
-
- int fd;
- if(int e = mlibc::sys_open(pattern, O_RDWR | O_CREAT | O_EXCL | flags, S_IRUSR | S_IWUSR, &fd); !e) {
- return fd;
- }else if(e != EEXIST) {
- errno = e;
- return -1;
- }
- }
-
- errno = EEXIST;
- return -1;
-}
-
-int mkostemp(char *pattern, int flags) {
- return mkostemps(pattern, flags, 0);
-}
-
-int mkstemp(char *path) {
- return mkostemp(path, 0);
-}
-
-int mkstemps(char *pattern, int suffixlen) {
- return mkostemps(pattern, suffixlen, 0);
-}
-
-char *mkdtemp(char *pattern) {
- mlibc::infoLogger() << "mlibc mkdtemp(" << pattern << ") called" << frg::endlog;
- auto n = strlen(pattern);
- __ensure(n >= 6);
- if(n < 6) {
- errno = EINVAL;
- return NULL;
- }
- for(size_t i = 0; i < 6; i++) {
- if(pattern[n - 6 + i] == 'X')
- continue;
- errno = EINVAL;
- return NULL;
- }
-
- // TODO: Do an exponential search.
- for(size_t i = 0; i < 999999; i++) {
- __ensure(sprintf(pattern + (n - 6), "%06zu", i) == 6);
- if(int e = mlibc::sys_mkdir(pattern, S_IRWXU); !e) {
- return pattern;
- }else if(e != EEXIST) {
- errno = e;
- return NULL;
- }
- }
-
- errno = EEXIST;
- return NULL;
-}
-
-char *realpath(const char *path, char *out) {
- if(debugPathResolution)
- mlibc::infoLogger() << "mlibc realpath(): Called on '" << path << "'" << frg::endlog;
- frg::string_view path_view{path};
-
- // In case of the root, the string only contains the null-terminator.
- frg::small_vector<char, PATH_MAX, MemoryAllocator> resolv{getAllocator()};
- size_t ps;
-
- // If the path is relative, we have to preprend the working directory.
- if(path[0] == '/') {
- resolv.push_back(0);
- ps = 1;
- }else{
- MLIBC_CHECK_OR_ENOSYS(mlibc::sys_getcwd, nullptr);
-
- // Try to getcwd() until the buffer is large enough.
- resolv.resize(128);
- while(true) {
- int e = mlibc::sys_getcwd(resolv.data(), resolv.size());
- if(e == ERANGE) {
- resolv.resize(2 * resolv.size());
- }else if(!e) {
- break;
- }else{
- errno = e;
- return nullptr;
- }
- }
- frg::string_view cwd_view{resolv.data()};
- if(cwd_view == "/") {
- // Restore our invariant that we only store the null-terminator for the root.
- resolv.resize(1);
- resolv[0] = 0;
- }else{
- resolv.resize(cwd_view.size() + 1);
- }
- ps = 0;
- }
-
- // Contains unresolved links as a relative path compared to resolv.
- frg::small_vector<char, PATH_MAX, MemoryAllocator> lnk{getAllocator()};
- size_t ls = 0;
-
- auto process_segment = [&] (frg::string_view s_view) -> int {
- if(debugPathResolution)
- mlibc::infoLogger() << "mlibc realpath(): resolv is '" << resolv.data() << "'"
- << ", segment is " << s_view.data()
- << ", size: " << s_view.size() << frg::endlog;
-
- if(!s_view.size() || s_view == ".") {
- // Keep resolv invariant.
- return 0;
- }else if(s_view == "..") {
- // Remove a single segment from resolv.
- if(resolv.size() > 1) {
- auto slash = strrchr(resolv.data(), '/');
- __ensure(slash); // We never remove the leading sla.
- resolv.resize((slash - resolv.data()) + 1);
- *slash = 0; // Replace the slash by a null-terminator.
- }
- return 0;
- }
-
- // Append the segment to resolv.
- auto rsz = resolv.size();
- resolv[rsz - 1] = '/'; // Replace null-terminator by a slash.
- resolv.resize(rsz + s_view.size() + 1);
- memcpy(resolv.data() + rsz, s_view.data(), s_view.size());
- resolv[rsz + s_view.size()] = 0;
-
- // stat() the path to (1) see if it exists and (2) see if it is a link.
- if(!mlibc::sys_stat) {
- MLIBC_MISSING_SYSDEP();
- return ENOSYS;
- }
- if(debugPathResolution)
- mlibc::infoLogger() << "mlibc realpath(): stat()ing '"
- << resolv.data() << "'" << frg::endlog;
- struct stat st;
- if(int e = mlibc::sys_stat(mlibc::fsfd_target::path,
- -1, resolv.data(), AT_SYMLINK_NOFOLLOW, &st); e)
- return e;
-
- if(S_ISLNK(st.st_mode)) {
- if(debugPathResolution) {
- mlibc::infoLogger() << "mlibc realpath(): Encountered symlink '"
- << resolv.data() << "'" << frg::endlog;
- }
-
- if(!mlibc::sys_readlink) {
- MLIBC_MISSING_SYSDEP();
- return ENOSYS;
- }
-
- ssize_t sz = 0;
- char path[512];
-
- if (int e = mlibc::sys_readlink(resolv.data(), path, 512, &sz); e)
- return e;
-
- if(debugPathResolution) {
- mlibc::infoLogger() << "mlibc realpath(): Symlink resolves to '"
- << frg::string_view{path, static_cast<size_t>(sz)} << "'" << frg::endlog;
- }
-
- if (path[0] == '/') {
- // Absolute path, replace resolv
- resolv.resize(sz);
- strncpy(resolv.data(), path, sz - 1);
- resolv.data()[sz - 1] = 0;
-
- if(debugPathResolution) {
- mlibc::infoLogger() << "mlibc realpath(): Symlink is absolute, resolv: '"
- << resolv.data() << "'" << frg::endlog;
- }
- } else {
- // Relative path, revert changes to resolv, prepend to lnk
- resolv.resize(rsz);
- resolv[rsz - 1] = 0;
-
- auto lsz = lnk.size();
- lnk.resize((lsz - ls) + sz + 1);
- memmove(lnk.data() + sz, lnk.data() + ls, lsz - ls);
- memcpy(lnk.data(), path, sz);
- lnk[(lsz - ls) + sz] = 0;
-
- ls = 0;
-
- if(debugPathResolution) {
- mlibc::infoLogger() << "mlibc realpath(): Symlink is relative, resolv: '"
- << resolv.data() << "' lnk: '"
- << frg::string_view{lnk.data(), lnk.size()} << "'" << frg::endlog;
- }
- }
- }
-
- return 0;
- };
-
- // Each iteration of this outer loop consumes segment of the input path.
- // This design avoids copying the input path into lnk;
- // the latter could often involve additional allocations.
- while(ps < path_view.size()) {
- frg::string_view ps_view;
- if(auto slash = strchr(path + ps, '/'); slash) {
- ps_view = frg::string_view{path + ps, static_cast<size_t>(slash - (path + ps))};
- }else{
- ps_view = frg::string_view{path + ps, strlen(path) - ps};
- }
- ps += ps_view.size() + 1;
-
- // Handle one segment from the input path.
- if(int e = process_segment(ps_view); e) {
- errno = e;
- return nullptr;
- }
-
- // This inner loop consumes segments of lnk.
- while(ls < lnk.size()) {
- frg::string_view ls_view;
- if(auto slash = strchr(lnk.data() + ls, '/'); slash) {
- ls_view = frg::string_view{lnk.data() + ls, static_cast<size_t>(slash - (lnk.data() + ls))};
- }else{
- ls_view = frg::string_view{lnk.data() + ls, strlen(lnk.data()) - ls};
- }
- ls += ls_view.size() + 1;
-
- // Handle one segment from the link
- if(int e = process_segment(ls_view); e) {
- errno = e;
- return nullptr;
- }
- }
-
- // All of lnk was consumed, reset it
- lnk.resize(0);
- ls = 0;
- }
-
- if(resolv.size() == 1) {
- resolv.resize(0);
- resolv.push_back('/');
- resolv.push_back(0);
- }
-
- if(debugPathResolution)
- mlibc::infoLogger() << "mlibc realpath(): Returns '" << resolv.data() << "'" << frg::endlog;
-
- if(resolv.size() > PATH_MAX) {
- errno = ENAMETOOLONG;
- return nullptr;
- }
-
- if(!out)
- out = reinterpret_cast<char *>(getAllocator().allocate(resolv.size()));
- strcpy(out, resolv.data());
- return out;
-}
-
-// ----------------------------------------------------------------------------
-// Pseudoterminals
-// ----------------------------------------------------------------------------
-
-int ptsname_r(int fd, char *buffer, size_t length) {
- auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_ptsname, ENOSYS);
-
- if(int e = sysdep(fd, buffer, length); e)
- return e;
-
- return 0;
-}
-
-char *ptsname(int fd) {
- static char buffer[128];
-
- auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_ptsname, NULL);
-
- if(int e = sysdep(fd, buffer, 128); e) {
- errno = e;
- return NULL;
- }
-
- return buffer;
-}
-
-int posix_openpt(int flags) {
- int fd;
- if(int e = mlibc::sys_open("/dev/ptmx", flags, 0, &fd); e) {
- errno = e;
- return -1;
- }
-
- return fd;
-}
-
-int unlockpt(int fd) {
- auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_unlockpt, -1);
-
- if(int e = sysdep(fd); e) {
- errno = e;
- return -1;
- }
-
- return 0;
-}
-
-int grantpt(int) {
- return 0;
-}
-
-double strtod_l(const char *__restrict__ nptr, char ** __restrict__ endptr, locale_t) {
- mlibc::infoLogger() << "mlibc: strtod_l ignores locale!" << frg::endlog;
- return strtod(nptr, endptr);
-}
-
-long double strtold_l(const char *__restrict__, char ** __restrict__, locale_t) {
- __ensure(!"Not implemented");
- __builtin_unreachable();
-}
-
-float strtof_l(const char *__restrict__ nptr, char **__restrict__ endptr, locale_t) {
- mlibc::infoLogger() << "mlibc: strtof_l ignores locales" << frg::endlog;
- return strtof(nptr, endptr);
-}
-
-int strcoll_l(const char *, const char *, locale_t) {
- __ensure(!"Not implemented");
- __builtin_unreachable();
-}
-
-int getloadavg(double *, int) {
- __ensure(!"Not implemented");
- __builtin_unreachable();
-}
-
-char *secure_getenv(const char *name) {
- if (mlibc::rtdlConfig().secureRequired)
- return NULL;
- else
- return getenv(name);
-}
-
-void *reallocarray(void *ptr, size_t m, size_t n) {
- if(n && m > -1 / n) {
- errno = ENOMEM;
- return 0;
- }
-
- return realloc(ptr, m * n);
-}
-
-char *canonicalize_file_name(const char *name) {
- return realpath(name, NULL);
-}