diff options
author | Ian Moffett <ian@osmora.org> | 2024-03-07 17:28:52 -0500 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2024-03-07 18:24:51 -0500 |
commit | f5e48e94a2f4d4bbd6e5628c7f2afafc6dbcc459 (patch) | |
tree | 93b156621dc0303816b37f60ba88051b702d92f6 /lib/mlibc/options/posix | |
parent | bd5969fc876a10b18613302db7087ef3c40f18e1 (diff) |
build: Build mlibc + add distclean target
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'lib/mlibc/options/posix')
146 files changed, 0 insertions, 19812 deletions
diff --git a/lib/mlibc/options/posix/generic/arpa-inet-stubs.cpp b/lib/mlibc/options/posix/generic/arpa-inet-stubs.cpp deleted file mode 100644 index 0bc9727..0000000 --- a/lib/mlibc/options/posix/generic/arpa-inet-stubs.cpp +++ /dev/null @@ -1,220 +0,0 @@ - -#include <arpa/inet.h> -#include <bits/ensure.h> -#include <stdlib.h> -#include <ctype.h> -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <mlibc/bitutil.hpp> -#include <mlibc/debug.hpp> - -const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; -const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT; - -uint32_t htonl(uint32_t x) { -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - return mlibc::bit_util<uint32_t>::byteswap(x); -#else - return x; -#endif -} -uint16_t htons(uint16_t x) { -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - return mlibc::bit_util<uint16_t>::byteswap(x); -#else - return x; -#endif -} -uint32_t ntohl(uint32_t x) { -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - return mlibc::bit_util<uint32_t>::byteswap(x); -#else - return x; -#endif -} -uint16_t ntohs(uint16_t x) { -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - return mlibc::bit_util<uint16_t>::byteswap(x); -#else - return x; -#endif -} - -// ---------------------------------------------------------------------------- -// IPv4 address manipulation. -// ---------------------------------------------------------------------------- -in_addr_t inet_addr(const char *p) { - struct in_addr a; - if(!inet_aton(p, &a)) - return -1; - return a.s_addr; -} -char *inet_ntoa(struct in_addr addr) { - // string: xxx.yyy.zzz.aaa - // 4 * 3 + 3 + 1 = 12 + 4 = 16 - thread_local static char buffer[16]; - uint32_t proper = htonl(addr.s_addr); - snprintf(buffer, sizeof(buffer), "%d.%d.%d.%d", - (proper >> 24) & 0xff, ((proper >> 16) & 0xff), - (proper >> 8) & 0xff, proper & 0xff); - return buffer; -} -int inet_aton(const char *string, struct in_addr *dest) { - int array[4]; - int i = 0; - char *end; - - for (; i < 4; i++) { - array[i] = strtoul(string, &end, 0); - if (*end && *end != '.') - return 0; - if (!*end) - break; - string = end + 1; - } - - switch (i) { - case 0: - dest->s_addr = htonl(array[0]); - break; - case 1: - if (array[0] > 255 || array[1] > 0xffffff) - return 0; - dest->s_addr = htonl((array[0] << 24) | array[1]); - break; - case 2: - if (array[0] > 255 || array[1] > 255 || - array[2] > 0xffff) - return 0; - dest->s_addr = htonl((array[0] << 24) | (array[1] << 16) | - array[2]); - break; - case 3: - if (array[0] > 255 || array[1] > 255 || - array[2] > 255 || array[3] > 255) - return 0; - dest->s_addr = htonl((array[0] << 24) | (array[1] << 16) | - (array[2] << 8) | array[3]); - break; - } - - return 1; -} - -// ---------------------------------------------------------------------------- -// Generic IP address manipulation. -// ---------------------------------------------------------------------------- -const char *inet_ntop(int af, const void *__restrict src, char *__restrict dst, - socklen_t size) { - switch (af) { - case AF_INET: { - auto source = reinterpret_cast<const struct in_addr*>(src); - if (snprintf(dst, size, "%d.%d.%d.%d", - source->s_addr & 0xff, - (source->s_addr & 0xffff) >> 8, - (source->s_addr & 0xffffff) >> 16, - source->s_addr >> 24) < (int)size) - return dst; - break; - } - case AF_INET6: { - auto source = reinterpret_cast<const struct in6_addr*>(src); - size_t cur_zeroes_off = 0; - size_t cur_zeroes_len = 0; - size_t max_zeroes_off = 0; - size_t max_zeroes_len = 0; - - /* we look for the largest block of zeroed quartet(s) */ - for(size_t i = 0; i < 8; i++) { - auto ptr = source->s6_addr + (i * 2); - if(!ptr[0] && !ptr[1]) { - cur_zeroes_len++; - if(max_zeroes_len < cur_zeroes_len) { - max_zeroes_len = cur_zeroes_len; - max_zeroes_off = cur_zeroes_off; - } - } else { - /* advance the offset to the next quartet to check */ - cur_zeroes_len = 0; - cur_zeroes_off = i + 1; - } - } - - size_t off = 0; - for(size_t i = 0; i < 8; i++) { - auto ptr = source->s6_addr + (i * 2); - - /* if we are at the beginning of the largest block of zeroed quartets, place "::" */ - if(i == max_zeroes_off && max_zeroes_len >= 2) { - if(off < size) { - dst[off++] = ':'; - } - if(off < size) { - dst[off++] = ':'; - } - i += max_zeroes_len - 1; - - continue; - } - - /* place a colon if we're not at the beginning of the string and it is not already there */ - if(off && dst[off - 1] != ':') { - if(off < size) { - dst[off++] = ':'; - } - } - - off += snprintf(dst + off, size - off, "%x", ptr[0] << 8 | ptr[1]); - } - - dst[off] = 0; - - return dst; - } - default: - errno = EAFNOSUPPORT; - return NULL; - } - - errno = ENOSPC; - return NULL; -} -int inet_pton(int af, const char *__restrict src, void *__restrict dst) { - switch (af) { - case AF_INET: { - uint8_t array[4] = {}; - for (int i = 0; i < 4; i++) { - char *end; - long int value = strtol(src, &end, 10); - if (value > 255) - return 0; - if (*end != '\0' && *end != '.') - return 0; - src = end + 1; - array[i] = value; - } - auto addr = reinterpret_cast<struct in_addr*>(dst); - memcpy(&addr->s_addr, array, 4); - break; - } - case AF_INET6: - mlibc::infoLogger() << "inet_pton: ipv6 is not implemented!" << frg::endlog; - /* fallthrough */ - default: - errno = EAFNOSUPPORT; - return -1; - } - - return 1; -} - -struct in_addr inet_makeaddr(in_addr_t, in_addr_t) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -in_addr_t inet_netof(struct in_addr) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} diff --git a/lib/mlibc/options/posix/generic/dirent-stubs.cpp b/lib/mlibc/options/posix/generic/dirent-stubs.cpp deleted file mode 100644 index 1352585..0000000 --- a/lib/mlibc/options/posix/generic/dirent-stubs.cpp +++ /dev/null @@ -1,180 +0,0 @@ - -#include <errno.h> -#include <dirent.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/stat.h> -#include <stdlib.h> - -#include <bits/ensure.h> -#include <frg/allocation.hpp> -#include <mlibc/allocator.hpp> -#include <mlibc/posix-sysdeps.hpp> -#include <mlibc/debug.hpp> - -// Code taken from musl -int alphasort(const struct dirent **a, const struct dirent **b) { - return strcoll((*a)->d_name, (*b)->d_name); -} - -int closedir(DIR *dir) { - // TODO: Deallocate the dir structure. - close(dir->__handle); - return 0; -} -int dirfd(DIR *dir) { - return dir->__handle; -} -DIR *fdopendir(int fd) { - struct stat st; - - if(fstat(fd, &st) < 0) { - return nullptr; - } - // Musl implements this, but O_PATH is only declared on the linux abi - /*if(fcntl(fd, F_GETFL) & O_PATH) { - errno = EBADF; - return nullptr; - }*/ - if(!S_ISDIR(st.st_mode)) { - errno = ENOTDIR; - return nullptr; - } - auto dir = frg::construct<__mlibc_dir_struct>(getAllocator()); - __ensure(dir); - dir->__ent_next = 0; - dir->__ent_limit = 0; - int flags = fcntl(fd, F_GETFD); - fcntl(fd, F_SETFD, flags | FD_CLOEXEC); - dir->__handle = fd; - return dir; -} -DIR *opendir(const char *path) { - auto dir = frg::construct<__mlibc_dir_struct>(getAllocator()); - __ensure(dir); - dir->__ent_next = 0; - dir->__ent_limit = 0; - - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_open_dir, nullptr); - if(int e = mlibc::sys_open_dir(path, &dir->__handle); e) { - errno = e; - frg::destruct(getAllocator(), dir); - return nullptr; - }else{ - return dir; - } -} -struct dirent *readdir(DIR *dir) { - __ensure(dir->__ent_next <= dir->__ent_limit); - if(dir->__ent_next == dir->__ent_limit) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_read_entries, nullptr); - if(int e = mlibc::sys_read_entries(dir->__handle, dir->__ent_buffer, 2048, &dir->__ent_limit); e) - __ensure(!"mlibc::sys_read_entries() failed"); - dir->__ent_next = 0; - if(!dir->__ent_limit) - return nullptr; - } - - auto entp = reinterpret_cast<struct dirent *>(dir->__ent_buffer + dir->__ent_next); - // We only copy as many bytes as we need to avoid buffer-overflows. - memcpy(&dir->__current, entp, offsetof(struct dirent, d_name) + strlen(entp->d_name) + 1); - dir->__ent_next += entp->d_reclen; - return &dir->__current; -} -int readdir_r(DIR *dir, struct dirent *entry, struct dirent **result) { - if(!mlibc::sys_read_entries) { - MLIBC_MISSING_SYSDEP(); - return ENOSYS; - } - - __ensure(dir->__ent_next <= dir->__ent_limit); - if(dir->__ent_next == dir->__ent_limit) { - if(int e = mlibc::sys_read_entries(dir->__handle, dir->__ent_buffer, 2048, &dir->__ent_limit); e) - __ensure(!"mlibc::sys_read_entries() failed"); - dir->__ent_next = 0; - if(!dir->__ent_limit) { - *result = NULL; - return 0; - } - } - - auto entp = reinterpret_cast<struct dirent *>(dir->__ent_buffer + dir->__ent_next); - // We only copy as many bytes as we need to avoid buffer-overflows. - memcpy(entry, entp, offsetof(struct dirent, d_name) + strlen(entp->d_name) + 1); - dir->__ent_next += entp->d_reclen; - *result = entry; - return 0; -} - -void rewinddir(DIR *dir) { - lseek(dir->__handle, 0, SEEK_SET); - dir->__ent_next = 0; -} - -int scandir(const char *path, struct dirent ***res, int (*select)(const struct dirent *), - int (*compare)(const struct dirent **, const struct dirent **)) { - DIR *dir = opendir(path); - if (!dir) - return -1; // errno will be set by opendir() - - // we should save the errno - int old_errno = errno; - errno = 0; - - struct dirent *dir_ent; - struct dirent **array = nullptr, **tmp = nullptr; - int length = 0; - int count = 0; - while((dir_ent = readdir(dir)) && !errno) { - if(select && !select(dir_ent)) - continue; - - if(count >= length) { - length = 2*length + 1; - tmp = static_cast<struct dirent**>(realloc(array, - length * sizeof(struct dirent*))); - // we need to check the call actually goes through - // before we overwrite array so that we can - // deallocate the already written entries should realloc() - // have failed - if(!tmp) - break; - array = tmp; - } - array[count] = static_cast<struct dirent*>(malloc(dir_ent->d_reclen)); - if(!array[count]) - break; - - memcpy(array[count], dir_ent, dir_ent->d_reclen); - count++; - } - - if(errno) { - if(array) - while(count-- > 0) - free(array[count]); - free(array); - return -1; - } - - // from here we can set the old errno back - errno = old_errno; - - if(compare) - qsort(array, count, sizeof(struct dirent*), - (int (*)(const void *, const void *)) compare); - *res = array; - return count; -} -void seekdir(DIR *, long) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long telldir(DIR *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int versionsort(const struct dirent **a, const struct dirent **b) { - return strverscmp((*a)->d_name, (*b)->d_name); -} diff --git a/lib/mlibc/options/posix/generic/dlfcn-stubs.cpp b/lib/mlibc/options/posix/generic/dlfcn-stubs.cpp deleted file mode 100644 index fc9fd84..0000000 --- a/lib/mlibc/options/posix/generic/dlfcn-stubs.cpp +++ /dev/null @@ -1,64 +0,0 @@ - -#include <bits/ensure.h> -#include <dlfcn.h> - -#include <mlibc/debug.hpp> - -struct __dlapi_symbol { - const char *file; - void *base; - const char *symbol; - void *address; -}; - -extern "C" const char *__dlapi_error(); -extern "C" void *__dlapi_open(const char *, int, void *); -extern "C" void *__dlapi_resolve(void *, const char *, void *); -extern "C" int __dlapi_reverse(const void *, __dlapi_symbol *); -extern "C" int __dlapi_close(void *); - -int dlclose(void *handle) { - return __dlapi_close(handle); -} - -char *dlerror(void) { - return const_cast<char *>(__dlapi_error()); -} - -[[gnu::noinline]] -void *dlopen(const char *file, int flags) { - auto ra = __builtin_extract_return_addr(__builtin_return_address(0)); - return __dlapi_open(file, flags, ra); -} - -[[gnu::noinline]] -void *dlsym(void *__restrict handle, const char *__restrict string) { - auto ra = __builtin_extract_return_addr(__builtin_return_address(0)); - return __dlapi_resolve(handle, string, ra); -} - -[[gnu::noinline]] -void *dlvsym(void *__restrict handle, const char *__restrict string, const char *__restrict version) { - mlibc::infoLogger() << "mlibc: dlvsym ignores version " << version << frg::endlog; - auto ra = __builtin_extract_return_addr(__builtin_return_address(0)); - return __dlapi_resolve(handle, string, ra); -} - -//gnu extensions -int dladdr(const void *ptr, Dl_info *out) { - __dlapi_symbol info; - if(__dlapi_reverse(ptr, &info)) - return 0; - - out->dli_fname = info.file; - out->dli_fbase = info.base; - out->dli_sname = info.symbol; - out->dli_saddr = info.address; - return 1; -} - -int dlinfo(void *, int, void *) { - __ensure(!"dlinfo() not implemented"); - __builtin_unreachable(); -} - diff --git a/lib/mlibc/options/posix/generic/fcntl-stubs.cpp b/lib/mlibc/options/posix/generic/fcntl-stubs.cpp deleted file mode 100644 index 66e2d12..0000000 --- a/lib/mlibc/options/posix/generic/fcntl-stubs.cpp +++ /dev/null @@ -1,108 +0,0 @@ - -#include <errno.h> -#include <bits/ensure.h> -#include <fcntl.h> -#include <stdarg.h> - -#include <mlibc/debug.hpp> -#include <mlibc/posix-sysdeps.hpp> - -int creat(const char *pathname, mode_t mode) { - return open(pathname, O_CREAT|O_WRONLY|O_TRUNC, mode); -} - -int fallocate(int, int, off_t, off_t) { - mlibc::infoLogger() << "mlibc: fallocate() is a no-op" << frg::endlog; - errno = ENOSYS; - return -1; -} - -int fcntl(int fd, int command, ...) { - va_list args; - va_start(args, command); - int result; - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_fcntl, -1); - if(int e = mlibc::sys_fcntl(fd, command, args, &result); e) { - errno = e; - return -1; - } - va_end(args); - return result; -} - -int openat(int dirfd, const char *pathname, int flags, ...) { - va_list args; - va_start(args, flags); - mode_t mode = 0; - int fd; - - if((flags & (O_CREAT | O_TMPFILE))) - mode = va_arg(args, mode_t); - - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_openat, -1); - if(int e = mlibc::sys_openat(dirfd, pathname, flags, mode, &fd); e) { - errno = e; - return -1; - } - va_end(args); - return fd; -} - -int posix_fadvise(int fd, off_t offset, off_t length, int advice) { - if(!mlibc::sys_fadvise) { - mlibc::infoLogger() << "mlibc: fadvise() ignored due to missing sysdep" << frg::endlog; - return 0; - } - - // posix_fadvise() returns an error instead of setting errno. - return mlibc::sys_fadvise(fd, offset, length, advice); -} - -int posix_fallocate(int fd, off_t offset, off_t size) { - // posix_fallocate() returns an error instead of setting errno. - if(!mlibc::sys_fallocate) { - MLIBC_MISSING_SYSDEP(); - return ENOSYS; - } - return mlibc::sys_fallocate(fd, offset, size); -} - -// This is a linux extension -int name_to_handle_at(int, const char *, struct file_handle *, int *, int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int open_by_handle_at(int, struct file_handle *, int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -ssize_t splice(int, off_t *, int, off_t *, size_t, unsigned int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -ssize_t vmsplice(int, const struct iovec *, size_t, unsigned int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int open(const char *pathname, int flags, ...) { - mode_t mode = 0; - - if ((flags & O_CREAT) || (flags & O_TMPFILE)) { - va_list args; - va_start(args, flags); - mode = va_arg(args, mode_t); - va_end(args); - } - - int fd; - if(int e = mlibc::sys_open(pathname, flags, mode, &fd); e) { - errno = e; - return -1; - } - return fd; -} - diff --git a/lib/mlibc/options/posix/generic/ftw-stubs.cpp b/lib/mlibc/options/posix/generic/ftw-stubs.cpp deleted file mode 100644 index 2d93995..0000000 --- a/lib/mlibc/options/posix/generic/ftw-stubs.cpp +++ /dev/null @@ -1,18 +0,0 @@ - -#include <ftw.h> - -#include <bits/ensure.h> - -int ftw(const char *, int (*fn)(const char *, const struct stat *, int), int) { - (void)fn; - __ensure(!"ftw() not implemented"); - __builtin_unreachable(); -} - -int nftw(const char *, int (*fn)(const char *, const struct stat *, int, struct FTW *), - int, int) { - (void)fn; - __ensure(!"nftw() not implemented"); - __builtin_unreachable(); -} - diff --git a/lib/mlibc/options/posix/generic/grp-stubs.cpp b/lib/mlibc/options/posix/generic/grp-stubs.cpp deleted file mode 100644 index f8b2813..0000000 --- a/lib/mlibc/options/posix/generic/grp-stubs.cpp +++ /dev/null @@ -1,316 +0,0 @@ - -#include <grp.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <bits/ensure.h> - -#include <mlibc/debug.hpp> -#include <mlibc/posix-sysdeps.hpp> - -namespace { - FILE *global_file; - - bool open_global_file() { - if(!global_file) { - global_file = fopen("/etc/group", "r"); - if(!global_file) { - errno = EIO; - return false; - } - } - - return true; - } - - void close_global_file() { - if(global_file) { - fclose(global_file); - global_file = nullptr; - } - } - - template<typename F> - void walk_segments(frg::string_view line, char delimiter, F fn) { - size_t s = 0; - while(true) { - size_t d = line.find_first(delimiter, s); - if(d == size_t(-1)) - break; - auto chunk = line.sub_string(s, d - s); - fn(chunk); - s = d + 1; - } - if(line[s]) { - auto chunk = line.sub_string(s, line.size() - s); - - if (chunk.size() > 0) { - // Remove trailing newline - if (chunk[chunk.size() - 1] == '\n') - chunk = chunk.sub_string(0, chunk.size() - 1); - - fn(chunk); - } - } - } - - bool extract_entry(frg::string_view line, group *entry) { - frg::string_view segments[5]; - - // Parse the line into 3 or 4 segments (depending if the group has members or not) - int n = 0; - walk_segments(line, ':', [&] (frg::string_view s) { - __ensure(n < 4); - segments[n++] = s; - }); - - if(n < 3) // n can be 3 when there are no members in the group - return false; - - // TODO: Handle strndup() and malloc() failure. - auto name = strndup(segments[0].data(), segments[0].size()); - __ensure(name); - - auto passwd = strndup(segments[1].data(), segments[1].size()); - - auto gid = segments[2].to_number<int>(); - if(!gid) - return false; - - size_t n_members = 0; - walk_segments(segments[3], ',', [&] (frg::string_view) { - n_members++; - }); - - auto members = reinterpret_cast<char **>(malloc(sizeof(char *) * (n_members + 1))); - __ensure(members); - size_t k = 0; - walk_segments(segments[3], ',', [&] (frg::string_view m) { - members[k] = strndup(m.data(), m.size()); - __ensure(members[k]); - k++; - }); - members[k] = nullptr; - - entry->gr_name = name; - entry->gr_passwd = passwd; - entry->gr_gid = *gid; - entry->gr_mem = members; - return true; - } - - void clear_entry(group *entry) { - free(entry->gr_name); - if(entry->gr_mem) { - for(size_t i = 0; entry->gr_mem[i]; i++) - free(entry->gr_mem[i]); - free(entry->gr_mem); - } - entry->gr_name = nullptr; - entry->gr_mem = nullptr; - } - - template<typename C> - int walk_file(struct group *entry, C cond) { - auto file = fopen("/etc/group", "r"); - if(!file) { - return EIO; - } - - char line[512]; - while(fgets(line, 512, file)) { - if(!extract_entry(line, entry)) - continue; - if(cond(entry)) { - fclose(file); - return 0; - } - } - - int err = ESRCH; - if(ferror(file)) { - err = EIO; - } - - fclose(file); - return err; - } - - int copy_to_buffer(struct group *grp, char *buffer, size_t size) { - // Adjust to correct alignment so that we can put gr_mem first in buffer - uintptr_t mask = sizeof(char *) - 1; - size_t offset = (reinterpret_cast<uintptr_t>(buffer) % sizeof(char *) + mask) & ~mask; - if (size < offset) - return ERANGE; - - buffer += offset; - size -= offset; - - // Calculate the amount of space we need - size_t nmemb, required_size = 0; - for (nmemb = 0; grp->gr_mem[nmemb] != nullptr; nmemb++) { - // One for the string's null terminator and one for the pointer in gr_mem - required_size += strlen(grp->gr_mem[nmemb]) + 1 + sizeof(char *); - } - - // One for null terminator of gr_name, plus sizeof(char *) for nullptr terminator of gr_mem - required_size += strlen(grp->gr_name) + 1 + sizeof(char *); - if (size < required_size) - return ERANGE; - - // Put the gr_mem array first in the buffer as we are guaranteed - // that the pointer is aligned correctly - char *string_data = buffer + (nmemb + 1) * sizeof(char *); - - for (size_t i = 0; i < nmemb; i++) { - reinterpret_cast<char **>(buffer)[i] = string_data; - string_data = stpcpy(string_data, grp->gr_mem[i]) + 1; - free(grp->gr_mem[i]); - } - - reinterpret_cast<char **>(buffer)[nmemb] = nullptr; - free(grp->gr_mem); - grp->gr_mem = reinterpret_cast<char **>(buffer); - - char *gr_name = stpcpy(string_data, grp->gr_name) + 1; - free(grp->gr_name); - grp->gr_name = string_data; - - __ensure(gr_name <= buffer + size); - return 0; - } -} - -void endgrent(void) { - close_global_file(); -} - -struct group *getgrent(void) { - static group entry; - char line[512]; - - if(!open_global_file()) { - return nullptr; - } - - if(fgets(line, 512, global_file)) { - clear_entry(&entry); - if(!extract_entry(line, &entry)) { - errno = EINVAL; - return nullptr; - } - return &entry; - } - - if(ferror(global_file)) { - errno = EIO; - } - - return nullptr; -} - -struct group *getgrgid(gid_t gid) { - static group entry; - - int err = walk_file(&entry, [&] (group *entry) { - return entry->gr_gid == gid; - }); - - if (err) { - errno = err; - return nullptr; - } - - return &entry; -} - -int getgrgid_r(gid_t gid, struct group *grp, char *buffer, size_t size, struct group **result) { - *result = nullptr; - int err = walk_file(grp, [&] (group *entry) { - return entry->gr_gid == gid; - }); - - if (err) { - return err; - } - - err = copy_to_buffer(grp, buffer, size); - if (err) { - return err; - } - - *result = grp; - return 0; -} - -struct group *getgrnam(const char *name) { - static group entry; - - int err = walk_file(&entry, [&] (group *entry) { - return !strcmp(entry->gr_name, name); - }); - - if (err) { - errno = err; - return nullptr; - } - - return &entry; -} - -int getgrnam_r(const char *name, struct group *grp, char *buffer, size_t size, struct group **result) { - *result = nullptr; - - int err = walk_file(grp, [&] (group *entry) { - return !strcmp(entry->gr_name, name); - }); - - if (err) { - return err; - } - - err = copy_to_buffer(grp, buffer, size); - if (err) { - return err; - } - - *result = grp; - return 0; -} - -void setgrent(void) { - if(!open_global_file()) { - return; - } - rewind(global_file); -} - -int setgroups(size_t size, const gid_t *list) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_setgroups, -1); - if(int e = mlibc::sys_setgroups(size, list); e) { - errno = e; - return -1; - } - return 0; -} - -int initgroups(const char *, gid_t) { - mlibc::infoLogger() << "mlibc: initgroups is a stub" << frg::endlog; - return 0; -} - -int putgrent(const struct group *, FILE *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -struct group *fgetgrent(FILE *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int getgrouplist(const char *, gid_t, gid_t *, int *) { - mlibc::infoLogger() << "mlibc: getgrouplist is a stub" << frg::endlog; - return 0; -} diff --git a/lib/mlibc/options/posix/generic/langinfo-stubs.cpp b/lib/mlibc/options/posix/generic/langinfo-stubs.cpp deleted file mode 100644 index b239cbd..0000000 --- a/lib/mlibc/options/posix/generic/langinfo-stubs.cpp +++ /dev/null @@ -1,15 +0,0 @@ - -#include <langinfo.h> -#include <bits/ensure.h> -#include <mlibc/debug.hpp> -#include <mlibc/locale.hpp> - -char *nl_langinfo(nl_item item) { - return mlibc::nl_langinfo(item); -} - -char *nl_langinfo_l(nl_item, locale_t) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - diff --git a/lib/mlibc/options/posix/generic/libgen-stubs.cpp b/lib/mlibc/options/posix/generic/libgen-stubs.cpp deleted file mode 100644 index ff80349..0000000 --- a/lib/mlibc/options/posix/generic/libgen-stubs.cpp +++ /dev/null @@ -1,51 +0,0 @@ - -#include <bits/ensure.h> -#include <libgen.h> -#include <string.h> - -#include <mlibc/debug.hpp> - -// Adopted from musl's code. -char *basename(char *s) { - // This empty string behavior is specified by POSIX. - if (!s || !*s) - return const_cast<char *>("."); - - // Delete trailing slashes. - // Note that we do not delete the slash at index zero. - auto i = strlen(s) - 1; - for(; i && s[i] == '/'; i--) - s[i] = 0; - - // Find the last non-trailing slash. - for(; i && s[i - 1] != '/'; i--) - ; - return s + i; -} - -char *dirname(char *s) { - if (!s || !(*s)) - return const_cast<char *>("."); - - auto i = strlen(s) - 1; - - // Skip trailing slashes. - for (; s[i] == '/'; i--) - if(!i) // Path only consists of slashes. - return const_cast<char *>("/"); - - // Skip the last non-slash path component. - for (; s[i] != '/'; i--) - if(!i) // Path only contains a single component. - return const_cast<char *>("."); - - // Skip slashes. - for (; s[i] == '/'; i--) - if(!i) // Path is entry in root directory. - return const_cast<char *>("/"); - - s[i+1] = 0; - - return s; -} - diff --git a/lib/mlibc/options/posix/generic/lookup.cpp b/lib/mlibc/options/posix/generic/lookup.cpp deleted file mode 100644 index f877fe5..0000000 --- a/lib/mlibc/options/posix/generic/lookup.cpp +++ /dev/null @@ -1,512 +0,0 @@ -#include <mlibc/lookup.hpp> -#include <mlibc/resolv_conf.hpp> -#include <mlibc/debug.hpp> -#include <bits/ensure.h> - -#include <frg/string.hpp> -#include <mlibc/allocator.hpp> -#include <string.h> -#include <errno.h> -#include <arpa/inet.h> -#include <unistd.h> -#include <stdio.h> -#include <ctype.h> - -namespace mlibc { - -namespace { - constexpr unsigned int RECORD_A = 1; - constexpr unsigned int RECORD_CNAME = 5; - constexpr unsigned int RECORD_PTR = 12; -} - -static frg::string<MemoryAllocator> read_dns_name(char *buf, char *&it) { - frg::string<MemoryAllocator> res{getAllocator()}; - while (true) { - char code = *it++; - if ((code & 0xC0) == 0xC0) { - // pointer - uint8_t offset = ((code & 0x3F) << 8) | *it++; - auto offset_it = buf + offset; - return res + read_dns_name(buf, offset_it); - } else if (!(code & 0xC0)) { - if (!code) - break; - - for (int i = 0; i < code; i++) - res += (*it++); - - if (*it) - res += '.'; - } else { - break; - } - } - - return res; -} - -int lookup_name_dns(struct lookup_result &buf, const char *name, - frg::string<MemoryAllocator> &canon_name) { - frg::string<MemoryAllocator> request{getAllocator()}; - - int num_q = 1; - struct dns_header header; - header.identification = htons(123); - header.flags = htons(0x100); - header.no_q = htons(num_q); - header.no_ans = htons(0); - header.no_auths = htons(0); - header.no_additional = htons(0); - - request.resize(sizeof(header)); - memcpy(request.data(), &header, sizeof(header)); - - const char *end = name; - while (*end != '\0') { - end = strchrnul(name, '.'); - size_t length = end - name; - frg::string_view substring{name, length}; - name += length + 1; - request += char(length); - request += substring; - } - - request += char(0); - // set question type to fetch A records - request += 0; - request += 1; - // set CLASS to IN - request += 0; - request += 1; - - struct sockaddr_in sin = {}; - sin.sin_family = AF_INET; - // TODO(geert): we could probably make this use the service lookup - // for dns - sin.sin_port = htons(53); - - auto nameserver = get_nameserver(); - if (!inet_aton(nameserver ? nameserver->name.data() : "127.0.0.1", &sin.sin_addr)) { - mlibc::infoLogger() << "lookup_name_dns(): inet_aton() failed!" << frg::endlog; - return -EAI_SYSTEM; - } - - int fd = socket(AF_INET, SOCK_DGRAM, 0); - if (fd < 0) { - mlibc::infoLogger() << "lookup_name_dns(): socket() failed" << frg::endlog; - return -EAI_SYSTEM; - } - - size_t sent = sendto(fd, request.data(), request.size(), 0, - (struct sockaddr*)&sin, sizeof(sin)); - if (sent != request.size()) { - mlibc::infoLogger() << "lookup_name_dns(): sendto() failed to send everything" << frg::endlog; - return -EAI_SYSTEM; - } - - char response[256]; - ssize_t rlen; - int num_ans = 0; - while ((rlen = recvfrom(fd, response, 256, 0, NULL, NULL)) >= 0) { - if ((size_t)rlen < sizeof(struct dns_header)) - continue; - auto response_header = reinterpret_cast<struct dns_header*>(response); - if (response_header->identification != header.identification) - return -EAI_FAIL; - - auto it = response + sizeof(struct dns_header); - for (int i = 0; i < ntohs(response_header->no_q); i++) { - auto dns_name = read_dns_name(response, it); - (void) dns_name; - it += 4; - } - - for (int i = 0; i < ntohs(response_header->no_ans); i++) { - struct dns_addr_buf buffer; - auto dns_name = read_dns_name(response, it); - - uint16_t rr_type = (it[0] << 8) | it[1]; - uint16_t rr_class = (it[2] << 8) | it[3]; - uint16_t rr_length = (it[8] << 8) | it[9]; - it += 10; - (void)rr_class; - - switch (rr_type) { - case RECORD_A: - memcpy(buffer.addr, it, rr_length); - it += rr_length; - buffer.family = AF_INET; - buffer.name = std::move(dns_name); - buf.buf.push(std::move(buffer)); - break; - case RECORD_CNAME: - canon_name = read_dns_name(response, it); - buf.aliases.push(std::move(dns_name)); - break; - default: - mlibc::infoLogger() << "lookup_name_dns: unknown rr type " - << rr_type << frg::endlog; - break; - } - } - num_ans += ntohs(response_header->no_ans); - - if (num_ans >= num_q) - break; - } - - close(fd); - return buf.buf.size(); -} - -int lookup_addr_dns(frg::span<char> name, frg::array<uint8_t, 16> &addr, int family) { - frg::string<MemoryAllocator> request{getAllocator()}; - - int num_q = 1; - struct dns_header header; - header.identification = htons(123); - header.flags = htons(0x100); - header.no_q = htons(num_q); - header.no_ans = htons(0); - header.no_auths = htons(0); - header.no_additional = htons(0); - - request.resize(sizeof(header)); - memcpy(request.data(), &header, sizeof(header)); - - char addr_str[64]; - if(!inet_ntop(family, addr.data(), addr_str, sizeof(addr_str))) { - switch(errno) { - case EAFNOSUPPORT: - return -EAI_FAMILY; - case ENOSPC: - return -EAI_OVERFLOW; - default: - return -EAI_FAIL; - } - } - frg::string<MemoryAllocator> req_str{getAllocator(), addr_str}; - req_str += ".in-addr.arpa"; - - frg::string_view req_view{req_str.data(), req_str.size()}; - size_t ptr = 0; - do { - size_t next = req_view.find_first('.', ptr); - size_t length = next != (size_t)-1 ? next - ptr : req_view.size() - ptr; - frg::string_view substring = req_view.sub_string(ptr, length); - request += char(length); - request += substring; - ptr = next + 1; - } while(ptr != 0); - - request += char(0); - // set question type to fetch PTR records - request += 0; - request += 12; - // set CLASS to IN - request += 0; - request += 1; - - - struct sockaddr_in sin = {}; - sin.sin_family = AF_INET; - // TODO(geert): we could probably make this use the service lookup - // for dns - sin.sin_port = htons(53); - - auto nameserver = get_nameserver(); - if (!inet_aton(nameserver ? nameserver->name.data() : "127.0.0.1", &sin.sin_addr)) { - mlibc::infoLogger() << "lookup_name_dns(): inet_aton() failed!" << frg::endlog; - return -EAI_SYSTEM; - } - - int fd = socket(AF_INET, SOCK_DGRAM, 0); - if (fd < 0) { - mlibc::infoLogger() << "lookup_name_dns(): socket() failed" << frg::endlog; - return -EAI_SYSTEM; - } - - size_t sent = sendto(fd, request.data(), request.size(), 0, - (struct sockaddr*)&sin, sizeof(sin)); - if (sent != request.size()) { - mlibc::infoLogger() << "lookup_name_dns(): sendto() failed to send everything" << frg::endlog; - return -EAI_SYSTEM; - } - - char response[256]; - ssize_t rlen; - int num_ans = 0; - while ((rlen = recvfrom(fd, response, 256, 0, NULL, NULL)) >= 0) { - if ((size_t)rlen < sizeof(struct dns_header)) - continue; - auto response_header = reinterpret_cast<struct dns_header*>(response); - if (response_header->identification != header.identification) - return -EAI_FAIL; - - auto it = response + sizeof(struct dns_header); - for (int i = 0; i < ntohs(response_header->no_q); i++) { - auto dns_name = read_dns_name(response, it); - (void) dns_name; - it += 4; - } - - for (int i = 0; i < ntohs(response_header->no_ans); i++) { - struct dns_addr_buf buffer; - auto dns_name = read_dns_name(response, it); - - uint16_t rr_type = (it[0] << 8) | it[1]; - uint16_t rr_class = (it[2] << 8) | it[3]; - uint16_t rr_length = (it[8] << 8) | it[9]; - it += 10; - (void)rr_class; - (void)rr_length; - - (void)dns_name; - - switch (rr_type) { - case RECORD_PTR: { - auto ptr_name = read_dns_name(response, it); - if (ptr_name.size() >= name.size()) - return -EAI_OVERFLOW; - std::copy(ptr_name.begin(), ptr_name.end(), name.data()); - name.data()[ptr_name.size()] = '\0'; - return 1; - } - default: - mlibc::infoLogger() << "lookup_addr_dns: unknown rr type " - << rr_type << frg::endlog; - break; - } - num_ans += ntohs(response_header->no_ans); - - if (num_ans >= num_q) - break; - } - } - - close(fd); - return 0; -} - -int lookup_name_hosts(struct lookup_result &buf, const char *name, - frg::string<MemoryAllocator> &canon_name) { - auto file = fopen("/etc/hosts", "r"); - if (!file) { - switch (errno) { - case ENOENT: - case ENOTDIR: - case EACCES: - return -EAI_SERVICE; - default: - return -EAI_SYSTEM; - } - } - - char line[128]; - int name_length = strlen(name); - while (fgets(line, 128, file)) { - char *pos; - // same way to deal with comments as in services.cpp - if ((pos = strchr(line, '#'))) { - *pos++ = '\n'; - *pos = '\0'; - } - - for(pos = line + 1; (pos = strstr(pos, name)) && - (!isspace(pos[-1]) || !isspace(pos[name_length])); pos++); - if (!pos) - continue; - - for (pos = line; !isspace(*pos); pos++); - *pos = '\0'; - - // TODO(geert): we assume ipv4 for now - struct in_addr addr; - if (!inet_aton(line, &addr)) - continue; - - pos++; - for(; *pos && isspace(*pos); pos++); - char *end; - for(end = pos; *end && !isspace(*end); end++); - - struct dns_addr_buf buffer; - memcpy(buffer.addr, &addr, 4); - buffer.family = AF_INET; - buffer.name = frg::string<MemoryAllocator>{pos, - static_cast<size_t>(end - pos), getAllocator()}; - canon_name = buffer.name; - - buf.buf.push(std::move(buffer)); - - pos = end; - while (pos[1]) { - for (; *pos && isspace(*pos); pos++); - for (end = pos; *end && !isspace(*end); end++); - auto name = frg::string<MemoryAllocator>{pos, - static_cast<size_t>(end - pos), getAllocator()}; - buf.aliases.push(std::move(name)); - pos = end; - } - } - - fclose(file); - return buf.buf.size(); -} - -int lookup_addr_hosts(frg::span<char> name, frg::array<uint8_t, 16> &addr, int family) { - auto file = fopen("/etc/hosts", "r"); - if (!file) { - switch (errno) { - case ENOENT: - case ENOTDIR: - case EACCES: - return -EAI_SERVICE; - default: - return -EAI_SYSTEM; - } - } - - // Buffer to hold ASCII version of address - char addr_str[64]; - if(!inet_ntop(family, addr.data(), addr_str, sizeof(addr_str))) { - switch(errno) { - case EAFNOSUPPORT: - return -EAI_FAMILY; - case ENOSPC: - return -EAI_OVERFLOW; - default: - return -EAI_FAIL; - } - } - int addr_str_len = strlen(addr_str); - - char line[128]; - while (fgets(line, 128, file)) { - char *pos; - // same way to deal with comments as in services.cpp - if ((pos = strchr(line, '#'))) { - *pos++ = '\n'; - *pos = '\0'; - } - if (strncmp(line, addr_str, addr_str_len)) - continue; - - for (pos = line + addr_str_len + 1; isspace(*pos); pos++); - char *begin = pos; - for (; !isspace(*pos); pos++); - char *end = pos; - - size_t size = end - begin; - if (size >= name.size()) - return -EAI_OVERFLOW; - std::copy(begin, end, name.data()); - name.data()[size] = '\0'; - return 1; - } - return 0; -} - -int lookup_name_null(struct lookup_result &buf, int flags, int family) { - if (flags & AI_PASSIVE) { - if (family != AF_INET6) { - struct dns_addr_buf addr_buf; - addr_buf.family = AF_INET; - - in_addr_t addr = INADDR_ANY; - memcpy(&addr_buf.addr, &addr, 4); - - buf.buf.push_back(addr_buf); - } - if (family != AF_INET) { - struct dns_addr_buf addr_buf; - addr_buf.family = AF_INET6; - - struct in6_addr addr = IN6ADDR_ANY_INIT; - memcpy(&addr_buf.addr, &addr, 16); - - buf.buf.push_back(addr_buf); - } - } else { - if (family != AF_INET6) { - struct dns_addr_buf addr_buf; - addr_buf.family = AF_INET; - - in_addr_t addr = INADDR_LOOPBACK; - memcpy(&addr_buf.addr, &addr, 4); - - buf.buf.push_back(addr_buf); - } - if (family != AF_INET) { - struct dns_addr_buf addr_buf; - addr_buf.family = AF_INET6; - - struct in6_addr addr = IN6ADDR_LOOPBACK_INIT; - memcpy(&addr_buf.addr, &addr, 16); - - buf.buf.push_back(addr_buf); - } - } - return buf.buf.size(); -} - -int lookup_name_ip(struct lookup_result &buf, const char *name, int family) { - if (family == AF_INET) { - in_addr_t addr = 0; - int res = inet_pton(AF_INET, name, &addr); - - if (res <= 0) - return -EAI_NONAME; - - struct dns_addr_buf addr_buf; - addr_buf.family = AF_INET; - memcpy(&addr_buf.addr, &addr, 4); - - buf.buf.push_back(addr_buf); - return 1; - } - - if (family == AF_INET6) { - struct in6_addr addr{0}; - int res = inet_pton(AF_INET6, name, &addr); - - if (res <= 0) - return -EAI_NONAME; - - struct dns_addr_buf addr_buf; - addr_buf.family = AF_INET6; - memcpy(&addr_buf.addr, &addr, 16); - - buf.buf.push_back(addr_buf); - return 1; - } - - // If no family was specified we try ipv4 and then ipv6. - in_addr_t addr4 = 0; - int res = inet_pton(AF_INET, name, &addr4); - - if (res > 0) { - struct dns_addr_buf addr_buf; - addr_buf.family = AF_INET; - memcpy(&addr_buf.addr, &addr4, 4); - - buf.buf.push_back(addr_buf); - return 1; - } - - struct in6_addr addr6{0}; - res = inet_pton(AF_INET6, name, &addr6); - - if (res <= 0) - return -EAI_NONAME; - - struct dns_addr_buf addr_buf; - addr_buf.family = AF_INET6; - memcpy(&addr_buf.addr, &addr6, 16); - - buf.buf.push_back(addr_buf); - return 1; -} - -} // namespace mlibc diff --git a/lib/mlibc/options/posix/generic/mqueue.cpp b/lib/mlibc/options/posix/generic/mqueue.cpp deleted file mode 100644 index d635419..0000000 --- a/lib/mlibc/options/posix/generic/mqueue.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include <mqueue.h> -#include <bits/ensure.h> - -int mq_getattr(mqd_t, struct mq_attr *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int mq_setattr(mqd_t, const struct mq_attr *__restrict__, struct mq_attr *__restrict__) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int mq_unlink(const char *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -mqd_t mq_open(const char *, int, ...) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} diff --git a/lib/mlibc/options/posix/generic/net-if-stubs.cpp b/lib/mlibc/options/posix/generic/net-if-stubs.cpp deleted file mode 100644 index 6a65a5c..0000000 --- a/lib/mlibc/options/posix/generic/net-if-stubs.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include <errno.h> -#include <net/if.h> -#include <stdlib.h> - -#include <bits/ensure.h> -#include <mlibc/debug.hpp> -#include <mlibc/posix-sysdeps.hpp> - -void if_freenameindex(struct if_nameindex *) { - mlibc::infoLogger() << "mlibc: if_freenameindex is a no-op" << frg::endlog; -} - -char *if_indextoname(unsigned int index, char *name) { - auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_if_indextoname, NULL); - - if(int e = sysdep(index, name); e) { - errno = e; - return NULL; - } - - return name; -} - -struct if_nameindex *if_nameindex(void) { - mlibc::infoLogger() << "mlibc: if_nameindex() is a no-op" << frg::endlog; - errno = ENOSYS; - return NULL; -} - -unsigned int if_nametoindex(const char *name) { - auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_if_nametoindex, 0); - unsigned int ret = 0; - - if(int e = sysdep(name, &ret); e) { - errno = e; - return 0; - } - - return ret; -} diff --git a/lib/mlibc/options/posix/generic/netdb-stubs.cpp b/lib/mlibc/options/posix/generic/netdb-stubs.cpp deleted file mode 100644 index 455444b..0000000 --- a/lib/mlibc/options/posix/generic/netdb-stubs.cpp +++ /dev/null @@ -1,486 +0,0 @@ -#include <netdb.h> -#include <bits/ensure.h> - -#include <mlibc/debug.hpp> -#include <mlibc/lookup.hpp> -#include <mlibc/allocator.hpp> -#include <mlibc/services.hpp> -#include <frg/vector.hpp> -#include <frg/array.hpp> -#include <frg/span.hpp> -#include <sys/socket.h> -#include <arpa/inet.h> -#include <stdlib.h> -#include <stdio.h> -#include <stddef.h> -#include <errno.h> - -__thread int __mlibc_h_errno; - -// This function is from musl -int *__h_errno_location(void) { - return &__mlibc_h_errno; -} - -void endhostent(void) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -void endnetent(void) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -void endprotoent(void) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -void endservent(void) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -void freeaddrinfo(struct addrinfo *ptr) { - if (ptr) { - auto buf = (struct mlibc::ai_buf*) ptr - offsetof(struct mlibc::ai_buf, ai); - // this string was allocated by a frg::string - getAllocator().free(ptr->ai_canonname); - free(buf); - } -} - -const char *gai_strerror(int code) { - static thread_local char buffer[128]; - snprintf(buffer, sizeof(buffer), "Unknown error (%d)", code); - return buffer; -} - -int getaddrinfo(const char *__restrict node, const char *__restrict service, - const struct addrinfo *__restrict hints, struct addrinfo **__restrict res) { - if (!node && !service) - return EAI_NONAME; - - int socktype = 0, protocol = 0, family = AF_UNSPEC, flags = AI_V4MAPPED | AI_ADDRCONFIG; - if (hints) { - socktype = hints->ai_socktype; - protocol = hints->ai_protocol; - family = hints->ai_family; - flags = hints->ai_flags; - - int mask = AI_V4MAPPED | AI_ADDRCONFIG | AI_NUMERICHOST | AI_PASSIVE | - AI_CANONNAME | AI_ALL | AI_NUMERICSERV; - if ((flags & mask) != flags) - return EAI_BADFLAGS; - - if (family != AF_INET && family != AF_INET6 && family != AF_UNSPEC) - return EAI_FAMILY; - } - - mlibc::service_result serv_buf{getAllocator()}; - int serv_count = mlibc::lookup_serv_by_name(serv_buf, service, protocol, socktype, flags); - if (serv_count < 0) - return -serv_count; - - struct mlibc::lookup_result addr_buf; - int addr_count = 1; - frg::string<MemoryAllocator> canon{getAllocator()}; - if (node) { - if ((addr_count = mlibc::lookup_name_ip(addr_buf, node, family)) <= 0) { - if (flags & AI_NUMERICHOST) - addr_count = -EAI_NONAME; - else if ((addr_count = mlibc::lookup_name_hosts(addr_buf, node, canon)) <= 0) - addr_count = mlibc::lookup_name_dns(addr_buf, node, canon); - else - addr_count = 1; - } - - if (addr_count < 0) - return -addr_count; - if (!addr_count) - return EAI_NONAME; - } else { - /* There is no node specified */ - if (flags & AI_NUMERICHOST) - return EAI_NONAME; - addr_count = lookup_name_null(addr_buf, flags, family); - } - - auto out = (struct mlibc::ai_buf *) calloc(serv_count * addr_count, - sizeof(struct mlibc::ai_buf)); - - if (node && !canon.size()) - canon = frg::string<MemoryAllocator>{node, getAllocator()}; - - for (int i = 0, k = 0; i < addr_count; i++) { - for (int j = 0; j < serv_count; j++, k++) { - out[i].ai.ai_family = addr_buf.buf[i].family; - out[i].ai.ai_socktype = serv_buf[j].socktype; - out[i].ai.ai_protocol = serv_buf[j].protocol; - out[i].ai.ai_flags = flags; - out[i].ai.ai_addr = (struct sockaddr *) &out[i].sa; - if (canon.size()) - out[i].ai.ai_canonname = canon.data(); - else - out[i].ai.ai_canonname = NULL; - out[i].ai.ai_next = NULL; - switch (addr_buf.buf[i].family) { - case AF_INET: - out[i].ai.ai_addrlen = sizeof(struct sockaddr_in); - out[i].sa.sin.sin_port = htons(serv_buf[j].port); - out[i].sa.sin.sin_family = AF_INET; - memcpy(&out[i].sa.sin.sin_addr, addr_buf.buf[i].addr, 4); - break; - case AF_INET6: - out[i].ai.ai_addrlen = sizeof(struct sockaddr_in6); - out[i].sa.sin6.sin6_family = htons(serv_buf[j].port); - out[i].sa.sin6.sin6_family = AF_INET6; - memcpy(&out[i].sa.sin6.sin6_addr, addr_buf.buf[i].addr, 16); - break; - } - } - } - if (canon.size()) - canon.detach(); - - *res = &out[0].ai; - return 0; -} - -struct hostent *gethostent(void) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int getnameinfo(const struct sockaddr *__restrict addr, socklen_t addr_len, - char *__restrict host, socklen_t host_len, char *__restrict serv, - socklen_t serv_len, int flags) { - frg::array<uint8_t, 16> addr_array; - int family = addr->sa_family; - - switch(family) { - case AF_INET: { - if (addr_len < sizeof(struct sockaddr_in)) - return EAI_FAMILY; - auto sockaddr = reinterpret_cast<const struct sockaddr_in*>(addr); - memcpy(addr_array.data(), reinterpret_cast<const char*>(&sockaddr->sin_addr), 4); - break; - } - case AF_INET6: { - mlibc::infoLogger() << "getnameinfo(): ipv6 is not fully supported in this function" << frg::endlog; - if (addr_len < sizeof(struct sockaddr_in6)) - return EAI_FAMILY; - auto sockaddr = reinterpret_cast<const struct sockaddr_in6*>(addr); - memcpy(addr_array.data(), reinterpret_cast<const char*>(&sockaddr->sin6_addr), 16); - break; - } - default: - return EAI_FAMILY; - } - - if (host && host_len) { - frg::span<char> host_span{host, host_len}; - int res = 0; - if (!(flags & NI_NUMERICHOST)) - res = mlibc::lookup_addr_hosts(host_span, addr_array, family); - if (!(flags & NI_NUMERICHOST) && !res) - res = mlibc::lookup_addr_dns(host_span, addr_array, family); - - if (!res) { - if (flags & NI_NAMEREQD) - return EAI_NONAME; - if(!inet_ntop(family, addr_array.data(), host, host_len)) { - switch(errno) { - case EAFNOSUPPORT: - return EAI_FAMILY; - case ENOSPC: - return EAI_OVERFLOW; - default: - return EAI_FAIL; - } - } - } - - if (res < 0) - return -res; - } - - if (serv && serv_len) { - __ensure("getnameinfo(): not implemented service resolution yet!"); - __builtin_unreachable(); - } - - return 0; -} - -struct netent *getnetbyaddr(uint32_t, int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -struct netent *getnetbyname(const char *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -struct netent *getnetent(void) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -struct hostent *gethostbyname(const char *name) { - if (!name) { - h_errno = HOST_NOT_FOUND; - return NULL; - } - - struct mlibc::lookup_result buf; - frg::string<MemoryAllocator> canon{getAllocator()}; - int ret = 0; - if ((ret = mlibc::lookup_name_hosts(buf, name, canon)) <= 0) - ret = mlibc::lookup_name_dns(buf, name, canon); - if (ret <= 0) { - h_errno = HOST_NOT_FOUND; - return NULL; - } - - static struct hostent h; - if (h.h_name) { - getAllocator().free(h.h_name); - for (int i = 0; h.h_aliases[i] != NULL; i++) - getAllocator().free(h.h_aliases[i]); - free(h.h_aliases); - - if (h.h_addr_list) { - for (int i = 0; h.h_addr_list[i] != NULL; i++) - free(h.h_addr_list[i]); - free(h.h_addr_list); - } - } - h = {}; - - if (!canon.size()) - canon = frg::string<MemoryAllocator>{name, getAllocator()}; - - h.h_name = canon.data(); - - h.h_aliases = reinterpret_cast<char**>(malloc((buf.aliases.size() + 1) - * sizeof(char*))); - int alias_pos = 0; - for (auto &buf_name : buf.aliases) { - h.h_aliases[alias_pos] = buf_name.data(); - buf_name.detach(); - alias_pos++; - } - h.h_aliases[alias_pos] = NULL; - canon.detach(); - - // just pick the first family as the one for all addresses...?? - h.h_addrtype = buf.buf[0].family; - if (h.h_addrtype != AF_INET && h.h_addrtype != AF_INET6) { - // this is not allowed per spec - h_errno = NO_DATA; - return NULL; - } - - // can only be AF_INET or AF_INET6 - h.h_length = h.h_addrtype == AF_INET ? 4 : 16; - h.h_addr_list = reinterpret_cast<char**>(malloc((ret + 1) * sizeof(char*))); - int addr_pos = 0; - for (int i = 0; i < ret; i++) { - if (buf.buf[i].family != h.h_addrtype) - continue; - h.h_addr_list[addr_pos] = reinterpret_cast<char*>(malloc(h.h_length)); - memcpy(h.h_addr_list[addr_pos], buf.buf[i].addr, h.h_length); - addr_pos++; - } - h.h_addr_list[addr_pos] = NULL; - - return &h; -} - -struct hostent *gethostbyname2(const char *, int) { - __ensure(!"gethostbyname2() not implemented"); - __builtin_unreachable(); -} - -struct hostent *gethostbyaddr(const void *, socklen_t, int) { - __ensure(!"gethostbyaddr() not implemented"); - __builtin_unreachable(); -} - -int gethostbyaddr_r(const void *__restrict, socklen_t, int, struct hostent *__restrict, - char *__restrict, size_t, struct hostent **__restrict, int *__restrict) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int gethostbyname_r(const char *__restrict, struct hostent *__restrict, char *__restrict, size_t, - struct hostent **__restrict, int *__restrict) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -struct protoent *getprotobyname(const char *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -struct protoent *getprotobynumber(int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -struct protoent *getprotoent(void) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -struct servent *getservbyname(const char *name, const char *proto) { - int iproto = -1; - if (proto &&(!strncmp(proto, "tcp", 3) || !strncmp(proto, "TCP", 3))) - iproto = IPPROTO_TCP; - else if (proto && (!strncmp(proto, "udp", 3) || !strncmp(proto, "UDP", 3))) - iproto = IPPROTO_UDP; - - static struct servent ret; - if (ret.s_name) { - free(ret.s_name); - ret.s_name = nullptr; - - for (char **alias = ret.s_aliases; *alias != NULL; alias++) { - free(*alias); - *alias = nullptr; - } - - free(ret.s_proto); - ret.s_proto = nullptr; - } - - mlibc::service_result serv_buf{getAllocator()}; - int count = mlibc::lookup_serv_by_name(serv_buf, name, iproto, - 0, 0); - if (count <= 0) - return NULL; - - ret.s_name = serv_buf[0].name.data(); - serv_buf[0].name.detach(); - // Sanity check. - if (strncmp(name, serv_buf[0].name.data(), serv_buf[0].name.size())) - return NULL; - - ret.s_aliases = reinterpret_cast<char**>(malloc((serv_buf[0].aliases.size() + 1) * sizeof(char*))); - int alias_pos = 0; - for (auto &buf_name : serv_buf[0].aliases) { - ret.s_aliases[alias_pos] = buf_name.data(); - buf_name.detach(); - alias_pos++; - } - ret.s_aliases[alias_pos] = NULL; - - ret.s_port = htons(serv_buf[0].port); - - auto proto_string = frg::string<MemoryAllocator>(getAllocator()); - if (!proto) { - if (serv_buf[0].protocol == IPPROTO_TCP) - proto_string = frg::string<MemoryAllocator>("tcp", getAllocator()); - else if (serv_buf[0].protocol == IPPROTO_UDP) - proto_string = frg::string<MemoryAllocator>("udp", getAllocator()); - else - return NULL; - } else { - proto_string = frg::string<MemoryAllocator>(proto, getAllocator()); - } - ret.s_proto = proto_string.data(); - proto_string.detach(); - - return &ret; -} - -struct servent *getservbyport(int port, const char *proto) { - int iproto = -1; - if (proto && (!strncmp(proto, "tcp", 3) || !strncmp(proto, "TCP", 3))) - iproto = IPPROTO_TCP; - else if (proto && (!strncmp(proto, "udp", 3) || !strncmp(proto, "UDP", 3))) - iproto = IPPROTO_UDP; - - static struct servent ret; - if (ret.s_name) { - free(ret.s_name); - ret.s_name = nullptr; - - for (char **alias = ret.s_aliases; *alias != NULL; alias++) { - free(*alias); - *alias = nullptr; - } - - free(ret.s_proto); - ret.s_proto = nullptr; - } - - mlibc::service_result serv_buf{getAllocator()}; - int count = mlibc::lookup_serv_by_port(serv_buf, iproto, ntohs(port)); - if (count <= 0) - return NULL; - - ret.s_name = serv_buf[0].name.data(); - serv_buf[0].name.detach(); - - ret.s_aliases = reinterpret_cast<char**>(malloc((serv_buf[0].aliases.size() + 1) * sizeof(char*))); - int alias_pos = 0; - for (auto &buf_name : serv_buf[0].aliases) { - ret.s_aliases[alias_pos] = buf_name.data(); - buf_name.detach(); - alias_pos++; - } - ret.s_aliases[alias_pos] = NULL; - - ret.s_port = port; - - auto proto_string = frg::string<MemoryAllocator>(getAllocator()); - if (!proto) { - if (serv_buf[0].protocol == IPPROTO_TCP) - proto_string = frg::string<MemoryAllocator>("tcp", getAllocator()); - else if (serv_buf[0].protocol == IPPROTO_UDP) - proto_string = frg::string<MemoryAllocator>("udp", getAllocator()); - else - return NULL; - } else { - proto_string = frg::string<MemoryAllocator>(proto, getAllocator()); - } - ret.s_proto = proto_string.data(); - proto_string.detach(); - - return &ret; -} - -struct servent *getservent(void) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -void sethostent(int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -void setnetent(int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -void setprotoent(int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -void setservent(int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -const char *hstrerror(int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} diff --git a/lib/mlibc/options/posix/generic/poll.cpp b/lib/mlibc/options/posix/generic/poll.cpp deleted file mode 100644 index c34e25e..0000000 --- a/lib/mlibc/options/posix/generic/poll.cpp +++ /dev/null @@ -1,31 +0,0 @@ - -#include <errno.h> -#include <poll.h> - -#include <bits/ensure.h> -#include <mlibc/debug.hpp> -#include <mlibc/posix-sysdeps.hpp> - -int poll(struct pollfd *fds, nfds_t count, int timeout) { - int num_events; - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_poll, -1); - if(int e = mlibc::sys_poll(fds, count, timeout, &num_events); e) { - errno = e; - return -1; - } - return num_events; -} - -#if __MLIBC_LINUX_OPTION -int ppoll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts, const sigset_t *sigmask) { - sigset_t origmask; - int timeout = (timeout_ts == NULL) ? -1 : (timeout_ts->tv_sec * 1000 + timeout_ts->tv_nsec / 1000000); - - sigprocmask(SIG_SETMASK, sigmask, &origmask); - int ready = poll(fds, nfds, timeout); - sigprocmask(SIG_SETMASK, &origmask, NULL); - - return ready; -} -#endif // __MLIBC_LINUX_OPTION - diff --git a/lib/mlibc/options/posix/generic/posix-file-io.cpp b/lib/mlibc/options/posix/generic/posix-file-io.cpp deleted file mode 100644 index 1a4f38b..0000000 --- a/lib/mlibc/options/posix/generic/posix-file-io.cpp +++ /dev/null @@ -1,275 +0,0 @@ -#include <mlibc/posix-file-io.hpp> -#include <mlibc/debug.hpp> -#include <mlibc/posix-sysdeps.hpp> - -#include <errno.h> - -namespace mlibc { - -int mem_file::reopen(const char *, const char *) { - mlibc::panicLogger() << "mlibc: freopen() on a mem_file stream is unimplemented!" << frg::endlog; - return -1; -} - -int mem_file::determine_type(stream_type *type) { - *type = stream_type::file_like; - return 0; -} - -int mem_file::determine_bufmode(buffer_mode *mode) { - *mode = buffer_mode::no_buffer; - return 0; -} - -memstream_mem_file::memstream_mem_file(char **ptr, size_t *sizeloc, int flags, void (*do_dispose)(abstract_file *)) -: mem_file{flags, do_dispose}, _bufloc{ptr}, _sizeloc{sizeloc} { } - - -int memstream_mem_file::close() { - _update_ptrs(); - _buf.detach(); - - return 0; -} - -int memstream_mem_file::io_read(char *buffer, size_t max_size, size_t *actual_size) { - if ((_pos >= 0 && _pos >= _max_size) || !max_size) { - *actual_size = 0; - return 0; - } - - size_t bytes_read = std::min(size_t(_max_size - _pos), max_size); - memcpy(buffer, _buffer().data() + _pos, bytes_read); - _pos += bytes_read; - *actual_size = bytes_read; - return 0; -} - -int memstream_mem_file::io_write(const char *buffer, size_t max_size, size_t *actual_size) { - if (_pos + max_size >= _buffer_size()) { - _buf.resize(_pos + max_size + 1, '\0'); - _update_ptrs(); - } - - size_t bytes_write = std::min(static_cast<size_t>(_buffer_size() - _pos), max_size); - memcpy(_buffer().data() + _pos, buffer, bytes_write); - _pos += max_size; - *actual_size = max_size; - - return 0; -} - -int memstream_mem_file::io_seek(off_t offset, int whence, off_t *new_offset) { - switch (whence) { - case SEEK_SET: - _pos = offset; - if (_pos >= 0 && size_t(_pos) >= _buffer_size()) { - _buf.resize(_pos + 1, '\0'); - _update_ptrs(); - } - *new_offset = _pos; - break; - case SEEK_CUR: - _pos += offset; - if (_pos >= 0 && size_t(_pos) >= _buffer_size()) { - _buf.resize(_pos + 1, '\0'); - _update_ptrs(); - } - *new_offset = _pos; - break; - case SEEK_END: - _pos = _buffer_size() ? _buffer_size() - 1 + offset : _buffer_size() + offset; - _buf.resize(_pos + 1, '\0'); - _update_ptrs(); - *new_offset = _pos; - break; - default: - return EINVAL; - } - return 0; -} - -void memstream_mem_file::_update_ptrs() { - *_bufloc = _buf.data(); - *_sizeloc = _buf.size() - 1; -} - -fmemopen_mem_file::fmemopen_mem_file(void *in_buf, size_t size, int flags, void (*do_dispose)(abstract_file *)) -: mem_file{flags, do_dispose}, _inBuffer{in_buf}, _inBufferSize{size} { - if(!_inBuffer) { - _inBuffer = getAllocator().allocate(size); - _needsDeallocation = true; - } - - if(_flags & O_APPEND) { - // the initial seek-size for append is zero if buf was NULL, or the first '\0' found, or the size - _max_size = (_needsDeallocation) ? 0 : strnlen(reinterpret_cast<char *>(_inBuffer), _inBufferSize); - _pos = _max_size; - } else if((_flags & O_WRONLY || _flags & O_RDWR) && _flags & O_CREAT && _flags & O_TRUNC) { - // modes: "w", "w+" - _max_size = 0; - } else { - _max_size = size; - } -} - -int fmemopen_mem_file::close() { - if(_needsDeallocation) { - getAllocator().free(_inBuffer); - } - - return 0; -} - -int fmemopen_mem_file::io_read(char *buffer, size_t max_size, size_t *actual_size) { - if ((_pos >= 0 && _pos >= _max_size) || !max_size) { - *actual_size = 0; - return 0; - } - - size_t bytes_read = std::min(size_t(_max_size - _pos), max_size); - memcpy(buffer, _buffer().data() + _pos, bytes_read); - _pos += bytes_read; - *actual_size = bytes_read; - return 0; -} - -int fmemopen_mem_file::io_write(const char *buffer, size_t max_size, size_t *actual_size) { - off_t bytes_write = std::min(static_cast<size_t>(_buffer_size() - _pos), max_size); - memcpy(_buffer().data() + _pos, buffer, bytes_write); - _pos += bytes_write; - *actual_size = bytes_write; - - if(_pos > _max_size) { - _max_size = _pos; - } - - // upon flushing, we need to put a null byte at the current position or at the end of the buffer - size_t null = _pos; - // a special case is if the mode is set to updating ('+'), then it always goes at the end - if(null >= _buffer_size() || _flags & O_RDWR) { - null = _buffer_size() - 1; - } - - if(_buffer_size()) { - _buffer()[null] = '\0'; - } - - return 0; -} - -int fmemopen_mem_file::io_seek(off_t offset, int whence, off_t *new_offset) { - switch (whence) { - case SEEK_SET: - if(offset < 0 || size_t(offset) > _buffer_size()) { - return EINVAL; - } - _pos = offset; - *new_offset = _pos; - break; - case SEEK_CUR: - // seeking to negative positions or positions larger than the buffer is disallowed in fmemopen(3) - if((_pos + offset) < 0 || size_t(_pos + offset) > _buffer_size()) { - return EINVAL; - } - _pos += offset; - *new_offset = _pos; - break; - case SEEK_END: - if((_max_size + offset) < 0 || size_t(_max_size + offset) > _buffer_size()) { - return EINVAL; - } - _pos = _max_size + offset; - *new_offset = _pos; - break; - default: - return EINVAL; - } - return 0; -} - -int cookie_file::close() { - if(!_funcs.close) { - return 0; - } - - return _funcs.close(_cookie); -} - -int cookie_file::reopen(const char *, const char *) { - mlibc::panicLogger() << "mlibc: freopen() on a cookie_file stream is unimplemented!" << frg::endlog; - return -1; -} - -int cookie_file::determine_type(stream_type *type) { - *type = stream_type::file_like; - return 0; -} - -int cookie_file::determine_bufmode(buffer_mode *mode) { - *mode = buffer_mode::no_buffer; - return 0; -} - -int cookie_file::io_read(char *buffer, size_t max_size, size_t *actual_size) { - if(!_funcs.read) { - return EOF; - } - - *actual_size = _funcs.read(_cookie, buffer, max_size); - - return 0; -} - -int cookie_file::io_write(const char *buffer, size_t max_size, size_t *actual_size) { - if(!_funcs.write) { - return 0; - } - - *actual_size = _funcs.write(_cookie, buffer, max_size); - - return 0; -} - -int cookie_file::io_seek(off_t offset, int whence, off_t *new_offset) { - if(!_funcs.seek) { - return ENOTSUP; - } - - *new_offset = offset; - - return _funcs.seek(_cookie, new_offset, whence); -} - -} // namespace mlibc - -FILE *fdopen(int fd, const char *mode) { - int flags = mlibc::fd_file::parse_modestring(mode); - - flags &= ~O_TRUNC; // 'w' should not truncate the file - - if (flags & O_APPEND) { - int cur_flags = fcntl(fd, F_GETFL, 0); - if (cur_flags < 0) { - errno = EINVAL; - return nullptr; - } else if (!(cur_flags & O_APPEND)) { - if (fcntl(fd, F_SETFL, cur_flags | O_APPEND)) { - errno = EINVAL; - return nullptr; - } - } - } - - if (flags & O_CLOEXEC) { - if (fcntl(fd, F_SETFD, FD_CLOEXEC)) { - errno = EINVAL; - return nullptr; - } - } - - // TODO: We may need to activate line buffered mode for terminals. - - return frg::construct<mlibc::fd_file>(getAllocator(), fd, - mlibc::file_dispose_cb<mlibc::fd_file>); -} diff --git a/lib/mlibc/options/posix/generic/posix_ctype.cpp b/lib/mlibc/options/posix/generic/posix_ctype.cpp deleted file mode 100644 index 19f129f..0000000 --- a/lib/mlibc/options/posix/generic/posix_ctype.cpp +++ /dev/null @@ -1,136 +0,0 @@ -#include <ctype.h> -#include <wctype.h> - -#include <bits/ensure.h> - -int isalnum_l(int c, locale_t) { - return isalnum(c); -} - -int isalpha_l(int c, locale_t) { - return isalpha(c); -} - -int isblank_l(int c, locale_t) { - return isblank(c); -} - -int iscntrl_l(int c, locale_t) { - return iscntrl(c); -} - -int isdigit_l(int c, locale_t) { - return isdigit(c); -} - -int isgraph_l(int c, locale_t) { - return isgraph(c); -} - -int islower_l(int c, locale_t) { - return islower(c); -} - -int isprint_l(int c, locale_t) { - return isprint(c); -} - -int ispunct_l(int c, locale_t) { - return ispunct(c); -} - -int isspace_l(int c, locale_t) { - return isspace(c); -} - -int isupper_l(int c, locale_t) { - return isupper(c); -} - -int isxdigit_l(int c, locale_t) { - return isxdigit(c); -} - -int isascii_l(int c, locale_t) { - return isascii(c); -} - -int tolower_l(int c, locale_t) { - return tolower(c); -} - -int toupper_l(int c, locale_t) { - return toupper(c); -} - -int iswalnum_l(wint_t c, locale_t) { - return iswalnum(c); -} - -int iswblank_l(wint_t c, locale_t) { - return iswblank(c); -} - -int iswcntrl_l(wint_t c, locale_t) { - return iswcntrl(c); -} - -int iswdigit_l(wint_t c, locale_t) { - return iswdigit(c); -} - -int iswgraph_l(wint_t c, locale_t) { - return iswgraph(c); -} - -int iswlower_l(wint_t c, locale_t) { - return iswlower(c); -} - -int iswprint_l(wint_t c, locale_t) { - return iswprint(c); -} - -int iswpunct_l(wint_t c, locale_t) { - return iswpunct(c); -} - -int iswspace_l(wint_t c, locale_t) { - return iswspace(c); -} - -int iswupper_l(wint_t c, locale_t) { - return iswupper(c); -} - -int iswxdigit_l(wint_t c, locale_t) { - return iswxdigit(c); -} - -int iswalpha_l(wint_t c, locale_t) { - return iswalpha(c); -} - -wctype_t wctype_l(const char* p, locale_t) { - return wctype(p); -} - -int iswctype_l(wint_t w, wctype_t t, locale_t) { - return iswctype(w, t); -} - -wint_t towlower_l(wint_t c, locale_t) { - return towlower(c); -} - -wint_t towupper_l(wint_t c, locale_t) { - return towupper(c); -} - -wctrans_t wctrans_l(const char* c, locale_t) { - return wctrans(c); -} - -wint_t towctrans_l(wint_t c, wctrans_t desc, locale_t) { - return towctrans(c, desc); -} diff --git a/lib/mlibc/options/posix/generic/posix_locale.cpp b/lib/mlibc/options/posix/generic/posix_locale.cpp deleted file mode 100644 index bd8710a..0000000 --- a/lib/mlibc/options/posix/generic/posix_locale.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include <bits/posix/posix_locale.h> -#include <bits/ensure.h> -#include <mlibc/debug.hpp> - -namespace { - -bool newlocale_seen = false; -bool uselocale_seen = false; - -} - -locale_t newlocale(int, const char *, locale_t) { - // Due to all of the locale functions being stubs, the locale will not be used - if(!newlocale_seen) { - mlibc::infoLogger() << "mlibc: newlocale() is a no-op" << frg::endlog; - newlocale_seen = true; - } - return nullptr; -} - -void freelocale(locale_t) { - mlibc::infoLogger() << "mlibc: freelocale() is a no-op" << frg::endlog; - return; -} - -locale_t uselocale(locale_t) { - if(!uselocale_seen) { - mlibc::infoLogger() << "mlibc: uselocale() is a no-op" << frg::endlog; - uselocale_seen = true; - } - return nullptr; -} - -locale_t duplocale(locale_t) { - mlibc::infoLogger() << "mlibc: duplocale() is a no-op" << frg::endlog; - return nullptr; -} diff --git a/lib/mlibc/options/posix/generic/posix_signal.cpp b/lib/mlibc/options/posix/generic/posix_signal.cpp deleted file mode 100644 index eef3ef3..0000000 --- a/lib/mlibc/options/posix/generic/posix_signal.cpp +++ /dev/null @@ -1,151 +0,0 @@ - -#include <errno.h> -#include <signal.h> -#include <unistd.h> -#include <bits/ensure.h> - -#include <mlibc/posix-sysdeps.hpp> -#include <mlibc/tcb.hpp> - -int sigsuspend(const sigset_t *sigmask) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_sigsuspend, -1); - - // This is guaranteed to return an error (EINTR most probably) - errno = mlibc::sys_sigsuspend(sigmask); - return -1; -} - -int pthread_sigmask(int how, const sigset_t *__restrict set, sigset_t *__restrict retrieve) { - if(!mlibc::sys_sigprocmask) { - MLIBC_MISSING_SYSDEP(); - return ENOSYS; - } - if(int e = mlibc::sys_sigprocmask(how, set, retrieve); e) { - return e; - } - return 0; -} - -int pthread_kill(pthread_t thread, int sig) { - auto tcb = reinterpret_cast<Tcb *>(thread); - auto pid = getpid(); - - if(!mlibc::sys_tgkill) { - MLIBC_MISSING_SYSDEP(); - return ENOSYS; - } - - if(int e = mlibc::sys_tgkill(pid, tcb->tid, sig); e) { - return e; - } - - return 0; -} - -int sigaction(int signum, const struct sigaction *__restrict act, struct sigaction *__restrict oldact) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_sigaction, -1); - if(int e = mlibc::sys_sigaction(signum, act, oldact); e) { - errno = e; - return -1; - } - return 0; -} - -int siginterrupt(int sig, int flag) { - int ret; - struct sigaction act; - - sigaction(sig, NULL, &act); - if (flag) - act.sa_flags &= ~SA_RESTART; - else - act.sa_flags |= SA_RESTART; - - ret = sigaction(sig, &act, NULL); - return ret; -} - -int kill(pid_t pid, int number) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_kill, -1); - if(int e = mlibc::sys_kill(pid, number); e) { - errno = e; - return -1; - } - return 0; -} - -int killpg(pid_t pgrp, int sig) { - if(pgrp > 1) { - return kill(-pgrp, sig); - } - - errno = EINVAL; - return -1; -} - -int sigtimedwait(const sigset_t *__restrict set, siginfo_t *__restrict info, const struct timespec *__restrict timeout) { - auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_sigtimedwait, -1); - - int signo; - - if (int e = sysdep(set, info, timeout, &signo)) { - errno = e; - return -1; - } - - return signo; -} - -int sigwaitinfo(const sigset_t *__restrict set, siginfo_t *__restrict info) { - // NOTE: This assumes the sysdep behavior noted in mlibc/posix-sysdeps.hpp - return sigtimedwait(set, info, nullptr); -} - -int sigwait(const sigset_t *__restrict set, int *__restrict sig) { - if (int e = sigwaitinfo(set, nullptr); e < 0) { - return e; - } else { - if (sig) - *sig = e; - - return 0; - } -} - -int sigpending(sigset_t *set) { - auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_sigpending, -1); - - if(int e = sysdep(set)) { - errno = e; - return -1; - } - - return 0; -} - -int sigaltstack(const stack_t *__restrict ss, stack_t *__restrict oss) { - if (ss && ss->ss_size < MINSIGSTKSZ && !(ss->ss_flags & SS_DISABLE)) { - errno = ENOMEM; - return -1; - } - - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_sigaltstack, -1); - if (int e = mlibc::sys_sigaltstack(ss, oss); e) { - errno = e; - return -1; - } - - return 0; -} - -#if __MLIBC_GLIBC_OPTION -int sigisemptyset(const sigset_t *set) { - return !(*set); -} -#endif // __MLIBC_GLIBC_OPTION - -int sigqueue(pid_t, int, const union sigval) { - __ensure(!"sigqueue() not implemented"); - __builtin_unreachable(); -} - diff --git a/lib/mlibc/options/posix/generic/posix_stdio.cpp b/lib/mlibc/options/posix/generic/posix_stdio.cpp deleted file mode 100644 index fc77a54..0000000 --- a/lib/mlibc/options/posix/generic/posix_stdio.cpp +++ /dev/null @@ -1,209 +0,0 @@ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> - -#include <bits/ensure.h> -#include <mlibc/ansi-sysdeps.hpp> -#include <mlibc/debug.hpp> -#include <mlibc/file-io.hpp> -#include <mlibc/posix-file-io.hpp> -#include <mlibc/posix-sysdeps.hpp> - -struct popen_file : mlibc::fd_file { - popen_file(int fd, void (*do_dispose)(abstract_file *) = nullptr) - : fd_file(fd, do_dispose) {} - - pid_t get_popen_pid() { - return _popen_pid; - } - - void set_popen_pid(pid_t new_pid) { - _popen_pid = new_pid; - } - -private: - // Underlying PID in case of popen() - pid_t _popen_pid; -}; - -FILE *fmemopen(void *buf, size_t size, const char *__restrict mode) { - int flags = mlibc::fd_file::parse_modestring(mode); - - return frg::construct<mlibc::fmemopen_mem_file>(getAllocator(), buf, size, flags, - mlibc::file_dispose_cb<mlibc::mem_file>); -} - -int pclose(FILE *stream) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_waitpid, -1); - - auto file = static_cast<popen_file *>(stream); - - int status; - pid_t pid = file->get_popen_pid(); - - fclose(file); - - if (mlibc::sys_waitpid(pid, &status, 0, NULL, &pid) != 0) { - errno = ECHILD; - return -1; - } - - return status; -} - -FILE *popen(const char *command, const char *typestr) { - bool is_write; - pid_t child; - FILE *ret = nullptr; - - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_fork && mlibc::sys_dup2 && mlibc::sys_execve && - mlibc::sys_sigprocmask && mlibc::sys_sigaction && mlibc::sys_pipe, nullptr); - - if (typestr == NULL) { - errno = EINVAL; - return nullptr; - } - - if (strstr(typestr, "w") != NULL) { - is_write = true; - } else if (strstr(typestr, "r") != NULL) { - is_write = false; - } else { - errno = EINVAL; - return nullptr; - } - - bool cloexec = false; - if (strstr(typestr, "e") != NULL) { - // Set FD_CLOEXEC on the new file descriptor - cloexec = true; - } - - int fds[2]; - if (int e = mlibc::sys_pipe(fds, 0)) { - errno = e; - return nullptr; - } - - struct sigaction new_sa, old_int, old_quit; - sigset_t new_mask, old_mask; - - new_sa.sa_handler = SIG_IGN; - new_sa.sa_flags = 0; - sigemptyset(&new_sa.sa_mask); - mlibc::sys_sigaction(SIGINT, &new_sa, &old_int); - mlibc::sys_sigaction(SIGQUIT, &new_sa, &old_quit); - - sigemptyset(&new_mask); - sigaddset(&new_mask, SIGCHLD); - mlibc::sys_sigprocmask(SIG_BLOCK, &new_mask, &old_mask); - - int parent_end = is_write ? 1 : 0; - int child_end = is_write ? 0 : 1; - - if (int e = mlibc::sys_fork(&child)) { - errno = e; - mlibc::sys_close(fds[0]); - mlibc::sys_close(fds[1]); - } else if (!child) { - // For the child - mlibc::sys_sigaction(SIGINT, &old_int, nullptr); - mlibc::sys_sigaction(SIGQUIT, &old_quit, nullptr); - mlibc::sys_sigprocmask(SIG_SETMASK, &old_mask, nullptr); - - mlibc::sys_close(fds[parent_end]); - - if (mlibc::sys_dup2(fds[child_end], 0, is_write ? 0 : 1)) { - __ensure(!"sys_dup2() failed in popen()"); - } - mlibc::sys_close(fds[child_end]); - - const char *args[] = { - "sh", "-c", command, nullptr - }; - - mlibc::sys_execve("/bin/sh", const_cast<char **>(args), environ); - _Exit(127); - } else { - // For the parent - mlibc::sys_close(fds[child_end]); - - ret = frg::construct<popen_file>( - getAllocator(), - fds[parent_end], - mlibc::file_dispose_cb<popen_file> - ); - __ensure(ret); - - auto file = static_cast<popen_file *>(ret); - - file->set_popen_pid(child); - - if (cloexec == true) { - fcntl(file->fd(), F_SETFD, O_CLOEXEC); - } - } - - mlibc::sys_sigaction(SIGINT, &old_int, nullptr); - mlibc::sys_sigaction(SIGQUIT, &old_quit, nullptr); - mlibc::sys_sigprocmask(SIG_SETMASK, &old_mask, nullptr); - - return ret; -} - -FILE *open_memstream(char **buf, size_t *sizeloc) { - return frg::construct<mlibc::memstream_mem_file>(getAllocator(), buf, sizeloc, O_RDWR, - mlibc::file_dispose_cb<mlibc::mem_file>); -} - -int fseeko(FILE *file_base, off_t offset, int whence) { - auto file = static_cast<mlibc::abstract_file *>(file_base); - if(int e = file->seek(offset, whence); e) { - errno = e; - return -1; - } - return 0; -} - -off_t ftello(FILE *file_base) { - auto file = static_cast<mlibc::abstract_file *>(file_base); - off_t current_offset; - if(int e = file->tell(¤t_offset); e) { - errno = e; - return -1; - } - return current_offset; -} - -int dprintf(int fd, const char *format, ...) { - va_list args; - va_start(args, format); - int result = vdprintf(fd, format, args); - va_end(args); - return result; -} - -int vdprintf(int fd, const char *format, __builtin_va_list args) { - mlibc::fd_file file{fd}; - int ret = vfprintf(&file, format, args); - file.flush(); - return ret; -} - -char *fgetln(FILE *, size_t *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -FILE *fopencookie(void *cookie, const char *__restrict mode, cookie_io_functions_t funcs) { - int flags = mlibc::fd_file::parse_modestring(mode); - - return frg::construct<mlibc::cookie_file>(getAllocator(), cookie, flags, funcs, - mlibc::file_dispose_cb<mlibc::cookie_file>); -} 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); -} diff --git a/lib/mlibc/options/posix/generic/posix_string.cpp b/lib/mlibc/options/posix/generic/posix_string.cpp deleted file mode 100644 index d0bc7b5..0000000 --- a/lib/mlibc/options/posix/generic/posix_string.cpp +++ /dev/null @@ -1,174 +0,0 @@ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include <bits/ensure.h> -#include <stdlib.h> -#include <string.h> -#include <strings.h> -#include <signal.h> - -#include <mlibc/debug.hpp> - -char *strdup(const char *string) { - auto num_bytes = strlen(string); - - char *new_string = (char *)malloc(num_bytes + 1); - if(!new_string) // TODO: set errno - return nullptr; - - memcpy(new_string, string, num_bytes); - new_string[num_bytes] = 0; - return new_string; -} - -char *strndup(const char *string, size_t max_size) { - auto num_bytes = strnlen(string, max_size); - char *new_string = (char *)malloc(num_bytes + 1); - if(!new_string) // TODO: set errno - return nullptr; - - memcpy(new_string, string, num_bytes); - new_string[num_bytes] = 0; - return new_string; -} - -char *stpcpy(char *__restrict dest, const char *__restrict src) { - auto n = strlen(src); - memcpy(dest, src, n + 1); - return dest + n; -} - -char *stpncpy(char *__restrict dest, const char *__restrict src, size_t n) { - size_t nulls, copied, srcLen = strlen(src); - if (n >= srcLen) { - nulls = n - srcLen; - copied = srcLen; - } else { - nulls = 0; - copied = n; - } - - memcpy(dest, src, copied); - memset(dest + srcLen, 0, nulls); - return dest + n - nulls; -} - -size_t strnlen(const char *s, size_t n) { - size_t len = 0; - while(len < n && s[len]) - ++len; - return len; -} - -char *strsep(char **m, const char *del) { - __ensure(m); - - auto tok = *m; - if(!tok) - return nullptr; - - // Replace the following delimiter by a null-terminator. - // After this loop: *p is null iff we reached the end of the string. - auto p = tok; - while(*p && !strchr(del, *p)) - p++; - - if(*p) { - *p = 0; - *m = p + 1; - }else{ - *m = nullptr; - } - return tok; -} - -char *strsignal(int sig) { - #define CASE_FOR(sigconst) case sigconst: s = #sigconst; break; - const char *s; - switch(sig) { - CASE_FOR(SIGABRT) - CASE_FOR(SIGFPE) - CASE_FOR(SIGILL) - CASE_FOR(SIGINT) - CASE_FOR(SIGSEGV) - CASE_FOR(SIGTERM) - CASE_FOR(SIGPROF) - CASE_FOR(SIGIO) - CASE_FOR(SIGPWR) - CASE_FOR(SIGALRM) - CASE_FOR(SIGBUS) - CASE_FOR(SIGCHLD) - CASE_FOR(SIGCONT) - CASE_FOR(SIGHUP) - CASE_FOR(SIGKILL) - CASE_FOR(SIGPIPE) - CASE_FOR(SIGQUIT) - CASE_FOR(SIGSTOP) - CASE_FOR(SIGTSTP) - CASE_FOR(SIGTTIN) - CASE_FOR(SIGTTOU) - CASE_FOR(SIGUSR1) - CASE_FOR(SIGUSR2) - CASE_FOR(SIGSYS) - CASE_FOR(SIGTRAP) - CASE_FOR(SIGURG) - CASE_FOR(SIGVTALRM) - CASE_FOR(SIGXCPU) - CASE_FOR(SIGXFSZ) - CASE_FOR(SIGWINCH) - default: - mlibc::infoLogger() << "mlibc: Unknown signal number " << sig << frg::endlog; - s = "Unknown signal number"; - } - return const_cast<char *>(s); -} - -char *strcasestr(const char *s, const char *pattern) { - size_t plen = strlen(pattern); - const char *p = s; - while(*p) { - // Need strncasecmp() to avoid checking past the end of a successful match. - if(!strncasecmp(p, pattern, plen)) - return const_cast<char *>(p); - ++p; - } - return nullptr; -} - -void *memccpy(void *__restrict, const void *__restrict, int, size_t) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -// This implementation was taken from musl -void *memrchr(const void *m, int c, size_t n) { - const unsigned char *s = (const unsigned char *)m; - c = (unsigned char)c; - while(n--) { - if(s[n] == c) - return (void *)(s + n); - } - return 0; -} - -// BSD extensions. -// Taken from musl -size_t strlcpy(char *d, const char *s, size_t n) { - char *d0 = d; - - if(!n--) - goto finish; - for(; n && (*d=*s); n--, s++, d++); - *d = 0; -finish: - return d-d0 + strlen(s); -} - -size_t strlcat(char *d, const char *s, size_t n) { - size_t l = strnlen(d, n); - if(l == n) { - return l + strlen(s); - } - return l + strlcpy(d + l, s, n - l); -} diff --git a/lib/mlibc/options/posix/generic/posix_time.cpp b/lib/mlibc/options/posix/generic/posix_time.cpp deleted file mode 100644 index d93ebbc..0000000 --- a/lib/mlibc/options/posix/generic/posix_time.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include <bits/posix/posix_time.h> -#include <bits/ensure.h> -#include <mlibc/posix-sysdeps.hpp> -#include <errno.h> - -int utimes(const char *filename, const struct timeval times[2]) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_utimensat, -1); - struct timespec time[2]; - if(times == nullptr) { - time[0].tv_sec = UTIME_NOW; - time[0].tv_nsec = UTIME_NOW; - time[1].tv_sec = UTIME_NOW; - time[1].tv_nsec = UTIME_NOW; - } else { - time[0].tv_sec = times[0].tv_sec; - time[0].tv_nsec = times[0].tv_usec * 1000; - time[1].tv_sec = times[1].tv_sec; - time[1].tv_nsec = times[1].tv_usec * 1000; - } - - if (int e = mlibc::sys_utimensat(AT_FDCWD, filename, time, 0); e) { - errno = e; - return -1; - } - - return 0; -} - -int futimes(int, const struct timeval[2]) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} diff --git a/lib/mlibc/options/posix/generic/pthread-stubs.cpp b/lib/mlibc/options/posix/generic/pthread-stubs.cpp deleted file mode 100644 index 9720bc2..0000000 --- a/lib/mlibc/options/posix/generic/pthread-stubs.cpp +++ /dev/null @@ -1,1426 +0,0 @@ - -#include <stddef.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <pthread.h> -#include <unistd.h> -#include <errno.h> -#include <inttypes.h> - -#include <bits/ensure.h> -#include <frg/allocation.hpp> -#include <frg/array.hpp> -#include <mlibc/allocator.hpp> -#include <mlibc/debug.hpp> -#include <mlibc/posix-sysdeps.hpp> -#include <mlibc/thread.hpp> -#include <mlibc/tcb.hpp> -#include <mlibc/tid.hpp> -#include <mlibc/threads.hpp> - -static bool enableTrace = false; - -struct ScopeTrace { - ScopeTrace(const char *file, int line, const char *function) - : _file(file), _line(line), _function(function) { - if(!enableTrace) - return; - mlibc::infoLogger() << "trace: Enter scope " - << _file << ":" << _line << " (in function " - << _function << ")" << frg::endlog; - } - - ~ScopeTrace() { - if(!enableTrace) - return; - mlibc::infoLogger() << "trace: Exit scope" << frg::endlog; - } - -private: - const char *_file; - int _line; - const char *_function; -}; - -#define SCOPE_TRACE() ScopeTrace(__FILE__, __LINE__, __FUNCTION__) - -static constexpr unsigned int mutexRecursive = 1; -static constexpr unsigned int mutexErrorCheck = 2; - -// TODO: either use uint32_t or determine the bit based on sizeof(int). -static constexpr unsigned int mutex_owner_mask = (static_cast<uint32_t>(1) << 30) - 1; -static constexpr unsigned int mutex_waiters_bit = static_cast<uint32_t>(1) << 31; - -// Only valid for the internal __mlibc_m mutex of wrlocks. -static constexpr unsigned int mutex_excl_bit = static_cast<uint32_t>(1) << 30; - -static constexpr unsigned int rc_count_mask = (static_cast<uint32_t>(1) << 31) - 1; -static constexpr unsigned int rc_waiters_bit = static_cast<uint32_t>(1) << 31; - -static constexpr size_t default_stacksize = 0x200000; -static constexpr size_t default_guardsize = 4096; - -// ---------------------------------------------------------------------------- -// pthread_attr and pthread functions. -// ---------------------------------------------------------------------------- - -// pthread_attr functions. -int pthread_attr_init(pthread_attr_t *attr) { - *attr = pthread_attr_t{}; - attr->__mlibc_stacksize = default_stacksize; - attr->__mlibc_guardsize = default_guardsize; - attr->__mlibc_detachstate = PTHREAD_CREATE_JOINABLE; - return 0; -} - -int pthread_attr_destroy(pthread_attr_t *) { - return 0; -} - -int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate) { - *detachstate = attr->__mlibc_detachstate; - return 0; -} -int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate) { - if (detachstate != PTHREAD_CREATE_DETACHED && - detachstate != PTHREAD_CREATE_JOINABLE) - return EINVAL; - - attr->__mlibc_detachstate = detachstate; - return 0; -} - -int pthread_attr_getstacksize(const pthread_attr_t *__restrict attr, size_t *__restrict stacksize) { - *stacksize = attr->__mlibc_stacksize; - return 0; -} - -int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize) { - if (stacksize < PTHREAD_STACK_MIN) - return EINVAL; - attr->__mlibc_stacksize = stacksize; - return 0; -} - -int pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr) { - *stackaddr = attr->__mlibc_stackaddr; - return 0; -} -int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr) { - attr->__mlibc_stackaddr = stackaddr; - return 0; -} - -int pthread_attr_getstack(const pthread_attr_t *attr, void **stackaddr, size_t *stacksize) { - *stackaddr = attr->__mlibc_stackaddr; - *stacksize = attr->__mlibc_stacksize; - return 0; -} -int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize) { - if (stacksize < PTHREAD_STACK_MIN) - return EINVAL; - attr->__mlibc_stacksize = stacksize; - attr->__mlibc_stackaddr = stackaddr; - return 0; -} - -int pthread_attr_getguardsize(const pthread_attr_t *__restrict attr, size_t *__restrict guardsize) { - *guardsize = attr->__mlibc_guardsize; - return 0; -} -int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize) { - attr->__mlibc_guardsize = guardsize; - return 0; -} - -int pthread_attr_getscope(const pthread_attr_t *attr, int *scope) { - *scope = attr->__mlibc_scope; - return 0; -} -int pthread_attr_setscope(pthread_attr_t *attr, int scope) { - if (scope != PTHREAD_SCOPE_SYSTEM && - scope != PTHREAD_SCOPE_PROCESS) - return EINVAL; - if (scope == PTHREAD_SCOPE_PROCESS) - return ENOTSUP; - attr->__mlibc_scope = scope; - return 0; -} - -int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched) { - *inheritsched = attr->__mlibc_inheritsched; - return 0; -} -int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched) { - if (inheritsched != PTHREAD_INHERIT_SCHED && - inheritsched != PTHREAD_EXPLICIT_SCHED) - return EINVAL; - attr->__mlibc_inheritsched = inheritsched; - return 0; -} - -int pthread_attr_getschedparam(const pthread_attr_t *__restrict attr, struct sched_param *__restrict schedparam) { - *schedparam = attr->__mlibc_schedparam; - return 0; -} -int pthread_attr_setschedparam(pthread_attr_t *__restrict attr, const struct sched_param *__restrict schedparam) { - // TODO: this is supposed to return EINVAL for when the schedparam doesn't make sense - // for the given schedpolicy. - attr->__mlibc_schedparam = *schedparam; - return 0; -} - -int pthread_attr_getschedpolicy(const pthread_attr_t *__restrict attr, int *__restrict policy) { - *policy = attr->__mlibc_schedpolicy; - return 0; -} -int pthread_attr_setschedpolicy(pthread_attr_t *__restrict attr, int policy) { - if (policy != SCHED_FIFO && policy != SCHED_RR && - policy != SCHED_OTHER) - return EINVAL; - attr->__mlibc_schedpolicy = policy; - return 0; -} - -#if __MLIBC_LINUX_OPTION -int pthread_attr_getaffinity_np(const pthread_attr_t *__restrict attr, - size_t cpusetsize, cpu_set_t *__restrict cpusetp) { - if (!attr) - return EINVAL; - - if (!attr->__mlibc_cpuset) { - memset(cpusetp, -1, cpusetsize); - return 0; - } - - for (size_t cnt = cpusetsize; cnt < attr->__mlibc_cpusetsize; cnt++) - if (reinterpret_cast<char*>(attr->__mlibc_cpuset)[cnt] != '\0') - return ERANGE; - - auto p = memcpy(cpusetp, attr->__mlibc_cpuset, - std::min(cpusetsize, attr->__mlibc_cpusetsize)); - if (cpusetsize > attr->__mlibc_cpusetsize) - memset(p, '\0', cpusetsize - attr->__mlibc_cpusetsize); - - return 0; -} - -int pthread_attr_setaffinity_np(pthread_attr_t *__restrict attr, - size_t cpusetsize, const cpu_set_t *__restrict cpusetp) { - if (!attr) - return EINVAL; - - if (!cpusetp || !cpusetsize) { - attr->__mlibc_cpuset = NULL; - attr->__mlibc_cpusetsize = 0; - return 0; - } - - if (attr->__mlibc_cpusetsize != cpusetsize) { - auto newp = realloc(attr->__mlibc_cpuset, cpusetsize); - if (!newp) - return ENOMEM; - - attr->__mlibc_cpuset = static_cast<cpu_set_t*>(newp); - attr->__mlibc_cpusetsize = cpusetsize; - } - - memcpy(attr->__mlibc_cpuset, cpusetp, cpusetsize); - return 0; -} - -int pthread_attr_getsigmask_np(const pthread_attr_t *__restrict attr, - sigset_t *__restrict sigmask) { - if (!attr) - return EINVAL; - - if (!attr->__mlibc_sigmaskset) { - sigemptyset(sigmask); - return PTHREAD_ATTR_NO_SIGMASK_NP; - } - - *sigmask = attr->__mlibc_sigmask; - - return 0; -} -int pthread_attr_setsigmask_np(pthread_attr_t *__restrict attr, - const sigset_t *__restrict sigmask) { - if (!attr) - return EINVAL; - - if (!sigmask) { - attr->__mlibc_sigmaskset = 0; - return 0; - } - - attr->__mlibc_sigmask = *sigmask; - attr->__mlibc_sigmaskset = 1; - - // Filter out internally used signals. - sigdelset(&attr->__mlibc_sigmask, SIGCANCEL); - - return 0; -} - -namespace { - void get_own_stackinfo(void **stack_addr, size_t *stack_size) { - auto fp = fopen("/proc/self/maps", "r"); - if (!fp) { - mlibc::infoLogger() << "mlibc pthreads: /proc/self/maps does not exist! Producing incorrect" - " stack results!" << frg::endlog; - return; - } - - char line[256]; - auto sp = mlibc::get_sp(); - while (fgets(line, 256, fp)) { - uintptr_t from, to; - if(sscanf(line, "%" SCNxPTR "-%" SCNxPTR, &from, &to) != 2) - continue; - if (sp < to && sp > from) { - // We need to return the lowest byte of the stack. - *stack_addr = reinterpret_cast<void*>(from); - *stack_size = to - from; - fclose(fp); - return; - } - } - - fclose(fp); - } -} - -int pthread_getattr_np(pthread_t thread, pthread_attr_t *attr) { - auto tcb = reinterpret_cast<Tcb*>(thread); - *attr = pthread_attr_t{}; - - if (!tcb->stackAddr || !tcb->stackSize) { - get_own_stackinfo(&attr->__mlibc_stackaddr, &attr->__mlibc_stacksize); - } else { - attr->__mlibc_stacksize = tcb->stackSize; - attr->__mlibc_stackaddr = tcb->stackAddr; - } - - attr->__mlibc_guardsize = tcb->guardSize; - attr->__mlibc_detachstate = tcb->isJoinable ? PTHREAD_CREATE_JOINABLE : PTHREAD_CREATE_DETACHED; - mlibc::infoLogger() << "pthread_getattr_np(): Implementation is incomplete!" << frg::endlog; - return 0; -} - -int pthread_getaffinity_np(pthread_t thread, size_t cpusetsize, cpu_set_t *mask) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_getthreadaffinity, ENOSYS); - return mlibc::sys_getthreadaffinity(reinterpret_cast<Tcb*>(thread)->tid, cpusetsize, mask); -} - -int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize, const cpu_set_t *mask) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_setthreadaffinity, ENOSYS); - return mlibc::sys_setthreadaffinity(reinterpret_cast<Tcb*>(thread)->tid, cpusetsize, mask); -} -#endif // __MLIBC_LINUX_OPTION - -extern "C" Tcb *__rtdl_allocateTcb(); - -// pthread functions. -int pthread_create(pthread_t *__restrict thread, const pthread_attr_t *__restrict attrp, - void *(*entry) (void *), void *__restrict user_arg) { - return mlibc::thread_create(thread, attrp, reinterpret_cast<void *>(entry), user_arg, false); -} - -pthread_t pthread_self(void) { - return reinterpret_cast<pthread_t>(mlibc::get_current_tcb()); -} - -int pthread_equal(pthread_t t1, pthread_t t2) { - if(t1 == t2) - return 1; - return 0; -} - -namespace { - struct key_global_info { - bool in_use; - - void (*dtor)(void *); - uint64_t generation; - }; - - constinit frg::array< - key_global_info, - PTHREAD_KEYS_MAX - > key_globals_{}; - - FutexLock key_mutex_; -} - -namespace mlibc { - __attribute__ ((__noreturn__)) void do_exit() { - sys_thread_exit(); - __builtin_unreachable(); - } -} - -__attribute__ ((__noreturn__)) void pthread_exit(void *ret_val) { - auto self = mlibc::get_current_tcb(); - - if (__atomic_load_n(&self->cancelBits, __ATOMIC_RELAXED) & tcbExitingBit) - mlibc::do_exit(); - - __atomic_fetch_or(&self->cancelBits, tcbExitingBit, __ATOMIC_RELAXED); - - auto hand = self->cleanupEnd; - while (hand) { - auto old = hand; - hand->func(hand->arg); - hand = hand->prev; - frg::destruct(getAllocator(), old); - } - - for (size_t j = 0; j < PTHREAD_DESTRUCTOR_ITERATIONS; j++) { - for (size_t i = 0; i < PTHREAD_KEYS_MAX; i++) { - if (auto v = pthread_getspecific(i)) { - key_mutex_.lock(); - auto dtor = key_globals_[i].dtor; - key_mutex_.unlock(); - - if (dtor) { - dtor(v); - (*self->localKeys)[i].value = nullptr; - } - } - } - } - - self->returnValue.voidPtr = ret_val; - __atomic_store_n(&self->didExit, 1, __ATOMIC_RELEASE); - mlibc::sys_futex_wake(&self->didExit); - - // TODO: clean up thread resources when we are detached. - - // TODO: do exit(0) when we're the only thread instead - mlibc::do_exit(); -} - -int pthread_join(pthread_t thread, void **ret) { - return mlibc::thread_join(thread, ret); -} - -int pthread_detach(pthread_t thread) { - auto tcb = reinterpret_cast<Tcb*>(thread); - if (!__atomic_load_n(&tcb->isJoinable, __ATOMIC_RELAXED)) - return EINVAL; - - int expected = 1; - if(!__atomic_compare_exchange_n(&tcb->isJoinable, &expected, 0, false, __ATOMIC_RELEASE, - __ATOMIC_RELAXED)) - return EINVAL; - - return 0; -} - -void pthread_cleanup_push(void (*func) (void *), void *arg) { - auto self = mlibc::get_current_tcb(); - - auto hand = frg::construct<Tcb::CleanupHandler>(getAllocator()); - hand->func = func; - hand->arg = arg; - hand->next = nullptr; - hand->prev = self->cleanupEnd; - - if (self->cleanupEnd) - self->cleanupEnd->next = hand; - - self->cleanupEnd = hand; - - if (!self->cleanupBegin) - self->cleanupBegin = self->cleanupEnd; -} - -void pthread_cleanup_pop(int execute) { - auto self = mlibc::get_current_tcb(); - - auto hand = self->cleanupEnd; - - if (self->cleanupEnd) - self->cleanupEnd = self->cleanupEnd->prev; - if (self->cleanupEnd) - self->cleanupEnd->next = nullptr; - - if (execute) - hand->func(hand->arg); - - frg::destruct(getAllocator(), hand); -} - -int pthread_setname_np(pthread_t thread, const char *name) { - auto tcb = reinterpret_cast<Tcb*>(thread); - - auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_thread_setname, ENOSYS); - if(int e = sysdep(tcb, name); e) { - return e; - } - - return 0; -} - -int pthread_getname_np(pthread_t thread, char *name, size_t size) { - auto tcb = reinterpret_cast<Tcb*>(thread); - - auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_thread_getname, ENOSYS); - if(int e = sysdep(tcb, name, size); e) { - return e; - } - - return 0; -} - -int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param) { - auto tcb = reinterpret_cast<Tcb*>(thread); - - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_setschedparam, ENOSYS); - if(int e = mlibc::sys_setschedparam(tcb, policy, param); e) { - return e; - } - - return 0; -} - -int pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *param) { - auto tcb = reinterpret_cast<Tcb*>(thread); - - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_getschedparam, ENOSYS); - if(int e = mlibc::sys_getschedparam(tcb, policy, param); e) { - return e; - } - - return 0; -} - -//pthread cancel functions - -extern "C" void __mlibc_do_cancel() { - //TODO(geert): for now the same as pthread_exit() - pthread_exit(PTHREAD_CANCELED); -} - -namespace { - - void sigcancel_handler(int signal, siginfo_t *info, void *ucontext) { - ucontext_t *uctx = static_cast<ucontext_t*>(ucontext); - // The function could be called from other signals, or from another - // process, in which case we should do nothing. - if (signal != SIGCANCEL || info->si_pid != getpid() || - info->si_code != SI_TKILL) - return; - - auto tcb = reinterpret_cast<Tcb*>(mlibc::get_current_tcb()); - int old_value = tcb->cancelBits; - - /* - * When a thread is marked with deferred cancellation and performs a blocking syscall, - * the spec mandates that the syscall can get interrupted before it has caused any side - * effects (e.g. before a read() has read any bytes from disk). If the syscall has - * already caused side effects it should return its partial work, and set the program - * counter just after the syscall. If the syscall hasn't caused any side effects, it - * should fail with EINTR and set the program counter to the syscall instruction. - * - * cancellable_syscall: - * test whether_a_cancel_is_queued - * je cancel - * syscall - * end_cancellable_syscall - * - * The mlibc::sys_before_cancellable_syscall sysdep should return 1 when the - * program counter is between the 'canellable_syscall' and 'end_cancellable_syscall' label. - */ - if (!(old_value & tcbCancelAsyncBit) && - mlibc::sys_before_cancellable_syscall && !mlibc::sys_before_cancellable_syscall(uctx)) - return; - - int bitmask = tcbCancelTriggerBit | tcbCancelingBit; - while (1) { - int new_value = old_value | bitmask; - - // Check if we are already cancelled or exiting - if (old_value == new_value || old_value & tcbExitingBit) - return; - - int current_value = old_value; - if (__atomic_compare_exchange_n(&tcb->cancelBits, ¤t_value, - new_value, true,__ATOMIC_RELAXED, __ATOMIC_RELAXED)) { - tcb->returnValue.voidPtr = PTHREAD_CANCELED; - - // Perform cancellation - __mlibc_do_cancel(); - - break; - } - - old_value = current_value; - } - } -} - -namespace mlibc { -namespace { - -struct PthreadSignalInstaller { - PthreadSignalInstaller() { - struct sigaction sa; - sa.sa_sigaction = sigcancel_handler; - sa.sa_flags = SA_SIGINFO; - auto e = ENOSYS; - if(sys_sigaction) - e = sys_sigaction(SIGCANCEL, &sa, NULL); - // Opt-out of cancellation support. - if(e == ENOSYS) - return; - __ensure(!e); - } -}; - -PthreadSignalInstaller pthread_signal_installer; - -} // anonymous namespace -} // namespace mlibc - -int pthread_setcanceltype(int type, int *oldtype) { - if (type != PTHREAD_CANCEL_DEFERRED && type != PTHREAD_CANCEL_ASYNCHRONOUS) - return EINVAL; - - auto self = reinterpret_cast<Tcb *>(mlibc::get_current_tcb()); - int old_value = self->cancelBits; - while (1) { - int new_value = old_value & ~tcbCancelAsyncBit; - if (type == PTHREAD_CANCEL_ASYNCHRONOUS) - new_value |= tcbCancelAsyncBit; - - if (oldtype) - *oldtype = ((old_value & tcbCancelAsyncBit) - ? PTHREAD_CANCEL_ASYNCHRONOUS - : PTHREAD_CANCEL_DEFERRED); - - // Avoid unecessary atomic op. - if (old_value == new_value) - break; - - int current_value = old_value; - if (__atomic_compare_exchange_n(&self->cancelBits, ¤t_value, - new_value, true, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) { - - if (mlibc::tcb_async_cancelled(new_value)) - __mlibc_do_cancel(); - - break; - } - - old_value = current_value; - } - - return 0; -} -int pthread_setcancelstate(int state, int *oldstate) { - if (state != PTHREAD_CANCEL_ENABLE && state != PTHREAD_CANCEL_DISABLE) - return EINVAL; - - auto self = reinterpret_cast<Tcb *>(mlibc::get_current_tcb()); - int old_value = self->cancelBits; - while (1) { - int new_value = old_value & ~tcbCancelEnableBit; - if (state == PTHREAD_CANCEL_ENABLE) - new_value |= tcbCancelEnableBit; - - if (oldstate) - *oldstate = ((old_value & tcbCancelEnableBit) - ? PTHREAD_CANCEL_ENABLE - : PTHREAD_CANCEL_DISABLE); - - // Avoid unecessary atomic op. - if (old_value == new_value) - break; - - int current_value = old_value; - if (__atomic_compare_exchange_n(&self->cancelBits, ¤t_value, - new_value, true, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) { - - if (mlibc::tcb_async_cancelled(new_value)) - __mlibc_do_cancel(); - - sigset_t set = {}; - sigaddset(&set, SIGCANCEL); - if (new_value & PTHREAD_CANCEL_ENABLE) - sigprocmask(SIG_UNBLOCK, &set, NULL); - else - sigprocmask(SIG_BLOCK, &set, NULL); - break; - } - - old_value = current_value; - } - - return 0; -} -void pthread_testcancel(void) { - auto self = reinterpret_cast<Tcb *>(mlibc::get_current_tcb()); - int value = self->cancelBits; - if ((value & tcbCancelEnableBit) && (value & tcbCancelTriggerBit)) { - __mlibc_do_cancel(); - __builtin_unreachable(); - } -} -int pthread_cancel(pthread_t thread) { - if (!mlibc::sys_tgkill) { - MLIBC_MISSING_SYSDEP(); - return ENOSYS; - } - - auto tcb = reinterpret_cast<Tcb *>(thread); - // Check if the TCB is valid, somewhat.. - if (tcb->selfPointer != tcb) - return ESRCH; - - int old_value = __atomic_load_n(&tcb->cancelBits, __ATOMIC_RELAXED); - while (1) { - int bitmask = tcbCancelTriggerBit; - - int new_value = old_value | bitmask; - if (old_value == new_value) - break; - - int current_value = old_value; - if (__atomic_compare_exchange_n(&tcb->cancelBits, ¤t_value, - new_value, true, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) { - if (mlibc::tcb_cancel_enabled(new_value)) { - pid_t pid = getpid(); - - int res = mlibc::sys_tgkill(pid, tcb->tid, SIGCANCEL); - - current_value = __atomic_load_n(&tcb->cancelBits, __ATOMIC_RELAXED); - - // If we can't find the thread anymore, it's possible that it exited between - // us setting the cancel trigger bit, and us sending the signal. Check the - // cancelBits for tcbExitingBit to confirm that. - // XXX(qookie): This will be an use-after-free once we start freeing TCBs on - // exit. Perhaps the TCB should be refcounted. - if (!(res == ESRCH && (current_value & tcbExitingBit))) - return res; - } - - break; - } - - old_value = current_value; - } - - return 0; -} - -int pthread_atfork(void (*prepare) (void), void (*parent) (void), void (*child) (void)) { - auto self = mlibc::get_current_tcb(); - - auto hand = frg::construct<Tcb::AtforkHandler>(getAllocator()); - if (!hand) - return -1; - - hand->prepare = prepare; - hand->parent = parent; - hand->child = child; - hand->next = nullptr; - hand->prev = self->atforkEnd; - - if (self->atforkEnd) - self->atforkEnd->next = hand; - - self->atforkEnd = hand; - - if (!self->atforkBegin) - self->atforkBegin = self->atforkEnd; - - return 0; -} - -// ---------------------------------------------------------------------------- -// pthread_key functions. -// ---------------------------------------------------------------------------- - -int pthread_key_create(pthread_key_t *out, void (*destructor)(void *)) { - SCOPE_TRACE(); - - auto g = frg::guard(&key_mutex_); - - pthread_key_t key = PTHREAD_KEYS_MAX; - for (size_t i = 0; i < PTHREAD_KEYS_MAX; i++) { - if (!key_globals_[i].in_use) { - key = i; - break; - } - } - - if (key == PTHREAD_KEYS_MAX) - return EAGAIN; - - key_globals_[key].in_use = true; - key_globals_[key].dtor = destructor; - - *out = key; - - return 0; -} - -int pthread_key_delete(pthread_key_t key) { - SCOPE_TRACE(); - - auto g = frg::guard(&key_mutex_); - - if (key >= PTHREAD_KEYS_MAX || !key_globals_[key].in_use) - return EINVAL; - - key_globals_[key].in_use = false; - key_globals_[key].dtor = nullptr; - key_globals_[key].generation++; - - return 0; -} - -void *pthread_getspecific(pthread_key_t key) { - SCOPE_TRACE(); - - auto self = mlibc::get_current_tcb(); - auto g = frg::guard(&key_mutex_); - - if (key >= PTHREAD_KEYS_MAX || !key_globals_[key].in_use) - return nullptr; - - if (key_globals_[key].generation > (*self->localKeys)[key].generation) { - (*self->localKeys)[key].value = nullptr; - (*self->localKeys)[key].generation = key_globals_[key].generation; - } - - return (*self->localKeys)[key].value; -} - -int pthread_setspecific(pthread_key_t key, const void *value) { - SCOPE_TRACE(); - - auto self = mlibc::get_current_tcb(); - auto g = frg::guard(&key_mutex_); - - if (key >= PTHREAD_KEYS_MAX || !key_globals_[key].in_use) - return EINVAL; - - (*self->localKeys)[key].value = const_cast<void *>(value); - (*self->localKeys)[key].generation = key_globals_[key].generation; - - return 0; -} - -// ---------------------------------------------------------------------------- -// pthread_once functions. -// ---------------------------------------------------------------------------- - -static constexpr unsigned int onceComplete = 1; -static constexpr unsigned int onceLocked = 2; - -int pthread_once(pthread_once_t *once, void (*function) (void)) { - SCOPE_TRACE(); - - auto expected = __atomic_load_n(&once->__mlibc_done, __ATOMIC_ACQUIRE); - - // fast path: the function was already run. - while(!(expected & onceComplete)) { - if(!expected) { - // try to acquire the mutex. - if(!__atomic_compare_exchange_n(&once->__mlibc_done, - &expected, onceLocked, false, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE)) - continue; - - function(); - - // unlock the mutex. - __atomic_exchange_n(&once->__mlibc_done, onceComplete, __ATOMIC_RELEASE); - if(int e = mlibc::sys_futex_wake((int *)&once->__mlibc_done); e) - __ensure(!"sys_futex_wake() failed"); - return 0; - }else{ - // a different thread is currently running the initializer. - __ensure(expected == onceLocked); - if(int e = mlibc::sys_futex_wait((int *)&once->__mlibc_done, onceLocked, nullptr); e) - __ensure(!"sys_futex_wait() failed"); - expected = __atomic_load_n(&once->__mlibc_done, __ATOMIC_ACQUIRE); - } - } - - return 0; -} - -// ---------------------------------------------------------------------------- -// pthread_mutexattr and pthread_mutex functions. -// ---------------------------------------------------------------------------- - -// pthread_mutexattr functions -int pthread_mutexattr_init(pthread_mutexattr_t *attr) { - SCOPE_TRACE(); - return mlibc::thread_mutexattr_init(attr); -} - -int pthread_mutexattr_destroy(pthread_mutexattr_t *attr) { - SCOPE_TRACE(); - return mlibc::thread_mutexattr_destroy(attr); -} - -int pthread_mutexattr_gettype(const pthread_mutexattr_t *__restrict attr, int *__restrict type) { - return mlibc::thread_mutexattr_gettype(attr, type); -} - -int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type) { - return mlibc::thread_mutexattr_settype(attr, type); -} - -int pthread_mutexattr_getrobust(const pthread_mutexattr_t *__restrict attr, - int *__restrict robust) { - *robust = attr->__mlibc_robust; - return 0; -} -int pthread_mutexattr_setrobust(pthread_mutexattr_t *attr, int robust) { - if (robust != PTHREAD_MUTEX_STALLED && robust != PTHREAD_MUTEX_ROBUST) - return EINVAL; - - attr->__mlibc_robust = robust; - return 0; -} - -int pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr, int *pshared) { - *pshared = attr->__mlibc_pshared; - return 0; -} -int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared) { - if (pshared != PTHREAD_PROCESS_PRIVATE && pshared != PTHREAD_PROCESS_SHARED) - return EINVAL; - - attr->__mlibc_pshared = pshared; - return 0; -} - -int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *__restrict attr, - int *__restrict protocol) { - *protocol = attr->__mlibc_protocol; - return 0; -} - -int pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, int protocol) { - if (protocol != PTHREAD_PRIO_NONE && protocol != PTHREAD_PRIO_INHERIT - && protocol != PTHREAD_PRIO_PROTECT) - return EINVAL; - - attr->__mlibc_protocol = protocol; - return 0; -} - -int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *__restrict attr, - int *__restrict prioceiling) { - (void)attr; - (void)prioceiling; - return EINVAL; -} - -int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr, int prioceiling) { - (void)attr; - (void)prioceiling; - return EINVAL; -} - -// pthread_mutex functions -int pthread_mutex_init(pthread_mutex_t *__restrict mutex, - const pthread_mutexattr_t *__restrict attr) { - SCOPE_TRACE(); - - return mlibc::thread_mutex_init(mutex, attr); -} - -int pthread_mutex_destroy(pthread_mutex_t *mutex) { - return mlibc::thread_mutex_destroy(mutex); -} - -int pthread_mutex_lock(pthread_mutex_t *mutex) { - SCOPE_TRACE(); - - return mlibc::thread_mutex_lock(mutex); -} - -int pthread_mutex_trylock(pthread_mutex_t *mutex) { - SCOPE_TRACE(); - - unsigned int this_tid = mlibc::this_tid(); - unsigned int expected = __atomic_load_n(&mutex->__mlibc_state, __ATOMIC_RELAXED); - if(!expected) { - // Try to take the mutex here. - if(__atomic_compare_exchange_n(&mutex->__mlibc_state, - &expected, this_tid, false, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE)) { - __ensure(!mutex->__mlibc_recursion); - mutex->__mlibc_recursion = 1; - return 0; - } - } else { - // If this (recursive) mutex is already owned by us, increment the recursion level. - if((expected & mutex_owner_mask) == this_tid) { - if(!(mutex->__mlibc_flags & mutexRecursive)) { - return EBUSY; - } - ++mutex->__mlibc_recursion; - return 0; - } - } - - return EBUSY; -} - -int pthread_mutex_timedlock(pthread_mutex_t *__restrict, - const struct timespec *__restrict) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int pthread_mutex_unlock(pthread_mutex_t *mutex) { - SCOPE_TRACE(); - - return mlibc::thread_mutex_unlock(mutex); -} - -int pthread_mutex_consistent(pthread_mutex_t *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -// ---------------------------------------------------------------------------- -// pthread_condattr and pthread_cond functions. -// ---------------------------------------------------------------------------- - -int pthread_condattr_init(pthread_condattr_t *attr) { - attr->__mlibc_pshared = PTHREAD_PROCESS_PRIVATE; - attr->__mlibc_clock = CLOCK_REALTIME; - return 0; -} - -int pthread_condattr_destroy(pthread_condattr_t *attr) { - memset(attr, 0, sizeof(*attr)); - return 0; -} - -int pthread_condattr_getclock(const pthread_condattr_t *__restrict attr, - clockid_t *__restrict clock) { - *clock = attr->__mlibc_clock; - return 0; -} - -int pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clock) { - if (clock != CLOCK_REALTIME && clock != CLOCK_MONOTONIC - && clock != CLOCK_MONOTONIC_RAW && clock != CLOCK_REALTIME_COARSE - && clock != CLOCK_MONOTONIC_COARSE && clock != CLOCK_BOOTTIME) - return EINVAL; - - attr->__mlibc_clock = clock; - return 0; -} - -int pthread_condattr_getpshared(const pthread_condattr_t *__restrict attr, - int *__restrict pshared) { - *pshared = attr->__mlibc_pshared; - return 0; -} - -int pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared) { - if (pshared != PTHREAD_PROCESS_PRIVATE && pshared != PTHREAD_PROCESS_SHARED) - return EINVAL; - - attr->__mlibc_pshared = pshared; - return 0; -} - -int pthread_cond_init(pthread_cond_t *__restrict cond, const pthread_condattr_t *__restrict attr) { - SCOPE_TRACE(); - - return mlibc::thread_cond_init(cond, attr); -} - -int pthread_cond_destroy(pthread_cond_t *cond) { - SCOPE_TRACE(); - - return mlibc::thread_cond_destroy(cond); -} - -int pthread_cond_wait(pthread_cond_t *__restrict cond, pthread_mutex_t *__restrict mutex) { - return pthread_cond_timedwait(cond, mutex, nullptr); -} - -int pthread_cond_timedwait(pthread_cond_t *__restrict cond, pthread_mutex_t *__restrict mutex, - const struct timespec *__restrict abstime) { - return mlibc::thread_cond_timedwait(cond, mutex, abstime); -} - -int pthread_cond_signal(pthread_cond_t *cond) { - SCOPE_TRACE(); - - return pthread_cond_broadcast(cond); -} - -int pthread_cond_broadcast(pthread_cond_t *cond) { - SCOPE_TRACE(); - - return mlibc::thread_cond_broadcast(cond); -} - -// ---------------------------------------------------------------------------- -// pthread_barrierattr and pthread_barrier functions. -// ---------------------------------------------------------------------------- - -int pthread_barrierattr_init(pthread_barrierattr_t *attr) { - attr->__mlibc_pshared = PTHREAD_PROCESS_PRIVATE; - return 0; -} - -int pthread_barrierattr_getpshared(const pthread_barrierattr_t *__restrict attr, - int *__restrict pshared) { - *pshared = attr->__mlibc_pshared; - return 0; -} - -int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared) { - if (pshared != PTHREAD_PROCESS_SHARED && pshared != PTHREAD_PROCESS_PRIVATE) - return EINVAL; - - attr->__mlibc_pshared = pshared; - return 0; -} - -int pthread_barrierattr_destroy(pthread_barrierattr_t *) { - return 0; -} - -int pthread_barrier_init(pthread_barrier_t *__restrict barrier, - const pthread_barrierattr_t *__restrict attr, unsigned count) { - if (count == 0) - return EINVAL; - - barrier->__mlibc_waiting = 0; - barrier->__mlibc_inside = 0; - barrier->__mlibc_seq = 0; - barrier->__mlibc_count = count; - - // Since we don't implement these yet, set a flag to error later. - auto pshared = attr ? attr->__mlibc_pshared : PTHREAD_PROCESS_PRIVATE; - barrier->__mlibc_flags = pshared; - - return 0; -} - -int pthread_barrier_destroy(pthread_barrier_t *barrier) { - // Wait until there are no threads still using the barrier. - unsigned inside = 0; - do { - unsigned expected = __atomic_load_n(&barrier->__mlibc_inside, __ATOMIC_RELAXED); - if (expected == 0) - break; - - int e = mlibc::sys_futex_wait((int *)&barrier->__mlibc_inside, expected, nullptr); - if (e != 0 && e != EAGAIN && e != EINTR) - mlibc::panicLogger() << "mlibc: sys_futex_wait() returned error " << e << frg::endlog; - } while (inside > 0); - - memset(barrier, 0, sizeof *barrier); - return 0; -} - -int pthread_barrier_wait(pthread_barrier_t *barrier) { - if (barrier->__mlibc_flags != 0) { - mlibc::panicLogger() << "mlibc: pthread_barrier_t flags were non-zero" - << frg::endlog; - } - - // inside is incremented on entry and decremented on exit. - // This is used to synchronise with pthread_barrier_destroy, to ensure that a thread doesn't pass - // the barrier and immediately destroy its state while other threads still rely on it. - - __atomic_fetch_add(&barrier->__mlibc_inside, 1, __ATOMIC_ACQUIRE); - - auto leave = [&](){ - unsigned inside = __atomic_sub_fetch(&barrier->__mlibc_inside, 1, __ATOMIC_RELEASE); - if (inside == 0) - mlibc::sys_futex_wake((int *)&barrier->__mlibc_inside); - }; - - unsigned seq = __atomic_load_n(&barrier->__mlibc_seq, __ATOMIC_ACQUIRE); - - while (true) { - unsigned expected = __atomic_load_n(&barrier->__mlibc_waiting, __ATOMIC_RELAXED); - bool swapped = __atomic_compare_exchange_n(&barrier->__mlibc_waiting, &expected, expected + 1, false, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE); - - if (swapped) { - if (expected + 1 == barrier->__mlibc_count) { - // We were the last thread to hit the barrier. Reset waiters and wake the others. - __atomic_fetch_add(&barrier->__mlibc_seq, 1, __ATOMIC_ACQUIRE); - __atomic_store_n(&barrier->__mlibc_waiting, 0, __ATOMIC_RELEASE); - - mlibc::sys_futex_wake((int *)&barrier->__mlibc_seq); - - leave(); - return PTHREAD_BARRIER_SERIAL_THREAD; - } - - while (true) { - int e = mlibc::sys_futex_wait((int *)&barrier->__mlibc_seq, seq, nullptr); - if (e != 0 && e != EAGAIN && e != EINTR) - mlibc::panicLogger() << "mlibc: sys_futex_wait() returned error " << e << frg::endlog; - - unsigned newSeq = __atomic_load_n(&barrier->__mlibc_seq, __ATOMIC_ACQUIRE); - if (newSeq > seq) { - leave(); - return 0; - } - } - } - } -} - -// ---------------------------------------------------------------------------- -// pthread_rwlock functions. -// ---------------------------------------------------------------------------- - -namespace { - void rwlock_m_lock(pthread_rwlock_t *rw, bool excl) { - unsigned int m_expected = __atomic_load_n(&rw->__mlibc_m, __ATOMIC_RELAXED); - while(true) { - if(m_expected) { - __ensure(m_expected & mutex_owner_mask); - - // Try to set the waiters bit. - if(!(m_expected & mutex_waiters_bit)) { - unsigned int desired = m_expected | mutex_waiters_bit; - if(!__atomic_compare_exchange_n(&rw->__mlibc_m, - &m_expected, desired, false, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) - continue; - } - - // Wait on the futex. - mlibc::sys_futex_wait((int *)&rw->__mlibc_m, m_expected | mutex_waiters_bit, nullptr); - - // Opportunistically try to take the lock after we wake up. - m_expected = 0; - }else{ - // Try to lock the mutex. - unsigned int desired = 1; - if(excl) - desired |= mutex_excl_bit; - if(__atomic_compare_exchange_n(&rw->__mlibc_m, - &m_expected, desired, false, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) - break; - } - } - } - - int rwlock_m_trylock(pthread_rwlock_t *rw, bool excl) { - unsigned int m_expected = __atomic_load_n(&rw->__mlibc_m, __ATOMIC_RELAXED); - if(!m_expected) { - // Try to lock the mutex. - unsigned int desired = 1; - if(excl) - desired |= mutex_excl_bit; - if(__atomic_compare_exchange_n(&rw->__mlibc_m, - &m_expected, desired, false, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) - return 0; - } - - __ensure(m_expected & mutex_owner_mask); - - // POSIX says that this function should never block but also that - // readers should not be blocked by readers. We implement this by returning EAGAIN - // (and not EBUSY) if a reader would block a reader. - if(!excl && !(m_expected & mutex_excl_bit)) - return EAGAIN; - - return EBUSY; - } - - void rwlock_m_unlock(pthread_rwlock_t *rw) { - auto m = __atomic_exchange_n(&rw->__mlibc_m, 0, __ATOMIC_RELEASE); - if(m & mutex_waiters_bit) - mlibc::sys_futex_wake((int *)&rw->__mlibc_m); - } -} - -int pthread_rwlockattr_init(pthread_rwlockattr_t *attr) { - attr->__mlibc_pshared = PTHREAD_PROCESS_PRIVATE; - return 0; -} - -int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *__restrict attr, - int *__restrict pshared) { - *pshared = attr->__mlibc_pshared; - return 0; -} - -int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared) { - if (pshared != PTHREAD_PROCESS_SHARED && pshared != PTHREAD_PROCESS_PRIVATE) - return EINVAL; - - attr->__mlibc_pshared = pshared; - return 0; -} - -int pthread_rwlockattr_destroy(pthread_rwlockattr_t *) { - return 0; -} - -int pthread_rwlock_init(pthread_rwlock_t *__restrict rw, const pthread_rwlockattr_t *__restrict attr) { - SCOPE_TRACE(); - rw->__mlibc_m = 0; - rw->__mlibc_rc = 0; - - // Since we don't implement this yet, set a flag to error later. - auto pshared = attr ? attr->__mlibc_pshared : PTHREAD_PROCESS_PRIVATE; - rw->__mlibc_flags = pshared; - return 0; -} - -int pthread_rwlock_destroy(pthread_rwlock_t *rw) { - __ensure(!rw->__mlibc_m); - __ensure(!rw->__mlibc_rc); - return 0; -} - -int pthread_rwlock_trywrlock(pthread_rwlock_t *rw) { - SCOPE_TRACE(); - - if (rw->__mlibc_flags != 0) { - mlibc::panicLogger() << "mlibc: pthread_rwlock_t flags were non-zero" - << frg::endlog; - } - - // Take the __mlibc_m mutex. - // Will be released in pthread_rwlock_unlock(). - if(int e = rwlock_m_trylock(rw, true)) - return e; - - // Check that there are no readers. - unsigned int rc_expected = __atomic_load_n(&rw->__mlibc_rc, __ATOMIC_ACQUIRE); - if(rc_expected) { - rwlock_m_unlock(rw); - return EBUSY; - } - - return 0; -} - -int pthread_rwlock_wrlock(pthread_rwlock_t *rw) { - SCOPE_TRACE(); - - if (rw->__mlibc_flags != 0) { - mlibc::panicLogger() << "mlibc: pthread_rwlock_t flags were non-zero" - << frg::endlog; - } - - // Take the __mlibc_m mutex. - // Will be released in pthread_rwlock_unlock(). - rwlock_m_lock(rw, true); - - // Now wait until there are no more readers. - unsigned int rc_expected = __atomic_load_n(&rw->__mlibc_rc, __ATOMIC_ACQUIRE); - while(true) { - if(!rc_expected) - break; - - __ensure(rc_expected & rc_count_mask); - - // Try to set the waiters bit. - if(!(rc_expected & rc_waiters_bit)) { - unsigned int desired = rc_expected | rc_count_mask; - if(!__atomic_compare_exchange_n(&rw->__mlibc_rc, - &rc_expected, desired, false, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE)) - continue; - } - - // Wait on the futex. - mlibc::sys_futex_wait((int *)&rw->__mlibc_rc, rc_expected | rc_waiters_bit, nullptr); - - // Re-check the reader counter. - rc_expected = __atomic_load_n(&rw->__mlibc_rc, __ATOMIC_ACQUIRE); - } - - return 0; -} - -int pthread_rwlock_tryrdlock(pthread_rwlock_t *rw) { - SCOPE_TRACE(); - - if (rw->__mlibc_flags != 0) { - mlibc::panicLogger() << "mlibc: pthread_rwlock_t flags were non-zero" - << frg::endlog; - } - - // Increment the reader count while holding the __mlibc_m mutex. - if(int e = rwlock_m_trylock(rw, false); e) - return e; - __atomic_fetch_add(&rw->__mlibc_rc, 1, __ATOMIC_ACQUIRE); - rwlock_m_unlock(rw); - - return 0; -} - -int pthread_rwlock_rdlock(pthread_rwlock_t *rw) { - SCOPE_TRACE(); - - if (rw->__mlibc_flags != 0) { - mlibc::panicLogger() << "mlibc: pthread_rwlock_t flags were non-zero" - << frg::endlog; - } - - // Increment the reader count while holding the __mlibc_m mutex. - rwlock_m_lock(rw, false); - __atomic_fetch_add(&rw->__mlibc_rc, 1, __ATOMIC_ACQUIRE); - rwlock_m_unlock(rw); - - return 0; -} - -int pthread_rwlock_unlock(pthread_rwlock_t *rw) { - SCOPE_TRACE(); - - unsigned int rc_expected = __atomic_load_n(&rw->__mlibc_rc, __ATOMIC_RELAXED); - if(!rc_expected) { - // We are doing a write-unlock. - rwlock_m_unlock(rw); - return 0; - }else{ - // We are doing a read-unlock. - while(true) { - unsigned int count = rc_expected & rc_count_mask; - __ensure(count); - - // Try to decrement the count. - if(count == 1 && (rc_expected & rc_waiters_bit)) { - unsigned int desired = 0; - if(!__atomic_compare_exchange_n(&rw->__mlibc_rc, - &rc_expected, desired, false, __ATOMIC_RELEASE, __ATOMIC_RELAXED)) - continue; - - // Wake the futex. - mlibc::sys_futex_wake((int *)&rw->__mlibc_rc); - break; - }else{ - unsigned int desired = (rc_expected & ~rc_count_mask) | (count - 1); - if(!__atomic_compare_exchange_n(&rw->__mlibc_rc, - &rc_expected, desired, false, __ATOMIC_RELEASE, __ATOMIC_RELAXED)) - continue; - break; - } - } - - return 0; - } -} - -int pthread_getcpuclockid(pthread_t, clockid_t *) { - mlibc::infoLogger() << "mlibc: pthread_getcpuclockid() always returns ENOENT" - << frg::endlog; - return ENOENT; -} diff --git a/lib/mlibc/options/posix/generic/pwd-stubs.cpp b/lib/mlibc/options/posix/generic/pwd-stubs.cpp deleted file mode 100644 index 5d8f618..0000000 --- a/lib/mlibc/options/posix/generic/pwd-stubs.cpp +++ /dev/null @@ -1,284 +0,0 @@ - -#include <errno.h> -#include <pwd.h> -#include <stdio.h> -#include <stdlib.h> -#include <bits/ensure.h> - -#include <mlibc/debug.hpp> - -namespace { - FILE *global_file; // Used by setpwent/getpwent/endpwent. - - bool open_global_file() { - if(!global_file) { - global_file = fopen("/etc/passwd", "r"); - if(!global_file) { - errno = EIO; - return false; - } - } - - return true; - } - - void close_global_file() { - if(global_file) { - fclose(global_file); - global_file = nullptr; - } - } - - bool extract_entry(frg::string_view line, passwd *entry) { - frg::string_view segments[8]; - - // Parse the line into 7 or 8 segments. - size_t s = 0; - int n; - for(n = 0; n < 7; n++) { - size_t d = line.find_first(':', s); - if(d == size_t(-1)) - break; - segments[n] = line.sub_string(s, d - s); - s = d + 1; - } - if(line.find_first(':', s) != size_t(-1)) - return false; - segments[n] = line.sub_string(s, line.size() - s); - n++; - - if(n < 7) - return false; - - // TODO: Handle strndup() failure. - auto name = strndup(segments[0].data(), segments[0].size()); - __ensure(name); - - auto passwd = strndup(segments[1].data(), segments[1].size()); - __ensure(passwd); - - auto uid = segments[2].to_number<int>(); - if(!uid) - return false; - auto gid = segments[3].to_number<int>(); - if(!gid) - return false; - - auto real_name = strndup(segments[4].data(), segments[4].size()); - __ensure(real_name); - auto dir = strndup(segments[5].data(), segments[5].size()); - __ensure(dir); - auto shell = strndup(segments[6].data(), segments[6].size()); - __ensure(shell); - - // Chop the newline off the end of shell - __ensure(strlen(shell) > 0); - shell[strlen(shell) - 1] = '\0'; - - entry->pw_name = name; - entry->pw_passwd = passwd; - entry->pw_uid = *uid; - entry->pw_gid = *gid; - entry->pw_dir = dir; - entry->pw_shell = shell; - entry->pw_gecos = real_name; - return true; - } - - void copy_to_buffer(passwd *pwd, char *buffer, size_t size) { - char *pw_dir = stpcpy(buffer, pwd->pw_name) + 1; - free(pwd->pw_name); - pwd->pw_name = buffer; - - char *pw_shell = stpcpy(pw_dir, pwd->pw_dir) + 1; - free(pwd->pw_dir); - pwd->pw_dir = pw_dir; - - char *pw_passwd = stpcpy(pw_shell, pwd->pw_shell) + 1; - free(pwd->pw_shell); - pwd->pw_shell = pw_shell; - - char *end = stpcpy(pw_passwd, pwd->pw_passwd); - __ensure(end <= buffer + size); - free(pwd->pw_passwd); - pwd->pw_passwd = pw_passwd; - } - - void clear_entry(passwd *entry) { - free(entry->pw_name); - free(entry->pw_dir); - free(entry->pw_passwd); - free(entry->pw_shell); - entry->pw_name = nullptr; - entry->pw_dir = nullptr; - entry->pw_passwd = nullptr; - entry->pw_shell = nullptr; - } -} - -struct passwd *getpwent(void) { - static passwd entry; - char line[NSS_BUFLEN_PASSWD]; - - if(!open_global_file()) { - return nullptr; - } - - if (fgets(line, NSS_BUFLEN_PASSWD, global_file)) { - clear_entry(&entry); - if(!extract_entry(line, &entry)) { - errno = EINVAL; // I suppose this can be a valid errno? - return nullptr; - } - return &entry; - } - - if(ferror(global_file)) { - errno = EIO; - } - - return nullptr; -} - -struct passwd *getpwnam(const char *name) { - static passwd entry; - auto file = fopen("/etc/passwd", "r"); - if(!file) - return nullptr; - - char line[NSS_BUFLEN_PASSWD]; - while(fgets(line, NSS_BUFLEN_PASSWD, file)) { - clear_entry(&entry); - if(!extract_entry(line, &entry)) - continue; - if(!strcmp(entry.pw_name, name)) { - fclose(file); - return &entry; - } - } - - int err = errno; - if(ferror(file)) { - err = EIO; - } - - fclose(file); - errno = err; - return nullptr; -} - -int getpwnam_r(const char *name, struct passwd *pwd, char *buffer, size_t size, struct passwd **result) { - *result = nullptr; - auto file = fopen("/etc/passwd", "r"); - if(!file) { - return EIO; - } - - char line[NSS_BUFLEN_PASSWD]; - while(fgets(line, NSS_BUFLEN_PASSWD, file)) { - if(!extract_entry(line, pwd)) - continue; - if(!strcmp(pwd->pw_name, name)) { - fclose(file); - - size_t required_size = strlen(pwd->pw_name) + strlen(pwd->pw_dir) - + strlen(pwd->pw_shell) + strlen(pwd->pw_passwd) + 4; - if (size < required_size) - return ERANGE; - - copy_to_buffer(pwd, buffer, size); - *result = pwd; - return 0; - } - } - - int ret = 0; - if(ferror(file)) { - ret = EIO; - } - - fclose(file); - return ret; -} - -struct passwd *getpwuid(uid_t uid) { - static passwd entry; - auto file = fopen("/etc/passwd", "r"); - if(!file) - return nullptr; - - char line[NSS_BUFLEN_PASSWD]; - while(fgets(line, NSS_BUFLEN_PASSWD, file)) { - clear_entry(&entry); - if(!extract_entry(line, &entry)) - continue; - if(entry.pw_uid == uid) { - fclose(file); - return &entry; - } - } - - int err = ESRCH; - if(ferror(file)) { - err = EIO; - } - - fclose(file); - errno = err; - return nullptr; -} - -int getpwuid_r(uid_t uid, struct passwd *pwd, char *buffer, size_t size, struct passwd **result) { - *result = nullptr; - auto file = fopen("/etc/passwd", "r"); - if(!file) { - return EIO; - } - - char line[NSS_BUFLEN_PASSWD]; - while(fgets(line, NSS_BUFLEN_PASSWD, file)) { - if(!extract_entry(line, pwd)) - continue; - if(pwd->pw_uid == uid) { - fclose(file); - - size_t required_size = strlen(pwd->pw_name) + strlen(pwd->pw_dir) - + strlen(pwd->pw_shell) + + strlen(pwd->pw_passwd) + 4; - if (size < required_size) - return ERANGE; - - copy_to_buffer(pwd, buffer, size); - *result = pwd; - return 0; - } - } - - int ret = 0; - if(ferror(file)) { - ret = EIO; - } - - fclose(file); - return ret; -} - -void setpwent(void) { - if(!open_global_file()) { - return; - } - rewind(global_file); -} - -void endpwent(void) { - close_global_file(); -} - -int putpwent(const struct passwd *, FILE *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -struct passwd *fgetpwent(FILE *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} diff --git a/lib/mlibc/options/posix/generic/resolv_conf.cpp b/lib/mlibc/options/posix/generic/resolv_conf.cpp deleted file mode 100644 index a5c3aa7..0000000 --- a/lib/mlibc/options/posix/generic/resolv_conf.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include <mlibc/resolv_conf.hpp> -#include <mlibc/allocator.hpp> -#include <stdio.h> -#include <ctype.h> - -namespace mlibc { - -frg::optional<struct nameserver_data> get_nameserver() { - auto file = fopen("/etc/resolv.conf", "r"); - if (!file) - return frg::null_opt; - - char line[128]; - struct nameserver_data ret; - while (fgets(line, 128, file)) { - char *pos; - if (!strchr(line, '\n') && !feof(file)) { - // skip truncated lines - for (int c = getc(file); c != '\n' && c != EOF; c = getc(file)); - continue; - } - - // TODO(geert): resolv.conf can actually have multiple nameservers - // but we just pick the first one for now - if (!strncmp(line, "nameserver", 10) && isspace(line[10])) { - char *end; - for (pos = line + 11; isspace(*pos); pos++); - for (end = pos; *end && !isspace(*end); end++); - *end = '\0'; - ret.name = frg::string<MemoryAllocator>( - pos, end - pos, getAllocator()); - break; - } - } - - fclose(file); - if(ret.name.empty()) - return frg::null_opt; - return ret; -} - -} // namespace mlibc diff --git a/lib/mlibc/options/posix/generic/sched-stubs.cpp b/lib/mlibc/options/posix/generic/sched-stubs.cpp deleted file mode 100644 index 9d75d50..0000000 --- a/lib/mlibc/options/posix/generic/sched-stubs.cpp +++ /dev/null @@ -1,50 +0,0 @@ - -#include <bits/ensure.h> -#include <errno.h> -#include <limits.h> -#include <sched.h> - -#include <mlibc/debug.hpp> -#include <mlibc/posix-sysdeps.hpp> - -int sched_yield(void) { - if(mlibc::sys_yield) { - mlibc::sys_yield(); - }else{ - // Missing sched_yield() is not an error. - MLIBC_MISSING_SYSDEP(); - } - return 0; -} - -int sched_get_priority_max(int policy) { - int res = 0; - - auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_get_max_priority, -1); - if(int e = sysdep(policy, &res); e) { - errno = e; - return -1; - } - return res; -} - -int sched_get_priority_min(int policy) { - int res = 0; - - auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_get_min_priority, -1); - if(int e = sysdep(policy, &res); e) { - errno = e; - return -1; - } - return res; -} - -int sched_setscheduler(pid_t, int, const struct sched_param *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int sched_getparam(pid_t, struct sched_param *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} diff --git a/lib/mlibc/options/posix/generic/search.cpp b/lib/mlibc/options/posix/generic/search.cpp deleted file mode 100644 index e6f8c1d..0000000 --- a/lib/mlibc/options/posix/generic/search.cpp +++ /dev/null @@ -1,151 +0,0 @@ - -#include <bits/ensure.h> -#include <search.h> -#include <stddef.h> -#include <new> -#include <mlibc/allocator.hpp> -#include <frg/stack.hpp> -#include <stdlib.h> - -struct node { - const void *key; - void *a[2]; - int h; -}; - -namespace { - int height(struct node *node) { - return node ? node->h : 0; - } - - int rotate(struct node **nodep, int side) { - struct node *node = *nodep; - struct node *x = static_cast<struct node *>(node->a[side]); - struct node *y = static_cast<struct node *>(x->a[!side]); - struct node *z = static_cast<struct node *>(x->a[side]); - - int height_node = node->h; - int height_y = height(y); - if (height_y > height(z)) { - // Perform double rotation - node->a[side] = y->a[!side]; - x->a[!side] = y->a[side]; - y->a[!side] = node; - y->a[side] = x; - node->h = height_y; - x->h = height_y; - y->h = height_y + 1; - } else { - // Perform single rotation - node->a[side] = y; - x->a[!side] = node; - node->h = height_y + 1; - x->h = height_y + 2; - y = x; - - } - *nodep = y; - return y->h - height_node; - } - - int balance_tree(struct node **nodep) { - struct node *node = *nodep; - int height_a = height(static_cast<struct node *>(node->a[0])); - int height_b = height(static_cast<struct node *>(node->a[1])); - if (height_a - height_b < 2) { - int old = node->h; - node->h = height_a < height_b ? height_b + 1 : height_a + 1; - return node->h - old; - } - - return rotate(nodep, height_a < height_b); - } -} - -void *tsearch(const void *key, void **rootp, int(*compar)(const void *, const void *)) { - if (!rootp) - return NULL; - - struct node *n = static_cast<struct node *>(*rootp); - frg::stack<struct node **, MemoryAllocator> nodes(getAllocator()); - nodes.push(reinterpret_cast<struct node **>(rootp)); - int c = 0; - for (;;) { - if (!n) - break; - c = compar(key, n->key); - if (!c) - return n; - nodes.push(reinterpret_cast<struct node **>(&n->a[c > 0])); - n = static_cast<struct node *>(n->a[c > 0]); - } - - struct node *insert = static_cast<struct node*>(malloc(sizeof(struct node))); - if (!insert) - return NULL; - insert->key = key; - insert->a[0] = insert->a[1] = NULL; - insert->h = 1; - - (*nodes.top()) = insert; - nodes.pop(); - while(nodes.size() && balance_tree(nodes.top())) nodes.pop(); - return insert; -} - -// This implementation is taken from musl -void *tfind(const void *key, void *const *rootp, int (*compar)(const void *, const void *)) { - if(!rootp) - return 0; - - struct node *n = (struct node *)*rootp; - for(;;) { - if(!n) - break; - int c = compar(key, n->key); - if(!c) - break; - n = (struct node *)n->a[c > 0]; - } - return n; -} - -void *tdelete(const void *, void **, int(*compar)(const void *, const void *)) { - (void)compar; - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -void twalk(const void *, void (*action)(const void *, VISIT, int)) { - (void)action; - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -void tdestroy(void *, void (*free_node)(void *)) { - (void)free_node; - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -void *lsearch(const void *key, void *base, size_t *nelp, size_t width, - int (*compar)(const void *, const void *)) { - (void)key; - (void)base; - (void)nelp; - (void)width; - (void)compar; - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -void *lfind(const void *key, const void *base, size_t *nelp, - size_t width, int (*compar)(const void *, const void *)) { - (void)key; - (void)base; - (void)nelp; - (void)width; - (void)compar; - __ensure(!"Not implemented"); - __builtin_unreachable(); -} diff --git a/lib/mlibc/options/posix/generic/semaphore-stubs.cpp b/lib/mlibc/options/posix/generic/semaphore-stubs.cpp deleted file mode 100644 index d41eccb..0000000 --- a/lib/mlibc/options/posix/generic/semaphore-stubs.cpp +++ /dev/null @@ -1,114 +0,0 @@ -#include <semaphore.h> -#include <errno.h> - -#include <bits/ensure.h> -#include <mlibc/debug.hpp> -#include <mlibc/ansi-sysdeps.hpp> -#include <mlibc/posix-sysdeps.hpp> - -static constexpr unsigned int semaphoreHasWaiters = static_cast<uint32_t>(1 << 31); -static constexpr unsigned int semaphoreCountMask = static_cast<uint32_t>(1 << 31) - 1; - -int sem_init(sem_t *sem, int pshared, unsigned int initial_count) { - if (pshared) { - mlibc::infoLogger() << "mlibc: shared semaphores are unsuppored" << frg::endlog; - errno = ENOSYS; - return -1; - } - - if (initial_count > SEM_VALUE_MAX) { - errno = EINVAL; - return -1; - } - - sem->__mlibc_count = initial_count; - - return 0; -} - -int sem_destroy(sem_t *) { - return 0; -} - -int sem_wait(sem_t *sem) { - unsigned int state = 0; - - while (1) { - if (!(state & semaphoreCountMask)) { - if (__atomic_compare_exchange_n(&sem->__mlibc_count, &state, semaphoreHasWaiters, - false, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE)) { - int e = mlibc::sys_futex_wait((int *)&sem->__mlibc_count, state, nullptr); - if (e == 0 || e == EAGAIN) { - continue; - } else if (e == EINTR) { - errno = EINTR; - return -1; - } else { - mlibc::panicLogger() << "sys_futex_wait() failed with error code " << e << frg::endlog; - } - } - } else { - unsigned int desired = (state - 1); - if (__atomic_compare_exchange_n(&sem->__mlibc_count, &state, desired, false, - __ATOMIC_RELAXED, __ATOMIC_RELAXED)) - return 0; - } - } -} - -int sem_timedwait(sem_t *sem, const struct timespec *) { - mlibc::infoLogger() << "\e[31mmlibc: sem_timedwait is implemented as sem_wait\e[0m" << frg::endlog; - return sem_wait(sem); -} - -int sem_post(sem_t *sem) { - auto old_count = __atomic_load_n(&sem->__mlibc_count, __ATOMIC_RELAXED) & semaphoreCountMask; - - if (old_count + 1 > SEM_VALUE_MAX) { - errno = EOVERFLOW; - return -1; - } - - auto state = __atomic_exchange_n(&sem->__mlibc_count, old_count + 1, __ATOMIC_RELEASE); - - if (state & semaphoreHasWaiters) - if (int e = mlibc::sys_futex_wake((int *)&sem->__mlibc_count); e) - __ensure(!"sys_futex_wake() failed"); - - return 0; -} - -sem_t *sem_open(const char *, int, ...) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int sem_close(sem_t *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int sem_getvalue(sem_t *, int *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int sem_unlink(const char *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int sem_trywait(sem_t *sem) { - while (true) { - auto state = __atomic_load_n(&sem->__mlibc_count, __ATOMIC_ACQUIRE); - - if (state & semaphoreHasWaiters) { - return EAGAIN; - } - - auto desired = state - 1; - if (__atomic_compare_exchange_n(&sem->__mlibc_count, &state, desired, false, __ATOMIC_RELEASE, __ATOMIC_RELAXED)) { - return 0; - } - } -} diff --git a/lib/mlibc/options/posix/generic/services.cpp b/lib/mlibc/options/posix/generic/services.cpp deleted file mode 100644 index 8ae0656..0000000 --- a/lib/mlibc/options/posix/generic/services.cpp +++ /dev/null @@ -1,222 +0,0 @@ -#include <mlibc/services.hpp> -#include <netdb.h> -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <stdlib.h> -#include <ctype.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <mlibc/debug.hpp> - -namespace mlibc { - -static int parse_rest(service_buf &buf, char *end, int proto) { - if (!strncmp(end, "/udp", 4)) { - if (proto == IPPROTO_TCP && proto != -1) - return 0; - buf.protocol = IPPROTO_UDP; - buf.socktype = SOCK_DGRAM; - } else if (!strncmp(end, "/tcp", 4)) { - if (proto == IPPROTO_UDP && proto != -1) - return 0; - buf.protocol = IPPROTO_TCP; - buf.socktype = SOCK_STREAM; - } else { - return 0; - } - - //TODO(geert): also parse aliases. - - return 1; -} - -static int lookup_serv_file_port(service_result &buf, int proto, int port) { - auto file = fopen(_PATH_SERVICES, "r"); - if (!file) { - switch (errno) { - case ENOENT: - case ENOTDIR: - case EACCES: - return -EAI_SERVICE; - default: - return -EAI_SYSTEM; - } - } - - char line_buf[129] = {0}; - char *line = line_buf + 1; - while(fgets(line, 128, file)) { - int name_length = 0; - char *pos; - // easy way to handle comments, just move the end of the line - // to the beginning of the comment - if ((pos = strchr(line, '#'))) { - *pos++ = '\n'; - *pos = '\0'; - } - - char *end = NULL; - for (pos = line; *pos; pos++) { - for (; isalpha(*pos); pos++); - int rport = strtoul(pos, &end, 10); - if (rport != port || rport > 65535) { - pos = end; - continue; - } - - // We have found the port, time to rewind to the start - // of the line. - for (; pos[-1]; pos--) - if(!isspace(pos[-1])) - name_length++; - break; - } - - if (!pos) - continue; - - if (!name_length) - continue; - - auto name = frg::string<MemoryAllocator>(pos, name_length, - getAllocator()); - - struct service_buf sbuf = {}; - sbuf.port = port; - sbuf.name = std::move(name); - if (!parse_rest(sbuf, end, proto)) - continue; - buf.push_back(std::move(sbuf)); - } - - fclose(file); - return buf.size(); -} - -static int lookup_serv_file_name(service_result &buf, const char *name, - int proto) { - auto file = fopen(_PATH_SERVICES, "r"); - if (!file) { - switch (errno) { - case ENOENT: - case ENOTDIR: - case EACCES: - return -EAI_SERVICE; - default: - return -EAI_SYSTEM; - } - } - - char line[128]; - int name_length = strlen(name); - while(fgets(line, 128, file)) { - char *pos; - // easy way to handle comments, just move the end of the line - // to the beginning of the comment - if ((pos = strchr(line, '#'))) { - *pos++ = '\n'; - *pos = '\0'; - } - - for (pos = line; (pos = strstr(pos, name)); pos++) { - // the name must start and end with a space - if (pos > line && !isspace(pos[-1])) - continue; - if (pos[name_length] && !isspace(pos[name_length])) - continue; - break; - } - if (!pos) - continue; - - // Skip the name at the beginning of the line. - for(pos = line; *pos && !isspace(*pos); pos++) - ; - - char *end = NULL; - int port = strtoul(pos, &end, 10); - if (port > 65535 || end == pos) - continue; - - struct service_buf sbuf; - sbuf.port = port; - sbuf.name = frg::string<MemoryAllocator>(name, getAllocator()); - if (!parse_rest(sbuf, end, proto)) - continue; - - buf.push_back(sbuf); - - } - - fclose(file); - return buf.size(); -} - - -// This function returns a negative error code, since a positive -// return code means success. -int lookup_serv_by_name(service_result &buf, const char *name, int proto, - int socktype, int flags) { - switch(socktype) { - case SOCK_STREAM: - if (!proto) - proto = IPPROTO_TCP; - else if (proto != IPPROTO_TCP) - return -EAI_SERVICE; - break; - case SOCK_DGRAM: - if (!proto) - proto = IPPROTO_UDP; - else if (proto != IPPROTO_UDP) - return -EAI_SERVICE; - break; - case 0: - break; - default: - if (name) - return -EAI_SERVICE; - buf[0].port = 0; - buf[0].socktype = socktype; - buf[0].protocol = proto; - return 1; - } - - char *end = nullptr; - unsigned int port = 0; - int count = 0; - - if (name) { - if (!*name) - return -EAI_SERVICE; - port = strtoul(name, &end, 10); - } - // The end pointer is a null pointer so the name was a port - // or the name was not specified. - if (!end || !*end) { - if (proto != IPPROTO_UDP) { - buf[count].port = port; - buf[count].protocol = IPPROTO_TCP; - buf[count].socktype = SOCK_STREAM; - count++; - } - if (proto != IPPROTO_TCP) { - buf[count].port = port; - buf[count].protocol = IPPROTO_UDP; - buf[count].socktype = SOCK_DGRAM; - count++; - } - return count; - } - - if (flags & AI_NUMERICSERV) - return -EAI_NONAME; - - return lookup_serv_file_name(buf, name, proto); -} - -int lookup_serv_by_port(service_result &buf, int proto, int port) { - return lookup_serv_file_port(buf, proto, port); -} - -} // namespace mlibc diff --git a/lib/mlibc/options/posix/generic/spawn-stubs.cpp b/lib/mlibc/options/posix/generic/spawn-stubs.cpp deleted file mode 100644 index cf7edfc..0000000 --- a/lib/mlibc/options/posix/generic/spawn-stubs.cpp +++ /dev/null @@ -1,376 +0,0 @@ - -#include <spawn.h> -#include <errno.h> -#include <pthread.h> -#include <fcntl.h> -#include <unistd.h> -#include <limits.h> -#include <sched.h> -#include <stdlib.h> -#include <signal.h> -#include <sys/wait.h> - -#include <bits/ensure.h> -#include <mlibc/debug.hpp> - -/* - * Musl places this in a seperate header called fdop.h - * This header isn't present in glibc, or on my host, so I - * include it's contents here - */ - -#define FDOP_CLOSE 1 -#define FDOP_DUP2 2 -#define FDOP_OPEN 3 -#define FDOP_CHDIR 4 -#define FDOP_FCHDIR 5 - -struct fdop { - struct fdop *next, *prev; - int cmd, fd, srcfd, oflag; - mode_t mode; - char path[]; -}; - -/* - * This posix_spawn implementation is taken from musl - */ - -static unsigned long handler_set[NSIG / (8 * sizeof(long))]; - -static void __get_handler_set(sigset_t *set) { - memcpy(set, handler_set, sizeof handler_set); -} - -struct args { - int p[2]; - sigset_t oldmask; - const char *path; - const posix_spawn_file_actions_t *fa; - const posix_spawnattr_t *__restrict attr; - char *const *argv, *const *envp; -}; - -static int child(void *args_vp) { - int i, ret; - struct sigaction sa = {}; - struct args *args = (struct args *)args_vp; - int p = args->p[1]; - const posix_spawn_file_actions_t *fa = args->fa; - const posix_spawnattr_t *__restrict attr = args->attr; - sigset_t hset; - bool use_execvpe = false; - - if(attr->__fn) - use_execvpe = true; - - close(args->p[0]); - - /* All signal dispositions must be either SIG_DFL or SIG_IGN - * before signals are unblocked. Otherwise a signal handler - * from the parent might get run in the child while sharing - * memory, with unpredictable and dangerous results. To - * reduce overhead, sigaction has tracked for us which signals - * potentially have a signal handler. */ - __get_handler_set(&hset); - for(i = 1; i < NSIG; i++) { - if((attr->__flags & POSIX_SPAWN_SETSIGDEF) && sigismember(&attr->__def, i)) { - sa.sa_handler = SIG_DFL; - } else if(sigismember(&hset, i)) { - if (i - 32 < 3) { - sa.sa_handler = SIG_IGN; - } else {; - sigaction(i, 0, &sa); - if(sa.sa_handler == SIG_IGN) - continue; - sa.sa_handler = SIG_DFL; - } - } else { - continue; - } - sigaction(i, &sa, 0); - } - - if(attr->__flags & POSIX_SPAWN_SETSID) { - if((ret = setsid()) < 0) - goto fail; - } - - if(attr->__flags & POSIX_SPAWN_SETPGROUP) { - mlibc::infoLogger() << "mlibc: posix_spawn: ignoring SETPGROUP" << frg::endlog; - //if((ret = setpgid(0, attr->__pgrp))) - // goto fail; - } - - if(attr->__flags & POSIX_SPAWN_RESETIDS) { - if((ret = setgid(getgid())) || (ret = setuid(getuid())) ) - goto fail; - } - - if(fa && fa->__actions) { - struct fdop *op; - int fd; - for(op = (struct fdop *)fa->__actions; op->next; op = op->next); - for(; op; op = op->prev) { - /* It's possible that a file operation would clobber - * the pipe fd used for synchronizing with the - * parent. To avoid that, we dup the pipe onto - * an unoccupied fd. */ - if(op->fd == p) { - ret = dup(p); - if(ret < 0) - goto fail; - close(p); - p = ret; - } - switch(op->cmd) { - case FDOP_CLOSE: - close(op->fd); - break; - case FDOP_DUP2: - fd = op->srcfd; - if(fd == p) { - ret = -EBADF; - goto fail; - } - if(fd != op->fd) { - if((ret = dup2(fd, op->fd)) < 0) - goto fail; - } else { - ret = fcntl(fd, F_GETFD); - ret = fcntl(fd, F_SETFD, ret & ~FD_CLOEXEC); - if(ret < 0) - goto fail; - } - break; - case FDOP_OPEN: - fd = open(op->path, op->oflag, op->mode); - if((ret = fd) < 0) - goto fail; - if(fd != op->fd) { - if((ret = dup2(fd, op->fd)) < 0) - goto fail; - close(fd); - } - break; - case FDOP_CHDIR: - ret = chdir(op->path); - if(ret < 0) - goto fail; - break; - case FDOP_FCHDIR: - ret = fchdir(op->fd); - if(ret < 0) - goto fail; - break; - } - } - } - - /* Close-on-exec flag may have been lost if we moved the pipe - * to a different fd. */ - fcntl(p, F_SETFD, FD_CLOEXEC); - - pthread_sigmask(SIG_SETMASK, (attr->__flags & POSIX_SPAWN_SETSIGMASK) - ? &attr->__mask : &args->oldmask, 0); - - if(use_execvpe) - execvpe(args->path, args->argv, args->envp); - else - execve(args->path, args->argv, args->envp); - ret = -errno; - -fail: - /* Since sizeof errno < PIPE_BUF, the write is atomic. */ - ret = -ret; - if(ret) - while(write(p, &ret, sizeof ret) < 0); - _exit(127); -} - -int posix_spawn(pid_t *__restrict res, const char *__restrict path, - const posix_spawn_file_actions_t *file_actions, - const posix_spawnattr_t *__restrict attrs, - char *const argv[], char *const envp[]) { - pid_t pid; - int ec = 0, cs; - struct args args; - const posix_spawnattr_t empty_attr = {}; - sigset_t full_sigset; - sigfillset(&full_sigset); - - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); - - args.path = path; - args.fa = file_actions; - args.attr = attrs ? attrs : &empty_attr; - args.argv = argv; - args.envp = envp; - pthread_sigmask(SIG_BLOCK, &full_sigset, &args.oldmask); - - /* The lock guards both against seeing a SIGABRT disposition change - * by abort and against leaking the pipe fd to fork-without-exec. */ - //LOCK(__abort_lock); - - if(pipe2(args.p, O_CLOEXEC)) { - //UNLOCK(__abort_lock); - ec = errno; - goto fail; - } - - /* Mlibc change: We use fork + execve, as clone is not implemented. - * This yields the same result in the end. */ - //pid = clone(child, stack + sizeof stack, CLONE_VM | CLONE_VFORK | SIGCHLD, &args); - pid = fork(); - if(!pid) { - child(&args); - } - close(args.p[1]); - //UNLOCK(__abort_lock); - - if(pid > 0) { - if(read(args.p[0], &ec, sizeof ec) != sizeof ec) - ec = 0; - else - waitpid(pid, 0, 0); - } else { - ec = -pid; - } - - close(args.p[0]); - - if(!ec && res) - *res = pid; - -fail: - pthread_sigmask(SIG_SETMASK, &args.oldmask, 0); - pthread_setcancelstate(cs, 0); - - return ec; -} - -int posix_spawnattr_init(posix_spawnattr_t *attr) { - *attr = (posix_spawnattr_t){}; - return 0; -} - -int posix_spawnattr_destroy(posix_spawnattr_t *) { - return 0; -} - -int posix_spawnattr_setflags(posix_spawnattr_t *attr, short flags) { - const unsigned all_flags = - POSIX_SPAWN_RESETIDS | - POSIX_SPAWN_SETPGROUP | - POSIX_SPAWN_SETSIGDEF | - POSIX_SPAWN_SETSIGMASK | - POSIX_SPAWN_SETSCHEDPARAM | - POSIX_SPAWN_SETSCHEDULER | - POSIX_SPAWN_USEVFORK | - POSIX_SPAWN_SETSID; - if(flags & ~all_flags) - return EINVAL; - attr->__flags = flags; - return 0; -} - -int posix_spawnattr_setsigdefault(posix_spawnattr_t *__restrict attr, - const sigset_t *__restrict sigdefault) { - attr->__def = *sigdefault; - return 0; -} - -int posix_spawnattr_setschedparam(posix_spawnattr_t *__restrict, - const struct sched_param *__restrict) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int posix_spawnattr_setschedpolicy(posix_spawnattr_t *, int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int posix_spawnattr_setsigmask(posix_spawnattr_t *__restrict attr, - const sigset_t *__restrict sigmask) { - attr->__mask = *sigmask; - return 0; -} - -int posix_spawnattr_setpgroup(posix_spawnattr_t *attr, pid_t pgroup) { - attr->__pgrp = pgroup; - return 0; -} - -int posix_spawn_file_actions_init(posix_spawn_file_actions_t *file_actions) { - file_actions->__actions = 0; - return 0; -} - -int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *file_actions) { - struct fdop *op = (struct fdop *)file_actions->__actions, *next; - while(op) { - next = op->next; - free(op); - op = next; - } - return 0; -} - -int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *file_actions, - int fildes, int newfildes) { - struct fdop *op = (struct fdop *)malloc(sizeof *op); - if(!op) - return ENOMEM; - op->cmd = FDOP_DUP2; - op->srcfd = fildes; - op->fd = newfildes; - if((op->next = (struct fdop *)file_actions->__actions)) - op->next->prev = op; - op->prev = 0; - file_actions->__actions = op; - return 0; -} - -int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *file_actions, - int fildes) { - struct fdop *op = (struct fdop *)malloc(sizeof *op); - if(!op) - return ENOMEM; - op->cmd = FDOP_CLOSE; - op->fd = fildes; - if((op->next = (struct fdop *)file_actions->__actions)) - op->next->prev = op; - op->prev = 0; - file_actions->__actions = op; - return 0; -} - -int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t *__restrict file_actions, - int fildes, const char *__restrict path, int oflag, mode_t mode) { - struct fdop *op = (struct fdop *)malloc(sizeof *op + strlen(path) + 1); - if(!op) - return ENOMEM; - op->cmd = FDOP_OPEN; - op->fd = fildes; - op->oflag = oflag; - op->mode = mode; - strcpy(op->path, path); - if((op->next = (struct fdop *)file_actions->__actions)) - op->next->prev = op; - op->prev = 0; - file_actions->__actions = op; - return 0; -} - -int posix_spawnp(pid_t *__restrict pid, const char *__restrict file, - const posix_spawn_file_actions_t *file_actions, - const posix_spawnattr_t *__restrict attrp, - char *const argv[], char *const envp[]) { - posix_spawnattr_t spawnp_attr = {}; - if(attrp) - spawnp_attr = *attrp; - spawnp_attr.__fn = (void *)execvpe; - return posix_spawn(pid, file, file_actions, &spawnp_attr, argv, envp); -} - diff --git a/lib/mlibc/options/posix/generic/strings-stubs.cpp b/lib/mlibc/options/posix/generic/strings-stubs.cpp deleted file mode 100644 index 524c424..0000000 --- a/lib/mlibc/options/posix/generic/strings-stubs.cpp +++ /dev/null @@ -1,107 +0,0 @@ - -#include <strings.h> -#include <string.h> - -#include <ctype.h> -#include <bits/ensure.h> -#include <mlibc/strings.hpp> - -char *index (const char *s, int c) { - return strchr(s, c); -} - -char *rindex(const char *s, int c) { - return strrchr(s, c); -} - -namespace { - - template<typename T> - int ffs_generic(T i) { - //Non-portably assume a byte has 8 bits; fine in all plausible cases. - for(size_t b = 0; b < sizeof(T) * 8;) - if(i & (static_cast<T>(0x1) << b++)) - return b; - - return 0; - } - -} - -// On RISC-V, __builtin_ffs just calls into ffs, so we can't use it here. -#if defined(__has_builtin) && !defined(__riscv) -# if __has_builtin(__builtin_ffs) -# define __mlibc_ffs __builtin_ffs -# endif -# if __has_builtin(__builtin_ffsl) -# define __mlibc_ffsl __builtin_ffsl -# endif -# if __has_builtin(__builtin_ffsll) -# define __mlibc_ffsll __builtin_ffsll -# endif -#endif - -int ffs(int i) { -#ifdef __mlibc_ffs - return __mlibc_ffs(i); -#else - return ffs_generic<int>(i); -#endif -} - -/* - Both ffsl() and ffsll() are glibc extensions - defined in string.h. They are however implemented - here because of similarity in logic and - shared code. -*/ - -int ffsl(long i) { -#ifdef __mlibc_ffsl - return __mlibc_ffsl(i); -#else - return ffs_generic<long>(i); -#endif -} - -int ffsll(long long i) { -#ifdef __mlibc_ffsll - return __mlibc_ffsll(i); -#else - return ffs_generic<long long>(i); -#endif -} - -int strcasecmp(const char *a, const char *b) { - size_t i = 0; - while(true) { - unsigned char a_byte = tolower(a[i]); - unsigned char b_byte = tolower(b[i]); - if(!a_byte && !b_byte) - return 0; - // If only one char is null, one of the following cases applies. - if(a_byte < b_byte) - return -1; - if(a_byte > b_byte) - return 1; - i++; - } -} - -int strncasecmp(const char *a, const char *b, size_t size) { - return mlibc::strncasecmp(a, b, size); -} - -// Marked as obsolete in posix 2008 but used by at least tracker -int bcmp(const void *s1, const void *s2, size_t n) { - return memcmp(s1, s2, n); -} - -void bcopy(const void *s1, void *s2, size_t n) { - memmove(s2, s1, n); -} - -void bzero(void *s, size_t n) { - memset(s, 0, n); -} - diff --git a/lib/mlibc/options/posix/generic/sys-file-stubs.cpp b/lib/mlibc/options/posix/generic/sys-file-stubs.cpp deleted file mode 100644 index e1cc9ab..0000000 --- a/lib/mlibc/options/posix/generic/sys-file-stubs.cpp +++ /dev/null @@ -1,16 +0,0 @@ - -#include <sys/file.h> -#include <mlibc/posix-sysdeps.hpp> -#include <errno.h> - -#include <bits/ensure.h> - -int flock(int fd, int opt) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_flock, -1); - if(int e = mlibc::sys_flock(fd, opt); e) { - errno = e; - return -1; - } - return 0; -} - diff --git a/lib/mlibc/options/posix/generic/sys-ipc.cpp b/lib/mlibc/options/posix/generic/sys-ipc.cpp deleted file mode 100644 index b9e0d3d..0000000 --- a/lib/mlibc/options/posix/generic/sys-ipc.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include <sys/ipc.h> - -#include <bits/ensure.h> - -key_t ftok(const char *, int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} diff --git a/lib/mlibc/options/posix/generic/sys-mman-stubs.cpp b/lib/mlibc/options/posix/generic/sys-mman-stubs.cpp deleted file mode 100644 index 9383976..0000000 --- a/lib/mlibc/options/posix/generic/sys-mman-stubs.cpp +++ /dev/null @@ -1,177 +0,0 @@ - -#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 */ diff --git a/lib/mlibc/options/posix/generic/sys-msg.cpp b/lib/mlibc/options/posix/generic/sys-msg.cpp deleted file mode 100644 index 95f067e..0000000 --- a/lib/mlibc/options/posix/generic/sys-msg.cpp +++ /dev/null @@ -1,23 +0,0 @@ - -#include <bits/ensure.h> -#include <sys/msg.h> - -int msgget(key_t, int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int msgctl(int, int, struct msqid_ds *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -ssize_t msgrcv(int, void *, size_t, long, int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int msgsnd(int, const void *, size_t, int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} diff --git a/lib/mlibc/options/posix/generic/sys-resource-stubs.cpp b/lib/mlibc/options/posix/generic/sys-resource-stubs.cpp deleted file mode 100644 index 597de4d..0000000 --- a/lib/mlibc/options/posix/generic/sys-resource-stubs.cpp +++ /dev/null @@ -1,57 +0,0 @@ - -#include <errno.h> -#include <sys/resource.h> - -#include <bits/ensure.h> -#include <mlibc/debug.hpp> -#include <mlibc/posix-sysdeps.hpp> - -int getpriority(int which, id_t who) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_getpriority, -1); - int value = 0; - if(int e = mlibc::sys_getpriority(which, who, &value); e) { - errno = e; - } - return value; -} - -int setpriority(int which, id_t who, int prio) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_setpriority, -1); - if(int e = mlibc::sys_setpriority(which, who, prio); e) { - errno = e; - return -1; - } - return 0; -} - -int getrusage(int scope, struct rusage *usage) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_getrusage, -1); - if(int e = mlibc::sys_getrusage(scope, usage); e) { - errno = e; - return -1; - } - return 0; -} - -int getrlimit(int resource, struct rlimit *limit) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_getrlimit, -1); - if(int e = mlibc::sys_getrlimit(resource, limit); e) { - errno = e; - return -1; - } - return 0; -} - -int setrlimit(int resource, const struct rlimit *limit) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_setrlimit, -1); - if(int e = mlibc::sys_setrlimit(resource, limit); e) { - errno = e; - return -1; - } - return 0; -} - -int prlimit(pid_t, int, const struct rlimit *, struct rlimit *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} diff --git a/lib/mlibc/options/posix/generic/sys-select-stubs.cpp b/lib/mlibc/options/posix/generic/sys-select-stubs.cpp deleted file mode 100644 index e8ff927..0000000 --- a/lib/mlibc/options/posix/generic/sys-select-stubs.cpp +++ /dev/null @@ -1,58 +0,0 @@ - -#include <string.h> -#include <sys/select.h> -#include <unistd.h> -#include <errno.h> - -#include <bits/ensure.h> -#include <mlibc-config.h> - -#include <mlibc/posix-sysdeps.hpp> - -void __FD_CLR(int fd, fd_set *set) { - __ensure(fd < FD_SETSIZE); - set->__mlibc_elems[fd / 8] &= ~(1 << (fd % 8)); -} -int __FD_ISSET(int fd, fd_set *set) { - __ensure(fd < FD_SETSIZE); - return set->__mlibc_elems[fd / 8] & (1 << (fd % 8)); -} -void __FD_SET(int fd, fd_set *set) { - __ensure(fd < FD_SETSIZE); - set->__mlibc_elems[fd / 8] |= 1 << (fd % 8); -} -void __FD_ZERO(fd_set *set) { - memset(set->__mlibc_elems, 0, sizeof(fd_set)); -} - -int select(int num_fds, fd_set *__restrict read_set, fd_set *__restrict write_set, - fd_set *__restrict except_set, struct timeval *__restrict timeout) { - int num_events = 0; - struct timespec timeouts = {}; - struct timespec *timeout_ptr = NULL; - if (timeout) { - timeouts.tv_sec = timeout->tv_sec; - timeouts.tv_nsec = timeout->tv_usec * 1000; - timeout_ptr = &timeouts; - } - - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_pselect, -1); - if(int e = mlibc::sys_pselect(num_fds, read_set, write_set, except_set, - timeout_ptr, NULL, &num_events); e) { - errno = e; - return -1; - } - return num_events; -} - -int pselect(int num_fds, fd_set *read_set, fd_set *write_set, fd_set *except_set, - const struct timespec *timeout, const sigset_t *sigmask) { - int num_events = 0; - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_pselect, -1); - if(int e = mlibc::sys_pselect(num_fds, read_set, write_set, except_set, - timeout, sigmask, &num_events); e) { - errno = e; - return -1; - } - return num_events; -} diff --git a/lib/mlibc/options/posix/generic/sys-sem.cpp b/lib/mlibc/options/posix/generic/sys-sem.cpp deleted file mode 100644 index ac3df69..0000000 --- a/lib/mlibc/options/posix/generic/sys-sem.cpp +++ /dev/null @@ -1,51 +0,0 @@ - -#include <bits/ensure.h> -#include <errno.h> -#include <limits.h> -#include <sys/sem.h> - -#include <mlibc/posix-sysdeps.hpp> - -int semget(key_t key, int n, int fl) { - if(n > USHRT_MAX) { - errno = EINVAL; - return -1; - } - - int id = 0; - auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_semget, -1); - if(int e = sysdep(key, n, fl, &id); e) { - errno = e; - return -1; - } - return id; -} - -int semop(int, struct sembuf *, size_t) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -union semun { - int val; - struct semid_ds *buf; - unsigned short *array; -}; - -int semctl(int id, int num, int cmd, ...) { - union semun semun; - int ret = 0; - - va_list ap; - va_start(ap, cmd); - semun = va_arg(ap, union semun); - va_end(ap); - - auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_semctl, -1); - if(int e = sysdep(id, num, cmd, semun.buf, &ret); e) { - errno = e; - return -1; - } - - return ret; -} diff --git a/lib/mlibc/options/posix/generic/sys-shm.cpp b/lib/mlibc/options/posix/generic/sys-shm.cpp deleted file mode 100644 index 3af7e90..0000000 --- a/lib/mlibc/options/posix/generic/sys-shm.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include <sys/shm.h> - -#include <bits/ensure.h> -#include <mlibc/debug.hpp> - -void *shmat(int, const void *, int) { - __ensure(!"Function is not implemented"); - __builtin_unreachable(); -} - -int shmctl(int, int, struct shmid_ds *) { - __ensure(!"Function is not implemented"); - __builtin_unreachable(); -} - -int shmdt(const void *) { - __ensure(!"Function is not implemented"); - __builtin_unreachable(); -} - -int shmget(key_t, size_t, int) { - mlibc::infoLogger() << "mlibc: shmget() is a no-op!" << frg::endlog; - return -1; -} diff --git a/lib/mlibc/options/posix/generic/sys-socket-stubs.cpp b/lib/mlibc/options/posix/generic/sys-socket-stubs.cpp deleted file mode 100644 index 037a994..0000000 --- a/lib/mlibc/options/posix/generic/sys-socket-stubs.cpp +++ /dev/null @@ -1,225 +0,0 @@ - -#include <errno.h> -#include <fcntl.h> -#include <limits.h> -#include <sys/socket.h> - -#include <bits/ensure.h> -#include <mlibc/debug.hpp> -#include <mlibc/posix-sysdeps.hpp> - -int accept(int fd, struct sockaddr *__restrict addr_ptr, socklen_t *__restrict addr_length) { - int newfd; - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_accept, -1); - if(int e = mlibc::sys_accept(fd, &newfd, addr_ptr, addr_length, 0); e) { - errno = e; - return -1; - } - return newfd; -} - -int accept4(int fd, struct sockaddr *__restrict addr_ptr, socklen_t *__restrict addr_length, int flags) { - int newfd; - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_accept, -1); - if(int e = mlibc::sys_accept(fd, &newfd, addr_ptr, addr_length, flags); e) { - errno = e; - return -1; - } - - return newfd; -} - -int bind(int fd, const struct sockaddr *addr_ptr, socklen_t addr_len) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_bind, -1); - if(int e = mlibc::sys_bind(fd, addr_ptr, addr_len); e) { - errno = e; - return -1; - } - return 0; -} - -int connect(int fd, const struct sockaddr *addr_ptr, socklen_t addr_len) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_connect, -1); - if(int e = mlibc::sys_connect(fd, addr_ptr, addr_len); e) { - errno = e; - return -1; - } - return 0; -} - -int getpeername(int fd, struct sockaddr *addr_ptr, socklen_t *__restrict addr_length) { - socklen_t actual_length; - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_peername, -1); - if(int e = mlibc::sys_peername(fd, addr_ptr, *addr_length, &actual_length); e) { - errno = e; - return -1; - } - *addr_length = actual_length; - return 0; -} - -int getsockname(int fd, struct sockaddr *__restrict addr_ptr, socklen_t *__restrict addr_length) { - socklen_t actual_length; - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_sockname, -1); - if(int e = mlibc::sys_sockname(fd, addr_ptr, *addr_length, &actual_length); e) { - errno = e; - return -1; - } - *addr_length = actual_length; - return 0; -} - -int getsockopt(int fd, int layer, int number, - void *__restrict buffer, socklen_t *__restrict size) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_getsockopt, -1); - return mlibc::sys_getsockopt(fd, layer, number, buffer, size); -} - -int listen(int fd, int backlog) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_listen, -1); - if(int e = mlibc::sys_listen(fd, backlog); e) { - errno = e; - return -1; - } - return 0; -} - -ssize_t recv(int sockfd, void *__restrict buf, size_t len, int flags) { - return recvfrom(sockfd, buf, len, flags, NULL, NULL); -} - -ssize_t recvfrom(int sockfd, void *__restrict buf, size_t len, int flags, - struct sockaddr *__restrict src_addr, socklen_t *__restrict addrlen) { - if(mlibc::sys_recvfrom) { - ssize_t length; - if(int e = mlibc::sys_recvfrom(sockfd, buf, len, flags, src_addr, addrlen, &length); e) { - errno = e; - return -1; - } - return length; - } - - struct iovec iov = {}; - iov.iov_base = buf; - iov.iov_len = len; - - struct msghdr hdr = {}; - hdr.msg_name = src_addr; - if (addrlen) { - hdr.msg_namelen = *addrlen; - } - hdr.msg_iov = &iov; - hdr.msg_iovlen = 1; - - int ret = recvmsg(sockfd, &hdr, flags); - if (ret < 0) - return ret; - - if(addrlen) - *addrlen = hdr.msg_namelen; - return ret; -} - -ssize_t recvmsg(int fd, struct msghdr *hdr, int flags) { - ssize_t length; - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_msg_recv, -1); - if(int e = mlibc::sys_msg_recv(fd, hdr, flags, &length); e) { - errno = e; - return -1; - } - return length; -} - -int recvmmsg(int, struct mmsghdr *, unsigned int, int, struct timespec *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -ssize_t send(int fd, const void *buffer, size_t size, int flags) { - return sendto(fd, buffer, size, flags, nullptr, 0); -} - -ssize_t sendto(int fd, const void *buffer, size_t size, int flags, - const struct sockaddr *sock_addr, socklen_t addr_length) { - if(mlibc::sys_sendto) { - ssize_t length; - if(int e = mlibc::sys_sendto(fd, buffer, size, flags, sock_addr, addr_length, &length); e) { - errno = e; - return -1; - } - return length; - } - - struct iovec iov = {}; - iov.iov_base = const_cast<void *>(buffer); - iov.iov_len = size; - - struct msghdr hdr = {}; - hdr.msg_name = const_cast<struct sockaddr *>(sock_addr); - hdr.msg_namelen = addr_length; - hdr.msg_iov = &iov; - hdr.msg_iovlen = 1; - - return sendmsg(fd, &hdr, flags); -} - -ssize_t sendmsg(int fd, const struct msghdr *hdr, int flags) { - if(hdr->msg_iovlen > IOV_MAX) - return EMSGSIZE; - - ssize_t length; - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_msg_send, -1); - if(int e = mlibc::sys_msg_send(fd, hdr, flags, &length); e) { - errno = e; - return -1; - } - return length; -} - -int sendmmsg(int, struct mmsghdr *, unsigned int, int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int setsockopt(int fd, int layer, int number, - const void *buffer, socklen_t size) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_setsockopt, -1); - return mlibc::sys_setsockopt(fd, layer, number, buffer, size); -} - -int shutdown(int sockfd, int how) { - auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_shutdown, -1); - if(int e = sysdep(sockfd, how); e) { - errno = e; - return -1; - } - - return 0; -} - -int sockatmark(int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int socket(int family, int type, int protocol) { - int fd; - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_socket, -1); - if(int e = mlibc::sys_socket(family, type, protocol, &fd); e) { - errno = e; - return -1; - } - return fd; -} - -int socketpair(int domain, int type, int protocol, int sv[2]) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_socketpair, -1); - if(int e = mlibc::sys_socketpair(domain, type, protocol, sv); e) { - errno = e; - return -1; - } - return 0; -} - -// connectpair() is provided by the platform - diff --git a/lib/mlibc/options/posix/generic/sys-stat-stubs.cpp b/lib/mlibc/options/posix/generic/sys-stat-stubs.cpp deleted file mode 100644 index 2eca445..0000000 --- a/lib/mlibc/options/posix/generic/sys-stat-stubs.cpp +++ /dev/null @@ -1,155 +0,0 @@ - -#include <errno.h> -#include <bits/ensure.h> -#include <sys/stat.h> - -#include <mlibc/debug.hpp> -#include <mlibc/posix-sysdeps.hpp> - -int chmod(const char *pathname, mode_t mode) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_chmod, -1); - if(int e = mlibc::sys_chmod(pathname, mode); e) { - errno = e; - return -1; - } - return 0; -} - -int fchmod(int fd, mode_t mode) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_fchmod, -1); - if(int e = mlibc::sys_fchmod(fd, mode); e) { - errno = e; - return -1; - } - return 0; -} - -int fchmodat(int dirfd, const char *pathname, mode_t mode, int flags) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_fchmodat, -1); - if(int e = mlibc::sys_fchmodat(dirfd, pathname, mode, flags); e) { - errno = e; - return -1; - } - return 0; -} - -int fstatat(int dirfd, const char *path, struct stat *result, int flags) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_stat, -1); - if(int e = mlibc::sys_stat(mlibc::fsfd_target::fd_path, dirfd, path, flags, result); e) { - errno = e; - return -1; - } - return 0; -} - -int futimens(int fd, const struct timespec times[2]) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_utimensat, -1); - - if (int e = mlibc::sys_utimensat(fd, nullptr, times, 0); e) { - errno = e; - return -1; - } - - return 0; -} - -int mkdir(const char *path, mode_t mode) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_mkdir, -1); - if(int e = mlibc::sys_mkdir(path, mode); e) { - errno = e; - return -1; - } - return 0; -} - -int mkdirat(int dirfd, const char *path, mode_t mode) { - mlibc::infoLogger() << "\e[31mmlibc: mkdirat() ignores its mode\e[39m" << frg::endlog; - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_mkdirat, -1); - if(int e = mlibc::sys_mkdirat(dirfd, path, mode); e) { - errno = e; - return -1; - } - return 0; -} - -int mkfifo(const char *path, mode_t mode) { - return mkfifoat(AT_FDCWD, path, mode); -} - -int mkfifoat(int dirfd, const char *path, mode_t mode) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_mkfifoat, -1); - if (int e = mlibc::sys_mkfifoat(dirfd, path, mode); e) { - errno = e; - return -1; - } - - return 0; -} - -int mknod(const char *path, mode_t mode, dev_t dev) { - return mknodat(AT_FDCWD, path, mode, dev); -} - -int mknodat(int dirfd, const char *path, mode_t mode, dev_t dev) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_mknodat, -1); - if (int e = mlibc::sys_mknodat(dirfd, path, mode, dev); e) { - errno = e; - return -1; - } - - return 0; -} - -mode_t umask(mode_t mode) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_umask, -1); - mode_t old; - if (int e = mlibc::sys_umask(mode, &old); e) { - errno = e; - return -1; - } - return old; -} - -int utimensat(int dirfd, const char *pathname, const struct timespec times[2], int flags) { - if(pathname == nullptr) { - errno = EINVAL; - return -1; - } - - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_utimensat, -1); - if (int e = mlibc::sys_utimensat(dirfd, pathname, times, flags); e) { - errno = e; - return -1; - } - - return 0; -} - -int stat(const char *path, struct stat *result) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_stat, -1); - if(int e = mlibc::sys_stat(mlibc::fsfd_target::path, -1, path, 0, result); e) { - errno = e; - return -1; - } - return 0; -} - -int lstat(const char *path, struct stat *result) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_stat, -1); - if(int e = mlibc::sys_stat(mlibc::fsfd_target::path, - -1, path, AT_SYMLINK_NOFOLLOW, result); e) { - errno = e; - return -1; - } - return 0; -} - -int fstat(int fd, struct stat *result) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_stat, -1); - if(int e = mlibc::sys_stat(mlibc::fsfd_target::fd, fd, "", 0, result); e) { - errno = e; - return -1; - } - return 0; -} - diff --git a/lib/mlibc/options/posix/generic/sys-statvfs-stubs.cpp b/lib/mlibc/options/posix/generic/sys-statvfs-stubs.cpp deleted file mode 100644 index c02cc39..0000000 --- a/lib/mlibc/options/posix/generic/sys-statvfs-stubs.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include <errno.h> -#include <sys/statvfs.h> - -#include <bits/ensure.h> -#include <mlibc/posix-sysdeps.hpp> - -int statvfs(const char *path, struct statvfs *out) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_statvfs, -1); - if(int e = mlibc::sys_statvfs(path, out); e) { - errno = e; - return -1; - } - return 0; -} - -int fstatvfs(int fd, struct statvfs *out) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_fstatvfs, -1); - if(int e = mlibc::sys_fstatvfs(fd, out); e) { - errno = e; - return -1; - } - return 0; -} - diff --git a/lib/mlibc/options/posix/generic/sys-time-stubs.cpp b/lib/mlibc/options/posix/generic/sys-time-stubs.cpp deleted file mode 100644 index 5cc0fe5..0000000 --- a/lib/mlibc/options/posix/generic/sys-time-stubs.cpp +++ /dev/null @@ -1,107 +0,0 @@ - -#include <errno.h> -#include <sys/time.h> -#include <time.h> - -#include <bits/ensure.h> -#include <mlibc/debug.hpp> -#include <mlibc/posix-sysdeps.hpp> - -int gettimeofday(struct timeval *__restrict result, void *__restrict unused) { - (void)unused; // Linux just ignores gettimeofday(). - - if(result) { - long nanos; - if(int e = mlibc::sys_clock_get(CLOCK_REALTIME, &result->tv_sec, &nanos); e) { - errno = e; - return -1; - } - result->tv_usec = nanos / 1000; - } - return 0; -} - -int settimeofday(const struct timeval *, const struct timezone *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -void timeradd(const struct timeval *a, const struct timeval *b, struct timeval *res) { - res->tv_sec = a->tv_sec + b->tv_sec; - res->tv_usec = a->tv_usec + b->tv_usec; - while(res->tv_usec > 999999) { - res->tv_usec -= 1000000; - res->tv_sec += 1; - } -} - -void timersub(const struct timeval *a, const struct timeval *b, struct timeval *res) { - res->tv_sec = a->tv_sec - b->tv_sec; - res->tv_usec = a->tv_usec - b->tv_usec; - while(res->tv_usec < 0) { - res->tv_usec += 1000000; - res->tv_sec -= 1; - } -} - -void timerclear(struct timeval *tvp) { - tvp->tv_sec = 0; - tvp->tv_usec = 0; -} - -int timerisset(struct timeval *tvp) { - if(tvp->tv_sec != 0 || tvp->tv_usec != 0) { - return 1; - } - return 0; -} - -int getitimer(int which, struct itimerval *curr_value) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_getitimer, -1); - if(int e = mlibc::sys_getitimer(which, curr_value); e) { - errno = e; - return -1; - } - return 0; -} - -int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_setitimer, -1); - if(int e = mlibc::sys_setitimer(which, new_value, old_value); e) { - errno = e; - return -1; - } - return 0; -} - -int timer_create(clockid_t clk, struct sigevent *__restrict evp, timer_t *__restrict res) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_timer_create, -1); - if(int e = mlibc::sys_timer_create(clk, evp, res); e) { - errno = e; - return -1; - } - return 0; -} - -int timer_settime(timer_t t, int flags, const struct itimerspec *__restrict val, struct itimerspec *__restrict old) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_timer_settime, -1); - if(int e = mlibc::sys_timer_settime(t, flags, val, old); e) { - errno = e; - return -1; - } - return 0; -} - -int timer_gettime(timer_t, struct itimerspec *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int timer_delete(timer_t t) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_timer_delete, -1); - if(int e = mlibc::sys_timer_delete(t); e) { - errno = e; - return -1; - } - return 0; -} diff --git a/lib/mlibc/options/posix/generic/sys-times.cpp b/lib/mlibc/options/posix/generic/sys-times.cpp deleted file mode 100644 index 61b6e25..0000000 --- a/lib/mlibc/options/posix/generic/sys-times.cpp +++ /dev/null @@ -1,19 +0,0 @@ - -#include <errno.h> -#include <sys/times.h> - -#include <bits/ensure.h> -#include <mlibc/debug.hpp> -#include <internal-config.h> -#include <mlibc/posix-sysdeps.hpp> - -clock_t times(struct tms *tms) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_times, -1); - clock_t ret; - if(int e = mlibc::sys_times(tms, &ret); e) { - errno = e; - return -1; - } - return ret; -} - diff --git a/lib/mlibc/options/posix/generic/sys-uio.cpp b/lib/mlibc/options/posix/generic/sys-uio.cpp deleted file mode 100644 index 0f14bc0..0000000 --- a/lib/mlibc/options/posix/generic/sys-uio.cpp +++ /dev/null @@ -1,67 +0,0 @@ - -#include <sys/uio.h> -#include <unistd.h> -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <limits.h> - -#include <frg/vector.hpp> -#include <mlibc/allocator.hpp> -#include <mlibc/debug.hpp> -#include <mlibc/posix-sysdeps.hpp> -#include <bits/ensure.h> - -ssize_t readv(int fd, const struct iovec *iovs, int iovc) { - ssize_t read_bytes = 0; - - auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_readv, -1); - - if (int e = sysdep(fd, iovs, iovc, &read_bytes); e) { - errno = e; - return -1; - } - - return read_bytes; -} - -ssize_t writev(int fd, const struct iovec *iovs, int iovc) { - __ensure(iovc); - - ssize_t written = 0; - size_t bytes = 0; - for(int i = 0; i < iovc; i++) { - if(SSIZE_MAX - bytes < iovs[i].iov_len) { - errno = EINVAL; - return -1; - } - bytes += iovs[i].iov_len; - } - frg::vector<char, MemoryAllocator> buffer{getAllocator()}; - buffer.resize(bytes); - - size_t to_copy = bytes; - char *bp = buffer.data(); - for(int i = 0; i < iovc; i++) { - size_t copy = frg::min(iovs[i].iov_len, to_copy); - - bp = (char *)mempcpy((void *)bp, (void *)iovs[i].iov_base, copy); - - to_copy -= copy; - if(to_copy == 0) - break; - } - - written = write(fd, buffer.data(), bytes); - return written; -} - -ssize_t preadv(int, const struct iovec *, int, off_t) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -ssize_t pwritev(int, const struct iovec *, int, off_t) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} diff --git a/lib/mlibc/options/posix/generic/sys-utsname.cpp b/lib/mlibc/options/posix/generic/sys-utsname.cpp deleted file mode 100644 index 3176574..0000000 --- a/lib/mlibc/options/posix/generic/sys-utsname.cpp +++ /dev/null @@ -1,24 +0,0 @@ - -#include <string.h> -#include <sys/utsname.h> -#include <errno.h> - -#include <bits/ensure.h> -#include <mlibc/debug.hpp> -#include <internal-config.h> -#include <mlibc/posix-sysdeps.hpp> - -int uname(struct utsname *p) { - if (p == NULL) { - errno = EFAULT; - return -1; - } - - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_uname, -1); - if(int e = mlibc::sys_uname(p); e) { - errno = e; - return -1; - } - return 0; -} - diff --git a/lib/mlibc/options/posix/generic/sys-wait-stubs.cpp b/lib/mlibc/options/posix/generic/sys-wait-stubs.cpp deleted file mode 100644 index 6e7cc78..0000000 --- a/lib/mlibc/options/posix/generic/sys-wait-stubs.cpp +++ /dev/null @@ -1,52 +0,0 @@ - -#include <errno.h> -#include <sys/wait.h> -#include <bits/ensure.h> - -#include <mlibc/ansi-sysdeps.hpp> -#include <mlibc/posix-sysdeps.hpp> -#include <mlibc/debug.hpp> - -int waitid(idtype_t idtype, id_t id, siginfo_t *info, int options) { - auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_waitid, -1); - if(int e = sysdep(idtype, id, info, options); e) { - errno = e; - return -1; - } - return 0; -} - -pid_t waitpid(pid_t pid, int *status, int flags) { - pid_t ret; - int tmp_status = 0; - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_waitpid, -1); - if(int e = mlibc::sys_waitpid(pid, &tmp_status, flags, NULL, &ret); e) { - errno = e; - return -1; - } - if(status) { - *status = tmp_status; - } - return ret; -} - -pid_t wait(int *status) { - return waitpid(-1, status, 0); -} - -pid_t wait3(int *status, int options, struct rusage *rusage) { - (void) rusage; - mlibc::infoLogger() << "\e[31mmlibc: wait3() is not implemented correctly\e[39m" - << frg::endlog; - return waitpid(-1, status, options); -} - -pid_t wait4(pid_t pid, int *status, int options, struct rusage *ru) { - pid_t ret; - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_waitpid, -1); - if(int e = mlibc::sys_waitpid(pid, status, options, ru, &ret); e) { - errno = e; - return -1; - } - return ret; -} diff --git a/lib/mlibc/options/posix/generic/syslog-stubs.cpp b/lib/mlibc/options/posix/generic/syslog-stubs.cpp deleted file mode 100644 index 6a80ff9..0000000 --- a/lib/mlibc/options/posix/generic/syslog-stubs.cpp +++ /dev/null @@ -1,152 +0,0 @@ - -#include <syslog.h> -#include <string.h> -#include <unistd.h> -#include <stdio.h> -#include <errno.h> -#include <time.h> -#include <fcntl.h> -#include <pthread.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <bits/ensure.h> - -#include <frg/mutex.hpp> -#include <mlibc/lock.hpp> -#include <mlibc/debug.hpp> - -// This syslog implementation is largely taken from musl - -static char log_ident[32]; -static int log_options; -static int log_facility = LOG_USER; -static int log_fd = -1; -static int log_opt; -static int log_mask = 0xff; - -static int use_mlibc_logger = 0; -static FutexLock __syslog_lock; - -static const struct sockaddr_un log_addr {AF_UNIX, "/dev/log"}; - -void closelog(void) { - frg::unique_lock<FutexLock> holder { __syslog_lock }; - close(log_fd); - log_fd = -1; -} - -static void __openlog() { - log_fd = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0); - if(log_fd >= 0) { - int ret = connect(log_fd, (const sockaddr *)&log_addr, sizeof log_addr); - if(ret) { - mlibc::infoLogger() << "\e[31mmlibc: syslog: connect returned an error, falling back to infoLogger\e[39m" << frg::endlog; - use_mlibc_logger = 1; - } - } -} - -void openlog(const char *ident, int options, int facility) { - frg::unique_lock<FutexLock> holder { __syslog_lock }; - if(ident) { - size_t n = strnlen(ident, sizeof log_ident - 1); - memcpy(log_ident, ident, n); - log_ident[n] = 0; - } else { - log_ident[0] = 0; - } - log_options = options; - log_facility = facility; - - if((options & LOG_NDELAY) && log_fd < 0) - __openlog(); -} - -int setlogmask(int mask) { - int old_mask = log_mask; - - log_mask = mask; - - return old_mask; -} - -static void _vsyslog(int priority, const char *message, va_list ap) { - auto is_lost_conn = [] (int e) { - return e == ECONNREFUSED || e == ECONNRESET || e == ENOTCONN || e == EPIPE; - }; - - if(!(priority & log_mask)) { - return; - } - - char timebuf[16]; - time_t now; - struct tm tm; - char buf[1024]; - int errno_save = errno; - int pid; - int l, l2; - int hlen; - int fd; - - if(log_fd < 0) - __openlog(); - - if(use_mlibc_logger) { - vsnprintf(buf, sizeof buf, message, ap); - mlibc::infoLogger() << "mlibc: syslog: " << buf << frg::endlog; - return; - } - - if(!(priority & LOG_FACMASK)) - priority |= log_facility; - - now = time(NULL); - gmtime_r(&now, &tm); - strftime(timebuf, sizeof timebuf, "%b %e %T", &tm); - - pid = (log_opt & LOG_PID) ? getpid() : 0; - l = snprintf(buf, sizeof buf, "<%d>%s %n%s%s%.0d%s: ", - priority, timebuf, &hlen, log_ident, "[" + !pid, pid, "]" + !pid); - errno = errno_save; - l2 = vsnprintf(buf + l, sizeof buf - l, message, ap); - if(l2 >= 0) { - if(l2 >= (long int)(sizeof buf - l)) - l = sizeof buf - 1; - else - l += l2; - if(buf[l - 1] != '\n') - buf[l++] = '\n'; - if(send(log_fd, buf, l, 0) < 0 && (!is_lost_conn(errno) - || connect(log_fd, (const sockaddr *)&log_addr, sizeof log_addr) < 0 - || send(log_fd, buf, l, 0) < 0) - && (log_opt & LOG_CONS)) { - fd = open("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC); - if(fd >= 0) { - dprintf(fd, "%.*s", l - hlen, buf + hlen); - close(fd); - } - } - if(log_opt & LOG_PERROR) - dprintf(STDERR_FILENO, "%.*s", l - hlen, buf + hlen); - } -} - -void syslog(int priority, const char *format, ...) { - va_list ap; - va_start(ap, format); - vsyslog(priority, format, ap); - va_end(ap); -} - -void vsyslog(int priority, const char *message, va_list ap) { - int cs; - if(!(log_mask & LOG_MASK(priority & 7)) || (priority & ~0x3ff)) { - mlibc::infoLogger() << "\e[31mmlibc: syslog: log_mask or priority out of range, not printing anything\e[39m" << frg::endlog; - return; - } - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); - frg::unique_lock<FutexLock> lock(__syslog_lock); - _vsyslog(priority, message, ap); - pthread_setcancelstate(cs, 0); -} diff --git a/lib/mlibc/options/posix/generic/termios-stubs.cpp b/lib/mlibc/options/posix/generic/termios-stubs.cpp deleted file mode 100644 index 631456a..0000000 --- a/lib/mlibc/options/posix/generic/termios-stubs.cpp +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE -#endif - -#include <errno.h> -#include <termios.h> -#include <sys/ioctl.h> - -#include <bits/ensure.h> -#include <mlibc/posix-sysdeps.hpp> - -speed_t cfgetispeed(const struct termios *tios) { - return tios->c_cflag & CBAUD; -} - -speed_t cfgetospeed(const struct termios *tios) { - return tios->c_cflag & CBAUD; -} - -int cfsetispeed(struct termios *termios, speed_t speed) { - return speed ? cfsetospeed(termios, speed) : 0; -} - -int cfsetospeed(struct termios *termios, speed_t speed) { - if(speed & ~CBAUD) { - errno = EINVAL; - return -1; - } - - termios->c_cflag &= ~CBAUD; - termios->c_cflag |= speed; - - return 0; -} - -void cfmakeraw(struct termios *t) { - t->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); - t->c_oflag &= ~OPOST; - t->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); - t->c_cflag &= ~(CSIZE | PARENB); - t->c_cflag |= CS8; - t->c_cc[VMIN] = 1; - t->c_cc[VTIME] = 0; -} - -int tcdrain(int fd) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_tcdrain, -1); - if(int e = mlibc::sys_tcdrain(fd); e) { - errno = e; - return -1; - } - return 0; -} - -int tcflow(int fd, int action) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_tcflow, -1); - if(int e = mlibc::sys_tcflow(fd, action); e) { - errno = e; - return -1; - } - return 0; -} - -int tcflush(int fd, int queue_selector) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_tcflush, -1); - if(int e = mlibc::sys_tcflush(fd, queue_selector); e) { - errno = e; - return -1; - } - return 0; -} - -int tcgetattr(int fd, struct termios *attr) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_tcgetattr, -1); - if(int e = mlibc::sys_tcgetattr(fd, attr); e) { - errno = e; - return -1; - } - return 0; -} - -pid_t tcgetsid(int fd) { - int sid; - if(ioctl(fd, TIOCGSID, &sid) < 0) { - return -1; - } - return sid; -} - -int tcsendbreak(int, int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int tcsetattr(int fd, int opts, const struct termios *attr) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_tcsetattr, -1); - if(int e = mlibc::sys_tcsetattr(fd, opts, attr); e) { - errno = e; - return -1; - } - return 0; -} - diff --git a/lib/mlibc/options/posix/generic/time.cpp b/lib/mlibc/options/posix/generic/time.cpp deleted file mode 100644 index 14193af..0000000 --- a/lib/mlibc/options/posix/generic/time.cpp +++ /dev/null @@ -1,505 +0,0 @@ -#include <ctype.h> -#include <langinfo.h> -#include <stdio.h> -#include <string.h> -#include <time.h> - -#include <bits/ensure.h> -#include <mlibc/strings.hpp> - -namespace { - -int month_to_day(int month) { - switch(month){ - case 0: return 0; - case 1: return 31; - case 2: return 59; - case 3: return 90; - case 4: return 120; - case 5: return 151; - case 6: return 181; - case 7: return 212; - case 8: return 243; - case 9: return 273; - case 10: return 304; - case 11: return 334; - } - return -1; -} - -int is_leapyear(int year) { - return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); -} - -int month_and_year_to_day_in_year(int month, int year){ - int day = month_to_day(month); - if(is_leapyear(year) && month < 2) - return day + 1; - - return day; -} - -int target_determination(int month) { - switch(month){ - case 0: return 3; - case 1: return 14; - case 2: return 14; - case 3: return 4; - case 4: return 9; - case 5: return 6; - case 6: return 11; - case 7: return 8; - case 8: return 5; - case 9: return 10; - case 10: return 7; - case 11: return 12; - } - - return -1; -} - -int doom_determination(int full_year) { - int century = full_year / 100; - int anchor = 2 + 5 * (century % 4) % 7; - - int year = full_year % 100; - - if(year % 2) - year += 11; - - year /= 2; - - if(year % 2) - year += 11; - - return 7 - (year % 7) + anchor; -} - -//Determine day of week through the doomsday algorithm. -int day_determination(int day, int month, int year) { - int doom = doom_determination(year); - bool leap = is_leapyear(year); - - int target = target_determination(month); - if(leap && month < 2) - target++; - - int doom_dif = (day - target) % 7; - return (doom + doom_dif) % 7; -} - -struct strptime_internal_state { - bool has_century; - bool has_year; - bool has_month; - bool has_day_of_month; - bool has_day_of_year; - bool has_day_of_week; - - bool full_year_given; - - int century; - - size_t format_index; - size_t input_index; -}; - -char *strptime_internal(const char *__restrict input, const char *__restrict format, - struct tm *__restrict tm, struct strptime_internal_state *__restrict state) { - auto matchLanginfoItem = [&] (int start, size_t num, int &dest, bool &flag) -> bool { - for(size_t i = start; i < (start + num); i++) { - const char *mon = nl_langinfo(i); - size_t len = strlen(mon); - if(mlibc::strncasecmp(&input[state->input_index], mon, len)) - continue; - state->input_index += len; - dest = i - start; - flag = true; - return true; - } - return false; - }; - - auto matchNumericRange = [&] (int start, int end, int &dest, bool *flag) -> bool { - int product = 0, n = 0; - sscanf(&input[state->input_index], "%d%n", &product, &n); - if(n == 0 || 2 < n) - return false; - if(product < start || product > end) - return false; - state->input_index += n; - dest = product; - if(flag) *flag = true; - return true; - }; - - while(isspace(input[state->input_index])) - state->input_index++; - - if(input[state->input_index] == '\0') - return NULL; - - while(format[state->format_index] != '\0'){ - if(format[state->format_index] != '%'){ - if(isspace(format[state->format_index])){ - while(isspace(input[state->input_index++])); - state->input_index--; - } - else { - if(format[state->format_index] != input[state->input_index++]) - return NULL; - } - state->format_index++; - continue; - } - state->format_index++; - switch(format[state->format_index]){ - case '%': - if(input[state->input_index++] != '%') - return NULL; - break; - case 'a': - case 'A': { - if (!matchLanginfoItem(DAY_1, 7, tm->tm_wday, state->has_day_of_week) && \ - !matchLanginfoItem(ABDAY_1, 7, tm->tm_wday, state->has_day_of_week)) - return NULL; - break; - } - case 'b': - case 'B': - case 'h': { - if (!matchLanginfoItem(MON_1, 12, tm->tm_mon, state->has_month) && \ - !matchLanginfoItem(ABMON_1, 12, tm->tm_mon, state->has_month)) - return NULL; - break; - } - case 'c': - __ensure(!"strptime() %c directive unimplemented."); - __builtin_unreachable(); - break; - case 'C': { - int product = 0, n = 0; - sscanf(&input[state->input_index], "%d%n", &product, &n); - if(n == 0 || 2 < n) - return NULL; - state->input_index += n; - state->century = product; - state->has_century = true; - break; - } - case 'd': //`%d` and `%e` are equivalent - case 'e': { - if(!matchNumericRange(1, 31, tm->tm_mday, &state->has_day_of_month)) - return NULL; - break; - } - case 'D': { //equivalent to `%m/%d/%y` - size_t pre_fi = state->format_index; - state->format_index = 0; - - char *result = strptime_internal(input, "%m/%d/%y", tm, state); - if(result == NULL) - return NULL; - - state->format_index = pre_fi; - break; - } - case 'H': { - if(!matchNumericRange(0, 23, tm->tm_hour, nullptr)) - return NULL; - break; - } - case 'I': { - if(!matchNumericRange(1, 12, tm->tm_hour, nullptr)) - return NULL; - break; - } - case 'j': { - if(!matchNumericRange(1, 366, tm->tm_yday, &state->has_day_of_year)) - return NULL; - tm->tm_yday--; - break; - } - case 'm': { - if(!matchNumericRange(1, 12, tm->tm_mon, &state->has_month)) - return NULL; - tm->tm_mon--; - break; - } - case 'M': { - if(!matchNumericRange(0, 59, tm->tm_min, nullptr)) - return NULL; - break; - } - case 'n': - case 't': { - size_t n = 0; - while(isspace(input[state->input_index++])) - n++; - if(n == 0) - return NULL; - state->input_index--; - break; - } - case 'p': { - const char *meridian_str = nl_langinfo(AM_STR); - size_t len = strlen(meridian_str); - if (!mlibc::strncasecmp(&input[state->input_index], meridian_str, len)) { - tm->tm_hour %= 12; - state->input_index += len; - break; - } - meridian_str = nl_langinfo(PM_STR); - len = strlen(meridian_str); - if (!mlibc::strncasecmp(&input[state->input_index], meridian_str, len)) { - tm->tm_hour %= 12; - tm->tm_hour += 12; - state->input_index += len; - break; - } - break; - } - case 'r': { //equivalent to `%I:%M:%S %p` - size_t pre_fi = state->format_index; - state->format_index = 0; - - char *result = strptime_internal(input, "%I:%M:%S %p", tm, state); - if(result == NULL) - return NULL; - - state->format_index = pre_fi; - break; - } - case 'R': { //equivalent to `%H:%M` - size_t pre_fi = state->format_index; - state->format_index = 0; - - char *result = strptime_internal(input, "%H:%M", tm, state); - if(result == NULL) - return NULL; - - state->format_index = pre_fi; - break; - } - case 'S': { - if(!matchNumericRange(0, 60, tm->tm_sec, nullptr)) - return NULL; - break; - } - case 'T': { //equivalent to `%H:%M:%S` - size_t pre_fi = state->format_index; - state->format_index = 0; - - char *result = strptime_internal(input, "%H:%M:%S", tm, state); - if(result == NULL) - return NULL; - - state->format_index = pre_fi; - break; - } - case 'U': - __ensure(!"strptime() %U directive unimplemented."); - __builtin_unreachable(); - break; - case 'w': { - int product = 0, n = 0; - sscanf(&input[state->input_index], "%d%n", &product, &n); - if(n == 0 || 1 < n) - return NULL; - state->input_index += n; - tm->tm_wday = product; - state->has_day_of_week = true; - break; - } - case 'W': - __ensure(!"strptime() %W directive unimplemented."); - __builtin_unreachable(); - break; - case 'x': - __ensure(!"strptime() %x directive unimplemented."); - __builtin_unreachable(); - break; - case 'X': - __ensure(!"strptime() %X directive unimplemented."); - __builtin_unreachable(); - break; - case 'y': { - int product = 0, n = 0; - sscanf(&input[state->input_index], "%d%n", &product, &n); - if(n == 0 || 2 < n) - return NULL; - if(product < 69) - product += 100; - state->input_index += n; - tm->tm_year = product; - state->has_year = true; - break; - } - case 'Y': { - int product = 0, n = 0; - sscanf(&input[state->input_index], "%d%n", &product, &n); - if(n == 0 || 4 < n) - return NULL; - state->input_index += n; - tm->tm_year = product - 1900; - state->has_year = true; - state->has_century = true; - state->full_year_given = true; - state->century = product / 100; - break; - } - case 'F': { //GNU extensions - //equivalent to `%Y-%m-%d` - size_t pre_fi = state->format_index; - state->format_index = 0; - - char *result = strptime_internal(input, "%Y-%m-%d", tm, state); - if(result == NULL) - return NULL; - - state->format_index = pre_fi; - break; - } - case 'g': - __ensure(!"strptime() %g directive unimplemented."); - __builtin_unreachable(); - break; - case 'G': - __ensure(!"strptime() %G directive unimplemented."); - __builtin_unreachable(); - break; - case 'u': { - if(!matchNumericRange(1, 7, tm->tm_wday, nullptr)) - return NULL; - tm->tm_wday--; - break; - } - case 'V': - __ensure(!"strptime() %V directive unimplemented."); - __builtin_unreachable(); - break; - case 'z': - __ensure(!"strptime() %z directive unimplemented."); - __builtin_unreachable(); - break; - case 'Z': - __ensure(!"strptime() %Z directive unimplemented."); - __builtin_unreachable(); - break; - case 's': //end of GNU extensions - __ensure(!"strptime() %s directive unimplemented."); - __builtin_unreachable(); - break; - case 'E': { //locale-dependent date & time representation - __ensure(!"strptime() %E* directives unimplemented."); - __builtin_unreachable(); - /* - state->format_index++; - switch(format[state->format_index]){ - case 'c': - break; - case 'C': - break; - case 'x': - break; - case 'X': - break; - case 'y': - break; - case 'Y': - break; - default: - return NULL; - } - */ - } - case 'O': { //locale-dependent numeric symbols - __ensure(!"strptime() %O* directives unimplemented."); - __builtin_unreachable(); - /* - state->format_index++; - switch(format[state->format_index]){ - case 'd': - case 'e': - break; - case 'H': - break; - case 'I': - break; - case 'm': - break; - case 'M': - break; - case 'S': - break; - case 'U': - break; - case 'w': - break; - case 'W': - break; - case 'y': - break; - default: - return NULL; - } - */ - } - default: - return NULL; - } - state->format_index++; - } - - return (char*)input + state->input_index; -} - -} //anonymous namespace - -char *strptime(const char *__restrict s, const char *__restrict format, struct tm *__restrict tm){ - struct strptime_internal_state state = {}; - - char *result = strptime_internal(s, format, tm, &state); - - if(result == NULL) - return NULL; - - if(state.has_century && !state.full_year_given){ - int full_year = state.century * 100; - - if(state.has_year){ - //Compensate for default century-adjustment of `%j` operand - if(tm->tm_year >= 100) - full_year += tm->tm_year - 100; - else - full_year += tm->tm_year; - } - - tm->tm_year = full_year - 1900; - - state.has_year = true; - } - - if(state.has_month && !state.has_day_of_year){ - int day = 0; - if(state.has_year) - day = month_and_year_to_day_in_year(tm->tm_mon, tm->tm_year); - else - day = month_to_day(tm->tm_mon); - - tm->tm_yday = day + tm->tm_mday - 1; - state.has_day_of_year = true; - } - - if(state.has_year && !state.has_day_of_week){ - if(!state.has_month && !state.has_day_of_month){ - tm->tm_wday = day_determination(0, 0, tm->tm_year + 1900); - } - else if(state.has_month && state.has_day_of_month){ - tm->tm_wday = day_determination(tm->tm_mday, tm->tm_mon, tm->tm_year + 1900); - } - state.has_day_of_week = true; - } - - return result; -} diff --git a/lib/mlibc/options/posix/generic/ucontext-stubs.cpp b/lib/mlibc/options/posix/generic/ucontext-stubs.cpp deleted file mode 100644 index 9413a78..0000000 --- a/lib/mlibc/options/posix/generic/ucontext-stubs.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include <ucontext.h> -#include <bits/ensure.h> - -int getcontext(ucontext_t *) { - __ensure(!"Not implemented!"); - __builtin_unreachable(); -} -int setcontext(const ucontext_t *) { - __ensure(!"Not implemented!"); - __builtin_unreachable(); -} -void makecontext(ucontext_t *, void (*)(), int, ...) { - __ensure(!"Not implemented!"); - __builtin_unreachable(); -} -int swapcontext(ucontext_t *, const ucontext_t *) { - __ensure(!"Not implemented!"); - __builtin_unreachable(); -} diff --git a/lib/mlibc/options/posix/generic/unistd-stubs.cpp b/lib/mlibc/options/posix/generic/unistd-stubs.cpp deleted file mode 100644 index 39cf76a..0000000 --- a/lib/mlibc/options/posix/generic/unistd-stubs.cpp +++ /dev/null @@ -1,1227 +0,0 @@ -#include <stdio.h> -#include <errno.h> -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> -#include <sys/resource.h> -#include <unistd.h> -#include <limits.h> -#include <termios.h> -#include <pwd.h> -#include <sys/ioctl.h> - -#include <bits/ensure.h> -#include <mlibc/allocator.hpp> -#include <mlibc/arch-defs.hpp> -#include <mlibc/debug.hpp> -#include <mlibc/posix-sysdeps.hpp> -#include <mlibc/bsd-sysdeps.hpp> -#include <mlibc/thread.hpp> - -namespace { - -constexpr bool logExecvpeTries = false; - -} - -unsigned int alarm(unsigned int seconds) { - struct itimerval it = {}, old = {}; - it.it_value.tv_sec = seconds; - setitimer(ITIMER_REAL, &it, &old); - return old.it_value.tv_sec + !! old.it_value.tv_usec; -} - -int chdir(const char *path) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_chdir, -1); - if(int e = mlibc::sys_chdir(path); e) { - errno = e; - return -1; - } - return 0; -} - -int fchdir(int fd) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_fchdir, -1); - if(int e = mlibc::sys_fchdir(fd); e) { - errno = e; - return -1; - } - return 0; -} - -int chown(const char *path, uid_t uid, gid_t gid) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_fchownat, -1); - if(int e = mlibc::sys_fchownat(AT_FDCWD, path, uid, gid, 0); e) { - errno = e; - return -1; - } - return 0; -} - -ssize_t confstr(int name, char *buf, size_t len) { - const char *str = ""; - if (name == _CS_PATH) { - str = "/bin:/usr/bin"; - } else if(name == _CS_GNU_LIBPTHREAD_VERSION) { - // We are not glibc, so we can return 0 here. - return 0; - } else if(name == _CS_GNU_LIBC_VERSION) { - // We are not glibc, so we can return 0 here. - return 0; - } else { - mlibc::infoLogger() << "\e[31mmlibc: confstr() request " << name << " is unimplemented\e[39m" - << frg::endlog; - __ensure(!"Not implemented"); - } - - return snprintf(buf, len, "%s", str) + 1; -} - -void _exit(int status) { - mlibc::sys_exit(status); -} - -int execl(const char *path, const char *arg0, ...) { - // TODO: It's a stupid idea to limit the number of arguments here. - char *argv[16]; - argv[0] = const_cast<char *>(arg0); - - va_list args; - int n = 1; - va_start(args, arg0); - while(true) { - __ensure(n < 15); - auto argn = va_arg(args, const char *); - argv[n++] = const_cast<char *>(argn); - if(!argn) - break; - } - va_end(args); - argv[n] = nullptr; - - return execve(path, argv, environ); -} - -// This function is taken from musl. -int execle(const char *path, const char *arg0, ...) { - int argc; - va_list ap; - va_start(ap, arg0); - for(argc = 1; va_arg(ap, const char *); argc++); - va_end(ap); - - int i; - char *argv[argc + 1]; - char **envp; - va_start(ap, arg0); - argv[0] = (char *)argv; - for(i = 1; i <= argc; i++) - argv[i] = va_arg(ap, char *); - envp = va_arg(ap, char **); - va_end(ap); - return execve(path, argv, envp); -} - -// This function is taken from musl -int execlp(const char *file, const char *argv0, ...) { - int argc; - va_list ap; - va_start(ap, argv0); - for(argc = 1; va_arg(ap, const char *); argc++); - va_end(ap); - { - int i; - char *argv[argc + 1]; - va_start(ap, argv0); - argv[0] = (char *)argv0; - for(i = 1; i < argc; i++) - argv[i] = va_arg(ap, char *); - argv[i] = NULL; - va_end(ap); - return execvp(file, argv); - } -} - -int execv(const char *path, char *const argv[]) { - return execve(path, argv, environ); -} - -int execvp(const char *file, char *const argv[]) { - return execvpe(file, argv, environ); -} - -int execvpe(const char *file, char *const argv[], char *const envp[]) { - char *null_list[] = { - nullptr - }; - - if(!argv) - argv = null_list; - if(!envp) - envp = null_list; - - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_execve, -1); - - if(strchr(file, '/')) { - int e = mlibc::sys_execve(file, argv, envp); - __ensure(e && "sys_execve() is supposed to never return with success"); - errno = e; - return -1; - } - - frg::string_view dirs; - if(const char *pv = getenv("PATH"); pv) { - dirs = pv; - }else{ - dirs = "/bin:/usr/bin"; - } - - size_t p = 0; - int res = ENOENT; - while(p < dirs.size()) { - size_t s; // Offset of next colon or end of string. - if(size_t cs = dirs.find_first(':', p); cs != size_t(-1)) { - s = cs; - }else{ - s = dirs.size(); - } - - frg::string<MemoryAllocator> path{getAllocator()}; - path += dirs.sub_string(p, s - p); - path += "/"; - path += file; - - if(logExecvpeTries) - mlibc::infoLogger() << "mlibc: execvpe() tries '" << path.data() << "'" << frg::endlog; - - int e = mlibc::sys_execve(path.data(), argv, envp); - __ensure(e && "sys_execve() is supposed to never return with success"); - switch(e) { - case ENOENT: - case ENOTDIR: - break; - case EACCES: - res = EACCES; - break; - default: - errno = e; - return -1; - } - - p = s + 1; - } - - errno = res; - return -1; -} - -int faccessat(int dirfd, const char *pathname, int mode, int flags) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_faccessat, -1); - if(int e = mlibc::sys_faccessat(dirfd, pathname, mode, flags); e) { - errno = e; - return -1; - } - return 0; -} - -int fchown(int fd, uid_t uid, gid_t gid) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_fchownat, -1); - if(int e = mlibc::sys_fchownat(fd, "", uid, gid, AT_EMPTY_PATH); e) { - errno = e; - return -1; - } - return 0; -} - -int fchownat(int fd, const char *path, uid_t uid, gid_t gid, int flags) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_fchownat, -1); - if(int e = mlibc::sys_fchownat(fd, path, uid, gid, flags); e) { - errno = e; - return -1; - } - return 0; -} - -int fdatasync(int fd) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_fdatasync, -1); - if(int e = mlibc::sys_fdatasync(fd); e) { - errno = e; - return -1; - } - return 0; -} - -int fexecve(int, char *const [], char *const []) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -long fpathconf(int, int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int fsync(int fd) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_fsync, -1); - if(auto e = mlibc::sys_fsync(fd); e) { - errno = e; - return -1; - } - return 0; -} - -int ftruncate(int fd, off_t size) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_ftruncate, -1); - if(int e = mlibc::sys_ftruncate(fd, size); e) { - errno = e; - return -1; - } - return 0; -} - -char *getcwd(char *buffer, size_t size) { - if (buffer) { - if (size == 0) { - errno = EINVAL; - return NULL; - } - } else if (!buffer) { - if (size == 0) - size = PATH_MAX; - - buffer = (char *)malloc(size); - } - - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_getcwd, nullptr); - if(int e = mlibc::sys_getcwd(buffer, size); e) { - errno = e; - return NULL; - } - - return buffer; -} - -int getgroups(int size, gid_t list[]) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_getgroups, -1); - int ret; - if(int e = mlibc::sys_getgroups(size, list, &ret); e) { - errno = e; - return -1; - } - return ret; -} - -long gethostid(void) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int gethostname(char *buffer, size_t bufsize) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_gethostname, -1); - if(auto e = mlibc::sys_gethostname(buffer, bufsize); e) { - errno = e; - return -1; - } - return 0; -} - -int sethostname(const char *buffer, size_t bufsize) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_sethostname, -1); - if(auto e = mlibc::sys_sethostname(buffer, bufsize); e) { - errno = e; - return -1; - } - return 0; -} - -// Code taken from musl -char *getlogin(void) { - return getenv("LOGNAME"); -} - -int getlogin_r(char *, size_t) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -// optarg and optind are provided to us by the GLIBC part of the mlibc. - -static char *scan = NULL; /* Private scan pointer. */ - -int getopt(int argc, char *const argv[], const char *optstring) { - char c; - char *place; - - optarg = NULL; - - if (!scan || *scan == '\0') { - if (optind == 0) - optind++; - - if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0') - return EOF; - if (argv[optind][1] == '-' && argv[optind][2] == '\0') { - optind++; - return EOF; - } - - scan = argv[optind]+1; - optind++; - } - - c = *scan++; - place = strchr(optstring, c); - - if (!place || c == ':') { - fprintf(stderr, "%s: unknown option -%c\n", argv[0], c); - return '?'; - } - - place++; - if (*place == ':') { - if (*scan != '\0') { - optarg = scan; - scan = NULL; - } else if( optind < argc ) { - optarg = argv[optind]; - optind++; - } else { - fprintf(stderr, "%s: option requires argument -%c\n", argv[0], c); - return ':'; - } - } - - return c; -} - -pid_t getpgid(pid_t pid) { - pid_t pgid; - - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_getpgid, -1); - if(int e = mlibc::sys_getpgid(pid, &pgid); e) { - errno = e; - return -1; - } - return pgid; -} - -pid_t getpgrp(void) { - return getpgid(0); -} - -pid_t getsid(pid_t pid) { - if(!mlibc::sys_getsid) { - MLIBC_MISSING_SYSDEP(); - return -1; - } - pid_t sid; - if(int e = mlibc::sys_getsid(pid, &sid); e) { - errno = e; - return -1; - } - return sid; -} - -int lchown(const char *path, uid_t uid, gid_t gid) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_fchownat, -1); - if(int e = mlibc::sys_fchownat(AT_FDCWD, path, uid, gid, AT_SYMLINK_NOFOLLOW); e) { - errno = e; - return -1; - } - return 0; -} - -int link(const char *old_path, const char *new_path) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_link, -1); - if(int e = mlibc::sys_link(old_path, new_path); e) { - errno = e; - return -1; - } - return 0; -} - -int linkat(int olddirfd, const char *old_path, int newdirfd, const char *new_path, int flags) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_linkat, -1); - if(int e = mlibc::sys_linkat(olddirfd, old_path, newdirfd, new_path, flags); e) { - errno = e; - return -1; - } - return 0; -} - -// Code take from musl -int lockf(int fd, int op, off_t size) { - struct flock l = { - .l_type = F_WRLCK, - .l_whence = SEEK_CUR, - .l_start = 0, - .l_len = size, - .l_pid = 0, - }; - - switch(op) { - case F_TEST: - l.l_type = F_RDLCK; - if(fcntl(fd, F_GETLK, &l) < 0) - return -1; - if(l.l_type == F_UNLCK || l.l_pid == getpid()) - return 0; - errno = EACCES; - return -1; - case F_ULOCK: - l.l_type = F_UNLCK; - [[fallthrough]]; - case F_TLOCK: - return fcntl(fd, F_SETLK, &l); - case F_LOCK: - return fcntl(fd, F_SETLKW, &l); - } - - errno = EINVAL; - return -1; -} - -int nice(int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -long pathconf(const char *, int name) { - switch (name) { - case _PC_NAME_MAX: - return NAME_MAX; - default: - mlibc::infoLogger() << "missing pathconf() entry " << name << frg::endlog; - errno = EINVAL; - return -1; - } -} - -int pause(void) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_pause, -1); - if(int e = mlibc::sys_pause(); e) { - errno = e; - return -1; - } - __ensure(!"There is no successful completion return value for pause"); - __builtin_unreachable(); -} - -int pipe(int *fds) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_pipe, -1); - if(int e = mlibc::sys_pipe(fds, 0); e) { - errno = e; - return -1; - } - return 0; -} - -int pipe2(int *fds, int flags) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_pipe, -1); - if(int e = mlibc::sys_pipe(fds, flags); e) { - errno = e; - return -1; - } - return 0; -} - -ssize_t pread(int fd, void *buf, size_t n, off_t off) { - ssize_t num_read; - - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_pread, -1); - if(int e = mlibc::sys_pread(fd, buf, n, off, &num_read); e) { - errno = e; - return -1; - } - return num_read; -} - -ssize_t pwrite(int fd, const void *buf, size_t n, off_t off) { - ssize_t num_written; - - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_pwrite, -1); - if(int e = mlibc::sys_pwrite(fd, buf, n, off, &num_written); e) { - errno = e; - return -1; - } - return num_written; -} - -ssize_t readlink(const char *__restrict path, char *__restrict buffer, size_t max_size) { - ssize_t length; - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_readlink, -1); - if(int e = mlibc::sys_readlink(path, buffer, max_size, &length); e) { - errno = e; - return -1; - } - return length; -} - -ssize_t readlinkat(int, const char *__restrict, char *__restrict, size_t) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int rmdir(const char *path) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_rmdir, -1); - if(int e = mlibc::sys_rmdir(path); e) { - errno = e; - return -1; - } - return 0; -} - -int setegid(gid_t egid) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_setegid, 0); - if(int e = mlibc::sys_setegid(egid); e) { - errno = e; - return -1; - } - return 0; -} - -int seteuid(uid_t euid) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_seteuid, 0); - if(int e = mlibc::sys_seteuid(euid); e) { - errno = e; - return -1; - } - return 0; -} - -int setgid(gid_t gid) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_setgid, 0); - if(int e = mlibc::sys_setgid(gid); e) { - errno = e; - return -1; - } - return 0; -} - -int setpgid(pid_t pid, pid_t pgid) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_setpgid, -1); - if(int e = mlibc::sys_setpgid(pid, pgid); e) { - errno = e; - return -1; - } - return 0; -} - -pid_t setpgrp(void) { - return setpgid(0, 0); -} - -int setregid(gid_t rgid, gid_t egid) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_setregid, -1); - if(int e = mlibc::sys_setregid(rgid, egid); e) { - errno = e; - return -1; - } - return 0; -} - -int setreuid(uid_t ruid, uid_t euid) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_setreuid, -1); - if(int e = mlibc::sys_setreuid(ruid, euid); e) { - errno = e; - return -1; - } - return 0; -} - -pid_t setsid(void) { - if(!mlibc::sys_setsid) { - MLIBC_MISSING_SYSDEP(); - return -1; - } - pid_t sid; - if(int e = mlibc::sys_setsid(&sid); e) { - errno = e; - return -1; - } - return sid; -} - -int setuid(uid_t uid) { - if(!mlibc::sys_setuid) { - MLIBC_MISSING_SYSDEP(); - mlibc::infoLogger() << "mlibc: missing sysdep sys_setuid(). Returning 0" << frg::endlog; - return 0; - } - if(int e = mlibc::sys_setuid(uid); e) { - errno = e; - return -1; - } - return 0; -} - -void swab(const void *__restrict, void *__restrict, ssize_t) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int symlink(const char *target_path, const char *link_path) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_symlink, -1); - if(int e = mlibc::sys_symlink(target_path, link_path); e) { - errno = e; - return -1; - } - return 0; -} - -int symlinkat(const char *target_path, int dirfd, const char *link_path) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_symlinkat, -1); - if(int e = mlibc::sys_symlinkat(target_path, dirfd, link_path); e) { - errno = e; - return -1; - } - return 0; -} - -void sync(void) { - if(!mlibc::sys_sync) { - MLIBC_MISSING_SYSDEP(); - } else { - mlibc::sys_sync(); - } -} - -long sysconf(int number) { - if(mlibc::sys_sysconf) { - long ret = 0; - - int e = mlibc::sys_sysconf(number, &ret); - - if(e && e != EINVAL) { - errno = e; - return -1; - } - - if(e != EINVAL) { - return ret; - } - } - - /* default return values, if not overriden by sysdep */ - switch(number) { - case _SC_ARG_MAX: - // On linux, it is defined to 2097152 in most cases, so define it to be 2097152 - return 2097152; - case _SC_PAGE_SIZE: - return mlibc::page_size; - case _SC_OPEN_MAX: - mlibc::infoLogger() << "\e[31mmlibc: sysconf(_SC_OPEN_MAX) returns fallback value 256\e[39m" << frg::endlog; - return 256; - case _SC_PHYS_PAGES: - mlibc::infoLogger() << "\e[31mmlibc: sysconf(_SC_PHYS_PAGES) returns fallback value 1024\e[39m" << frg::endlog; - return 1024; - case _SC_NPROCESSORS_ONLN: - mlibc::infoLogger() << "\e[31mmlibc: sysconf(_SC_NPROCESSORS_ONLN) returns fallback value 1\e[39m" << frg::endlog; - return 1; - case _SC_GETPW_R_SIZE_MAX: - return NSS_BUFLEN_PASSWD; - case _SC_GETGR_R_SIZE_MAX: - mlibc::infoLogger() << "\e[31mmlibc: sysconf(_SC_GETGR_R_SIZE_MAX) returns fallback value 1024\e[39m" << frg::endlog; - return 1024; - case _SC_CHILD_MAX: - mlibc::infoLogger() << "\e[31mmlibc: sysconf(_SC_CHILD_MAX) returns fallback value 25\e[39m" << frg::endlog; - // On linux, it is defined to 25 in most cases, so define it to be 25 - return 25; - case _SC_JOB_CONTROL: - mlibc::infoLogger() << "\e[31mmlibc: sysconf(_SC_JOB_CONTROL) returns fallback value 1\e[39m" << frg::endlog; - // If 1, job control is supported - return 1; - case _SC_CLK_TCK: - // TODO: This should be obsolete? - mlibc::infoLogger() << "\e[31mmlibc: sysconf(_SC_CLK_TCK) is obsolete and returns arbitrary value 1000000\e[39m" << frg::endlog; - return 1000000; - case _SC_NGROUPS_MAX: - mlibc::infoLogger() << "\e[31mmlibc: sysconf(_SC_NGROUPS_MAX) returns fallback value 65536\e[39m" << frg::endlog; - // On linux, it is defined to 65536 in most cases, so define it to be 65536 - return 65536; - case _SC_RE_DUP_MAX: - mlibc::infoLogger() << "\e[31mmlibc: sysconf(_SC_RE_DUP_MAX) returns fallback value RE_DUP_MAX\e[39m" << frg::endlog; - return RE_DUP_MAX; - case _SC_LINE_MAX: - mlibc::infoLogger() << "\e[31mmlibc: sysconf(_SC_LINE_MAX) returns fallback value 2048\e[39m" << frg::endlog; - // Linux defines it as 2048. - return 2048; - case _SC_XOPEN_CRYPT: -#if __MLIBC_CRYPT_OPTION - return _XOPEN_CRYPT; -#else - return -1; -#endif /* __MLIBC_CRYPT_OPTION */ - case _SC_NPROCESSORS_CONF: - // TODO: actually return a proper value for _SC_NPROCESSORS_CONF - mlibc::infoLogger() << "\e[31mmlibc: sysconf(_SC_NPROCESSORS_CONF) unconditionally returns fallback value 1\e[39m" << frg::endlog; - return 1; - case _SC_HOST_NAME_MAX: - mlibc::infoLogger() << "\e[31mmlibc: sysconf(_SC_HOST_NAME_MAX) unconditionally returns fallback value 256\e[39m" << frg::endlog; - return 256; - default: - mlibc::infoLogger() << "\e[31mmlibc: sysconf() call is not implemented, number: " << number << "\e[39m" << frg::endlog; - errno = EINVAL; - return -1; - } -} - -pid_t tcgetpgrp(int fd) { - int pgrp; - if(ioctl(fd, TIOCGPGRP, &pgrp) < 0) { - return -1; - } - return pgrp; -} - -int tcsetpgrp(int fd, pid_t pgrp) { - return ioctl(fd, TIOCSPGRP, &pgrp); -} - -int truncate(const char *, off_t) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -char *ttyname(int fd) { - const size_t size = 128; - static thread_local char buf[size]; - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_ttyname, nullptr); - if(int e = mlibc::sys_ttyname(fd, buf, size); e) { - errno = e; - return nullptr; - } - return buf; -} - -int ttyname_r(int fd, char *buf, size_t size) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_ttyname, -1); - if(int e = mlibc::sys_ttyname(fd, buf, size); e) { - return e; - } - return 0; -} - -int unlink(const char *path) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_unlinkat, -1); - if(int e = mlibc::sys_unlinkat(AT_FDCWD, path, 0); e) { - errno = e; - return -1; - } - return 0; -} - -int unlinkat(int fd, const char *path, int flags) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_unlinkat, -1); - if(int e = mlibc::sys_unlinkat(fd, path, flags); e) { - errno = e; - return -1; - } - return 0; -} - -int getpagesize() { - return mlibc::page_size; -} - -// Code taken from musl -// GLIBC extension for stdin/stdout -char *getpass(const char *prompt) { - int fdin, fdout; - struct termios s, t; - ssize_t l; - static char password[128]; - - if((fdin = open("/dev/tty", O_RDWR|O_NOCTTY|O_CLOEXEC)) < 0) { - fdin = STDIN_FILENO; - fdout = STDOUT_FILENO; - } else { - fdout = fdin; - } - - tcgetattr(fdin, &t); - s = t; - t.c_lflag &= ~(ECHO | ISIG); - t.c_lflag |= ICANON; - t.c_iflag &= ~(INLCR | IGNCR); - t.c_iflag |= ICRNL; - tcsetattr(fdin, TCSAFLUSH, &t); - tcdrain(fdin); - - dprintf(fdout, "%s", prompt); - - l = read(fdin, password, sizeof password); - if(l >= 0) { - if((l > 0 && password[l - 1] == '\n') || l == sizeof password) - l--; - password[l] = 0; - } - - tcsetattr(fdin, TCSAFLUSH, &s); - - dprintf(fdout, "\n"); - if(fdin != STDIN_FILENO) { - close(fdin); - } - - return l < 0 ? 0 : password; -} - -char *get_current_dir_name(void) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -// This is a Linux extension -pid_t gettid(void) { - if(!mlibc::sys_gettid) { - MLIBC_MISSING_SYSDEP(); - __ensure(!"Cannot continue without sys_gettid()"); - } - return mlibc::sys_gettid(); -} - -int getentropy(void *buffer, size_t length) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_getentropy, -1); - if(length > 256) { - errno = EIO; - return -1; - } - if(int e = mlibc::sys_getentropy(buffer, length); e) { - errno = e; - return -1; - } - return 0; -} - -ssize_t write(int fd, const void *buf, size_t count) { - ssize_t bytes_written; - if(int e = mlibc::sys_write(fd, buf, count, &bytes_written); e) { - errno = e; - return (ssize_t)-1; - } - return bytes_written; -} - -ssize_t read(int fd, void *buf, size_t count) { - ssize_t bytes_read; - if(int e = mlibc::sys_read(fd, buf, count, &bytes_read); e) { - errno = e; - return (ssize_t)-1; - } - return bytes_read; -} - -off_t lseek(int fd, off_t offset, int whence) { - off_t new_offset; - if(int e = mlibc::sys_seek(fd, offset, whence, &new_offset); e) { - errno = e; - return (off_t)-1; - } - return new_offset; -} - -off64_t lseek64(int fd, off64_t offset, int whence) { - off64_t new_offset; - if(int e = mlibc::sys_seek(fd, offset, whence, &new_offset); e) { - errno = e; - return (off64_t)-1; - } - return new_offset; -} - -int close(int fd) { - return mlibc::sys_close(fd); -} - -unsigned int sleep(unsigned int secs) { - time_t seconds = secs; - long nanos = 0; - if(!mlibc::sys_sleep) { - MLIBC_MISSING_SYSDEP(); - __ensure(!"Cannot continue without sys_sleep()"); - } - mlibc::sys_sleep(&seconds, &nanos); - return seconds; -} - -// In contrast to sleep() this functions returns 0/-1 on success/failure. -int usleep(useconds_t usecs) { - time_t seconds = 0; - long nanos = usecs * 1000; - if(!mlibc::sys_sleep) { - MLIBC_MISSING_SYSDEP(); - __ensure(!"Cannot continue without sys_sleep()"); - } - return mlibc::sys_sleep(&seconds, &nanos); -} - -int dup(int fd) { - int newfd; - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_dup, -1); - if(int e = mlibc::sys_dup(fd, 0, &newfd); e) { - errno = e; - return -1; - } - return newfd; -} - -int dup2(int fd, int newfd) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_dup2, -1); - if(int e = mlibc::sys_dup2(fd, 0, newfd); e) { - errno = e; - return -1; - } - return newfd; -} - -pid_t fork(void) { - auto self = mlibc::get_current_tcb(); - pid_t child; - - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_fork, -1); - - auto hand = self->atforkEnd; - while (hand) { - if (hand->prepare) - hand->prepare(); - - hand = hand->prev; - } - - if(int e = mlibc::sys_fork(&child); e) { - errno = e; - return -1; - } - - hand = self->atforkBegin; - while (hand) { - if (!child) { - if (hand->child) - hand->child(); - } else { - if (hand->parent) - hand->parent(); - } - hand = hand->next; - } - - return child; -} - -pid_t vfork(void) { - pid_t child; - /* - * Fork handlers established using pthread_atfork(3) are not - * called when a multithreaded program employing the NPTL - * threading library calls vfork(). Fork handlers are called - * in this case in a program using the LinuxThreads threading - * library. (See pthreads(7) for a description of Linux - * threading libraries.) - * - vfork(2), release 5.13 of the Linux man-pages project - * - * as a result, we call sys_fork instead of running atforks - */ - - /* deferring to fork as implementing vfork correctly requires assembly - * to handle not mucking up the stack - */ - if(!mlibc::sys_fork) { - MLIBC_MISSING_SYSDEP(); - errno = ENOSYS; - return -1; - } - - if(int e = mlibc::sys_fork(&child); e) { - errno = e; - return -1; - } - - return child; -} - -int execve(const char *path, char *const argv[], char *const envp[]) { - char *null_list[] = { - nullptr - }; - - if(!argv) - argv = null_list; - if(!envp) - envp = null_list; - - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_execve, -1); - int e = mlibc::sys_execve(path, argv, envp); - __ensure(e && "sys_execve() is expected to fail if it returns"); - errno = e; - return -1; -} - -gid_t getgid(void) { - if(!mlibc::sys_getgid) { - MLIBC_MISSING_SYSDEP(); - __ensure(!"Cannot continue without sys_getgid()"); - } - return mlibc::sys_getgid(); -} - -gid_t getegid(void) { - if(!mlibc::sys_getegid) { - MLIBC_MISSING_SYSDEP(); - __ensure(!"Cannot continue without sys_getegid()"); - } - return mlibc::sys_getegid(); -} - -uid_t getuid(void) { - if(!mlibc::sys_getuid) { - MLIBC_MISSING_SYSDEP(); - __ensure(!"Cannot continue without sys_getuid()"); - } - return mlibc::sys_getuid(); -} - -uid_t geteuid(void) { - if(!mlibc::sys_geteuid) { - MLIBC_MISSING_SYSDEP(); - __ensure(!"Cannot continue without sys_geteuid()"); - } - return mlibc::sys_geteuid(); -} - -pid_t getpid(void) { - if(!mlibc::sys_getpid) { - MLIBC_MISSING_SYSDEP(); - __ensure(!"Cannot continue without sys_getpid()"); - } - return mlibc::sys_getpid(); -} - -pid_t getppid(void) { - if(!mlibc::sys_getppid) { - MLIBC_MISSING_SYSDEP(); - __ensure(!"Cannot continue without sys_getppid()"); - } - return mlibc::sys_getppid(); -} - -int access(const char *path, int mode) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_access, -1); - if(int e = mlibc::sys_access(path, mode); e) { - errno = e; - return -1; - } - return 0; -} - -char *getusershell(void) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -void setusershell(void) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -void endusershell(void) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int isatty(int fd) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_isatty, 0); - if(int e = mlibc::sys_isatty(fd); e) { - errno = e; - return 0; - } - return 1; -} - -int chroot(const char *ptr) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_chroot, -1); - if(int e = mlibc::sys_chroot(ptr); e) { - errno = e; - return -1; - } - return 0; -} - -int daemon(int, int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -char *ctermid(char *s) { - return s ? strcpy(s, "/dev/tty") : const_cast<char *>("/dev/tty"); -} - -int setresuid(uid_t ruid, uid_t euid, uid_t suid) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_setresuid, -1); - if(int e = mlibc::sys_setresuid(ruid, euid, suid); e) { - errno = e; - return -1; - } - return 0; -} - -int setresgid(gid_t rgid, gid_t egid, gid_t sgid) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_setresgid, -1); - if(int e = mlibc::sys_setresgid(rgid, egid, sgid); e) { - errno = e; - return -1; - } - return 0; -} - -int getdomainname(char *, size_t) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int setdomainname(const char *, size_t) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_getresuid, -1); - if(int e = mlibc::sys_getresuid(ruid, euid, suid); e) { - errno = e; - return -1; - } - return 0; -} - -int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_getresgid, -1); - if(int e = mlibc::sys_getresgid(rgid, egid, sgid); e) { - errno = e; - return -1; - } - return 0; -} - -#if __MLIBC_CRYPT_OPTION -void encrypt(char[64], int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -#endif - -#if __MLIBC_BSD_OPTION -void *sbrk(intptr_t increment) { - if(increment) { - errno = ENOMEM; - return (void *)-1; - } - - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_brk, (void *)-1); - void *out; - if(int e = mlibc::sys_brk(&out); e) { - errno = e; - return (void *)-1; - } - return out; -} -#endif diff --git a/lib/mlibc/options/posix/generic/utime-stubs.cpp b/lib/mlibc/options/posix/generic/utime-stubs.cpp deleted file mode 100644 index f78729f..0000000 --- a/lib/mlibc/options/posix/generic/utime-stubs.cpp +++ /dev/null @@ -1,31 +0,0 @@ - -#include <utime.h> -#include <fcntl.h> -#include <errno.h> - -#include <bits/ensure.h> -#include <mlibc/posix-sysdeps.hpp> - -int utime(const char *filename, const struct utimbuf *times) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_utimensat, -1); - struct timespec time[2]; - if(times) { - time[0].tv_sec = times->actime; - time[0].tv_nsec = 0; - time[1].tv_sec = times->modtime; - time[1].tv_nsec = 0; - } else { - time[0].tv_sec = UTIME_NOW; - time[0].tv_nsec = UTIME_NOW; - time[1].tv_sec = UTIME_NOW; - time[1].tv_nsec = UTIME_NOW; - } - - if (int e = mlibc::sys_utimensat(AT_FDCWD, filename, time, 0); e) { - errno = e; - return -1; - } - - return 0; -} - diff --git a/lib/mlibc/options/posix/generic/wordexp-stubs.cpp b/lib/mlibc/options/posix/generic/wordexp-stubs.cpp deleted file mode 100644 index 8443527..0000000 --- a/lib/mlibc/options/posix/generic/wordexp-stubs.cpp +++ /dev/null @@ -1,342 +0,0 @@ -/* - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * code taken from OPNSense, with modifications - * - * Copyright (c) 2002 Tim J. Robbins. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <wordexp.h> -#include <fcntl.h> -#include <sys/wait.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <stdlib.h> -#include <signal.h> -#include <stdint.h> - -#define SHELL_PATH "/bin/sh" -#define SHELL_NAME "sh" - -static size_t we_read_fully(int fd, char *buffer, size_t len) { - size_t done = 0; - - do { - ssize_t nread = read(fd, buffer + done, len - done); - if(nread == -1 && errno == EINTR) - continue; - if(nread <= 0) - break; - done += nread; - } while (done != len); - - return done; -} - -static int we_askshell(const char *words, wordexp_t *we, int flags) { - int pdes[2]; /* pipe to child */ - char bbuf[9]; /* buffer for byte count */ - char wbuf[9]; /* buffer for word count */ - size_t nwords = 0; /* number of words from child */ - size_t nbytes = 0; /* number of bytes from child */ - size_t sofs = 0; /* offset into we->we_strings */ - size_t vofs = 0; /* offset into we->we_wordv */ - pid_t pid; /* PID of child */ - pid_t wpid; /* waitpid return value */ - int status; /* child exit status */ - int error; /* our return value */ - int serrno; /* errno to return */ - char *np, *p; /* handy pointers */ - char *nstrings; /* temporary for realloc() */ - char **new_wordv; /* temporary for realloc() */ - sigset_t newsigblock; - sigset_t oldsigblock; - const char *ifs = getenv("IFS"); - - serrno = errno; - - if(pipe2(pdes, O_CLOEXEC) < 0) - return WRDE_NOSPACE; - - (void)sigemptyset(&newsigblock); - (void)sigaddset(&newsigblock, SIGCHLD); - (void)sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock); - - if((pid = fork()) < 0) { - serrno = errno; - close(pdes[0]); - close(pdes[1]); - (void)sigprocmask(SIG_SETMASK, &oldsigblock, NULL); - errno = serrno; - return WRDE_NOSPACE; - } else if(pid == 0) { - /* - * We are the child; make /bin/sh expand `words'. - */ - (void)sigprocmask(SIG_SETMASK, &oldsigblock, NULL); - if((pdes[1] != STDOUT_FILENO ? dup2(pdes[1], STDOUT_FILENO) : fcntl(pdes[1], F_SETFD, 0)) < 0) - _exit(1); - - execl(SHELL_PATH, SHELL_NAME, flags & WRDE_UNDEF ? "-u" : "+u", - "-c", "IFS=$1;eval \"$2\";eval \"set -- $3\";IFS=;a=\"$*\";" - "printf '%08x' \"$#\" \"${#a}\";printf '%s\\0' \"$@\"", "", - ifs != NULL ? ifs : " \t\n", - flags & WRDE_SHOWERR ? "" : "exec 2>/dev/null", - words, - (char *)NULL); - _exit(1); - } - - /* - * We are the parent; read the output of the shell wordexp function, - * which is a 32-bit hexadecimal word count, a 32-bit hexadecimal - * byte count (not including terminating null bytes), followed by - * the expanded words separated by nulls. - */ - close(pdes[1]); - if(we_read_fully(pdes[0], wbuf, 8) != 8 || we_read_fully(pdes[0], bbuf, 8) != 8) { - error = flags & WRDE_UNDEF ? WRDE_BADVAL : WRDE_SYNTAX; - serrno = errno; - goto cleanup; - } - wbuf[8] = bbuf[8] = '\0'; - nwords = strtol(wbuf, NULL, 16); - nbytes = strtol(bbuf, NULL, 16) + nwords; - - /* - * Allocate or reallocate (when flags & WRDE_APPEND) the word vector - * and string storage buffers for the expanded words we're about to - * read from the child. - */ - sofs = we->we_nbytes; - vofs = we->we_wordc; - if((flags & (WRDE_DOOFFS|WRDE_APPEND)) == (WRDE_DOOFFS | WRDE_APPEND)) - vofs += we->we_offs; - we->we_wordc += nwords; - we->we_nbytes += nbytes; - - if((new_wordv = (char **) realloc(we->we_wordv, (we->we_wordc + 1 + (flags & WRDE_DOOFFS ? we->we_offs : 0)) * sizeof(char *))) == NULL) { - error = WRDE_NOSPACE; - goto cleanup; - } - - we->we_wordv = new_wordv; - - if((nstrings = (char *) realloc(we->we_strings, we->we_nbytes)) == NULL) { - error = WRDE_NOSPACE; - goto cleanup; - } - - for(size_t i = 0; i < vofs; i++) { - if(we->we_wordv[i] != NULL) - we->we_wordv[i] += nstrings - we->we_strings; - } - we->we_strings = nstrings; - - if(we_read_fully(pdes[0], we->we_strings + sofs, nbytes) != nbytes) { - error = flags & WRDE_UNDEF ? WRDE_BADVAL : WRDE_SYNTAX; - serrno = errno; - goto cleanup; - } - - error = 0; -cleanup: - close(pdes[0]); - - do { - wpid = waitpid(pid, &status, 0); - } while(wpid < 0 && errno == EINTR); - - (void)sigprocmask(SIG_SETMASK, &oldsigblock, NULL); - - if(error != 0) { - errno = serrno; - return error; - } - - if(wpid < 0 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) - return flags & WRDE_UNDEF ? WRDE_BADVAL : WRDE_SYNTAX; - - /* - * Break the null-terminated expanded word strings out into - * the vector. - */ - if(vofs == 0 && flags & WRDE_DOOFFS) { - while (vofs < we->we_offs) - we->we_wordv[vofs++] = NULL; - } - - p = we->we_strings + sofs; - while (nwords-- != 0) { - we->we_wordv[vofs++] = p; - if((np = (char *) memchr(p, '\0', nbytes)) == NULL) - return WRDE_NOSPACE; - - nbytes -= np - p + 1; - p = np + 1; - } - - we->we_wordv[vofs] = NULL; - return 0; -} - -/* - * we_check -- - * Check that the string contains none of the following unquoted - * special characters: <newline> |&;<>(){} - * or command substitutions when WRDE_NOCMD is set in flags. - */ -static int we_check(const char *words, int flags) -{ - char c; - int dquote, level, quote, squote; - - quote = squote = dquote = 0; - while ((c = *words++) != '\0') { - switch (c) { - case '\\': { - if(squote == 0) - quote ^= 1; - continue; - } - case '\'': { - if(quote + dquote == 0) - squote ^= 1; - break; - } - case '"': { - if(quote + squote == 0) - dquote ^= 1; - break; - } - case '`': { - if(quote + squote == 0 && flags & WRDE_NOCMD) - return WRDE_CMDSUB; - while ((c = *words++) != '\0' && c != '`') - if(c == '\\' && (c = *words++) == '\0') - break; - if(c == '\0') - return WRDE_SYNTAX; - break; - } - case '|': - case '&': - case ';': - case '<': - case '>': - case '{': - case '}': - case '(': - case ')': - case '\n': { - if(quote + squote + dquote == 0) - return WRDE_BADCHAR; - break; - } - case '$': { - if((c = *words++) == '\0') - break; - else if(quote + squote == 0 && c == '(') { - if(flags & WRDE_NOCMD && *words != '(') - return WRDE_CMDSUB; - level = 1; - while ((c = *words++) != '\0') { - if(c == '\\') { - if((c = *words++) == '\0') - break; - } else if(c == '(') - level++; - else if(c == ')' && --level == 0) - break; - } - if(c == '\0' || level != 0) - return WRDE_SYNTAX; - } else if(quote + squote == 0 && c == '{') { - level = 1; - while ((c = *words++) != '\0') { - if(c == '\\') { - if((c = *words++) == '\0') - break; - } else if(c == '{') - level++; - else if(c == '}' && --level == 0) - break; - } - if(c == '\0' || level != 0) - return WRDE_SYNTAX; - } else - --words; - break; - } - default: { - break; - } - } - quote = 0; - } - - if(quote + squote + dquote != 0) - return WRDE_SYNTAX; - - return 0; -} - -int wordexp(const char * __restrict words, wordexp_t * __restrict we, int flags) { - int error; - - if(flags & WRDE_REUSE) - wordfree(we); - - if((flags & WRDE_APPEND) == 0) { - we->we_wordc = 0; - we->we_wordv = NULL; - we->we_strings = NULL; - we->we_nbytes = 0; - } - - if((error = we_check(words, flags)) != 0) { - wordfree(we); - return error; - } - - if((error = we_askshell(words, we, flags)) != 0) { - wordfree(we); - return error; - } - - return 0; -} - -void wordfree(wordexp_t *we) { - if (we == NULL) - return; - free(we->we_wordv); - free(we->we_strings); - we->we_wordv = NULL; - we->we_strings = NULL; - we->we_nbytes = 0; - we->we_wordc = 0; -} diff --git a/lib/mlibc/options/posix/include/arpa/inet.h b/lib/mlibc/options/posix/include/arpa/inet.h deleted file mode 100644 index 599987e..0000000 --- a/lib/mlibc/options/posix/include/arpa/inet.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef _ARPA_INET_H -#define _ARPA_INET_H - -#include <netinet/in.h> -#include <stdint.h> -#include <sys/socket.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef __MLIBC_ABI_ONLY - -uint32_t htonl(uint32_t); -uint16_t htons(uint16_t); -uint32_t ntohl(uint32_t); -uint16_t ntohs(uint16_t); - -// ---------------------------------------------------------------------------- -// IPv4 address manipulation. -// ---------------------------------------------------------------------------- - -in_addr_t inet_addr(const char *); -char *inet_ntoa(struct in_addr); - -// GLIBC replacement for inet_addr(). -int inet_aton(const char *, struct in_addr *); - -// ---------------------------------------------------------------------------- -// Generic IP address manipulation. -// ---------------------------------------------------------------------------- -const char *inet_ntop(int, const void *__restrict, char *__restrict, - socklen_t) __attribute__((__nonnull__(3))); -int inet_pton(int, const char *__restrict, void *__restrict); - -struct in_addr inet_makeaddr(in_addr_t net, in_addr_t host); -in_addr_t inet_netof(struct in_addr in); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _ARPA_INET_H - diff --git a/lib/mlibc/options/posix/include/bits/posix/fd_set.h b/lib/mlibc/options/posix/include/bits/posix/fd_set.h deleted file mode 100644 index 554738e..0000000 --- a/lib/mlibc/options/posix/include/bits/posix/fd_set.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef MLIBC_FD_SET_H -#define MLIBC_FD_SET_H - -#include <bits/types.h> - -typedef struct { - union { - __mlibc_uint8 __mlibc_elems[128]; - // Some programs require the fds_bits field to be present - __mlibc_uint8 fds_bits[128]; - }; -} fd_set; - -#endif // MLIBC_FD_SET_H diff --git a/lib/mlibc/options/posix/include/bits/posix/id_t.h b/lib/mlibc/options/posix/include/bits/posix/id_t.h deleted file mode 100644 index f222bc1..0000000 --- a/lib/mlibc/options/posix/include/bits/posix/id_t.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _MLIBC_ID_T_H -#define _MLIBC_ID_T_H - -typedef unsigned int id_t; - -#endif // _MLIBC_ID_T_H diff --git a/lib/mlibc/options/posix/include/bits/posix/in_addr_t.h b/lib/mlibc/options/posix/include/bits/posix/in_addr_t.h deleted file mode 100644 index bac9ff2..0000000 --- a/lib/mlibc/options/posix/include/bits/posix/in_addr_t.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef MLIBC_IN_ADDR_H -#define MLIBC_IN_ADDR_H - -#include <stdint.h> - -typedef uint32_t in_addr_t; - -#endif // MLIBC_IN_ADDR_H diff --git a/lib/mlibc/options/posix/include/bits/posix/in_port_t.h b/lib/mlibc/options/posix/include/bits/posix/in_port_t.h deleted file mode 100644 index 0368159..0000000 --- a/lib/mlibc/options/posix/include/bits/posix/in_port_t.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef MLIBC_IN_PORT_H -#define MLIBC_IN_PORT_H - -#include <stdint.h> - -typedef uint16_t in_port_t; - -#endif // MLIBC_IN_PORT_H diff --git a/lib/mlibc/options/posix/include/bits/posix/iovec.h b/lib/mlibc/options/posix/include/bits/posix/iovec.h deleted file mode 100644 index c004f1c..0000000 --- a/lib/mlibc/options/posix/include/bits/posix/iovec.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef MLIBC_IOVEC_H -#define MLIBC_IOVEC_H - -#include <bits/types.h> - -struct iovec { - void *iov_base; - __mlibc_size iov_len; -}; - -#endif // MLIBC_IOVEC_H diff --git a/lib/mlibc/options/posix/include/bits/posix/locale_t.h b/lib/mlibc/options/posix/include/bits/posix/locale_t.h deleted file mode 100644 index c128d58..0000000 --- a/lib/mlibc/options/posix/include/bits/posix/locale_t.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _LOCALE_T_H -#define _LOCALE_T_H - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void *locale_t; - -#ifdef __cplusplus -} -#endif - -#endif // _LOCALE_T_H diff --git a/lib/mlibc/options/posix/include/bits/posix/posix_ctype.h b/lib/mlibc/options/posix/include/bits/posix/posix_ctype.h deleted file mode 100644 index 2b11057..0000000 --- a/lib/mlibc/options/posix/include/bits/posix/posix_ctype.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef _POSIX_CTYPE_H -#define _POSIX_CTYPE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <bits/posix/locale_t.h> - -#ifndef __MLIBC_ABI_ONLY - -int isalnum_l(int c, locale_t loc); -int isalpha_l(int c, locale_t loc); -int isblank_l(int c, locale_t loc); -int iscntrl_l(int c, locale_t loc); -int isdigit_l(int c, locale_t loc); -int isgraph_l(int c, locale_t loc); -int islower_l(int c, locale_t loc); -int isprint_l(int c, locale_t loc); -int ispunct_l(int c, locale_t loc); -int isspace_l(int c, locale_t loc); -int isupper_l(int c, locale_t loc); -int isxdigit_l(int c, locale_t loc); - -int isascii_l(int c, locale_t loc); - -int tolower_l(int c, locale_t loc); -int toupper_l(int c, locale_t loc); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _POSIX_CTYPE_H diff --git a/lib/mlibc/options/posix/include/bits/posix/posix_locale.h b/lib/mlibc/options/posix/include/bits/posix/posix_locale.h deleted file mode 100644 index 7554bc5..0000000 --- a/lib/mlibc/options/posix/include/bits/posix/posix_locale.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef MLIBC_POSIX_LOCALE_H -#define MLIBC_POSIX_LOCALE_H - -#include <bits/posix/locale_t.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef __MLIBC_ABI_ONLY - -locale_t newlocale(int category_mask, const char *locale, locale_t base); -void freelocale(locale_t locobj); -locale_t uselocale(locale_t locobj); -locale_t duplocale(locale_t locobj); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // MLIBC_POSIX_LOCALE_H diff --git a/lib/mlibc/options/posix/include/bits/posix/posix_signal.h b/lib/mlibc/options/posix/include/bits/posix/posix_signal.h deleted file mode 100644 index 20f030f..0000000 --- a/lib/mlibc/options/posix/include/bits/posix/posix_signal.h +++ /dev/null @@ -1,111 +0,0 @@ - -#ifndef MLIBC_POSIX_SIGNAL_H -#define MLIBC_POSIX_SIGNAL_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <bits/ansi/time_t.h> -#include <bits/ansi/timespec.h> -#include <bits/posix/pthread_t.h> -#include <bits/sigset_t.h> -#include <stddef.h> -#include <stdint.h> -#include <mlibc-config.h> - -#define FPE_INTDIV 1 /* integer divide by zero */ -#define FPE_INTOVF 2 /* integer overflow */ -#define FPE_FLTDIV 3 /* floating point divide by zero */ -#define FPE_FLTOVF 4 /* floating point overflow */ -#define FPE_FLTUND 5 /* floating point underflow */ -#define FPE_FLTRES 6 /* floating point inexact result */ -#define FPE_FLTINV 7 /* floating point invalid operation */ -#define FPE_FLTSUB 8 /* subscript out of range */ - -#define TRAP_BRKPT 1 /* process breakpoint */ -#define TRAP_TRACE 2 /* process trace trap */ - -// Start Glibc stuff - -struct _libc_fpxreg { - unsigned short int significand[4]; - unsigned short int exponent; - unsigned short int __glibc_reserved1[3]; -}; - -struct _libc_xmmreg { - uint32_t element[4]; -}; - -struct _libc_fpstate { - uint16_t cwd; - int16_t swd; - uint16_t ftw; - uint16_t fop; - uint64_t rip; - uint64_t dp; - uint32_t mxcsr; - uint32_t mxcr_mask; - struct _libc_fpxreg _st[8]; - struct _libc_xmmreg _xmm[16]; - uint32_t __glibc_reserved1[24]; -}; - -typedef struct _libc_fpstate *fpregset_t; -// End Glibc stuff - -typedef unsigned long int greg_t; - -#define FPE_INTDIV 1 /* integer divide by zero */ -#define FPE_INTOVF 2 /* integer overflow */ -#define FPE_FLTDIV 3 /* floating point divide by zero */ -#define FPE_FLTOVF 4 /* floating point overflow */ -#define FPE_FLTUND 5 /* floating point underflow */ -#define FPE_FLTRES 6 /* floating point inexact result */ -#define FPE_FLTINV 7 /* floating point invalid operation */ -#define FPE_FLTSUB 8 /* subscript out of range */ - -#define TRAP_BRKPT 1 /* process breakpoint */ -#define TRAP_TRACE 2 /* process trace trap */ - -#ifndef __MLIBC_ABI_ONLY - -// functions to block / wait for signals -int sigsuspend(const sigset_t *); -int sigprocmask(int, const sigset_t *__restrict, sigset_t *__restrict); - -int pthread_sigmask(int, const sigset_t *__restrict, sigset_t *__restrict); -int pthread_kill(pthread_t, int); - -// functions to handle signals -int sigaction(int, const struct sigaction *__restrict, struct sigaction *__restrict); -int sigpending(sigset_t *); - -int siginterrupt(int sig, int flag); - -int sigaltstack(const stack_t *__restrict ss, stack_t *__restrict oss); - -// functions to raise signals -int kill(pid_t, int); -int killpg(int, int); - -int sigtimedwait(const sigset_t *__restrict set, siginfo_t *__restrict info, const struct timespec *__restrict timeout); -int sigwait(const sigset_t *__restrict set, int *__restrict sig); -int sigwaitinfo(const sigset_t *__restrict set, siginfo_t *__restrict info); - -// Glibc extension -#if __MLIBC_GLIBC_OPTION -int sigisemptyset(const sigset_t *set); -#endif // __MLIBC_GLIBC_OPTION - -int sigqueue(pid_t pid, int sig, const union sigval value); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // MLIBC_POSIX_SIGNAL_H - diff --git a/lib/mlibc/options/posix/include/bits/posix/posix_stdio.h b/lib/mlibc/options/posix/include/bits/posix/posix_stdio.h deleted file mode 100644 index 4572a04..0000000 --- a/lib/mlibc/options/posix/include/bits/posix/posix_stdio.h +++ /dev/null @@ -1,72 +0,0 @@ - -#ifndef MLIBC_POSIX_STDIO_H -#define MLIBC_POSIX_STDIO_H - -#include <bits/off_t.h> -#include <bits/size_t.h> -#include <bits/ssize_t.h> - -// MISSING: var_list - -#ifdef __cplusplus -extern "C" { -#endif - -#define P_tmpdir "/tmp" - -#ifndef __MLIBC_ABI_ONLY - -typedef struct __mlibc_file_base FILE; - -int fileno(FILE *file); -FILE *fdopen(int fd, const char *mode); - -FILE *fmemopen(void *__restrict, size_t, const char *__restrict); -int pclose(FILE *); -FILE *popen(const char*, const char *); -FILE *open_memstream(char **, size_t *); - -int fseeko(FILE *stream, off_t offset, int whence); -off_t ftello(FILE *stream); - -int dprintf(int fd, const char *format, ...); -int vdprintf(int fd, const char *format, __builtin_va_list args); - -char *fgetln(FILE *, size_t *); - -#endif /* !__MLIBC_ABI_ONLY */ - -#define RENAME_EXCHANGE (1 << 1) - -// GNU extensions -typedef ssize_t (cookie_read_function_t)(void *, char *, size_t); -typedef ssize_t (cookie_write_function_t)(void *, const char *, size_t); -typedef int (cookie_seek_function_t)(void *, off_t *, int); -typedef int (cookie_close_function_t)(void *); - -typedef struct _IO_cookie_io_functions_t { - cookie_read_function_t *read; - cookie_write_function_t *write; - cookie_seek_function_t *seek; - cookie_close_function_t *close; -} cookie_io_functions_t; - -#ifndef __MLIBC_ABI_ONLY - -#if defined(_GNU_SOURCE) - -FILE *fopencookie(void *__restrict cookie, const char *__restrict mode, cookie_io_functions_t io_funcs); - -#endif // defined(_GNU_SOURCE) - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -// MISSING: various functions and macros - -#endif /* MLIBC_POSIX_STDIO_H */ - - diff --git a/lib/mlibc/options/posix/include/bits/posix/posix_stdlib.h b/lib/mlibc/options/posix/include/bits/posix/posix_stdlib.h deleted file mode 100644 index 5248fca..0000000 --- a/lib/mlibc/options/posix/include/bits/posix/posix_stdlib.h +++ /dev/null @@ -1,73 +0,0 @@ - -#ifndef MLIBC_POSIX_STDLIB_H -#define MLIBC_POSIX_STDLIB_H - -#include <bits/posix/locale_t.h> -#include <bits/size_t.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef __MLIBC_ABI_ONLY - -long random(void); -double drand48(void); -void srand48(long int); -char *initstate(unsigned int, char *, size_t); -char *setstate(char *); -void srandom(unsigned int); - -// ---------------------------------------------------------------------------- -// Environment. -// ---------------------------------------------------------------------------- - -int putenv(char *); -int setenv(const char *, const char *, int); -int unsetenv(const char *); - -// ---------------------------------------------------------------------------- -// Path handling. -// ---------------------------------------------------------------------------- - -int mkstemp(char *); -int mkstemps(char *pattern, int suffixlen); -int mkostemp(char *, int flags); -int mkostemps(char *pattern, int suffixlen, int flags); -char *mkdtemp(char *path); - -char *realpath(const char *__restrict, char *__restrict); - -// ---------------------------------------------------------------------------- -// Pseudoterminals -// ---------------------------------------------------------------------------- - -int posix_openpt(int flags); -int grantpt(int fd); -int unlockpt(int fd); -char *ptsname(int fd); -int ptsname_r(int fd, char *buf, size_t len); - -double strtod_l(const char *__restrict__ nptr, char ** __restrict__ endptr, locale_t loc); -long double strtold_l(const char *__restrict__ nptr, char ** __restrict__ endptr, locale_t loc); -float strtof_l(const char *__restrict string, char **__restrict end, locale_t loc); - -int getloadavg(double *, int); - -// GNU extension -char *secure_getenv(const char *); -char *canonicalize_file_name(const char *); - -// BSD extension -void *reallocarray(void *, size_t, size_t); - -int clearenv(void); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // MLIBC_POSIX_STDLIB_H - diff --git a/lib/mlibc/options/posix/include/bits/posix/posix_string.h b/lib/mlibc/options/posix/include/bits/posix/posix_string.h deleted file mode 100644 index 1f61942..0000000 --- a/lib/mlibc/options/posix/include/bits/posix/posix_string.h +++ /dev/null @@ -1,57 +0,0 @@ - -#ifndef MLIBC_POSIX_STRING_H -#define MLIBC_POSIX_STRING_H - -#include <alloca.h> -#include <bits/posix/locale_t.h> -#include <bits/size_t.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef __MLIBC_ABI_ONLY - -char *strdup(const char *string); -char *strndup(const char *, size_t); -size_t strnlen(const char *, size_t); -char *strtok_r(char *__restrict, const char *__restrict, char **__restrict); -char *strsep(char **stringp, const char *delim); -char *strsignal(int sig); -char *stpcpy(char *__restrict, const char *__restrict); -char *stpncpy(char *__restrict, const char *__restrict, size_t n); -void *memccpy(void *__restrict dest, const void *__restrict src, int c, size_t n); - -int strcoll_l(const char *s1, const char *s2, locale_t locale); - -// GNU extensions. -#if defined(_GNU_SOURCE) -char *strcasestr(const char *, const char *); -#define strdupa(x) ({ \ - const char *str = (x); \ - size_t len = strlen(str) + 1; \ - char *buf = alloca(len); \ - (char *) memcpy(buf, str, len); \ -}) -#define strndupa(x, y) ({ \ - const char *str = (x); \ - size_t len = strnlen(str, (y)) + 1; \ - char *buf = alloca(len); \ - buf[len - 1] = '\0'; \ - (char *) memcpy(buf, str, len - 1); \ -}) -void *memrchr(const void *, int, size_t); -#endif /* defined(_GNU_SOURCE) */ - -// BSD extensions -size_t strlcpy(char *d, const char *s, size_t n); -size_t strlcat(char *d, const char *s, size_t n); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // MLIBC_POSIX_STRING_H - diff --git a/lib/mlibc/options/posix/include/bits/posix/posix_time.h b/lib/mlibc/options/posix/include/bits/posix/posix_time.h deleted file mode 100644 index d3e8e1d..0000000 --- a/lib/mlibc/options/posix/include/bits/posix/posix_time.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef MLIBC_POSIX_TIME_H -#define MLIBC_POSIX_TIME_H - -#include <bits/posix/timeval.h> - -#define TIMER_ABSTIME 1 - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef __MLIBC_ABI_ONLY - -int utimes(const char *, const struct timeval[2]); - -// Not standardized, Linux and BSDs have it -int futimes(int, const struct timeval[2]); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // MLIBC_POSIX_TIME_H diff --git a/lib/mlibc/options/posix/include/bits/posix/posix_wctype.h b/lib/mlibc/options/posix/include/bits/posix/posix_wctype.h deleted file mode 100644 index 4d2887c..0000000 --- a/lib/mlibc/options/posix/include/bits/posix/posix_wctype.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef _POSIX_WCTYPE_H -#define _POSIX_WCTYPE_H - -#include <bits/posix/locale_t.h> -#include <bits/wint_t.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef __MLIBC_ABI_ONLY - -typedef unsigned long wctype_t; -typedef unsigned long wctrans_t; - -int iswalnum_l(wint_t, locale_t); -int iswblank_l(wint_t, locale_t); -int iswcntrl_l(wint_t, locale_t); -int iswdigit_l(wint_t, locale_t); -int iswgraph_l(wint_t, locale_t); -int iswlower_l(wint_t, locale_t); -int iswprint_l(wint_t, locale_t); -int iswpunct_l(wint_t, locale_t); -int iswspace_l(wint_t, locale_t); -int iswupper_l(wint_t, locale_t); -int iswxdigit_l(wint_t, locale_t); -int iswalpha_l(wint_t, locale_t); - -wctype_t wctype_l(const char *); -int iswctype_l(wint_t, wctype_t); - -wint_t towlower_l(wint_t, locale_t); -wint_t towupper_l(wint_t, locale_t); - -wctrans_t wctrans_l(const char *, locale_t); -wint_t towctrans_l(wint_t, wctrans_t, locale_t); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _POSIX_WCTYPE_H diff --git a/lib/mlibc/options/posix/include/bits/posix/pthread_t.h b/lib/mlibc/options/posix/include/bits/posix/pthread_t.h deleted file mode 100644 index 1310c40..0000000 --- a/lib/mlibc/options/posix/include/bits/posix/pthread_t.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _MLIBC_BITS_PTHREAD_T_HPP -#define _MLIBC_BITS_PTHREAD_T_HPP - -#include <bits/threads.h> - -typedef struct __mlibc_thread_data *pthread_t; - -#endif // _MLIBC_BITS_PTHREAD_T_HPP diff --git a/lib/mlibc/options/posix/include/bits/posix/stat.h b/lib/mlibc/options/posix/include/bits/posix/stat.h deleted file mode 100644 index 4dd081d..0000000 --- a/lib/mlibc/options/posix/include/bits/posix/stat.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef MLIBC_STAT_H -#define MLIBC_STAT_H - -#include <abi-bits/stat.h> - -// Used by utimensat and friends -#define UTIME_NOW ((1l << 30) - 1l) -#define UTIME_OMIT ((1l << 30) - 2l) - -#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) -#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) -#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) -#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) -#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) -#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) - -// POSIX compatibility macros -#define st_atime st_atim.tv_sec -#define st_mtime st_mtim.tv_sec -#define st_ctime st_ctim.tv_sec - -#endif // MLIBC_STAT_H - diff --git a/lib/mlibc/options/posix/include/bits/posix/timer_t.h b/lib/mlibc/options/posix/include/bits/posix/timer_t.h deleted file mode 100644 index b230501..0000000 --- a/lib/mlibc/options/posix/include/bits/posix/timer_t.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _MLIBC_TIMER_T_H -#define _MLIBC_TIMER_T_H - -typedef void * timer_t; - -#endif // _MLIBC_TIMER_T_H diff --git a/lib/mlibc/options/posix/include/bits/posix/timeval.h b/lib/mlibc/options/posix/include/bits/posix/timeval.h deleted file mode 100644 index 445ee7f..0000000 --- a/lib/mlibc/options/posix/include/bits/posix/timeval.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef MLIBC_TIMEVAL_H -#define MLIBC_TIMEVAL_H - -#include <bits/ansi/time_t.h> -#include <abi-bits/suseconds_t.h> - -struct timeval { - time_t tv_sec; - suseconds_t tv_usec; -}; - -#endif // MLIBC_TIMEVAL_H diff --git a/lib/mlibc/options/posix/include/byteswap.h b/lib/mlibc/options/posix/include/byteswap.h deleted file mode 100644 index 74b9fe2..0000000 --- a/lib/mlibc/options/posix/include/byteswap.h +++ /dev/null @@ -1,23 +0,0 @@ - -#ifndef _BYTESWAP_H -#define _BYTESWAP_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define bswap_16(x) __builtin_bswap16(x) -#define bswap_32(x) __builtin_bswap32(x) -#define bswap_64(x) __builtin_bswap64(x) - -// Some programs like eudev call these functions instead -#define __bswap_16(x) __builtin_bswap16(x) -#define __bswap_32(x) __builtin_bswap32(x) -#define __bswap_64(x) __builtin_bswap64(x) - -#ifdef __cplusplus -} -#endif - -#endif // _BYTESWAP_H - diff --git a/lib/mlibc/options/posix/include/dirent.h b/lib/mlibc/options/posix/include/dirent.h deleted file mode 100644 index b50566d..0000000 --- a/lib/mlibc/options/posix/include/dirent.h +++ /dev/null @@ -1,76 +0,0 @@ - -#ifndef _DIRENT_H -#define _DIRENT_H - -#include <abi-bits/ino_t.h> -#include <bits/off_t.h> -#include <bits/types.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#define DT_UNKNOWN 0 -#define DT_FIFO 1 -#define DT_CHR 2 -#define DT_DIR 4 -#define DT_BLK 6 -#define DT_REG 8 -#define DT_LNK 10 -#define DT_SOCK 12 -#define DT_WHT 14 - -#define __MLIBC_DIRENT_BODY ino_t d_ino; \ - off_t d_off; \ - unsigned short d_reclen; \ - unsigned char d_type; \ - char d_name[1024]; - -struct dirent { - __MLIBC_DIRENT_BODY -}; - -struct dirent64 { - __MLIBC_DIRENT_BODY -}; - -#define d_fileno d_ino - -#undef __MLIBC_DIRENT_BODY - -#define IFTODT(mode) (((mode) & 0170000) >> 12) - -struct __mlibc_dir_struct { - int __handle; - __mlibc_size __ent_next; - __mlibc_size __ent_limit; - char __ent_buffer[2048]; - struct dirent __current; -}; - -typedef struct __mlibc_dir_struct DIR; - -#ifndef __MLIBC_ABI_ONLY - -int alphasort(const struct dirent **, const struct dirent **); -int closedir(DIR *); -int dirfd(DIR *); -DIR *fdopendir(int); -DIR *opendir(const char *); -struct dirent *readdir(DIR *); -int readdir_r(DIR *__restrict, struct dirent *__restrict, struct dirent **__restrict); -void rewinddir(DIR *); -int scandir(const char *, struct dirent ***, int (*)(const struct dirent *), - int (*)(const struct dirent **, const struct dirent **)); -void seekdir(DIR *, long); -long telldir(DIR *); -int versionsort(const struct dirent **, const struct dirent **); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _DIRENT_H - diff --git a/lib/mlibc/options/posix/include/dlfcn.h b/lib/mlibc/options/posix/include/dlfcn.h deleted file mode 100644 index 3bb8a02..0000000 --- a/lib/mlibc/options/posix/include/dlfcn.h +++ /dev/null @@ -1,52 +0,0 @@ - -#ifndef _DLFCN_H -#define _DLFCN_H - -#define RTLD_LOCAL 0 -#define RTLD_NOW 1 -#define RTLD_GLOBAL 2 -#define RTLD_NOLOAD 4 -#define RTLD_NODELETE 8 -#define RTLD_DEEPBIND 16 -#define RTLD_LAZY 32 - -#define RTLD_NEXT ((void *)-1) -#define RTLD_DEFAULT ((void *)0) - -#define RTLD_DI_LINKMAP 2 - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef __MLIBC_ABI_ONLY - -int dlclose(void *); -char *dlerror(void); -void *dlopen(const char *, int); -void *dlsym(void *__restrict, const char *__restrict); -void *dlvsym(void *__restrict, const char *__restrict, const char *__restrict); - -#endif /* !__MLIBC_ABI_ONLY */ - -//gnu extension -typedef struct { - const char *dli_fname; - void *dli_fbase; - const char *dli_sname; - void *dli_saddr; -} Dl_info; - -#ifndef __MLIBC_ABI_ONLY - -int dladdr(const void *, Dl_info *); -int dlinfo(void *, int, void *); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _DLFCN_H - diff --git a/lib/mlibc/options/posix/include/fcntl.h b/lib/mlibc/options/posix/include/fcntl.h deleted file mode 100644 index 9983219..0000000 --- a/lib/mlibc/options/posix/include/fcntl.h +++ /dev/null @@ -1,76 +0,0 @@ - -#ifndef _FCNTL_H -#define _FCNTL_H - -#include <abi-bits/fcntl.h> -#include <abi-bits/seek-whence.h> -#include <abi-bits/mode_t.h> -#include <abi-bits/pid_t.h> -#include <bits/posix/iovec.h> -#include <bits/off_t.h> -#include <bits/ssize_t.h> -#include <bits/size_t.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#define O_NDELAY O_NONBLOCK - -struct flock { - short l_type; - short l_whence; - off_t l_start; - off_t l_len; - pid_t l_pid; -}; - -#ifndef __MLIBC_ABI_ONLY - -int creat(const char *, mode_t); -int fallocate(int fd, int mode, off_t offset, off_t len); -int fcntl(int fd, int command, ...); -int open(const char *path, int flags, ...); -int openat(int, const char *, int, ...); -int posix_fadvise(int, off_t, off_t, int); -int posix_fallocate(int, off_t, off_t); - -#endif /* !__MLIBC_ABI_ONLY */ - -// This is a linux extension - -struct file_handle { - unsigned int handle_bytes; - int handle_type; - unsigned char f_handle[0]; -}; - -#ifndef __MLIBC_ABI_ONLY - -int name_to_handle_at(int, const char *, struct file_handle *, int *, int); -int open_by_handle_at(int, struct file_handle *, int); - -ssize_t splice(int fd_in, off_t *off_in, int fd_out, off_t *off_out, size_t len, unsigned int flags); -ssize_t vmsplice(int fd, const struct iovec *iov, size_t nr_segs, unsigned int flags); - -#endif /* !__MLIBC_ABI_ONLY */ - -#define SPLICE_F_MOVE 1 -#define SPLICE_F_NONBLOCK 2 -#define SPLICE_F_MORE 4 -#define SPLICE_F_GIFT 8 - -#define AT_NO_AUTOMOUNT 0x800 - -#define F_SETPIPE_SZ 1031 -#define F_GETPIPE_SZ 1032 - -#define FALLOC_FL_KEEP_SIZE 1 -#define FALLOC_FL_PUNCH_HOLE 2 - -#ifdef __cplusplus -} -#endif - -#endif // _FCNTL_H - diff --git a/lib/mlibc/options/posix/include/fnmatch.h b/lib/mlibc/options/posix/include/fnmatch.h deleted file mode 100644 index 3eccbd0..0000000 --- a/lib/mlibc/options/posix/include/fnmatch.h +++ /dev/null @@ -1,33 +0,0 @@ - -#ifndef _FNMATCH_H -#define _FNMATCH_H - -#ifdef __cplusplus -extern "C" { -#endif - -// POSIX-defined fnmatch() flags. -#define FNM_PATHNAME 0x1 -#define FNM_NOESCAPE 0x2 -#define FNM_PERIOD 0x4 - -// GNU extensions for fnmatch() flags. -#define FNM_LEADING_DIR 0x8 -#define FNM_CASEFOLD 0x10 -#define FNM_EXTMATCH 0x20 - -// fnmatch() return values. -#define FNM_NOMATCH 1 - -#ifndef __MLIBC_ABI_ONLY - -int fnmatch(const char *, const char *, int); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _FNMATCH_H - diff --git a/lib/mlibc/options/posix/include/ftw.h b/lib/mlibc/options/posix/include/ftw.h deleted file mode 100644 index bde283d..0000000 --- a/lib/mlibc/options/posix/include/ftw.h +++ /dev/null @@ -1,43 +0,0 @@ - -#ifndef _FTW_H -#define _FTW_H - -#include <bits/posix/stat.h> - -#define FTW_F 1 -#define FTW_D 2 -#define FTW_DNR 3 -#define FTW_DP 4 -#define FTW_NS 5 -#define FTW_SL 6 -#define FTW_SLN 7 - -#define FTW_PHYS 1 -#define FTW_MOUNT 2 -#define FTW_DEPTH 4 -#define FTW_CHDIR 8 - -#define FTW_CONTINUE 0 - -#ifdef __cplusplus -extern "C" { -#endif - -struct FTW { - int base; - int level; -}; - -#ifndef __MLIBC_ABI_ONLY - -int ftw(const char *, int (*)(const char *, const struct stat *, int), int); -int nftw(const char *, int (*)(const char *, const struct stat *, int, struct FTW *), int, int); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _FTW_H - diff --git a/lib/mlibc/options/posix/include/glob.h b/lib/mlibc/options/posix/include/glob.h deleted file mode 100644 index 2bf9e48..0000000 --- a/lib/mlibc/options/posix/include/glob.h +++ /dev/null @@ -1,58 +0,0 @@ - -#ifndef _GLOB_H -#define _GLOB_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <bits/size_t.h> - -#define GLOB_APPEND 0x01 -#define GLOB_DOOFFS 0x02 -#define GLOB_ERR 0x04 -#define GLOB_MARK 0x08 -#define GLOB_NOCHECK 0x10 -#define GLOB_NOESCAPE 0x20 -#define GLOB_NOSORT 0x40 -#define GLOB_PERIOD 0x80 -#define GLOB_TILDE 0x100 -#define GLOB_TILDE_CHECK 0x200 -#define GLOB_BRACE 0x400 -#define GLOB_NOMAGIC 0x800 -#define GLOB_ALTDIRFUNC 0x1000 -#define GLOB_ONLYDIR 0x2000 -#define GLOB_MAGCHAR 0x4000 - -#define GLOB_ABORTED 1 -#define GLOB_NOMATCH 2 -#define GLOB_NOSPACE 3 -#define GLOB_NOSYS 4 - -struct stat; -typedef struct glob_t { - size_t gl_pathc; - char **gl_pathv; - size_t gl_offs; - int gl_flags; - void (*gl_closedir) (void *); - struct dirent *(*gl_readdir) (void *); - void *(*gl_opendir) (const char *); - int (*gl_lstat) (const char *__restrict, struct stat *__restrict); - int (*gl_stat) (const char *__restrict, struct stat *__restrict); -} glob_t; - -#ifndef __MLIBC_ABI_ONLY - -int glob(const char *__restirct, int, int(*)(const char *, int), struct glob_t *__restrict); -void globfree(struct glob_t *); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _GLOB_H - - diff --git a/lib/mlibc/options/posix/include/grp.h b/lib/mlibc/options/posix/include/grp.h deleted file mode 100644 index a50396e..0000000 --- a/lib/mlibc/options/posix/include/grp.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef _GRP_H -#define _GRP_H - -#include <stddef.h> -#include <stdio.h> -#include <abi-bits/gid_t.h> - -#ifdef __cplusplus -extern "C" { -#endif - -struct group { - char *gr_name; - char *gr_passwd; - gid_t gr_gid; - char **gr_mem; -}; - -#ifndef __MLIBC_ABI_ONLY - -void endgrent(void); -struct group *getgrent(void); -struct group *getgrgid(gid_t); -int getgrgid_r(gid_t, struct group *, char *, size_t, struct group **); -struct group *getgrnam(const char *); -int getgrnam_r(const char *, struct group *, char *, size_t, struct group **); -void setgrent(void); -int putgrent(const struct group *, FILE *); -struct group *fgetgrent(FILE *); - -int setgroups(size_t size, const gid_t *list); -int initgroups(const char *user, gid_t group); - -// Non standard extension -int getgrouplist(const char *, gid_t, gid_t *, int *); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _GRP_H diff --git a/lib/mlibc/options/posix/include/langinfo.h b/lib/mlibc/options/posix/include/langinfo.h deleted file mode 100644 index 5436a54..0000000 --- a/lib/mlibc/options/posix/include/langinfo.h +++ /dev/null @@ -1,24 +0,0 @@ - -#ifndef _LANGINFO_H -#define _LANGINFO_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <bits/posix/locale_t.h> -#include <bits/nl_item.h> - -#ifndef __MLIBC_ABI_ONLY - -char *nl_langinfo(nl_item); -char *nl_langinfo_l(nl_item, locale_t); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _LANGINFO_H - diff --git a/lib/mlibc/options/posix/include/libgen.h b/lib/mlibc/options/posix/include/libgen.h deleted file mode 100644 index fa53fc5..0000000 --- a/lib/mlibc/options/posix/include/libgen.h +++ /dev/null @@ -1,28 +0,0 @@ - -#ifndef _LIBGEN_H -#define _LIBGEN_H - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(basename) && defined(_GNU_SOURCE) -/* see: ./options/ansi/include/string.h, search for __mlibc_gnu_basename */ -# undef basename -#endif - -#ifndef __MLIBC_ABI_ONLY - -char *basename(char *); -#define basename basename -char *dirname(char *); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _LIBGEN_H - - diff --git a/lib/mlibc/options/posix/include/mlibc/lookup.hpp b/lib/mlibc/options/posix/include/mlibc/lookup.hpp deleted file mode 100644 index 71f84e7..0000000 --- a/lib/mlibc/options/posix/include/mlibc/lookup.hpp +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef _MLIBC_LOOKUP -#define _MLIBC_LOOKUP - -#include <stdint.h> -#include <netinet/in.h> -#include <netdb.h> -#include <frg/string.hpp> -#include <frg/vector.hpp> -#include <frg/span.hpp> -#include <frg/array.hpp> -#include <mlibc/allocator.hpp> - -namespace mlibc { - -struct dns_addr_buf { - dns_addr_buf() - : name(getAllocator()) {} - frg::string<MemoryAllocator> name; - int family; - uint8_t addr[16]; -}; - -struct lookup_result { - lookup_result() - : buf(getAllocator()), aliases(getAllocator()) {} - frg::vector<struct dns_addr_buf, MemoryAllocator> buf; - frg::vector<frg::string<MemoryAllocator>, MemoryAllocator> aliases; -}; - -struct dns_header { - uint16_t identification; - uint16_t flags; - uint16_t no_q; - uint16_t no_ans; - uint16_t no_auths; - uint16_t no_additional; -}; - -struct ai_buf { - struct addrinfo ai; - union sa { - struct sockaddr_in sin; - struct sockaddr_in6 sin6; - } sa; -}; - -int lookup_name_dns(struct lookup_result &buf, const char *name, - frg::string<MemoryAllocator> &canon_name); -int lookup_addr_dns(frg::span<char> name, frg::array<uint8_t, 16> &addr, int family); -int lookup_name_hosts(struct lookup_result &buf, const char *name, - frg::string<MemoryAllocator> &canon_name); -int lookup_addr_hosts(frg::span<char> name, frg::array<uint8_t, 16> &addr, int family); -int lookup_name_null(struct lookup_result &buf, int flags, int family); -int lookup_name_ip(struct lookup_result &buf, const char *name, int family); - -} // namespace mlibc - -#endif // _MLIBC_LOOKUP diff --git a/lib/mlibc/options/posix/include/mlibc/posix-file-io.hpp b/lib/mlibc/options/posix/include/mlibc/posix-file-io.hpp deleted file mode 100644 index ac316ac..0000000 --- a/lib/mlibc/options/posix/include/mlibc/posix-file-io.hpp +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef MLIBC_POSIX_FILE_IO_HPP -#define MLIBC_POSIX_FILE_IO_HPP - -#include <frg/span.hpp> -#include <frg/vector.hpp> -#include <mlibc/file-io.hpp> -#include <mlibc/allocator.hpp> - -namespace mlibc { - -struct mem_file : abstract_file { - mem_file(int flags, void (*do_dispose)(abstract_file *) = nullptr) : abstract_file{do_dispose}, _flags{flags} { }; - - int reopen(const char *path, const char *mode) override; -protected: - int determine_type(stream_type *type) override; - int determine_bufmode(buffer_mode *mode) override; - - virtual frg::span<char> _buffer() = 0; - virtual size_t _buffer_size() const = 0; - - off_t _pos = 0; - int _flags = 0; - // maintains the size of buffer contents as required by POSIX - off_t _max_size = 0; -}; - -struct memstream_mem_file final : public mem_file { - memstream_mem_file(char **ptr, size_t *sizeloc, int flags, void (*do_dispose)(abstract_file *) = nullptr); - - int close() override; - - int io_read(char *buffer, size_t max_size, size_t *actual_size) override; - int io_write(const char *buffer, size_t max_size, size_t *actual_size) override; - int io_seek(off_t offset, int whence, off_t *new_offset) override; - - frg::span<char> _buffer() override { - return {_buf.data(), _buffer_size()}; - } - - size_t _buffer_size() const override { - return _buf.size(); - } - -private: - void _update_ptrs(); - - // Where to write back buffer and size on flush and close. - char **_bufloc; - size_t *_sizeloc; - - frg::vector<char, MemoryAllocator> _buf = {getAllocator()}; -}; - -struct fmemopen_mem_file final : public mem_file { - fmemopen_mem_file(void *in_buf, size_t size, int flags, void (*do_dispose)(abstract_file *) = nullptr); - - int close() override; - - int io_read(char *buffer, size_t max_size, size_t *actual_size) override; - int io_write(const char *buffer, size_t max_size, size_t *actual_size) override; - int io_seek(off_t offset, int whence, off_t *new_offset) override; - - frg::span<char> _buffer() override { - return {reinterpret_cast<char *>(_inBuffer), _buffer_size()}; - } - - size_t _buffer_size() const override { - return _inBufferSize; - } - -private: - void *_inBuffer; - size_t _inBufferSize; - - bool _needsDeallocation = false; -}; - -struct cookie_file : abstract_file { - cookie_file(void *cookie, int flags, cookie_io_functions_t funcs, void (*do_dispose)(abstract_file *) = nullptr) - : abstract_file{do_dispose}, _cookie{cookie}, _flags{flags}, _funcs{funcs} { } - - int close() override; - int reopen(const char *path, const char *mode) override; -protected: - int determine_type(stream_type *type) override; - int determine_bufmode(buffer_mode *mode) override; - - int io_read(char *buffer, size_t max_size, size_t *actual_size) override; - int io_write(const char *buffer, size_t max_size, size_t *actual_size) override; - int io_seek(off_t offset, int whence, off_t *new_offset) override; - -private: - void *_cookie; - - int _flags; - cookie_io_functions_t _funcs; -}; - -} // namespace mlibc - -#endif // MLIBC_POSIX_FILE_IO_HPP diff --git a/lib/mlibc/options/posix/include/mlibc/posix-sysdeps.hpp b/lib/mlibc/options/posix/include/mlibc/posix-sysdeps.hpp deleted file mode 100644 index ba77b32..0000000 --- a/lib/mlibc/options/posix/include/mlibc/posix-sysdeps.hpp +++ /dev/null @@ -1,240 +0,0 @@ -#ifndef MLIBC_POSIX_SYSDEPS -#define MLIBC_POSIX_SYSDEPS - -#include <stddef.h> - -#include <abi-bits/seek-whence.h> -#include <abi-bits/vm-flags.h> -#include <bits/off_t.h> -#include <bits/ssize_t.h> -#include <mlibc/fsfd_target.hpp> - -#include <fcntl.h> -#include <time.h> -#include <abi-bits/pid_t.h> -#include <abi-bits/socklen_t.h> -#include <bits/posix/stat.h> -#include <poll.h> -#include <stdarg.h> -#include <sys/socket.h> -#include <sys/resource.h> -#include <sys/utsname.h> -#include <sys/select.h> -#include <sys/sem.h> -#include <sys/statvfs.h> -#include <sys/time.h> -#include <sys/times.h> -#include <sys/wait.h> -#include <sched.h> -#include <termios.h> -#include <time.h> -#include <ucontext.h> - -namespace [[gnu::visibility("hidden")]] mlibc { - -void sys_libc_log(const char *message); -[[noreturn]] void sys_libc_panic(); - -[[noreturn]] void sys_exit(int status); -[[noreturn, gnu::weak]] void sys_thread_exit(); -int sys_clock_get(int clock, time_t *secs, long *nanos); - -int sys_open(const char *pathname, int flags, mode_t mode, int *fd); -[[gnu::weak]] int sys_flock(int fd, int options); - -[[gnu::weak]] int sys_open_dir(const char *path, int *handle); -[[gnu::weak]] int sys_read_entries(int handle, void *buffer, size_t max_size, - size_t *bytes_read); - -int sys_read(int fd, void *buf, size_t count, ssize_t *bytes_read); -[[gnu::weak]] int sys_readv(int fd, const struct iovec *iovs, int iovc, ssize_t *bytes_read); - -int sys_write(int fd, const void *buf, size_t count, ssize_t *bytes_written); -[[gnu::weak]] int sys_pread(int fd, void *buf, size_t n, off_t off, ssize_t *bytes_read); -[[gnu::weak]] int sys_pwrite(int fd, const void *buf, size_t n, off_t off, ssize_t *bytes_read); - -int sys_seek(int fd, off_t offset, int whence, off_t *new_offset); -int sys_close(int fd); - -[[gnu::weak]] int sys_access(const char *path, int mode); -[[gnu::weak]] int sys_faccessat(int dirfd, const char *pathname, int mode, int flags); -[[gnu::weak]] int sys_dup(int fd, int flags, int *newfd); -[[gnu::weak]] int sys_dup2(int fd, int flags, int newfd); -// In contrast to the isatty() library function, the sysdep function uses return value -// zero (and not one) to indicate that the file is a terminal. -[[gnu::weak]] int sys_isatty(int fd); -[[gnu::weak]] int sys_stat(fsfd_target fsfdt, int fd, const char *path, int flags, - struct stat *statbuf); -[[gnu::weak]] int sys_statvfs(const char *path, struct statvfs *out); -[[gnu::weak]] int sys_fstatvfs(int fd, struct statvfs *out); -[[gnu::weak]] int sys_readlink(const char *path, void *buffer, size_t max_size, ssize_t *length); -[[gnu::weak]] int sys_rmdir(const char *path); -[[gnu::weak]] int sys_ftruncate(int fd, size_t size); -[[gnu::weak]] int sys_fallocate(int fd, off_t offset, size_t size); -[[gnu::weak]] int sys_unlinkat(int fd, const char *path, int flags); -[[gnu::weak]] int sys_openat(int dirfd, const char *path, int flags, mode_t mode, int *fd); -[[gnu::weak]] int sys_socket(int family, int type, int protocol, int *fd); -[[gnu::weak]] int sys_msg_send(int fd, const struct msghdr *hdr, int flags, ssize_t *length); -[[gnu::weak]] ssize_t sys_sendto(int fd, const void *buffer, size_t size, int flags, const struct sockaddr *sock_addr, socklen_t addr_length, ssize_t *length); -[[gnu::weak]] int sys_msg_recv(int fd, struct msghdr *hdr, int flags, ssize_t *length); -[[gnu::weak]] ssize_t sys_recvfrom(int fd, void *buffer, size_t size, int flags, struct sockaddr *sock_addr, socklen_t *addr_length, ssize_t *length); -[[gnu::weak]] int sys_listen(int fd, int backlog); -[[gnu::weak]] gid_t sys_getgid(); -[[gnu::weak]] gid_t sys_getegid(); -[[gnu::weak]] uid_t sys_getuid(); -[[gnu::weak]] uid_t sys_geteuid(); -[[gnu::weak]] pid_t sys_getpid(); -[[gnu::weak]] pid_t sys_gettid(); -[[gnu::weak]] pid_t sys_getppid(); -[[gnu::weak]] int sys_getpgid(pid_t pid, pid_t *pgid); -[[gnu::weak]] int sys_getsid(pid_t pid, pid_t *sid); -[[gnu::weak]] int sys_setpgid(pid_t pid, pid_t pgid); -[[gnu::weak]] int sys_setuid(uid_t uid); -[[gnu::weak]] int sys_seteuid(uid_t euid); -[[gnu::weak]] int sys_setgid(gid_t gid); -[[gnu::weak]] int sys_setegid(gid_t egid); -[[gnu::weak]] int sys_getgroups(size_t size, const gid_t *list, int *ret); -[[gnu::weak]] void sys_yield(); -[[gnu::weak]] int sys_sleep(time_t *secs, long *nanos); -[[gnu::weak]] int sys_fork(pid_t *child); -[[gnu::weak]] int sys_execve(const char *path, char *const argv[], char *const envp[]); -[[gnu::weak]] int sys_pselect(int num_fds, fd_set *read_set, fd_set *write_set, - fd_set *except_set, const struct timespec *timeout, const sigset_t *sigmask, int *num_events); -[[gnu::weak]] int sys_getrusage(int scope, struct rusage *usage); -[[gnu::weak]] int sys_getrlimit(int resource, struct rlimit *limit); -[[gnu::weak]] int sys_setrlimit(int resource, const struct rlimit *limit); -[[gnu::weak]] int sys_getpriority(int which, id_t who, int *value); -[[gnu::weak]] int sys_setpriority(int which, id_t who, int prio); -[[gnu::weak]] int sys_getschedparam(void *tcb, int *policy, struct sched_param *param); -[[gnu::weak]] int sys_setschedparam(void *tcb, int policy, const struct sched_param *param); -[[gnu::weak]] int sys_get_max_priority(int policy, int *out); -[[gnu::weak]] int sys_get_min_priority(int policy, int *out); -[[gnu::weak]] int sys_getcwd(char *buffer, size_t size); -[[gnu::weak]] int sys_chdir(const char *path); -[[gnu::weak]] int sys_fchdir(int fd); -[[gnu::weak]] int sys_chroot(const char *path); -[[gnu::weak]] int sys_mkdir(const char *path, mode_t mode); -[[gnu::weak]] int sys_mkdirat(int dirfd, const char *path, mode_t mode); -[[gnu::weak]] int sys_link(const char *old_path, const char *new_path); -[[gnu::weak]] int sys_linkat(int olddirfd, const char *old_path, int newdirfd, const char *new_path, int flags); -[[gnu::weak]] int sys_symlink(const char *target_path, const char *link_path); -[[gnu::weak]] int sys_symlinkat(const char *target_path, int dirfd, const char *link_path); -[[gnu::weak]] int sys_rename(const char *path, const char *new_path); -[[gnu::weak]] int sys_renameat(int olddirfd, const char *old_path, int newdirfd, const char *new_path); -[[gnu::weak]] int sys_fcntl(int fd, int request, va_list args, int *result); -[[gnu::weak]] int sys_ttyname(int fd, char *buf, size_t size); -[[gnu::weak]] int sys_fadvise(int fd, off_t offset, off_t length, int advice); -[[gnu::weak]] void sys_sync(); -[[gnu::weak]] int sys_fsync(int fd); -[[gnu::weak]] int sys_fdatasync(int fd); -[[gnu::weak]] int sys_chmod(const char *pathname, mode_t mode); -[[gnu::weak]] int sys_fchmod(int fd, mode_t mode); -[[gnu::weak]] int sys_fchmodat(int fd, const char *pathname, mode_t mode, int flags); -[[gnu::weak]] int sys_utimensat(int dirfd, const char *pathname, const struct timespec times[2], int flags); -[[gnu::weak]] int sys_mlock(const void *addr, size_t length); -[[gnu::weak]] int sys_munlock(const void *addr, size_t length); -[[gnu::weak]] int sys_mlockall(int flags); -[[gnu::weak]] int sys_mlock(const void *addr, size_t len); -[[gnu::weak]] int sys_munlockall(void); -[[gnu::weak]] int sys_mincore(void *addr, size_t length, unsigned char *vec); - -// mlibc assumes that anonymous memory returned by sys_vm_map() is zeroed by the kernel / whatever is behind the sysdeps -int sys_vm_map(void *hint, size_t size, int prot, int flags, int fd, off_t offset, void **window); - -[[gnu::weak]] int sys_vm_remap(void *pointer, size_t size, size_t new_size, void **window); -[[gnu::weak]] int sys_vm_protect(void *pointer, size_t size, int prot); - -int sys_vm_unmap(void *pointer, size_t size); - -[[gnu::weak]] int sys_setsid(pid_t *sid); -[[gnu::weak]] int sys_tcgetattr(int fd, struct termios *attr); -[[gnu::weak]] int sys_tcsetattr(int, int, const struct termios *attr); -[[gnu::weak]] int sys_tcflow(int, int); -[[gnu::weak]] int sys_tcflush(int fd, int queue); -[[gnu::weak]] int sys_tcdrain(int); -[[gnu::weak]] int sys_pipe(int *fds, int flags); -[[gnu::weak]] int sys_socketpair(int domain, int type_and_flags, int proto, int *fds); -[[gnu::weak]] int sys_poll(struct pollfd *fds, nfds_t count, int timeout, int *num_events); -[[gnu::weak]] int sys_ioctl(int fd, unsigned long request, void *arg, int *result); -[[gnu::weak]] int sys_getsockopt(int fd, int layer, int number, - void *__restrict buffer, socklen_t *__restrict size); -[[gnu::weak]] int sys_setsockopt(int fd, int layer, int number, - const void *buffer, socklen_t size); -[[gnu::weak]] int sys_shutdown(int sockfd, int how); -[[gnu::weak]] int sys_sigprocmask(int how, const sigset_t *__restrict set, - sigset_t *__restrict retrieve); -[[gnu::weak]] int sys_sigaction(int, const struct sigaction *__restrict, - struct sigaction *__restrict); -// NOTE: POSIX says that behavior of timeout = nullptr is unspecified. We treat this case -// as an infinite timeout, making sigtimedwait(..., nullptr) equivalent to sigwaitinfo(...) -[[gnu::weak]] int sys_sigtimedwait(const sigset_t *__restrict set, siginfo_t *__restrict info, const struct timespec *__restrict timeout, int *out_signal); -[[gnu::weak]] int sys_kill(int, int); -[[gnu::weak]] int sys_accept(int fd, int *newfd, struct sockaddr *addr_ptr, socklen_t *addr_length, int flags); -[[gnu::weak]] int sys_bind(int fd, const struct sockaddr *addr_ptr, socklen_t addr_length); -[[gnu::weak]] int sys_connect(int fd, const struct sockaddr *addr_ptr, socklen_t addr_length); -[[gnu::weak]] int sys_sockname(int fd, struct sockaddr *addr_ptr, socklen_t max_addr_length, - socklen_t *actual_length); -[[gnu::weak]] int sys_peername(int fd, struct sockaddr *addr_ptr, socklen_t max_addr_length, - socklen_t *actual_length); -[[gnu::weak]] int sys_gethostname(char *buffer, size_t bufsize); -[[gnu::weak]] int sys_sethostname(const char *buffer, size_t bufsize); -[[gnu::weak]] int sys_mkfifoat(int dirfd, const char *path, int mode); -[[gnu::weak]] int sys_getentropy(void *buffer, size_t length); -[[gnu::weak]] int sys_mknodat(int dirfd, const char *path, int mode, int dev); -[[gnu::weak]] int sys_umask(mode_t mode, mode_t *old); - -[[gnu::weak]] int sys_before_cancellable_syscall(ucontext_t *uctx); -[[gnu::weak]] int sys_tgkill(int tgid, int tid, int sig); - -[[gnu::weak]] int sys_fchownat(int dirfd, const char *pathname, uid_t owner, gid_t group, int flags); -[[gnu::weak]] int sys_sigaltstack(const stack_t *ss, stack_t *oss); -[[gnu::weak]] int sys_sigsuspend(const sigset_t *set); -[[gnu::weak]] int sys_sigpending(sigset_t *set); -[[gnu::weak]] int sys_setgroups(size_t size, const gid_t *list); -[[gnu::weak]] int sys_memfd_create(const char *name, int flags, int *fd); -[[gnu::weak]] int sys_madvise(void *addr, size_t length, int advice); -[[gnu::weak]] int sys_msync(void *addr, size_t length, int flags); - -[[gnu::weak]] int sys_getitimer(int which, struct itimerval *curr_value); -[[gnu::weak]] int sys_setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value); -[[gnu::weak]] int sys_timer_create(clockid_t clk, struct sigevent *__restrict evp, timer_t *__restrict res); -[[gnu::weak]] int sys_timer_settime(timer_t t, int flags, const struct itimerspec *__restrict val, struct itimerspec *__restrict old); -[[gnu::weak]] int sys_timer_delete(timer_t t); -[[gnu::weak]] int sys_times(struct tms *tms, clock_t *out); -[[gnu::weak]] int sys_uname(struct utsname *buf); -[[gnu::weak]] int sys_pause(); - -[[gnu::weak]] int sys_setresuid(uid_t ruid, uid_t euid, uid_t suid); -[[gnu::weak]] int sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid); -[[gnu::weak]] int sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); -[[gnu::weak]] int sys_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); -[[gnu::weak]] int sys_setreuid(uid_t ruid, uid_t euid); -[[gnu::weak]] int sys_setregid(gid_t rgid, gid_t egid); - -[[gnu::weak]] int sys_poll(struct pollfd *fds, nfds_t count, int timeout, int *num_events); - -[[gnu::weak]] int sys_if_indextoname(unsigned int index, char *name); -[[gnu::weak]] int sys_if_nametoindex(const char *name, unsigned int *ret); - -[[gnu::weak]] int sys_ptsname(int fd, char *buffer, size_t length); -[[gnu::weak]] int sys_unlockpt(int fd); - -[[gnu::weak]] int sys_thread_setname(void *tcb, const char *name); -[[gnu::weak]] int sys_thread_getname(void *tcb, char *name, size_t size); - -[[gnu::weak]] int sys_sysconf(int num, long *ret); - -[[gnu::weak]] int sys_semget(key_t key, int n, int fl, int *id); -[[gnu::weak]] int sys_semctl(int semid, int semnum, int cmd, void *semun, int *ret); - -[[gnu::weak]] int sys_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask); -[[gnu::weak]] int sys_getthreadaffinity(pid_t tid, size_t cpusetsize, cpu_set_t *mask); - -[[gnu::weak]] int sys_setaffinity(pid_t pid, size_t cpusetsize, const cpu_set_t *mask); -[[gnu::weak]] int sys_setthreadaffinity(pid_t tid, size_t cpusetsize, const cpu_set_t *mask); - -[[gnu::weak]] int sys_waitid(idtype_t idtype, id_t id, siginfo_t *info, int options); - -} //namespace mlibc - -#endif // MLIBC_POSIX_SYSDEPS diff --git a/lib/mlibc/options/posix/include/mlibc/resolv_conf.hpp b/lib/mlibc/options/posix/include/mlibc/resolv_conf.hpp deleted file mode 100644 index 2a349c7..0000000 --- a/lib/mlibc/options/posix/include/mlibc/resolv_conf.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _MLIBC_RESOLV_CONF -#define _MLIBC_RESOLV_CONF - -#include <frg/string.hpp> -#include <frg/optional.hpp> -#include <mlibc/allocator.hpp> - -namespace mlibc { - -struct nameserver_data { - nameserver_data() - : name(getAllocator()) {} - frg::string<MemoryAllocator> name; - // for in the future we can also store options here -}; - -frg::optional<struct nameserver_data> get_nameserver(); - -} // namespace mlibc - -#endif // _MLIBC_RESOLV_CONF diff --git a/lib/mlibc/options/posix/include/mlibc/services.hpp b/lib/mlibc/options/posix/include/mlibc/services.hpp deleted file mode 100644 index 10dec47..0000000 --- a/lib/mlibc/options/posix/include/mlibc/services.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef _MLIBC_SERVICES -#define _MLIBC_SERVICES - -#include <frg/small_vector.hpp> -#include <frg/vector.hpp> -#include <frg/string.hpp> -#include <mlibc/allocator.hpp> - -namespace mlibc { - -// Only two services for tcp and udp -#define SERV_MAX 2 - -struct service_buf { - service_buf() - : name(getAllocator()), aliases(getAllocator()) - { } - int port, protocol, socktype; - frg::string<MemoryAllocator> name; - frg::vector<frg::string<MemoryAllocator>, MemoryAllocator> aliases; -}; - -using service_result = frg::small_vector<service_buf, SERV_MAX, MemoryAllocator>; - -int lookup_serv_by_name(service_result &buf, const char *name, int proto, - int socktype, int flags); - -int lookup_serv_by_port(service_result &buf, int proto, int port); - - -} // namespace mlibc - -#endif // _MLIBC_SERVICES diff --git a/lib/mlibc/options/posix/include/mqueue.h b/lib/mlibc/options/posix/include/mqueue.h deleted file mode 100644 index 34ac990..0000000 --- a/lib/mlibc/options/posix/include/mqueue.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef _MQUEUE_H -#define _MQUEUE_H - -#include <abi-bits/mqueue.h> - -#ifdef __cplusplus -extern "C" { -#endif - -typedef int mqd_t; - -#ifndef __MLIBC_ABI_ONLY - -int mq_getattr(mqd_t mqdes, struct mq_attr *attr); -int mq_setattr(mqd_t mqdes, const struct mq_attr *__restrict__ newattr, struct mq_attr *__restrict__ oldattr); -int mq_unlink(const char *name); -mqd_t mq_open(const char *name, int flags, ...); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif /* _MQUEUE_H */ - diff --git a/lib/mlibc/options/posix/include/net/if.h b/lib/mlibc/options/posix/include/net/if.h deleted file mode 100644 index 10016fd..0000000 --- a/lib/mlibc/options/posix/include/net/if.h +++ /dev/null @@ -1,118 +0,0 @@ - -#ifndef _NET_IF_H -#define _NET_IF_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/socket.h> - -#define IF_NAMESIZE 16 -#define IFNAMSIZ IF_NAMESIZE -#define ALTIFNAMSIZ 128 -#define IFALIASZ 256 - -struct if_nameindex { - unsigned int if_index; - char *if_name; -}; - -struct ifmap { - unsigned long mem_start; - unsigned long mem_end; - unsigned short base_addr; - unsigned char irq; - unsigned char dma; - unsigned char port; -}; - -struct ifreq { - union { - char ifrn_name[IFNAMSIZ]; - } ifr_ifrn; - - union { - struct sockaddr ifru_addr; - struct sockaddr ifru_dstaddr; - struct sockaddr ifru_broadaddr; - struct sockaddr ifru_netmask; - struct sockaddr ifru_hwaddr; - short int ifru_flags; - int ifru_ivalue; - int ifru_mtu; - struct ifmap ifru_map; - char ifru_slave[IFNAMSIZ]; - char ifru_newname[IFNAMSIZ]; - char *ifru_data; - } ifr_ifru; -}; - -#define ifr_name ifr_ifrn.ifrn_name -#define ifr_hwaddr ifr_ifru.ifru_hwaddr -#define ifr_addr ifr_ifru.ifru_addr -#define ifr_dstaddr ifr_ifru.ifru_dstaddr -#define ifr_broadaddr ifr_ifru.ifru_broadaddr -#define ifr_netmask ifr_ifru.ifru_netmask -#define ifr_flags ifr_ifru.ifru_flags -#define ifr_metric ifr_ifru.ifru_ivalue -#define ifr_mtu ifr_ifru.ifru_mtu -#define ifr_map ifr_ifru.ifru_map -#define ifr_slave ifr_ifru.ifru_slave -#define ifr_data ifr_ifru.ifru_data -#define ifr_ifindex ifr_ifru.ifru_ivalue -#define ifr_bandwidth ifr_ifru.ifru_ivalue -#define ifr_qlen ifr_ifru.ifru_ivalue -#define ifr_newname ifr_ifru.ifru_newname - -struct ifconf { - int ifc_len; - union { - char *ifcu_buf; - struct ifreq *ifcu_req; - } ifc_ifcu; -}; - -#define ifc_buf ifc_ifcu.ifcu_buf -#define ifc_req ifc_ifcu.ifcu_req - -#ifndef __MLIBC_ABI_ONLY - -void if_freenameindex(struct if_nameindex *); -char *if_indextoname(unsigned int, char *); -struct if_nameindex *if_nameindex(void); -unsigned int if_nametoindex(const char *); - -#endif /* !__MLIBC_ABI_ONLY */ - -#define IFHWADDRLEN 6 - -#define IFF_UP 0x1 -#define IFF_BROADCAST 0x2 -#define IFF_DEBUG 0x4 -#define IFF_LOOPBACK 0x8 -#define IFF_POINTOPOINT 0x10 -#define IFF_NOTRAILERS 0x20 -#define IFF_RUNNING 0x40 -#define IFF_NOARP 0x80 -#define IFF_PROMISC 0x100 -#define IFF_ALLMULTI 0x200 -#define IFF_MASTER 0x400 -#define IFF_SLAVE 0x800 -#define IFF_MULTICAST 0x1000 -#define IFF_PORTSEL 0x2000 -#define IFF_AUTOMEDIA 0x4000 -#define IFF_DYNAMIC 0x8000 -#define IFF_LOWER_UP 0x10000 -#define IFF_DORMANT 0x20000 -#define IFF_ECHO 0x40000 -#define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST| \ - IFF_ECHO|IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT) - -#ifdef __cplusplus -} -#endif - -#endif // _NET_IF_H - - diff --git a/lib/mlibc/options/posix/include/net/if_arp.h b/lib/mlibc/options/posix/include/net/if_arp.h deleted file mode 100644 index de8a0c2..0000000 --- a/lib/mlibc/options/posix/include/net/if_arp.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef _NET_IF_ARP_H -#define _NET_IF_ARP_H - -#include <sys/types.h> -#include <sys/socket.h> -#include <stdint.h> - -#define ARPOP_REQUEST 1 -#define ARPOP_REPLY 2 -#define ARPOP_RREQUEST 3 -#define ARPOP_RREPLY 4 -#define ARPOP_InREQUEST 8 -#define ARPOP_InREPLY 9 -#define ARPOP_NAK 10 - -#define ARPHRD_NETROM 0 -#define ARPHRD_ETHER 1 -#define ARPHRD_EETHER 2 -#define ARPHRD_AX25 3 -#define ARPHRD_PRONET 4 -#define ARPHRD_CHAOS 5 -#define ARPHRD_IEEE802 6 -#define ARPHRD_ARCNET 7 -#define ARPHRD_APPLETLK 8 -#define ARPHRD_DLCI 15 -#define ARPHRD_ATM 19 -#define ARPHRD_METRICOM 23 -#define ARPHRD_IEEE1394 24 -#define ARPHRD_EUI64 27 -#define ARPHRD_INFINIBAND 32 -#define ARPHRD_SLIP 256 -#define ARPHRD_CSLIP 257 -#define ARPHRD_SLIP6 258 -#define ARPHRD_CSLIP6 259 -#define ARPHRD_RSRVD 260 -#define ARPHRD_ADAPT 264 -#define ARPHRD_ROSE 270 -#define ARPHRD_X25 271 -#define ARPHRD_HWX25 272 -#define ARPHRD_CAN 280 -#define ARPHRD_PPP 512 -#define ARPHRD_CISCO 513 -#define ARPHRD_HDLC ARPHRD_CISCO -#define ARPHRD_LAPB 516 -#define ARPHRD_DDCMP 517 -#define ARPHRD_RAWHDLC 518 -#define ARPHRD_RAWIP 519 - -#define ARPHRD_TUNNEL 768 -#define ARPHRD_TUNNEL6 769 -#define ARPHRD_FRAD 770 -#define ARPHRD_SKIP 771 -#define ARPHRD_LOOPBACK 772 -#define ARPHRD_LOCALTLK 773 -#define ARPHRD_FDDI 774 -#define ARPHRD_BIF 775 -#define ARPHRD_SIT 776 -#define ARPHRD_IPDDP 777 -#define ARPHRD_IPGRE 778 -#define ARPHRD_PIMREG 779 -#define ARPHRD_HIPPI 780 -#define ARPHRD_ASH 781 -#define ARPHRD_ECONET 782 -#define ARPHRD_IRDA 783 -#define ARPHRD_FCPP 784 -#define ARPHRD_FCAL 785 -#define ARPHRD_FCPL 786 -#define ARPHRD_FCFABRIC 787 -#define ARPHRD_IEEE802_TR 800 -#define ARPHRD_IEEE80211 801 -#define ARPHRD_IEEE80211_PRISM 802 -#define ARPHRD_IEEE80211_RADIOTAP 803 -#define ARPHRD_IEEE802154 804 -#define ARPHRD_IEEE802154_MONITOR 805 -#define ARPHRD_PHONET 820 -#define ARPHRD_PHONET_PIPE 821 -#define ARPHRD_CAIF 822 -#define ARPHRD_IP6GRE 823 -#define ARPHRD_NETLINK 824 -#define ARPHRD_6LOWPAN 825 -#define ARPHRD_VSOCKMON 826 - -#define ARPHRD_VOID 0xFFFF -#define ARPHRD_NONE 0xFFFE - -struct arphdr { - uint16_t ar_hrd; - uint16_t ar_pro; - uint8_t ar_hln; - uint8_t ar_pln; - uint16_t ar_op; -}; - -struct arpreq { - struct sockaddr arp_pa; - struct sockaddr arp_ha; - int arp_flags; - struct sockaddr arp_netmask; - char arp_dev[16]; -}; - -#endif // _NET_IF_ARP_H - diff --git a/lib/mlibc/options/posix/include/netdb.h b/lib/mlibc/options/posix/include/netdb.h deleted file mode 100644 index 368c74f..0000000 --- a/lib/mlibc/options/posix/include/netdb.h +++ /dev/null @@ -1,148 +0,0 @@ -#ifndef _NETDB_H -#define _NETDB_H - -#include <stdint.h> -#include <bits/size_t.h> -#include <bits/posix/in_port_t.h> -#include <bits/posix/in_addr_t.h> -#include <abi-bits/socklen_t.h> - -#define AI_PASSIVE 0x01 -#define AI_CANONNAME 0x02 -#define AI_NUMERICHOST 0x04 -#define AI_V4MAPPED 0x08 -#define AI_ALL 0x10 -#define AI_ADDRCONFIG 0x20 -#define AI_NUMERICSERV 0x40 - -#define NI_NOFQDN 0x01 -#define NI_NUMERICHOST 0x02 -#define NI_NAMEREQD 0x04 -#define NI_NUMERICSCOPE 0x08 -#define NI_DGRAM 0x10 - -#define NI_NUMERICSERV 2 -#define NI_MAXSERV 32 -#define NI_IDN 32 - -#define NI_MAXHOST 1025 - -#define EAI_AGAIN 1 -#define EAI_BADFLAGS 2 -#define EAI_FAIL 3 -#define EAI_FAMILY 4 -#define EAI_MEMORY 5 -#define EAI_NONAME 6 -#define EAI_SERVICE 7 -#define EAI_SOCKTYPE 8 -#define EAI_SYSTEM 9 -#define EAI_OVERFLOW 10 -#define EAI_NODATA 11 -#define EAI_ADDRFAMILY 12 - -#define HOST_NOT_FOUND 1 -#define TRY_AGAIN 2 -#define NO_RECOVERY 3 -#define NO_DATA 4 -#define NO_ADDRESS NO_DATA - -#define IPPORT_RESERVED 1024 - -#define _PATH_SERVICES "/etc/services" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef __MLIBC_ABI_ONLY - -int *__h_errno_location(void); -#define h_errno (*__h_errno_location()) - -#endif /* !__MLIBC_ABI_ONLY */ - -struct hostent { - char *h_name; - char **h_aliases; - int h_addrtype; - int h_length; - char **h_addr_list; -}; - -#define h_addr h_addr_list[0] // Required by some programs - -struct netent { - char *n_name; - char **n_aliases; - int n_addrtype; - uint32_t n_net; -}; - -struct protoent { - char *p_name; - char **p_aliases; - int p_proto; -}; - -struct servent { - char *s_name; - char **s_aliases; - int s_port; - char *s_proto; -}; - -struct addrinfo { - int ai_flags; - int ai_family; - int ai_socktype; - int ai_protocol; - socklen_t ai_addrlen; - struct sockaddr *ai_addr; - char *ai_canonname; - struct addrinfo *ai_next; -}; - -#ifndef __MLIBC_ABI_ONLY - -void endhostent(void); -void endnetent(void); -void endprotoent(void); -void endservent(void); -void freeaddrinfo(struct addrinfo *); -const char *gai_strerror(int); -int getaddrinfo(const char *__restrict, const char *__restrict, - const struct addrinfo *__restrict, struct addrinfo **__restrict); -struct hostent *gethostent(void); -struct hostent *gethostbyname(const char *); -struct hostent *gethostbyname2(const char *, int); -struct hostent *gethostbyaddr(const void *, socklen_t, int); -int gethostbyaddr_r(const void *__restrict, socklen_t, int, struct hostent *__restrict, - char *__restrict, size_t, struct hostent **__restrict, int *__restrict); -int gethostbyname_r(const char *__restrict, struct hostent *__restrict, char *__restrict, size_t, - struct hostent **__restrict, int *__restrict); -int getnameinfo(const struct sockaddr *__restrict, socklen_t, - char *__restrict, socklen_t, char *__restrict, socklen_t, int); -struct netent *getnetbyaddr(uint32_t, int); -struct netent *getnetbyname(const char *); -struct netent *getnetent(void); -struct protoent *getprotobyname(const char *); -struct protoent *getprotobynumber(int); -struct protoent *getprotoent(void); -struct servent *getservbyname(const char *, const char *); -struct servent *getservbyport(int, const char *); -struct servent *getservent(void); -void sethostent(int); -void setnetent(int); -void setprotoent(int); -void setservent(int); - -// Deprecated GNU extension -const char *hstrerror(int err); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _NETDB_H diff --git a/lib/mlibc/options/posix/include/netinet/icmp6.h b/lib/mlibc/options/posix/include/netinet/icmp6.h deleted file mode 100644 index 7dfe237..0000000 --- a/lib/mlibc/options/posix/include/netinet/icmp6.h +++ /dev/null @@ -1,139 +0,0 @@ -#ifndef _NETINET_ICMP6_H -#define _NETINET_ICMP6_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <stdint.h> -#include <abi-bits/in.h> -#include <mlibc-config.h> - -#if __MLIBC_GLIBC_OPTION -#include <bits/glibc/glibc_icmp6.h> -#endif // __MLIBC_GLIBC_OPTION - -#define ICMP6_FILTER 1 - -#define ICMP6_FILTER_BLOCK 1 -#define ICMP6_FILTER_PASS 2 -#define ICMP6_FILTER_BLOCKOTHERS 3 -#define ICMP6_FILTER_PASSONLY 4 -#define ICMP6_ECHO_REQUEST 128 - -struct icmp6_filter { - uint32_t icmp6_filt[8]; -}; - -struct icmp6_hdr { - uint8_t icmp6_type; - uint8_t icmp6_code; - uint16_t icmp6_cksum; - union { - uint32_t icmp6_un_data32[1]; - uint16_t icmp6_un_data16[2]; - uint8_t icmp6_un_data8[4]; - } icmp6_dataun; -}; - -#define icmp6_data32 icmp6_dataun.icmp6_un_data32 -#define icmp6_data16 icmp6_dataun.icmp6_un_data16 -#define icmp6_data8 icmp6_dataun.icmp6_un_data8 - -#define icmp6_pptr icmp6_data32[0] -#define icmp6_mtu icmp6_data32[0] -#define icmp6_id icmp6_data16[0] -#define icmp6_seq icmp6_data16[1] -#define icmp6_maxdelay icmp6_data16[0] - -#define ICMP6_FILTER_WILLPASS(type, filterp) \ - ((((filterp)->icmp6_filt[(type) >> 5]) & (1U << ((type) & 31))) == 0) - -#define ICMP6_FILTER_WILLBLOCK(type, filterp) \ - ((((filterp)->icmp6_filt[(type) >> 5]) & (1U << ((type) & 31))) != 0) - -#define ICMP6_FILTER_SETPASS(type, filterp) \ - ((((filterp)->icmp6_filt[(type) >> 5]) &= ~(1U << ((type) & 31)))) - -#define ICMP6_FILTER_SETBLOCK(type, filterp) \ - ((((filterp)->icmp6_filt[(type) >> 5]) |= (1U << ((type) & 31)))) - -#define ICMP6_FILTER_SETPASSALL(filterp) \ - memset (filterp, 0, sizeof (struct icmp6_filter)); - -#define ICMP6_FILTER_SETBLOCKALL(filterp) \ - memset (filterp, 0xFF, sizeof (struct icmp6_filter)); - -#define ND_ROUTER_SOLICIT 133 -#define ND_ROUTER_ADVERT 134 -#define ND_NEIGHBOR_SOLICIT 135 -#define ND_NEIGHBOR_ADVERT 136 -#define ND_REDIRECT 137 - -struct nd_router_solicit { - struct icmp6_hdr nd_rs_hdr; -}; - -#define nd_rs_type nd_rs_hdr.icmp6_type -#define nd_rs_code nd_rs_hdr.icmp6_code -#define nd_rs_cksum nd_rs_hdr.icmp6_cksum -#define nd_rs_reserved nd_rs_hdr.icmp6_data32[0] - -struct nd_router_advert { - struct icmp6_hdr nd_ra_hdr; - uint32_t nd_ra_reachable; - uint32_t nd_ra_retransmit; -}; - -struct nd_opt_hdr { - uint8_t nd_opt_type; - uint8_t nd_opt_len; -}; - -#define ND_OPT_SOURCE_LINKADDR 1 -#define ND_OPT_TARGET_LINKADDR 2 -#define ND_OPT_PREFIX_INFORMATION 3 -#define ND_OPT_REDIRECTED_HEADER 4 -#define ND_OPT_MTU 5 -#define ND_OPT_RTR_ADV_INTERVAL 7 -#define ND_OPT_HOME_AGENT_INFO 8 - -struct nd_opt_prefix_info { - uint8_t nd_opt_pi_type; - uint8_t nd_opt_pi_len; - uint8_t nd_opt_pi_prefix_len; - uint8_t nd_opt_pi_flags_reserved; - uint32_t nd_opt_pi_valid_time; - uint32_t nd_opt_pi_preferred_time; - uint32_t nd_opt_pi_reserved2; - struct in6_addr nd_opt_pi_prefix; -}; - -#define ND_OPT_PI_FLAG_RADDR 0x20 -#define ND_OPT_PI_FLAG_AUTO 0x40 -#define ND_OPT_PI_FLAG_ONLINK 0x80 - -#define nd_ra_type nd_ra_hdr.icmp6_type -#define nd_ra_code nd_ra_hdr.icmp6_code -#define nd_ra_cksum nd_ra_hdr.icmp6_cksum -#define nd_ra_curhoplimit nd_ra_hdr.icmp6_data8[0] -#define nd_ra_flags_reserved nd_ra_hdr.icmp6_data8[1] -#define nd_ra_router_lifetime nd_ra_hdr.icmp6_data16[1] - -#define ND_RA_FLAG_HOME_AGENT 0x20 -#define ND_RA_FLAG_OTHER 0x40 -#define ND_RA_FLAG_MANAGED 0x80 - -struct nd_opt_mtu { - uint8_t nd_opt_mtu_type; - uint8_t nd_opt_mtu_len; - uint16_t nd_opt_mtu_reserved; - uint32_t nd_opt_mtu_mtu; -}; - -#ifdef __cplusplus -} -#endif - -#endif // _NETINET_ICMP6_H - diff --git a/lib/mlibc/options/posix/include/netinet/if_ether.h b/lib/mlibc/options/posix/include/netinet/if_ether.h deleted file mode 100644 index c4ce173..0000000 --- a/lib/mlibc/options/posix/include/netinet/if_ether.h +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef _NETINET_IF_ETHER_H -#define _NETINET_IF_ETHER_H - -#include <net/if_arp.h> - -#define ETH_ALEN 6 -#define ETH_HLEN 14 -#define ETH_ZLEN 60 -#define ETH_FRAME_LEN 1514 -#define ETH_FCS_LEN 4 - -#define ETH_P_LOOP 0x0060 -#define ETH_P_PUP 0x0200 -#define ETH_P_PUPAT 0x0201 -#define ETH_P_IP 0x0800 -#define ETH_P_X25 0x0805 -#define ETH_P_ARP 0x0806 -#define ETH_P_BPQ 0x08FF -#define ETH_P_IEEEPUP 0x0a00 -#define ETH_P_IEEEPUPAT 0x0a01 -#define ETH_P_BATMAN 0x4305 -#define ETH_P_DEC 0x6000 -#define ETH_P_DNA_DL 0x6001 -#define ETH_P_DNA_RC 0x6002 -#define ETH_P_DNA_RT 0x6003 -#define ETH_P_LAT 0x6004 -#define ETH_P_DIAG 0x6005 -#define ETH_P_CUST 0x6006 -#define ETH_P_SCA 0x6007 -#define ETH_P_TEB 0x6558 -#define ETH_P_RARP 0x8035 -#define ETH_P_ATALK 0x809B -#define ETH_P_AARP 0x80F3 -#define ETH_P_8021Q 0x8100 -#define ETH_P_IPX 0x8137 -#define ETH_P_IPV6 0x86DD -#define ETH_P_PAUSE 0x8808 -#define ETH_P_SLOW 0x8809 -#define ETH_P_WCCP 0x883E -#define ETH_P_MPLS_UC 0x8847 -#define ETH_P_MPLS_MC 0x8848 -#define ETH_P_ATMMPOA 0x884c -#define ETH_P_PPP_DISC 0x8863 -#define ETH_P_PPP_SES 0x8864 -#define ETH_P_LINK_CTL 0x886c -#define ETH_P_ATMFATE 0x8884 -#define ETH_P_PAE 0x888E -#define ETH_P_AOE 0x88A2 -#define ETH_P_8021AD 0x88A8 -#define ETH_P_802_EX1 0x88B5 -#define ETH_P_TIPC 0x88CA -#define ETH_P_8021AH 0x88E7 -#define ETH_P_MVRP 0x88F5 -#define ETH_P_1588 0x88F7 -#define ETH_P_PRP 0x88FB -#define ETH_P_FCOE 0x8906 -#define ETH_P_TDLS 0x890D -#define ETH_P_FIP 0x8914 -#define ETH_P_80221 0x8917 -#define ETH_P_LOOPBACK 0x9000 -#define ETH_P_QINQ1 0x9100 -#define ETH_P_QINQ2 0x9200 -#define ETH_P_QINQ3 0x9300 -#define ETH_P_EDSA 0xDADA -#define ETH_P_AF_IUCV 0xFBFB - -#define ETH_P_802_3_MIN 0x0600 - -#define ETH_P_802_3 0x0001 -#define ETH_P_AX25 0x0002 -#define ETH_P_ALL 0x0003 -#define ETH_P_802_2 0x0004 -#define ETH_P_SNAP 0x0005 -#define ETH_P_DDCMP 0x0006 -#define ETH_P_WAN_PPP 0x0007 -#define ETH_P_PPP_MP 0x0008 -#define ETH_P_LOCALTALK 0x0009 -#define ETH_P_CAN 0x000C -#define ETH_P_CANFD 0x000D -#define ETH_P_PPPTALK 0x0010 -#define ETH_P_TR_802_2 0x0011 -#define ETH_P_MOBITEX 0x0015 -#define ETH_P_CONTROL 0x0016 -#define ETH_P_IRDA 0x0017 -#define ETH_P_ECONET 0x0018 -#define ETH_P_HDLC 0x0019 -#define ETH_P_ARCNET 0x001A -#define ETH_P_DSA 0x001B -#define ETH_P_TRAILER 0x001C -#define ETH_P_PHONET 0x00F5 -#define ETH_P_IEEE802154 0x00F6 -#define ETH_P_CAIF 0x00F7 - -#include <net/ethernet.h> -#include <net/if_arp.h> - -struct ether_arp { - struct arphdr ea_hdr; - uint8_t arp_sha[ETH_ALEN]; - uint8_t arp_spa[4]; - uint8_t arp_tha[ETH_ALEN]; - uint8_t arp_tpa[4]; -}; - -#endif //_NETINET_IF_ETHER_H diff --git a/lib/mlibc/options/posix/include/netinet/in.h b/lib/mlibc/options/posix/include/netinet/in.h deleted file mode 100644 index 9a42c47..0000000 --- a/lib/mlibc/options/posix/include/netinet/in.h +++ /dev/null @@ -1,118 +0,0 @@ - -#ifndef _NETINET_IN_H -#define _NETINET_IN_H - -#include <stdint.h> -#include <endian.h> -#include <sys/socket.h> // struct sockaddr -#include <abi-bits/socket.h> -#include <abi-bits/in.h> -#include <arpa/inet.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef __MLIBC_ABI_ONLY - -extern const struct in6_addr in6addr_any; -extern const struct in6_addr in6addr_loopback; - -uint32_t htonl(uint32_t); -uint16_t htons(uint16_t); -uint32_t ntohl(uint32_t); -uint16_t ntohs(uint16_t); - -#endif /* !__MLIBC_ABI_ONLY */ - -#define IN6_IS_ADDR_UNSPECIFIED(a) ({ \ - uint32_t *_a = (uint32_t *)(((struct in6_addr *) a)->s6_addr); \ - !_a[0] && \ - !_a[1] && \ - !_a[2] && \ - !_a[3]; \ -}) -#define IN6_IS_ADDR_LOOPBACK(a) ({ \ - uint32_t *_a = (uint32_t *)(((struct in6_addr *) a)->s6_addr); \ - !_a[0] && \ - !_a[1] && \ - !_a[2] && \ - _a[3] == htonl(0x0001); \ -}) -#define IN6_IS_ADDR_MULTICAST(a) (((const uint8_t *) (a))[0] == 0xff) -#define IN6_IS_ADDR_LINKLOCAL(a) ({ \ - uint32_t *_a = (uint32_t *)(((struct in6_addr *) a)->s6_addr); \ - _a[0] & htonl(0xffc00000) == htonl(0xfe800000); \ -}) -#define IN6_IS_ADDR_SITELOCAL(a) ({ \ - uint32_t *_a = (uint32_t *)(((struct in6_addr *) a)->s6_addr); \ - _a[0] & htonl(0xffc00000) == htonl(0xfec00000); \ -}) -#define IN6_IS_ADDR_V4MAPPED(a) ({ \ - uint32_t *_a = (uint32_t *)(((struct in6_addr *) a)->s6_addr); \ - !_a[0] && \ - !_a[1] && \ - _a[2] == htonl(0xffff); \ -}) -#define __ARE_4_BYTE_EQUAL(a, b) \ - ((a)[0] == (b)[0] && (a)[1] == (b)[1] && (a)[2] == (b)[2] && \ - (a)[3] == (b)[3] && (a)[4] == (b)[4]) -#define IN6_ARE_ADDR_EQUAL(a, b) \ - __ARE_4_BYTE_EQUAL((const uint32_t *)(a), (const uint32_t *)(b)) - -#define IN6_IS_ADDR_V4COMPAT(a) ({ \ - uint32_t *_a = (uint32_t *)(((struct in6_addr *) a)->s6_addr); \ - uint8_t *_a8 = (uint8_t *)(((struct in6_addr *) a)->s6_addr); \ - !_a[0] && !_a[1] && !_a[2] && (_a8[15] > 1); \ -}) -#define IN6_IS_ADDR_MC_NODELOCAL(a) ({ \ - (IN6_IS_ADDR_MULTICAST(a) && \ - ((((const uint8_t *)(a))[1] & 0xf) == 0x1)); \ -}) -#define IN6_IS_ADDR_MC_LINKLOCAL(a) ({ \ - (IN6_IS_ADDR_MULTICAST(a) && \ - ((((const uint8_t *)(a))[1] & 0xf) == 0x2)); \ -}) -#define IN6_IS_ADDR_MC_SITELOCAL(a) ({ \ - (IN6_IS_ADDR_MULTICAST(a) && \ - ((((const uint8_t *)(a))[1] & 0xf) == 0x5)); \ -}) -#define IN6_IS_ADDR_MC_ORGLOCAL(a) ({ \ - (IN6_IS_ADDR_MULTICAST(a) && \ - ((((const uint8_t *)(a))[1] & 0xf) == 0x8)); \ -}) -#define IN6_IS_ADDR_MC_GLOBAL(a) ({ \ - (IN6_IS_ADDR_MULTICAST(a) && \ - ((((const uint8_t *)(a))[1] & 0xf) == 0xe)); \ -}) - -#define IN_CLASSA(a) ((((in_addr_t)(a)) & 0x80000000) == 0) -#define IN_CLASSA_NET 0xff000000 -#define IN_CLASSA_NSHIFT 24 -#define IN_CLASSA_HOST (0xffffffff & ~IN_CLASSA_NET) -#define IN_CLASSA_MAX 128 -#define IN_CLASSB(a) ((((in_addr_t)(a)) & 0xc0000000) == 0x80000000) -#define IN_CLASSB_NET 0xffff0000 -#define IN_CLASSB_NSHIFT 16 -#define IN_CLASSB_HOST (0xffffffff & ~IN_CLASSB_NET) -#define IN_CLASSB_MAX 65536 -#define IN_CLASSC(a) ((((in_addr_t)(a)) & 0xe0000000) == 0xc0000000) -#define IN_CLASSC_NET 0xffffff00 -#define IN_CLASSC_NSHIFT 8 -#define IN_CLASSC_HOST (0xffffffff & ~IN_CLASSC_NET) -#define IN_CLASSD(a) ((((in_addr_t)(a)) & 0xf0000000) == 0xe0000000) -#define IN_MULTICAST(a) IN_CLASSD(a) -#define IN_EXPERIMENTAL(a) ((((in_addr_t)(a)) & 0xe0000000) == 0xe0000000) -#define IN_BADCLASS(a) ((((in_addr_t)(a)) & 0xf0000000) == 0xf0000000) - -#define IN_LOOPBACKNET 127 - -#define MCAST_EXCLUDE 0 -#define MCAST_INCLUDE 1 - -#ifdef __cplusplus -} -#endif - -#endif // _NETINET_IN_H - diff --git a/lib/mlibc/options/posix/include/netinet/ip.h b/lib/mlibc/options/posix/include/netinet/ip.h deleted file mode 100644 index 161aa18..0000000 --- a/lib/mlibc/options/posix/include/netinet/ip.h +++ /dev/null @@ -1,75 +0,0 @@ - -#ifndef _NETINET_IP_H -#define _NETINET_IP_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/types.h> -#include <netinet/in.h> - -#define IPTOS_TOS_MASK 0x1E -#define IPTOS_TOS(tos) ((tos) & IPTOS_TOS_MASK) -#define IPTOS_LOWDELAY 0x10 -#define IPTOS_THROUGHPUT 0x08 -#define IPTOS_RELIABILITY 0x04 -#define IPTOS_LOWCOST 0x02 -#define IPTOS_MINCOST IPTOS_LOWCOST -#define IPTOS_CLASS_CS4 0x80 -#define IPTOS_CLASS_CS6 0xC0 - -#define IPDEFTTL 64 - -struct ip { -#if __BYTE_ORDER == __LITTLE_ENDIAN - unsigned int ip_hl:4; - unsigned int ip_v:4; -#endif -#if __BYTE_ORDER == __BIG_ENDIAN - unsigned int ip_v:4; - unsigned int ip_hl:4; -#endif - uint8_t ip_tos; - unsigned short ip_len; - unsigned short ip_id; - unsigned short ip_off; -#define IP_RF 0x8000 -#define IP_DF 0x4000 -#define IP_MF 0x2000 -#define IP_OFFMASK 0x1fff - uint8_t ip_ttl; - uint8_t ip_p; - unsigned short ip_sum; - struct in_addr ip_src, ip_dst; -}; - -#define IPVERSION 4 - -struct iphdr { -#if __BYTE_ORDER == __LITTLE_ENDIAN - unsigned int ihl:4; - unsigned int version:4; -#elif __BYTE_ORDER == __BIG_ENDIAN - unsigned int version:4; - unsigned int ihl:4; -#else -# error "Please fix <endian.h>" -#endif - uint8_t tos; - uint16_t tot_len; - uint16_t id; - uint16_t frag_off; - uint8_t ttl; - uint8_t protocol; - uint16_t check; - uint32_t saddr; - uint32_t daddr; -}; - -#ifdef __cplusplus -} -#endif - -#endif // _NETINET_IP_H - diff --git a/lib/mlibc/options/posix/include/netinet/ip6.h b/lib/mlibc/options/posix/include/netinet/ip6.h deleted file mode 100644 index 88f0cb6..0000000 --- a/lib/mlibc/options/posix/include/netinet/ip6.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _NETINET_IP6_H -#define _NETINET_IP6_H - -#include <netinet/in.h> - -#ifdef __cplusplus -extern "C" { -#endif - -struct ip6_hdr { - union { - struct ip6_hdrctl { - uint32_t ip6_un1_flow; - uint16_t ip6_un1_plen; - uint8_t ip6_un1_nxt; - uint8_t ip6_un1_hlim; - } ip6_un1; - uint8_t ip6_un2_vfc; - } ip6_ctlun; - struct in6_addr ip6_src; - struct in6_addr ip6_dst; -}; - -#ifdef __cplusplus -} -#endif - -#endif // _NETINET_IP6_H diff --git a/lib/mlibc/options/posix/include/netinet/ip_icmp.h b/lib/mlibc/options/posix/include/netinet/ip_icmp.h deleted file mode 100644 index 56615e4..0000000 --- a/lib/mlibc/options/posix/include/netinet/ip_icmp.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef _NETINET_ICMP_H -#define _NETINET_ICMP_H - -#include <stdint.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#include <netinet/in.h> -#include <netinet/ip.h> - -#define ICMP_ECHOREPLY 0 -#define ICMP_ECHO 8 -#define ICMP_ADVLENMIN (8 + sizeof(struct ip) + 8) - -struct icmp_ra_addr { - uint32_t ira_addr; - uint32_t ira_preference; -}; - -struct icmp { - uint8_t icmp_type; - uint8_t icmp_code; - uint16_t icmp_cksum; - union { - unsigned char ih_pptr; - struct in_addr ih_gwaddr; - struct ih_idseq { - uint16_t icd_id; - uint16_t icd_seq; - } ih_idseq; - uint32_t ih_void; - - struct ih_pmtu { - uint16_t ipm_void; - uint16_t ipm_nextmtu; - } ih_pmtu; - - struct ih_rtradv { - uint8_t irt_num_addrs; - uint8_t irt_wpa; - uint16_t irt_lifetime; - } ih_rtradv; - } icmp_hun; - union { - struct { - uint32_t its_otime; - uint32_t its_rtime; - uint32_t its_ttime; - } id_ts; - struct { - struct ip idi_ip; - } id_ip; - struct icmp_ra_addr id_radv; - uint32_t id_mask; - uint8_t id_data[1]; - } icmp_dun; -}; - -#define icmp_pptr icmp_hun.ih_pptr -#define icmp_gwaddr icmp_hun.ih_gwaddr -#define icmp_id icmp_hun.ih_idseq.icd_id -#define icmp_seq icmp_hun.ih_idseq.icd_seq -#define icmp_void icmp_hun.ih_void -#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void -#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu -#define icmp_num_addrs icmp_hun.ih_rtradv.irt_num_addrs -#define icmp_wpa icmp_hun.ih_rtradv.irt_wpa -#define icmp_lifetime icmp_hun.ih_rtradv.irt_lifetime - -#define icmp_otime icmp_dun.id_ts.its_otime -#define icmp_rtime icmp_dun.id_ts.its_rtime -#define icmp_ttime icmp_dun.id_ts.its_ttime -#define icmp_ip icmp_dun.id_ip.idi_ip -#define icmp_radv icmp_dun.id_radv -#define icmp_mask icmp_dun.id_mask -#define icmp_data icmp_dun.id_data - -#ifdef __cplusplus -} -#endif - -#endif // _NETINET_ICMP_H diff --git a/lib/mlibc/options/posix/include/netinet/tcp.h b/lib/mlibc/options/posix/include/netinet/tcp.h deleted file mode 100644 index 9d64d7a..0000000 --- a/lib/mlibc/options/posix/include/netinet/tcp.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef _NETINET_TCP_H -#define _NETINET_TCP_H - -#ifdef __cplusplus -extern "C" { -#endif - -// Define some macros using same ABI as Linux -#define TCP_NODELAY 1 -#define TCP_MAXSEG 2 -#define TCP_KEEPIDLE 4 -#define TCP_KEEPINTVL 5 -#define TCP_KEEPCNT 6 -#define TCP_DEFER_ACCEPT 9 -#define TCP_CONGESTION 13 -#define TCP_FASTOPEN 23 - -#define TCP_ESTABLISHED 1 -#define TCP_SYN_SENT 2 -#define TCP_SYN_RECV 3 -#define TCP_FIN_WAIT1 4 -#define TCP_FIN_WAIT2 5 -#define TCP_TIME_WAIT 6 -#define TCP_CLOSE 7 -#define TCP_CLOSE_WAIT 8 -#define TCP_LAST_ACK 9 -#define TCP_LISTEN 10 -#define TCP_CLOSING 11 -#define TCP_QUICKACK 12 - -#define SOL_TCP 6 - -#ifdef __cplusplus -} -#endif - -#endif // _NETINET_TCP_H diff --git a/lib/mlibc/options/posix/include/netinet/udp.h b/lib/mlibc/options/posix/include/netinet/udp.h deleted file mode 100644 index 5cc887d..0000000 --- a/lib/mlibc/options/posix/include/netinet/udp.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef _NETINET_UDP_H -#define _NETINET_UDP_H - -#include <stdint.h> - -#ifdef __cplusplus -extern "C" { -#endif - -struct udphdr { - union { - struct { - uint16_t uh_sport; - uint16_t uh_dport; - uint16_t uh_ulen; - uint16_t uh_sum; - }; - struct { - uint16_t source; - uint16_t dest; - uint16_t len; - uint16_t check; - }; - }; -}; - -#ifdef __cplusplus -} -#endif - -#endif // _NETINET_UDP_H diff --git a/lib/mlibc/options/posix/include/nl_types.h b/lib/mlibc/options/posix/include/nl_types.h deleted file mode 100644 index f0099ba..0000000 --- a/lib/mlibc/options/posix/include/nl_types.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef NL_TYPES_H -#define NL_TYPES_H - - - -#endif // NL_TYPES_H
\ No newline at end of file diff --git a/lib/mlibc/options/posix/include/poll.h b/lib/mlibc/options/posix/include/poll.h deleted file mode 100644 index 7550015..0000000 --- a/lib/mlibc/options/posix/include/poll.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _POLL_H -#define _POLL_H - -#include <sys/poll.h> - -#endif // _POLL_H diff --git a/lib/mlibc/options/posix/include/pthread.h b/lib/mlibc/options/posix/include/pthread.h deleted file mode 100644 index 739f607..0000000 --- a/lib/mlibc/options/posix/include/pthread.h +++ /dev/null @@ -1,325 +0,0 @@ - -#ifndef _PTHREAD_H -#define _PTHREAD_H - -#include <abi-bits/clockid_t.h> -#include <bits/cpu_set.h> -// TODO: pthread is not required to define size_t. -#include <bits/size_t.h> -#include <bits/posix/pthread_t.h> -#include <bits/threads.h> -#include <mlibc-config.h> - -#include <signal.h> -#include <stdint.h> - -// pthread.h is required to include sched.h and time.h -#include <sched.h> -#include <time.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#define PTHREAD_CREATE_JOINABLE __MLIBC_THREAD_CREATE_JOINABLE -#define PTHREAD_CREATE_DETACHED __MLIBC_THREAD_CREATE_DETACHED - -// Values for pthread_attr_{get,set}scope -#define PTHREAD_SCOPE_SYSTEM 0 -#define PTHREAD_SCOPE_PROCESS 1 - -// Values for pthread_attr_{get,set}inheritsched -#define PTHREAD_INHERIT_SCHED 0 -#define PTHREAD_EXPLICIT_SCHED 1 - -// values for pthread_{get,set}canceltype(). -#define PTHREAD_CANCEL_DEFERRED 0 -#define PTHREAD_CANCEL_ASYNCHRONOUS 1 - -// values for pthread_{get,set}cancelstate(). -#define PTHREAD_CANCEL_ENABLE 0 -#define PTHREAD_CANCEL_DISABLE 1 - -// values for pthread_mutexattr_{get,set}type(). -#define PTHREAD_MUTEX_DEFAULT __MLIBC_THREAD_MUTEX_DEFAULT -#define PTHREAD_MUTEX_NORMAL __MLIBC_THREAD_MUTEX_NORMAL -#define PTHREAD_MUTEX_ERRORCHECK __MLIBC_THREAD_MUTEX_ERRORCHECK -#define PTHREAD_MUTEX_RECURSIVE __MLIBC_THREAD_MUTEX_RECURSIVE - -// values for pthread_mutexattr_{get,set}robust(). -#define PTHREAD_MUTEX_STALLED __MLIBC_THREAD_MUTEX_STALLED -#define PTHREAD_MUTEX_ROBUST __MLIBC_THREAD_MUTEX_ROBUST - -// values for pthread_mutexattr_{get,set}pshared(). -#define PTHREAD_PROCESS_PRIVATE __MLIBC_THREAD_PROCESS_PRIVATE -#define PTHREAD_PROCESS_SHARED __MLIBC_THREAD_PROCESS_SHARED - -// Values for pthread_mutexattr_{get,set}protocol() -#define PTHREAD_PRIO_NONE __MLIBC_THREAD_PRIO_NONE -#define PTHREAD_PRIO_INHERIT __MLIBC_THREAD_PRIO_INHERIT -#define PTHREAD_PRIO_PROTECT __MLIBC_THREAD_PRIO_PROTECT - -#define PTHREAD_ONCE_INIT {0} -#define PTHREAD_COND_INITIALIZER {0} -#define PTHREAD_MUTEX_INITIALIZER {0, 0, 0, 0} -#define PTHREAD_RWLOCK_INITIALIZER {0, 0, 0} - -#define PTHREAD_CANCELED ((void*) -1) - -#define PTHREAD_BARRIER_SERIAL_THREAD -1 - -// values for pthread_key -#define PTHREAD_DESTRUCTOR_ITERATIONS 8 - -#define PTHREAD_INHERIT_SCHED 0 -#define PTHREAD_EXPLICIT_SCHED 1 - -#define PTHREAD_STACK_MIN 16384 - -#define PTHREAD_ATTR_NO_SIGMASK_NP (-1) - -// TODO: move to own file and include in sys/types.h -typedef struct __mlibc_threadattr pthread_attr_t; - -typedef uintptr_t pthread_key_t; - -struct __mlibc_once { - unsigned int __mlibc_done; -}; -typedef struct __mlibc_once pthread_once_t; - -typedef struct __mlibc_mutexattr pthread_mutexattr_t; - -typedef struct __mlibc_mutex pthread_mutex_t; - -typedef struct __mlibc_condattr pthread_condattr_t; - -typedef struct __mlibc_cond pthread_cond_t; - -struct __mlibc_barrierattr_struct { - int __mlibc_pshared; -}; -typedef struct __mlibc_barrierattr_struct pthread_barrierattr_t; - -struct __mlibc_barrier { - unsigned int __mlibc_waiting; - unsigned int __mlibc_inside; - unsigned int __mlibc_count; - unsigned int __mlibc_seq; - unsigned int __mlibc_flags; -}; -typedef struct __mlibc_barrier pthread_barrier_t; - -struct __mlibc_fair_rwlock { - unsigned int __mlibc_m; // Mutex. - unsigned int __mlibc_rc; // Reader count (not reference count). - unsigned int __mlibc_flags; -}; -typedef struct __mlibc_fair_rwlock pthread_rwlock_t; - -struct __mlibc_rwlockattr { - int __mlibc_pshared; -}; -typedef struct __mlibc_rwlockattr pthread_rwlockattr_t; - -#ifndef __MLIBC_ABI_ONLY - -// ---------------------------------------------------------------------------- -// pthread_attr and pthread functions. -// ---------------------------------------------------------------------------- - -// pthread_attr functions. -int pthread_attr_init(pthread_attr_t *); -int pthread_attr_destroy(pthread_attr_t *); - -int pthread_attr_getdetachstate(const pthread_attr_t *, int *); -int pthread_attr_setdetachstate(pthread_attr_t *, int); - -int pthread_attr_getstacksize(const pthread_attr_t *__restrict, size_t *__restrict); -int pthread_attr_setstacksize(pthread_attr_t *, size_t); - -int pthread_attr_getstackaddr(const pthread_attr_t *, void **); -int pthread_attr_setstackaddr(pthread_attr_t *, void *); - -int pthread_attr_getstack(const pthread_attr_t *, void **, size_t*); -int pthread_attr_setstack(pthread_attr_t *, void *, size_t); - -int pthread_attr_getguardsize(const pthread_attr_t *__restrict, size_t *__restrict); -int pthread_attr_setguardsize(pthread_attr_t *, size_t); - -int pthread_attr_getscope(const pthread_attr_t *, int*); -int pthread_attr_setscope(pthread_attr_t *, int); - -int pthread_attr_getschedparam(const pthread_attr_t *__restrict, struct sched_param *__restrict); -int pthread_attr_setschedparam(pthread_attr_t *__restrict, const struct sched_param *__restrict); - -int pthread_attr_getschedpolicy(const pthread_attr_t *__restrict, int *__restrict); -int pthread_attr_setschedpolicy(pthread_attr_t *__restrict, int); - -int pthread_attr_getinheritsched(const pthread_attr_t *__restrict, int *__restrict); -int pthread_attr_setinheritsched(pthread_attr_t *__restrict, int); - -int pthread_attr_getschedparam(const pthread_attr_t *__restrict, struct sched_param *__restrict); -int pthread_attr_setschedparam(pthread_attr_t *__restrict, const struct sched_param *__restrict); - -#if __MLIBC_LINUX_OPTION -int pthread_attr_getaffinity_np(const pthread_attr_t *__restrict, size_t, cpu_set_t *__restrict); -int pthread_attr_setaffinity_np(pthread_attr_t *__restrict, size_t, const cpu_set_t *__restrict); - -int pthread_attr_getsigmask_np(const pthread_attr_t *__restrict, sigset_t *__restrict); -int pthread_attr_setsigmask_np(pthread_attr_t *__restrict, const sigset_t *__restrict); - -int pthread_getattr_np(pthread_t, pthread_attr_t *); - -int pthread_getaffinity_np(pthread_t thread, size_t cpusetsize, cpu_set_t *cpuset); -int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize, const cpu_set_t *cpuset); -#endif /* __MLIBC_LINUX_OPTION */ - -// pthread functions. -int pthread_create(pthread_t *__restrict, const pthread_attr_t *__restrict, - void *(*) (void *), void *__restrict); -pthread_t pthread_self(void); -int pthread_equal(pthread_t, pthread_t); -__attribute__ ((__noreturn__)) void pthread_exit(void *); - -int pthread_join(pthread_t, void **); -int pthread_detach(pthread_t); - -void pthread_cleanup_push(void (*) (void *), void *); -void pthread_cleanup_pop(int); - -int pthread_setname_np(pthread_t, const char *); -int pthread_getname_np(pthread_t, char *, size_t); - -int pthread_attr_setstack(pthread_attr_t *, void *, size_t); -int pthread_attr_getstack(const pthread_attr_t *, void **, size_t *); - -int pthread_getattr_np(pthread_t, pthread_attr_t *); - -int pthread_setschedparam(pthread_t, int, const struct sched_param *); -int pthread_getschedparam(pthread_t, int *, struct sched_param *); - -int pthread_setcanceltype(int, int *); -int pthread_setcancelstate(int, int *); -void pthread_testcancel(void); -int pthread_cancel(pthread_t); - -int pthread_atfork(void (*) (void), void (*) (void), void (*) (void)); - -// ---------------------------------------------------------------------------- -// pthread_key functions. -// ---------------------------------------------------------------------------- - -int pthread_key_create(pthread_key_t *, void (*) (void *)); -int pthread_key_delete(pthread_key_t); - -void *pthread_getspecific(pthread_key_t); -int pthread_setspecific(pthread_key_t, const void *); - -// ---------------------------------------------------------------------------- -// pthread_once functions. -// ---------------------------------------------------------------------------- - -int pthread_once(pthread_once_t *, void (*) (void)); - -// ---------------------------------------------------------------------------- -// pthread_mutexattr and pthread_mutex functions. -// ---------------------------------------------------------------------------- - -// pthread_mutexattr functions -int pthread_mutexattr_init(pthread_mutexattr_t *); -int pthread_mutexattr_destroy(pthread_mutexattr_t *); - -int pthread_mutexattr_gettype(const pthread_mutexattr_t *__restrict, int *__restrict); -int pthread_mutexattr_settype(pthread_mutexattr_t *, int); - -int pthread_mutexattr_getrobust(const pthread_mutexattr_t *__restrict, int *__restrict); -int pthread_mutexattr_setrobust(pthread_mutexattr_t *, int); - -int pthread_mutexattr_getpshared(const pthread_mutexattr_t *, int *); -int pthread_mutexattr_setpshared(pthread_mutexattr_t *, int); - -int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *__restrict, int *__restrict); -int pthread_mutexattr_setprotocol(pthread_mutexattr_t *, int); - -int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *, int *); -int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *, int); - -// pthread_mutex functions -int pthread_mutex_init(pthread_mutex_t *__restrict, const pthread_mutexattr_t *__restrict); -int pthread_mutex_destroy(pthread_mutex_t *); - -int pthread_mutex_lock(pthread_mutex_t *); -int pthread_mutex_trylock(pthread_mutex_t *); -int pthread_mutex_timedlock(pthread_mutex_t *__restrict, - const struct timespec *__restrict); -int pthread_mutex_unlock(pthread_mutex_t *); - -int pthread_mutex_consistent(pthread_mutex_t *); - -// ---------------------------------------------------------------------------- -// pthread_condattr and pthread_cond functions. -// ---------------------------------------------------------------------------- - -int pthread_condattr_init(pthread_condattr_t *); -int pthread_condattr_destroy(pthread_condattr_t *); - -int pthread_condattr_getclock(const pthread_condattr_t *__restrict, clockid_t *__restrict); -int pthread_condattr_setclock(pthread_condattr_t *, clockid_t); - -int pthread_condattr_getpshared(const pthread_condattr_t *__restrict, int *__restrict); -int pthread_condattr_setpshared(pthread_condattr_t *, int); - -int pthread_cond_init(pthread_cond_t *__restrict, const pthread_condattr_t *__restrict); -int pthread_cond_destroy(pthread_cond_t *); - -int pthread_cond_wait(pthread_cond_t *__restrict, pthread_mutex_t *__restrict); -int pthread_cond_timedwait(pthread_cond_t *__restrict, pthread_mutex_t *__restrict, - const struct timespec *__restrict); -int pthread_cond_signal(pthread_cond_t *); -int pthread_cond_broadcast(pthread_cond_t *); - -// ---------------------------------------------------------------------------- -// pthread_barrierattr and pthread_barrier functions. -// ---------------------------------------------------------------------------- - -int pthread_barrierattr_init(pthread_barrierattr_t *); -int pthread_barrierattr_destroy(pthread_barrierattr_t *); -int pthread_barrierattr_setpshared(pthread_barrierattr_t *, int); -int pthread_barrierattr_getpshared(const pthread_barrierattr_t *__restrict, - int *__restrict); - -int pthread_barrier_init(pthread_barrier_t *__restrict, const pthread_barrierattr_t *__restrict, - unsigned int); -int pthread_barrier_destroy(pthread_barrier_t *); - -int pthread_barrier_wait(pthread_barrier_t *); - -// ---------------------------------------------------------------------------- -// pthread_wrlockattr and pthread_rwlock functions. -// ---------------------------------------------------------------------------- - -int pthread_rwlockattr_init(pthread_rwlockattr_t *); -int pthread_rwlockattr_destroy(pthread_rwlockattr_t *); -int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, int); -int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *__restrict, - int *__restrict); - -int pthread_rwlock_init(pthread_rwlock_t *__restrict, const pthread_rwlockattr_t *__restrict); -int pthread_rwlock_destroy(pthread_rwlock_t *); -int pthread_rwlock_trywrlock(pthread_rwlock_t *); -int pthread_rwlock_wrlock(pthread_rwlock_t *); -int pthread_rwlock_tryrdlock(pthread_rwlock_t *); -int pthread_rwlock_rdlock(pthread_rwlock_t *); -int pthread_rwlock_unlock(pthread_rwlock_t *); - -int pthread_getcpuclockid(pthread_t, clockid_t *); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _PTHREAD_H - diff --git a/lib/mlibc/options/posix/include/pwd.h b/lib/mlibc/options/posix/include/pwd.h deleted file mode 100644 index b885f57..0000000 --- a/lib/mlibc/options/posix/include/pwd.h +++ /dev/null @@ -1,45 +0,0 @@ - -#ifndef _PWD_H -#define _PWD_H - -#include <abi-bits/uid_t.h> -#include <abi-bits/gid_t.h> -#include <bits/size_t.h> -#include <stdio.h> - -#ifdef __cplusplus -extern "C" { -#endif - -struct passwd { - char *pw_name; - char *pw_passwd; - uid_t pw_uid; - gid_t pw_gid; - char *pw_gecos; - char *pw_dir; - char *pw_shell; -}; - -#define NSS_BUFLEN_PASSWD 512 - -#ifndef __MLIBC_ABI_ONLY - -void endpwent(void); -struct passwd *getpwent(void); -struct passwd *getpwnam(const char *); -int getpwnam_r(const char *, struct passwd *, char *, size_t, struct passwd **); -struct passwd *getpwuid(uid_t); -int getpwuid_r(uid_t, struct passwd *, char *, size_t, struct passwd **); -void setpwent(void); -int putpwent(const struct passwd *, FILE *); -struct passwd *fgetpwent(FILE *); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _PWD_H - diff --git a/lib/mlibc/options/posix/include/regex.h b/lib/mlibc/options/posix/include/regex.h deleted file mode 100644 index b7f0a46..0000000 --- a/lib/mlibc/options/posix/include/regex.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef _REGEX_H -#define _REGEX_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <stddef.h> - -typedef ptrdiff_t regoff_t; - -typedef struct re_pattern_buffer { - size_t re_nsub; - void *__opaque, *__padding[4]; - size_t __nsub2; - char __padding2; -} regex_t; - -typedef struct { - regoff_t rm_so; - regoff_t rm_eo; -} regmatch_t; - -// Flags for regcomp(). -#define REG_EXTENDED 1 -#define REG_ICASE 2 -#define REG_NEWLINE 4 -#define REG_NOSUB 8 - -// Flags for regexec(). -#define REG_NOTBOL 1 -#define REG_NOTEOL 2 - -// Errors for regcomp() and regexec(). -#define REG_OK 0 -#define REG_NOMATCH 1 -#define REG_BADPAT 2 -#define REG_ECOLLATE 3 -#define REG_ECTYPE 4 -#define REG_EESCAPE 5 -#define REG_ESUBREG 6 -#define REG_EBRACK 7 -#define REG_EPAREN 8 -#define REG_EBRACE 9 -#define REG_BADBR 10 -#define REG_ERANGE 11 -#define REG_ESPACE 12 -#define REG_BADRPT 13 - -// Obsolete in POSIX. -#define REG_ENOSYS -1 - -#ifndef __MLIBC_ABI_ONLY - -int regcomp(regex_t *__restrict, const char *__restrict, int); -int regexec(const regex_t *__restrict, const char *__restrict, size_t, regmatch_t *__restrict, int); -size_t regerror(int, const regex_t *__restrict, char *__restrict, size_t); -void regfree(regex_t *); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/lib/mlibc/options/posix/include/sched.h b/lib/mlibc/options/posix/include/sched.h deleted file mode 100644 index 739d91e..0000000 --- a/lib/mlibc/options/posix/include/sched.h +++ /dev/null @@ -1,49 +0,0 @@ - -#ifndef _SCHED_H -#define _SCHED_H - -#include <abi-bits/pid_t.h> -#include <bits/threads.h> -#include <bits/size_t.h> -#include <mlibc-config.h> - -// MISSING: time_t, struct timespec - -// MISSING: POSIX [PS], [SS] and [TSP] options - -#ifdef __cplusplus -extern "C" { -#endif - -#if __MLIBC_LINUX_OPTION -#include <bits/linux/linux_sched.h> -#include <bits/linux/cpu_set.h> -#endif - -#define SCHED_OTHER 0 -#define SCHED_FIFO 1 -#define SCHED_RR 2 -#define SCHED_BATCH 3 -#define SCHED_IDLE 5 -#define SCHED_DEADLINE 6 -#define SCHED_RESET_ON_FORK 0x40000000 - -#ifndef __MLIBC_ABI_ONLY - -int sched_yield(void); - -int sched_get_priority_max(int policy); -int sched_get_priority_min(int policy); - -int sched_setscheduler(pid_t pid, int policy, const struct sched_param *param); - -int sched_getparam(pid_t pid, struct sched_param *param); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _SCHED_H - diff --git a/lib/mlibc/options/posix/include/search.h b/lib/mlibc/options/posix/include/search.h deleted file mode 100644 index 02e1913..0000000 --- a/lib/mlibc/options/posix/include/search.h +++ /dev/null @@ -1,37 +0,0 @@ - -#ifndef _SEARCH_H -#define _SEARCH_H - -#include <stddef.h> - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - preorder, - postorder, - endorder, - leaf -} VISIT; - -#ifndef __MLIBC_ABI_ONLY - -void *tsearch(const void *, void **, int(*compar)(const void *, const void *)); -void *tfind(const void *, void *const *, int (*compar)(const void *, const void *)); -void *tdelete(const void *, void **, int(*compar)(const void *, const void *)); -void twalk(const void *, void (*action)(const void *, VISIT, int)); -void tdestroy(void *, void (*free_node)(void *)); - -void *lsearch(const void *key, void *base, size_t *nelp, size_t width, - int (*compar)(const void *, const void *)); -void *lfind(const void *key, const void *base, size_t *nelp, - size_t width, int (*compar)(const void *, const void *)); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _SEARCH_H diff --git a/lib/mlibc/options/posix/include/semaphore.h b/lib/mlibc/options/posix/include/semaphore.h deleted file mode 100644 index 877527f..0000000 --- a/lib/mlibc/options/posix/include/semaphore.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef _SEMAPHORE_H -#define _SEMAPHORE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <bits/ansi/time_t.h> -#include <bits/ansi/timespec.h> - -#define SEM_VALUE_MAX 0x7FFFFFFF -#define SEM_FAILED ((sem_t *) 0) - -typedef struct sem_ { - unsigned int __mlibc_count; -} sem_t; - -#ifndef __MLIBC_ABI_ONLY - -int sem_init(sem_t *sem, int pshared, unsigned int initial_count); -sem_t *sem_open(const char *, int, ...); -int sem_close(sem_t *sem); -int sem_unlink(const char *); -int sem_destroy(sem_t *sem); -int sem_wait(sem_t *sem); -int sem_trywait(sem_t *sem); -int sem_timedwait(sem_t *sem, const struct timespec *abstime); -int sem_post(sem_t *sem); -int sem_getvalue(sem_t *sem, int *sval); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif //_SEMAPHORE_H diff --git a/lib/mlibc/options/posix/include/spawn.h b/lib/mlibc/options/posix/include/spawn.h deleted file mode 100644 index 3ab2004..0000000 --- a/lib/mlibc/options/posix/include/spawn.h +++ /dev/null @@ -1,82 +0,0 @@ - -#ifndef _SPAWN_H -#define _SPAWN_H - -#include <abi-bits/signal.h> -#include <abi-bits/mode_t.h> -#include <abi-bits/pid_t.h> -#include <sched.h> - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - int __flags; - pid_t __pgrp; - sigset_t __def, __mask; - int __prio, __pol; - void *__fn; - char __pad[64 - sizeof(void *)]; -} posix_spawnattr_t; - -typedef struct { - int __pad0[2]; - void *__actions; - int __pad[16]; -} posix_spawn_file_actions_t; - -// MISSIG: sigset_t - -struct sched_param; - -#define POSIX_SPAWN_RESETIDS 1 -#define POSIX_SPAWN_SETPGROUP 2 -#define POSIX_SPAWN_SETSIGDEF 4 -#define POSIX_SPAWN_SETSIGMASK 8 -#define POSIX_SPAWN_SETSCHEDPARAM 16 -#define POSIX_SPAWN_SETSCHEDULER 32 -#define POSIX_SPAWN_USEVFORK 64 -#define POSIX_SPAWN_SETSID 128 - -#ifndef __MLIBC_ABI_ONLY - -int posix_spawn(pid_t *__restrict pid, const char *__restrict path, - const posix_spawn_file_actions_t *file_actions, - const posix_spawnattr_t *__restrict attrs, - char *const argv[], char *const envp[]); - -int posix_spawnattr_init(posix_spawnattr_t *attr); -int posix_spawnattr_destroy(posix_spawnattr_t *attr); -int posix_spawnattr_setflags(posix_spawnattr_t *attr, short flags); -int posix_spawnattr_setsigdefault(posix_spawnattr_t *__restrict attr, - const sigset_t *__restrict sigdefault); -int posix_spawnattr_setschedparam(posix_spawnattr_t *__restrict attr, - const struct sched_param *__restrict schedparam); -int posix_spawnattr_setschedpolicy(posix_spawnattr_t *attr, int schedpolicy); -int posix_spawnattr_setsigmask(posix_spawnattr_t *__restrict attr, - const sigset_t *__restrict sigmask); -int posix_spawnattr_setpgroup(posix_spawnattr_t *attr, pid_t pgroup); -int posix_spawn_file_actions_init(posix_spawn_file_actions_t *file_actions); -int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *file_actions); -int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *file_actions, - int fildes, int newfildes); -int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *file_actions, - int fildes); -int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t *__restrict file_actions, - int fildes, const char *__restrict path, int oflag, mode_t mode); -int posix_spawnp(pid_t *__restrict pid, const char *__restrict file, - const posix_spawn_file_actions_t *file_actions, - const posix_spawnattr_t *__restrict attrp, - char *const argv[], char *const envp[]); - -// MISSING: all other functions - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // SPAWN_H - diff --git a/lib/mlibc/options/posix/include/strings.h b/lib/mlibc/options/posix/include/strings.h deleted file mode 100644 index a21c3d7..0000000 --- a/lib/mlibc/options/posix/include/strings.h +++ /dev/null @@ -1,32 +0,0 @@ - -#ifndef _STRINGS_H -#define _STRINGS_H - -#include <bits/size_t.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef __MLIBC_ABI_ONLY - -char *index (const char *s, int c); -char *rindex(const char *s, int c); - -int ffs(int word); -int strcasecmp(const char *a, const char *b); -int strncasecmp(const char *a, const char *b, size_t size); - -/* Marked as obsolete in posix 2008 but used by at least tracker */ -int bcmp(const void *s1, const void *s2, size_t n); -void bcopy(const void *s1, void *s2, size_t n); -void bzero(void *s, size_t n); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _STRINGS_H - diff --git a/lib/mlibc/options/posix/include/sys/file.h b/lib/mlibc/options/posix/include/sys/file.h deleted file mode 100644 index add43d3..0000000 --- a/lib/mlibc/options/posix/include/sys/file.h +++ /dev/null @@ -1,25 +0,0 @@ - -#ifndef _SYS_FILE_H -#define _SYS_FILE_H - -#define LOCK_SH 1 -#define LOCK_EX 2 -#define LOCK_NB 4 -#define LOCK_UN 8 - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef __MLIBC_ABI_ONLY - -int flock(int, int); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _SYS_FILE_H - diff --git a/lib/mlibc/options/posix/include/sys/ipc.h b/lib/mlibc/options/posix/include/sys/ipc.h deleted file mode 100644 index 8318dde..0000000 --- a/lib/mlibc/options/posix/include/sys/ipc.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef _SYS_IPC_H -#define _SYS_IPC_H - -#include <abi-bits/uid_t.h> -#include <abi-bits/gid_t.h> -#include <abi-bits/mode_t.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#define IPC_CREAT 01000 -#define IPC_EXCL 02000 -#define IPC_NOWAIT 04000 - -#define IPC_RMID 0 -#define IPC_SET 1 -#define IPC_STAT 2 -#define IPC_INFO 3 - -#define IPC_PRIVATE ((key_t) 0) - -#if defined(__aarch64__) || defined(__i386__) -#define IPC_64 0x100 -#elif defined(__x86_64__) || (defined(__riscv) && __riscv_xlen == 64) -#define IPC_64 0 -#else -#error "Unsupported arch!" -#endif - -typedef int key_t; - -struct ipc_perm { - key_t __ipc_perm_key; - uid_t uid; - gid_t gid; - uid_t cuid; - gid_t cgid; - mode_t mode; - int __ipc_perm_seq; -}; - -#ifndef __MLIBC_ABI_ONLY - -key_t ftok(const char *, int); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/lib/mlibc/options/posix/include/sys/mman.h b/lib/mlibc/options/posix/include/sys/mman.h deleted file mode 100644 index 784878e..0000000 --- a/lib/mlibc/options/posix/include/sys/mman.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef _SYS_MMAN_H -#define _SYS_MMAN_H - -#include <mlibc-config.h> -#include <abi-bits/mode_t.h> -#include <abi-bits/vm-flags.h> -#include <bits/off_t.h> -#include <bits/size_t.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef __MLIBC_ABI_ONLY - -void *mmap(void *, size_t, int, int, int, off_t); -int mprotect(void *, size_t, int); -int munmap(void *, size_t); - -int mlock(const void *, size_t); -int mlockall(int); -int munlock(const void *, size_t); -int munlockall(void); - -int posix_madvise(void *, size_t, int); -int msync(void *, size_t, int); - -int shm_open(const char *, int, mode_t); -int shm_unlink(const char *); - -// Linux extension: -void *mremap(void *, size_t, size_t, int, ...); -int remap_file_pages(void *, size_t, int, size_t, int); - -#if __MLIBC_LINUX_OPTION -int memfd_create(const char *, unsigned int); -int madvise(void *, size_t, int); -int mincore(void *, size_t, unsigned char *); -#endif /* __MLIBC_LINUX_OPTION */ - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _SYS_MMAN_H diff --git a/lib/mlibc/options/posix/include/sys/msg.h b/lib/mlibc/options/posix/include/sys/msg.h deleted file mode 100644 index d602f76..0000000 --- a/lib/mlibc/options/posix/include/sys/msg.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _SYS_MSG_H -#define _SYS_MSG_H - -#include <abi-bits/msg.h> -#include <bits/size_t.h> -#include <bits/ssize_t.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef __MLIBC_ABI_ONLY - -int msgget(key_t, int); - -int msgctl(int msqid, int cmd, struct msqid_ds *buf); - -ssize_t msgrcv(int, void *, size_t, long, int); -int msgsnd(int, const void *, size_t, int); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _SYS_MSG_H diff --git a/lib/mlibc/options/posix/include/sys/param.h b/lib/mlibc/options/posix/include/sys/param.h deleted file mode 100644 index 9bb4552..0000000 --- a/lib/mlibc/options/posix/include/sys/param.h +++ /dev/null @@ -1,36 +0,0 @@ - -#ifndef _SYS_PARAM_H -#define _SYS_PARAM_H - -#include <endian.h> -#include <limits.h> - -#define NBBY CHAR_BIT -#define NGROUPS NGROUPS_MAX - -// Report the same value as Linux here. -#define MAXNAMLEN 255 -#define MAXPATHLEN 4096 -#define HOST_NAME_MAX 64 -#define MAXSYMLINKS 20 -#define MAXHOSTNAMELEN HOST_NAME_MAX - -#ifdef __cplusplus -extern "C" { -#endif - -#undef MIN -#define MIN(a,b) (((a) < (b)) ? (a) : (b)) -#undef MAX -#define MAX(a,b) (((a) > (b)) ? (a) : (b)) - -#define howmany(x, y) (((x) + ((y) - 1)) / (y)) - -#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) - -#ifdef __cplusplus -} -#endif - -#endif // _SYS_PARAM_H - diff --git a/lib/mlibc/options/posix/include/sys/poll.h b/lib/mlibc/options/posix/include/sys/poll.h deleted file mode 100644 index 3edecab..0000000 --- a/lib/mlibc/options/posix/include/sys/poll.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef _SYS_POLL_H -#define _SYS_POLL_H - -#include <bits/types.h> -#include <bits/sigset_t.h> -#include <bits/ansi/timespec.h> -#include <abi-bits/poll.h> -#include <abi-bits/signal.h> -#include <mlibc-config.h> - -typedef __mlibc_size nfds_t; - -#ifdef __cplusplus -extern "C" { -#endif - -struct pollfd { - int fd; - short events; - short revents; -}; - -#ifndef __MLIBC_ABI_ONLY - -int poll(struct pollfd *, nfds_t, int); - -#if __MLIBC_LINUX_OPTION -int ppoll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts, const sigset_t *sigmask); -#endif // __MLIBC_LINUX_OPTION - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _SYS_POLL_H diff --git a/lib/mlibc/options/posix/include/sys/resource.h b/lib/mlibc/options/posix/include/sys/resource.h deleted file mode 100644 index c5453e2..0000000 --- a/lib/mlibc/options/posix/include/sys/resource.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef _SYS_RESOURCE_H -#define _SYS_RESOURCE_H - -#include <abi-bits/pid_t.h> -#include <abi-bits/resource.h> -#include <bits/posix/id_t.h> -#include <abi-bits/suseconds_t.h> -#include <bits/ansi/time_t.h> -#include <bits/posix/timeval.h> - -#define PRIO_PROCESS 1 -#define PRIO_PGRP 2 -#define PRIO_USER 3 - -#define PRIO_MIN (-20) -#define PRIO_MAX 20 - -#define RLIM_INFINITY ((rlim_t)-1) -#define RLIM_SAVED_MAX ((rlim_t)-1) -#define RLIM_SAVED_CUR ((rlim_t)-1) - -#define RLIM_NLIMITS RLIMIT_NLIMITS - -#ifdef __cplusplus -extern "C" { -#endif - -typedef unsigned long rlim_t; - -struct rlimit { - rlim_t rlim_cur; - rlim_t rlim_max; -}; - -#ifndef __MLIBC_ABI_ONLY - -int getpriority(int, id_t); -int setpriority(int, id_t, int); - -int getrusage(int, struct rusage *); -int getrlimit(int, struct rlimit *); -int setrlimit(int, const struct rlimit *); - -int prlimit(pid_t pid, int resource, const struct rlimit *new_limits, struct rlimit *old_limits); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _SYS_RESOURCE_H diff --git a/lib/mlibc/options/posix/include/sys/select.h b/lib/mlibc/options/posix/include/sys/select.h deleted file mode 100644 index 85a15b0..0000000 --- a/lib/mlibc/options/posix/include/sys/select.h +++ /dev/null @@ -1,49 +0,0 @@ - -#ifndef _SYS_SELECT_H -#define _SYS_SELECT_H - -#include <abi-bits/signal.h> - -#include <bits/ansi/time_t.h> -#include <bits/ansi/timespec.h> -#include <abi-bits/suseconds_t.h> -#include <bits/posix/timeval.h> -#include <bits/posix/fd_set.h> - -#define FD_SETSIZE 1024 - -#ifdef __cplusplus -extern "C" { -#endif - -typedef long int __fd_mask; -#define __NFDBITS (8 * (int) sizeof (__fd_mask)) - -typedef __fd_mask fd_mask; -#define NFDBITS __NFDBITS - -#ifndef __MLIBC_ABI_ONLY - -void __FD_CLR(int fd, fd_set *); -int __FD_ISSET(int fd, fd_set *); -void __FD_SET(int fd, fd_set *); -void __FD_ZERO(fd_set *); - -#define FD_CLR(fd, set) __FD_CLR(fd, set) -#define FD_ISSET(fd, set) __FD_ISSET(fd, set) -#define FD_SET(fd, set) __FD_SET(fd, set) -#define FD_ZERO(set) __FD_ZERO(set) - -int select(int, fd_set *__restrict, fd_set *__restrict, fd_set *__restrict, - struct timeval *__restrict); -int pselect(int, fd_set *, fd_set *, fd_set *, const struct timespec *, - const sigset_t *); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _SYS_SELECT_H - diff --git a/lib/mlibc/options/posix/include/sys/sem.h b/lib/mlibc/options/posix/include/sys/sem.h deleted file mode 100644 index cb3516a..0000000 --- a/lib/mlibc/options/posix/include/sys/sem.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef _SYS_SEM_H -#define _SYS_SEM_H - -#include <bits/ansi/time_t.h> -#include <sys/ipc.h> -#include <stddef.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#define GETALL 13 -#define SETVAL 16 -#define SETALL 17 - -#define SEM_UNDO 0x1000 - -struct sembuf { - unsigned short int sem_num; - short int sem_op; - short int sem_flg; -}; - -struct semid_ds { - struct ipc_perm sem_perm; - time_t sem_otime; - time_t sem_ctime; - - unsigned long sem_nsems; -}; - -#ifndef __MLIBC_ABI_ONLY - -int semget(key_t, int, int); -int semop(int, struct sembuf *, size_t); -int semctl(int, int, int, ...); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _SYS_SEM_H diff --git a/lib/mlibc/options/posix/include/sys/shm.h b/lib/mlibc/options/posix/include/sys/shm.h deleted file mode 100644 index 3767ced..0000000 --- a/lib/mlibc/options/posix/include/sys/shm.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef _SYS_SHM_H -#define _SYS_SHM_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <abi-bits/pid_t.h> -#include <abi-bits/shm.h> -#include <bits/size_t.h> -#include <time.h> - -#include <sys/ipc.h> - -#define SHM_R 0400 -#define SHM_W 0200 - -#define SHM_RDONLY 010000 -#define SHM_RND 020000 -#define SHM_REMAP 040000 -#define SHM_EXEC 0100000 - -#define SHM_LOCK 11 -#define SHM_UNLOCK 12 -#define SHM_STAT 13 -#define SHM_INFO 14 -#define SHM_STAT_ANY 15 -#define SHM_DEST 01000 -#define SHM_LOCKED 02000 -#define SHM_HUGETLB 04000 -#define SHM_NORESERVE 010000 - -#define SHM_HUGE_SHIFT 26 -#define SHM_HUGE_MASK 0x3f -#define SHM_HUGE_64KB (16 << 26) -#define SHM_HUGE_512KB (19 << 26) -#define SHM_HUGE_1MB (20 << 26) -#define SHM_HUGE_2MB (21 << 26) -#define SHM_HUGE_8MB (23 << 26) -#define SHM_HUGE_16MB (24 << 26) -#define SHM_HUGE_32MB (25 << 26) -#define SHM_HUGE_256MB (28 << 26) -#define SHM_HUGE_512MB (29 << 26) -#define SHM_HUGE_1GB (30 << 26) -#define SHM_HUGE_2GB (31 << 26) -#define SHM_HUGE_16GB (34U << 26) - -typedef unsigned long shmatt_t; - -struct shmid_ds { - struct ipc_perm shm_perm; - size_t shm_segsz; - time_t shm_atime; - time_t shm_dtime; - time_t shm_ctime; - pid_t shm_cpid; - pid_t shm_lpid; - unsigned long shm_nattch; -}; - -struct shminfo { - unsigned long shmmax; - unsigned long shmmin; - unsigned long shmmni; - unsigned long shmseg; - unsigned long shmall; - unsigned long __unused[4]; -}; - -#ifndef __MLIBC_ABI_ONLY - -void *shmat(int, const void *, int); -int shmctl(int, int, struct shmid_ds *); -int shmdt(const void *); -int shmget(key_t, size_t, int); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _SYS_SHM_H diff --git a/lib/mlibc/options/posix/include/sys/socket.h b/lib/mlibc/options/posix/include/sys/socket.h deleted file mode 100644 index 9552f93..0000000 --- a/lib/mlibc/options/posix/include/sys/socket.h +++ /dev/null @@ -1,105 +0,0 @@ - -#ifndef _SOCKET_H -#define _SOCKET_H - -#include <abi-bits/gid_t.h> -#include <abi-bits/pid_t.h> -#include <bits/size_t.h> -#include <abi-bits/socklen_t.h> -#include <bits/ssize_t.h> -#include <abi-bits/uid_t.h> -#include <bits/posix/iovec.h> -#include <abi-bits/socket.h> -#include <bits/ansi/time_t.h> -#include <bits/ansi/timespec.h> - -#include <stddef.h> - -#ifdef __cplusplus -extern "C" { -#endif - -struct sockaddr { - sa_family_t sa_family; - char sa_data[14]; -}; - -// Control message format: -// The offsets marked with ^ are aligned to alignof(size_t). -// -// |---HEADER---|---DATA---|---PADDING---|---HEADER---|... -// ^ ^ ^ -// |---------CMSG_LEN------| -// |---------------CMSG_SPACE------------| - -// Auxiliary macro. While there is basically no reason for applications -// to use this, it is exported by glibc. -#define CMSG_ALIGN(s) (((s) + __alignof__(size_t) - 1) & \ - ~(__alignof__(size_t) - 1)) - -// Basic macros to return content and padding size of a control message. -#define CMSG_LEN(s) (CMSG_ALIGN(sizeof(struct cmsghdr)) + (s)) -#define CMSG_SPACE(s) (CMSG_ALIGN(sizeof(struct cmsghdr)) + CMSG_ALIGN(s)) - -// Provides access to the data of a control message. -#define CMSG_DATA(c) ((char *)(c) + CMSG_ALIGN(sizeof(struct cmsghdr))) - -#define __MLIBC_CMSG_NEXT(c) ((char *)(c) + CMSG_ALIGN((c)->cmsg_len)) -#define __MLIBC_MHDR_LIMIT(m) ((char *)(m)->msg_control + (m)->msg_controllen) - -// For parsing control messages only. -// Returns a pointer to the first header or nullptr if there is none. -#define CMSG_FIRSTHDR(m) ((size_t)(m)->msg_controllen <= sizeof(struct cmsghdr) \ - ? (struct cmsghdr *)0 : (struct cmsghdr *) (m)->msg_control) - -// For parsing control messages only. -// Returns a pointer to the next header or nullptr if there is none. -#define CMSG_NXTHDR(m, c) \ - ((c)->cmsg_len < sizeof(struct cmsghdr) || \ - (ptrdiff_t)(sizeof(struct cmsghdr) + CMSG_ALIGN((c)->cmsg_len)) \ - >= __MLIBC_MHDR_LIMIT(m) - (char *)(c) \ - ? (struct cmsghdr *)0 : (struct cmsghdr *)__MLIBC_CMSG_NEXT(c)) - -struct linger{ - int l_onoff; - int l_linger; -}; - -struct ucred { - pid_t pid; - uid_t uid; - gid_t gid; -}; - -#ifndef __MLIBC_ABI_ONLY - -int accept(int, struct sockaddr *__restrict, socklen_t *__restrict); -int accept4(int, struct sockaddr *__restrict, socklen_t *__restrict, int); -int bind(int, const struct sockaddr *, socklen_t); -int connect(int, const struct sockaddr *, socklen_t); -int getpeername(int, struct sockaddr *__restrict, socklen_t *__restrict); -int getsockname(int, struct sockaddr *__restrict, socklen_t *__restrict); -int getsockopt(int, int, int, void *__restrict, socklen_t *__restrict); -int listen(int, int); -ssize_t recv(int, void *, size_t, int); -ssize_t recvfrom(int, void *__restrict, size_t, int, struct sockaddr *__restrict, socklen_t *__restrict); -ssize_t recvmsg(int, struct msghdr *, int); -ssize_t send(int, const void *, size_t, int); -ssize_t sendmsg(int, const struct msghdr *, int); -ssize_t sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t); -int recvmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, struct timespec *timeout); -int sendmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags); -int setsockopt(int, int, int, const void *, socklen_t); -int shutdown(int, int); -int sockatmark(int); -int socket(int, int, int); -int socketpair(int, int, int, int [2]); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _UNISTD_H - diff --git a/lib/mlibc/options/posix/include/sys/stat.h b/lib/mlibc/options/posix/include/sys/stat.h deleted file mode 100644 index 7159a77..0000000 --- a/lib/mlibc/options/posix/include/sys/stat.h +++ /dev/null @@ -1,37 +0,0 @@ - -#ifndef _SYS_STAT_H -#define _SYS_STAT_H - -#include <bits/posix/stat.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef __MLIBC_ABI_ONLY - -int chmod(const char *, mode_t); -int fchmod(int, mode_t); -int fchmodat(int, const char *, mode_t, int); -int fstat(int fd, struct stat *result); -int fstatat(int, const char *__restrict, struct stat *__restrict, int); -int futimens(int fd, const struct timespec times[2]); -int lstat(const char *__restrict, struct stat *__restrict); -int mkdir(const char *, mode_t); -int mkdirat(int, const char *, mode_t); -int mkfifo(const char *, mode_t); -int mkfifoat(int, const char *, mode_t); -int mknod(const char *, mode_t, dev_t); -int mknodat(int, const char *, mode_t, dev_t); -int stat(const char *__restrict, struct stat *__restrict); -mode_t umask(mode_t); -int utimensat(int, const char *, const struct timespec times[2], int); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _SYS_STAT_H - diff --git a/lib/mlibc/options/posix/include/sys/statvfs.h b/lib/mlibc/options/posix/include/sys/statvfs.h deleted file mode 100644 index 0e4c308..0000000 --- a/lib/mlibc/options/posix/include/sys/statvfs.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef _SYS_STATVFS_H -#define _SYS_STATVFS_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <abi-bits/statvfs.h> - -#ifndef __MLIBC_ABI_ONLY - -int statvfs(const char *__restrict, struct statvfs *__restrict); -int fstatvfs(int, struct statvfs *); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _SYS_STATVFS_H - diff --git a/lib/mlibc/options/posix/include/sys/syslog.h b/lib/mlibc/options/posix/include/sys/syslog.h deleted file mode 100644 index 7761ece..0000000 --- a/lib/mlibc/options/posix/include/sys/syslog.h +++ /dev/null @@ -1 +0,0 @@ -#include <syslog.h> diff --git a/lib/mlibc/options/posix/include/sys/termios.h b/lib/mlibc/options/posix/include/sys/termios.h deleted file mode 100644 index b23f171..0000000 --- a/lib/mlibc/options/posix/include/sys/termios.h +++ /dev/null @@ -1,6 +0,0 @@ - -#ifndef _SYS_TERMIOS_H -#define _SYS_TERMIOS_H -#include <termios.h> -#endif // _SYS_TERMIOS_H - diff --git a/lib/mlibc/options/posix/include/sys/time.h b/lib/mlibc/options/posix/include/sys/time.h deleted file mode 100644 index 838d7cc..0000000 --- a/lib/mlibc/options/posix/include/sys/time.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef _SYS_TIME_H -#define _SYS_TIME_H - -#include <abi-bits/time.h> -#include <abi-bits/signal.h> -#include <abi-bits/clockid_t.h> -#include <bits/ansi/time_t.h> -#include <abi-bits/suseconds_t.h> -#include <bits/posix/timer_t.h> -#include <bits/posix/timeval.h> - -#include <sys/select.h> - -#ifdef __cplusplus -extern "C" { -#endif - -struct timezone { - int tz_minuteswest; - int tz_dsttime; -}; - -#ifndef __MLIBC_ABI_ONLY - -// TODO: this function is [OB]. disable it by default and add a macro to enable it -int gettimeofday(struct timeval *__restrict result, void *__restrict unused); -int settimeofday(const struct timeval *result, const struct timezone *zone); - -void timeradd(const struct timeval *a, const struct timeval *b, struct timeval *res); -void timersub(const struct timeval *a, const struct timeval *b, struct timeval *res); -void timerclear(struct timeval *tvp); -int timerisset(struct timeval *tvp); - -#endif /* !__MLIBC_ABI_ONLY */ - -// timercmp taken from musl -#define timercmp(s,t,op) ((s)->tv_sec == (t)->tv_sec ? \ - (s)->tv_usec op (t)->tv_usec : (s)->tv_sec op (t)->tv_sec) - -#ifndef __MLIBC_ABI_ONLY - -int getitimer(int which, struct itimerval *curr_value); -int setitimer(int which, const struct itimerval *new_value, - struct itimerval *old_value); - -int timer_create(clockid_t clockid, struct sigevent *__restrict sevp, timer_t *__restrict timerid); -int timer_settime(timer_t timerid, int flags, const struct itimerspec *__restrict new_value, - struct itimerspec *__restrict old_value); -int timer_gettime(timer_t timerid, struct itimerspec *curr_value); -int timer_delete(timer_t timerid); - -#endif /* !__MLIBC_ABI_ONLY */ - -// The following 2 macros are taken from musl -#define TIMEVAL_TO_TIMESPEC(tv, ts) ( \ - (ts)->tv_sec = (tv)->tv_sec, \ - (ts)->tv_nsec = (tv)->tv_usec * 1000, \ - (void)0 ) -#define TIMESPEC_TO_TIMEVAL(tv, ts) ( \ - (tv)->tv_sec = (ts)->tv_sec, \ - (tv)->tv_usec = (ts)->tv_nsec / 1000, \ - (void)0 ) - -#ifdef __cplusplus -} -#endif - -#endif // _SYS_TIME_H diff --git a/lib/mlibc/options/posix/include/sys/times.h b/lib/mlibc/options/posix/include/sys/times.h deleted file mode 100644 index 2dd2889..0000000 --- a/lib/mlibc/options/posix/include/sys/times.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _SYS_TIMES_H -#define _SYS_TIMES_H - -// TODO: Only define the clock_t type. -#include <time.h> - -#ifdef __cplusplus -extern "C" { -#endif - -struct tms { - clock_t tms_utime; - clock_t tms_stime; - clock_t tms_cutime; - clock_t tms_cstime; -}; - -#ifndef __MLIBC_ABI_ONLY - -clock_t times(struct tms *); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _SYS_TIMES_H diff --git a/lib/mlibc/options/posix/include/sys/ttydefaults.h b/lib/mlibc/options/posix/include/sys/ttydefaults.h deleted file mode 100644 index c6d04f6..0000000 --- a/lib/mlibc/options/posix/include/sys/ttydefaults.h +++ /dev/null @@ -1,39 +0,0 @@ - -#ifndef _SYS_TTYDEFAULTS_H -#define _SYS_TTYDEFAULTS_H - -// Values taken from musl - -#define TTYDEF_IFLAG (BRKINT | ISTRIP | ICRNL | IMAXBEL | IXON | IXANY) -#define TTYDEF_OFLAG (OPOST | ONLCR | XTABS) -#define TTYDEF_LFLAG (ECHO | ICANON | ISIG | IEXTEN | ECHOE|ECHOKE|ECHOCTL) -#define TTYDEF_CFLAG (CREAD | CS7 | PARENB | HUPCL) -#define TTYDEF_SPEED (B9600) - -#define CTRL(x) ((x) & 037) -#define CEOF CTRL('d') - -#define CEOL '\0' -#define CEOL2 '\0' -#define CSTATUS '\0' - -#define CERASE 0177 -#define CINTR CTRL('c') -#define CKILL CTRL('u') -#define CMIN 1 -#define CQUIT 034 -#define CSUSP CTRL('z') -#define CTIME 0 -#define CDSUSP CTRL('y') -#define CSTART CTRL('q') -#define CSTOP CTRL('s') -#define CLNEXT CTRL('v') -#define CDISCARD CTRL('o') -#define CWERASE CTRL('w') -#define CREPRINT CTRL('r') -#define CEOT CEOF -#define CBRK CEOL -#define CRPRNT CREPRINT -#define CFLUSH CDISCARD - -#endif // _SYS_TTYDEFAULTS_H diff --git a/lib/mlibc/options/posix/include/sys/types.h b/lib/mlibc/options/posix/include/sys/types.h deleted file mode 100644 index ad837fc..0000000 --- a/lib/mlibc/options/posix/include/sys/types.h +++ /dev/null @@ -1,53 +0,0 @@ - -#ifndef _SYS_TYPES_H -#define _SYS_TYPES_H - -#include <bits/size_t.h> -#include <bits/ssize_t.h> -#include <bits/off_t.h> - -#include <bits/posix/id_t.h> -#include <abi-bits/uid_t.h> -#include <abi-bits/gid_t.h> -#include <abi-bits/pid_t.h> - -#include <abi-bits/mode_t.h> -#include <abi-bits/dev_t.h> -#include <abi-bits/ino_t.h> -#include <abi-bits/blksize_t.h> -#include <abi-bits/blkcnt_t.h> -#include <abi-bits/nlink_t.h> - -#include <bits/ansi/time_t.h> -#include <abi-bits/suseconds_t.h> - -#include <abi-bits/fsblkcnt_t.h> -#include <abi-bits/fsfilcnt_t.h> -#include <bits/posix/fd_set.h> - -#include <stdint.h> - -#include <sys/select.h> - -typedef unsigned int u_int; -typedef unsigned char u_char; -typedef unsigned short u_short; -typedef unsigned long int u_long; -typedef char *caddr_t; -typedef off64_t loff_t; - -typedef unsigned long int ulong; -typedef unsigned short int ushort; -typedef unsigned int uint; - -typedef uint8_t u_int8_t; -typedef uint16_t u_int16_t; -typedef uint32_t u_int32_t; -typedef uint64_t u_int64_t; - -// BSD extensions -typedef int64_t quad_t; -typedef uint64_t u_quad_t; - -#endif // _SYS_TYPES_H - diff --git a/lib/mlibc/options/posix/include/sys/uio.h b/lib/mlibc/options/posix/include/sys/uio.h deleted file mode 100644 index 04679a6..0000000 --- a/lib/mlibc/options/posix/include/sys/uio.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef _SYS_UIO_H -#define _SYS_UIO_H - -#include <bits/posix/iovec.h> -#include <bits/ssize_t.h> -#include <bits/off_t.h> -#include <bits/size_t.h> -#include <limits.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#define UIO_MAXIOV IOV_MAX - -#ifndef __MLIBC_ABI_ONLY - -ssize_t readv(int fd, const struct iovec *iov, int iovcnt); -ssize_t writev(int fd, const struct iovec *iov, int iovcnt); - -// Non standard extensions, also found on modern BSD's -ssize_t preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset); -ssize_t pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _SYS_UIO_H diff --git a/lib/mlibc/options/posix/include/sys/un.h b/lib/mlibc/options/posix/include/sys/un.h deleted file mode 100644 index bb9b5ad..0000000 --- a/lib/mlibc/options/posix/include/sys/un.h +++ /dev/null @@ -1,24 +0,0 @@ - -#ifndef _SYS_UN_H -#define _SYS_UN_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <abi-bits/socket.h> - -struct sockaddr_un { - sa_family_t sun_family; - char sun_path[108]; -}; - -// Evaluate to actual length of the `sockaddr_un' structure. -#define SUN_LEN(ptr) ((size_t) offsetof(struct sockaddr_un, sun_path) + strlen((ptr)->sun_path)) - -#ifdef __cplusplus -} -#endif - -#endif // _SYS_UN_H - diff --git a/lib/mlibc/options/posix/include/sys/utsname.h b/lib/mlibc/options/posix/include/sys/utsname.h deleted file mode 100644 index bd7b174..0000000 --- a/lib/mlibc/options/posix/include/sys/utsname.h +++ /dev/null @@ -1,22 +0,0 @@ - -#ifndef _SYS_UTSNAME_H -#define _SYS_UTSNAME_H - -#include <abi-bits/utsname.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef __MLIBC_ABI_ONLY - -int uname(struct utsname *); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _SYS_UTSNAME_H - diff --git a/lib/mlibc/options/posix/include/sys/wait.h b/lib/mlibc/options/posix/include/sys/wait.h deleted file mode 100644 index 5081041..0000000 --- a/lib/mlibc/options/posix/include/sys/wait.h +++ /dev/null @@ -1,40 +0,0 @@ - -#ifndef _SYS_WAIT_H -#define _SYS_WAIT_H - -#include <bits/posix/id_t.h> -#include <abi-bits/pid_t.h> -// for siginfo_t -#include <abi-bits/signal.h> -#include <abi-bits/wait.h> - -#ifdef __cplusplus -extern "C" { -#endif - -// According to POSIX, <sys/wait.h> does not make rusage available. -struct rusage; - -// TODO: move to own file and include in sys/types.h -typedef enum { - P_ALL, P_PID, P_PGID -} idtype_t; - -#ifndef __MLIBC_ABI_ONLY - -pid_t wait(int *status); -int waitid(idtype_t idtype, id_t id, siginfo_t *siginfo, int flags); -pid_t waitpid(pid_t pid, int *status, int flags); - -// GNU extensions. -pid_t wait3(int *, int, struct rusage *); -pid_t wait4(pid_t pid, int *status, int options, struct rusage *ru); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _SYS_WAIT_H - diff --git a/lib/mlibc/options/posix/include/syslog.h b/lib/mlibc/options/posix/include/syslog.h deleted file mode 100644 index 6c258cf..0000000 --- a/lib/mlibc/options/posix/include/syslog.h +++ /dev/null @@ -1,75 +0,0 @@ - -#ifndef _SYSLOG_H -#define _SYSLOG_H - -#include <stdarg.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#define LOG_PID 0x01 -#define LOG_CONS 0x02 -#define LOG_NDELAY 0x08 -#define LOG_ODELAY 0x04 -#define LOG_NOWAIT 0x10 -#define LOG_PERROR 0x20 - -#define LOG_KERN (0<<3) -#define LOG_USER (1<<3) -#define LOG_MAIL (2<<3) -#define LOG_DAEMON (3<<3) -#define LOG_AUTH (4<<3) -#define LOG_SYSLOG (5<<3) -#define LOG_LPR (6<<3) -#define LOG_NEWS (7<<3) -#define LOG_UUCP (8<<3) -#define LOG_CRON (9<<3) -#define LOG_AUTHPRIV (10<<3) -#define LOG_FTP (11<<3) - -#define LOG_LOCAL0 (16<<3) -#define LOG_LOCAL1 (17<<3) -#define LOG_LOCAL2 (18<<3) -#define LOG_LOCAL3 (19<<3) -#define LOG_LOCAL4 (20<<3) -#define LOG_LOCAL5 (21<<3) -#define LOG_LOCAL6 (22<<3) -#define LOG_LOCAL7 (23<<3) - -#define LOG_PRIMASK 7 -#define LOG_PRI(p) ((p)&LOG_PRIMASK) -#define LOG_MAKEPRI(f, p) (((f)<<3) | (p)) -#define LOG_MASK(p) (1<<(p)) -#define LOG_UPTO(p) ((1<<((p)+1))-1) -#define LOG_NFACILITIES 24 -#define LOG_FACMASK (0x7F<<3) -#define LOG_FAC(p) (((p)&LOG_FACMASK)>>3) - -#define LOG_EMERG 0 -#define LOG_ALERT 1 -#define LOG_CRIT 2 -#define LOG_ERR 3 -#define LOG_WARNING 4 -#define LOG_NOTICE 5 -#define LOG_INFO 6 -#define LOG_DEBUG 7 - -#ifndef __MLIBC_ABI_ONLY - -void closelog(void); -void openlog(const char *, int, int); -int setlogmask(int); -void syslog(int, const char *, ...); - -// This is a linux extension -void vsyslog(int, const char *, va_list); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _SYSLOG_H - diff --git a/lib/mlibc/options/posix/include/termios.h b/lib/mlibc/options/posix/include/termios.h deleted file mode 100644 index a5a6a2f..0000000 --- a/lib/mlibc/options/posix/include/termios.h +++ /dev/null @@ -1,100 +0,0 @@ - -#ifndef _TERMIOS_H -#define _TERMIOS_H - -#include <abi-bits/pid_t.h> -#include <abi-bits/termios.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#include <bits/winsize.h> - -#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) -#include <sys/ttydefaults.h> -#endif - -// baud rate constants for speed_t -#define B0 0 -#define B50 1 -#define B75 2 -#define B110 3 -#define B134 4 -#define B150 5 -#define B200 6 -#define B300 7 -#define B600 8 -#define B1200 9 -#define B1800 10 -#define B2400 11 -#define B4800 12 -#define B9600 13 -#define B19200 14 -#define B38400 15 -#define B57600 0010001 -#define B115200 0010002 -#define B230400 0010003 -#define B460800 0010004 -#define B500000 0010005 -#define B576000 0010006 -#define B921600 0010007 -#define B1000000 0010010 -#define B1152000 0010011 -#define B1500000 0010012 -#define B2000000 0010013 -#define B2500000 0010014 -#define B3000000 0010015 -#define B3500000 0010016 -#define B4000000 0010017 - -// constants for tcsetattr() -#define TCSANOW 0 -#define TCSADRAIN 1 -#define TCSAFLUSH 2 - -// constants for tcflush() -#define TCIFLUSH 0 -#define TCOFLUSH 1 -#define TCIOFLUSH 2 - -// constants for tcflow() -#define TCOOFF 0 -#define TCOON 1 -#define TCIOFF 2 -#define TCION 3 - -#define TIOCM_DTR 0x002 -#define TIOCM_RTS 0x004 - -#ifndef __MLIBC_ABI_ONLY - -speed_t cfgetispeed(const struct termios *); -speed_t cfgetospeed(const struct termios *); -int cfsetispeed(struct termios *, speed_t); -int cfsetospeed(struct termios *, speed_t); -void cfmakeraw(struct termios *); -int tcdrain(int); -int tcflow(int, int); -int tcflush(int, int); -int tcgetattr(int fd, struct termios *attr); -pid_t tcgetsid(int); -int tcsendbreak(int, int); -int tcsetattr(int, int, const struct termios *); - -#endif /* !__MLIBC_ABI_ONLY */ - -// This is a linux extension - -#define TIOCGPGRP 0x540F -#define TIOCSPGRP 0x5410 -#define TIOCGWINSZ 0x5413 -#define TIOCSWINSZ 0x5414 -#define TIOCGSID 0x5429 - -#ifdef __cplusplus -} -#endif - -#endif // _TERMIOS_H - diff --git a/lib/mlibc/options/posix/include/ucontext.h b/lib/mlibc/options/posix/include/ucontext.h deleted file mode 100644 index c50b0b1..0000000 --- a/lib/mlibc/options/posix/include/ucontext.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _UCONTEXT_H -#define _UCONTEXT_H - -#include <signal.h> - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -#ifndef __MLIBC_ABI_ONLY - -int getcontext(ucontext_t *); -int setcontext(const ucontext_t *); -void makecontext(ucontext_t *, void (*)(void), int, ...); -int swapcontext(ucontext_t *, const ucontext_t *); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif // _UCONTEXT_H diff --git a/lib/mlibc/options/posix/include/unistd.h b/lib/mlibc/options/posix/include/unistd.h deleted file mode 100644 index d29257d..0000000 --- a/lib/mlibc/options/posix/include/unistd.h +++ /dev/null @@ -1,360 +0,0 @@ - -#ifndef _UNISTD_H -#define _UNISTD_H - -#include <mlibc-config.h> -#include <bits/types.h> -#include <bits/size_t.h> -#include <bits/ssize_t.h> -#include <bits/off_t.h> -#include <bits/types.h> -#include <abi-bits/access.h> -#include <abi-bits/uid_t.h> -#include <abi-bits/gid_t.h> -#include <abi-bits/pid_t.h> -#include <abi-bits/seek-whence.h> - -#if __MLIBC_SYSDEP_HAS_BITS_SYSCALL_H && __MLIBC_LINUX_OPTION -#include <bits/syscall.h> -#endif /* __MLIBC_SYSDEP_HAS_BITS_SYSCALL_H && __MLIBC_LINUX_OPTION */ - -#ifdef __cplusplus -extern "C" { -#endif - -#define _POSIX_VERSION 200809L -#define _POSIX2_VERSION _POSIX_VERSION -#define _XOPEN_VERSION 700 - -#define _POSIX_FSYNC _POSIX_VERSION -#define _POSIX_IPV6 _POSIX_VERSION -#define _POSIX_JOB_CONTROL 1 -#define _POSIX_SAVED_IDS 1 -#define _POSIX_SHELL 1 -#define _POSIX_SPAWN _POSIX_VERSION -#define _POSIX_THREADS _POSIX_VERSION -#define _POSIX_THREAD_SAFE_FUNCTIONS _POSIX_VERSION -#define _POSIX_MONOTONIC_CLOCK 0 - -#if __MLIBC_CRYPT_OPTION -#define _XOPEN_CRYPT 1 -#endif - -// MISSING: additional _POSIX and _XOPEN feature macros -// MISSING: _POSIX_TIMESTAMP_RESOLUTION and _POSIX2_SYMLINKS - -#define _CS_PATH 0 -#define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS 1 -#define _CS_GNU_LIBC_VERSION 2 -#define _CS_GNU_LIBPTHREAD_VERSION 3 -#define _CS_POSIX_V5_WIDTH_RESTRICTED_ENVS 4 -#define _CS_POSIX_V7_WIDTH_RESTRICTED_ENVS 5 - -#define _CS_POSIX_V6_ILP32_OFF32_CFLAGS 1116 -#define _CS_POSIX_V6_ILP32_OFF32_LDFLAGS 1117 -#define _CS_POSIX_V6_ILP32_OFF32_LIBS 1118 -#define _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS 1119 -#define _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS 1120 -#define _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS 1121 -#define _CS_POSIX_V6_ILP32_OFFBIG_LIBS 1122 -#define _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS 1123 -#define _CS_POSIX_V6_LP64_OFF64_CFLAGS 1124 -#define _CS_POSIX_V6_LP64_OFF64_LDFLAGS 1125 -#define _CS_POSIX_V6_LP64_OFF64_LIBS 1126 -#define _CS_POSIX_V6_LP64_OFF64_LINTFLAGS 1127 -#define _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS 1128 -#define _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS 1129 -#define _CS_POSIX_V6_LPBIG_OFFBIG_LIBS 1130 -#define _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS 1131 -#define _CS_POSIX_V7_ILP32_OFF32_CFLAGS 1132 -#define _CS_POSIX_V7_ILP32_OFF32_LDFLAGS 1133 -#define _CS_POSIX_V7_ILP32_OFF32_LIBS 1134 -#define _CS_POSIX_V7_ILP32_OFF32_LINTFLAGS 1135 -#define _CS_POSIX_V7_ILP32_OFFBIG_CFLAGS 1136 -#define _CS_POSIX_V7_ILP32_OFFBIG_LDFLAGS 1137 -#define _CS_POSIX_V7_ILP32_OFFBIG_LIBS 1138 -#define _CS_POSIX_V7_ILP32_OFFBIG_LINTFLAGS 1139 -#define _CS_POSIX_V7_LP64_OFF64_CFLAGS 1140 -#define _CS_POSIX_V7_LP64_OFF64_LDFLAGS 1141 -#define _CS_POSIX_V7_LP64_OFF64_LIBS 1142 -#define _CS_POSIX_V7_LP64_OFF64_LINTFLAGS 1143 -#define _CS_POSIX_V7_LPBIG_OFFBIG_CFLAGS 1144 -#define _CS_POSIX_V7_LPBIG_OFFBIG_LDFLAGS 1145 -#define _CS_POSIX_V7_LPBIG_OFFBIG_LIBS 1146 -#define _CS_POSIX_V7_LPBIG_OFFBIG_LINTFLAGS 1147 -#define _CS_V6_ENV 1148 -#define _CS_V7_ENV 1149 - -// MISSING: SEEK macros from stdio.h - -#define F_LOCK 1 -#define F_TEST 2 -#define F_TLOCK 3 -#define F_ULOCK 4 - -// MISSING: _PC macros -// For now, use the Linux ABI for _PC constants. -#define _PC_LINK_MAX 0 -#define _PC_MAX_CANON 1 -#define _PC_MAX_INPUT 2 -#define _PC_NAME_MAX 3 -#define _PC_PATH_MAX 4 -#define _PC_PIPE_BUF 5 -#define _PC_CHOWN_RESTRICTED 6 -#define _PC_NO_TRUNC 7 -#define _PC_VDISABLE 8 - -#define _PC_FILESIZEBITS 9 -#define _PC_SYMLINK_MAX 10 - -// MISSING: remaining _SC_macros -#define _SC_ARG_MAX 0 -#define _SC_GETPW_R_SIZE_MAX 1 -#define _SC_PHYS_PAGES 2 -#define _SC_PAGE_SIZE 3 -#define _SC_PAGESIZE _SC_PAGE_SIZE -#define _SC_OPEN_MAX 5 -#define _SC_NPROCESSORS_ONLN 6 -#define _SC_GETGR_R_SIZE_MAX 7 - -#define _SC_CHILD_MAX 8 -#define _SC_CLK_TCK 9 -#define _SC_NGROUPS_MAX 10 -#define _SC_VERSION 11 -#define _SC_SAVED_IDS 12 -#define _SC_JOB_CONTROL 13 -#define _SC_HOST_NAME_MAX 14 -#define _SC_LINE_MAX 15 -#define _SC_XOPEN_CRYPT 16 -#define _SC_NPROCESSORS_CONF 17 -#define _SC_SYMLOOP_MAX 18 -#define _SC_TTY_NAME_MAX 19 -#define _SC_RE_DUP_MAX 20 - -#define _SC_ATEXIT_MAX 21 -#define _SC_LOGIN_NAME_MAX 22 -#define _SC_THREAD_DESTRUCTOR_ITERATIONS 23 -#define _SC_THREAD_KEYS_MAX 24 -#define _SC_THREAD_STACK_MIN 25 -#define _SC_THREAD_THREADS_MAX 26 -#define _SC_TZNAME_MAX 27 -#define _SC_ASYNCHRONOUS_IO 28 -#define _SC_FSYNC 29 -#define _SC_MAPPED_FILES 30 -#define _SC_MEMLOCK 31 -#define _SC_MEMLOCK_RANGE 32 -#define _SC_MEMORY_PROTECTION 33 -#define _SC_MESSAGE_PASSING 34 -#define _SC_PRIORITY_SCHEDULING 35 -#define _SC_REALTIME_SIGNALS 36 -#define _SC_SEMAPHORES 37 -#define _SC_SHARED_MEMORY_OBJECTS 38 -#define _SC_SYNCHRONIZED_IO 39 -#define _SC_THREADS 40 -#define _SC_THREAD_ATTR_STACKADDR 41 -#define _SC_THREAD_ATTR_STACKSIZE 42 -#define _SC_THREAD_PRIORITY_SCHEDULING 43 -#define _SC_THREAD_PRIO_INHERIT 44 -#define _SC_THREAD_PRIO_PROTECT 45 -#define _SC_THREAD_PROCESS_SHARED 46 -#define _SC_THREAD_SAFE_FUNCTIONS 47 -#define _SC_TIMERS 48 -#define _SC_TIMER_MAX 49 -#define _SC_2_CHAR_TERM 50 -#define _SC_2_C_BIND 51 -#define _SC_2_C_DEV 52 -#define _SC_2_FORT_DEV 53 -#define _SC_2_FORT_RUN 54 -#define _SC_2_LOCALEDEF 55 -#define _SC_2_SW_DEV 56 -#define _SC_2_UPE 57 -#define _SC_2_VERSION 58 -#define _SC_CLOCK_SELECTION 59 -#define _SC_CPUTIME 60 -#define _SC_THREAD_CPUTIME 61 -#define _SC_MONOTONIC_CLOCK 62 -#define _SC_READER_WRITER_LOCKS 63 -#define _SC_SPIN_LOCKS 64 -#define _SC_REGEXP 65 -#define _SC_SHELL 66 -#define _SC_SPAWN 67 -#define _SC_2_PBS 68 -#define _SC_2_PBS_ACCOUNTING 69 -#define _SC_2_PBS_LOCATE 70 -#define _SC_2_PBS_TRACK 71 -#define _SC_2_PBS_MESSAGE 72 -#define _SC_STREAM_MAX 73 -#define _SC_AIO_LISTIO_MAX 74 -#define _SC_AIO_MAX 75 -#define _SC_DELAYTIMER_MAX 76 -#define _SC_MQ_OPEN_MAX 77 -#define _SC_MQ_PRIO_MAX 78 -#define _SC_RTSIG_MAX 79 -#define _SC_SIGQUEUE_MAX 80 -#define _SC_IOV_MAX 81 - -#define STDERR_FILENO 2 -#define STDIN_FILENO 0 -#define STDOUT_FILENO 1 - -#define _POSIX_VDISABLE '\0' - -#define L_ctermid 20 - -#ifndef intptr_t -typedef __mlibc_intptr intptr_t; -#endif - -#ifndef __MLIBC_ABI_ONLY - -int access(const char *path, int mode); -unsigned int alarm(unsigned int seconds); -int chdir(const char *path); -int chown(const char *path, uid_t uid, gid_t gid); -int close(int fd); -ssize_t confstr(int, char *, size_t); -char *ctermid(char *s); -int dup(int fd); -int dup2(int src_fd, int dest_fd); -__attribute__((__noreturn__)) void _exit(int status); -void endusershell(void); -int execl(const char *, const char *, ...); -int execle(const char *, const char *, ...); -int execlp(const char *, const char *, ...); -int execv(const char *, char *const []); -int execve(const char *path, char *const argv[], char *const envp[]); -int execvp(const char *, char *const[]); -int execvpe(const char *path, char *const argv[], char *const envp[]); -int faccessat(int, const char *, int, int); -int fchdir(int fd); -int fchown(int fd, uid_t uid, gid_t gid); -int fchownat(int fd, const char *path, uid_t uid, gid_t gid, int flags); -int fdatasync(int); -int fexecve(int, char *const [], char *const []); -pid_t fork(void); -pid_t vfork(void); -long fpathconf(int, int); -int fsync(int); -int ftruncate(int, off_t); -char *getcwd(char *, size_t); -gid_t getegid(void); -uid_t geteuid(void); -gid_t getgid(void); -int getgroups(int, gid_t []); -long gethostid(void); -int gethostname(char *buffer, size_t max_length); -int sethostname(const char *buffer, size_t max_length); -char *getlogin(void); -int getlogin_r(char *, size_t); -int getopt(int, char *const [], const char *); -char *getpass(const char *); -pid_t getpgid(pid_t); -pid_t getpgrp(void); -pid_t getpid(void); -pid_t getppid(void); -pid_t getsid(pid_t); -uid_t getuid(void); -char *getusershell(void); -int isatty(int fd); -int lchown(const char *path, uid_t uid, gid_t gid); -int link(const char *, const char *); -int linkat(int, const char *, int, const char *, int); -int lockf(int, int, off_t); -off_t lseek(int fd, off_t offset, int whence); -off64_t lseek64(int fd, off64_t offset, int whence); -int nice(int); -long pathconf(const char *, int); -int pause(void); -int pipe(int [2]); -ssize_t pread(int, void *, size_t, off_t); -ssize_t pwrite(int, const void *, size_t, off_t); -ssize_t read(int fd, void *buffer, size_t size); -ssize_t readlink(const char *__restrict, char *__restrict, size_t); -ssize_t readlinkat(int, const char *__restrict, char *__restrict, size_t); -int rmdir(const char *); -int setegid(gid_t); -int seteuid(uid_t); -int setgid(gid_t); -int setpgid(pid_t, pid_t); -pid_t setpgrp(void); -int setregid(gid_t, gid_t); -int setreuid(uid_t, uid_t); -pid_t setsid(void); -int setuid(uid_t); -void setusershell(void); -unsigned int sleep(unsigned int); -void swab(const void *__restrict, void *__restrict, ssize_t); -int symlink(const char *, const char *); -int symlinkat(const char *, int, const char *); -void sync(void); -long sysconf(int); -pid_t tcgetpgrp(int); -int tcsetpgrp(int, pid_t); -int truncate(const char *, off_t); -char *ttyname(int); -int ttyname_r(int, char *, size_t); -int unlink(const char *); -int unlinkat(int, const char *, int); -ssize_t write(int fd, const void *buffer, size_t size); - -extern char **environ; -extern char *optarg; -extern int optind; -extern int opterr; -extern int optopt; - -#endif /* !__MLIBC_ABI_ONLY */ - -// Non-POSIX functions supported by Linux. -#if UINTPTR_MAX == UINT64_MAX -typedef __mlibc_uint64 useconds_t; -#else -typedef __mlibc_uint32 useconds_t; -#endif - -#ifndef __MLIBC_ABI_ONLY - -int getpagesize(void); -char *get_current_dir_name(void); -int usleep(useconds_t); -int chroot(const char *); -int daemon(int, int); - -// This is a Linux extension -pid_t gettid(void); -int getentropy(void *, size_t); - -int pipe2(int *pipefd, int flags); - -int setresuid(uid_t ruid, uid_t euid, uid_t suid); -int setresgid(gid_t rgid, gid_t egid, gid_t sgid); - -/* Glibc extensions. */ -int getdomainname(char *name, size_t len); -int setdomainname(const char *name, size_t len); - -int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); -int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); - -// Glibc doesn't provide them by default anymore, lock behind an option -#if __MLIBC_CRYPT_OPTION -char *crypt(const char *, const char *); -void encrypt(char block[64], int flags); -#endif - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#if __MLIBC_LINUX_OPTION -# include <bits/linux/linux_unistd.h> -#endif - -#if __MLIBC_BSD_OPTION -# include <bits/bsd/bsd_unistd.h> -#endif - -#endif // _UNISTD_H - diff --git a/lib/mlibc/options/posix/include/utime.h b/lib/mlibc/options/posix/include/utime.h deleted file mode 100644 index dcf053d..0000000 --- a/lib/mlibc/options/posix/include/utime.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _UTIME_H -#define _UTIME_H - -#include <bits/ansi/time_t.h> - -#ifdef __cplusplus -extern "C" { -#endif - -struct utimbuf { - time_t actime; - time_t modtime; -}; - -#ifndef __MLIBC_ABI_ONLY - -int utime(const char *, const struct utimbuf *); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif // _UTIME_H diff --git a/lib/mlibc/options/posix/include/wordexp.h b/lib/mlibc/options/posix/include/wordexp.h deleted file mode 100644 index e5d69ce..0000000 --- a/lib/mlibc/options/posix/include/wordexp.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef _WORDEXP_H -#define _WORDEXP_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <bits/size_t.h> - -#define WRDE_APPEND 1 -#define WRDE_DOOFFS 2 -#define WRDE_NOCMD 4 -#define WRDE_REUSE 8 -#define WRDE_SHOWERR 16 -#define WRDE_UNDEF 32 - -#define WRDE_SUCCESS 1 -#define WRDE_BADCHAR 1 -#define WRDE_BADVAL 2 -#define WRDE_CMDSUB 3 -#define WRDE_NOSPACE 4 -#define WRDE_SYNTAX 5 - -typedef struct { - size_t we_wordc; - char **we_wordv; - size_t we_offs; - char *we_strings; - size_t we_nbytes; -} wordexp_t; - -#ifndef __MLIBC_ABI_ONLY - -int wordexp(const char *s, wordexp_t *p, int flags); -void wordfree(wordexp_t *p); - -#endif /* !__MLIBC_ABI_ONLY */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/lib/mlibc/options/posix/meson.build b/lib/mlibc/options/posix/meson.build deleted file mode 100644 index 038dd2c..0000000 --- a/lib/mlibc/options/posix/meson.build +++ /dev/null @@ -1,175 +0,0 @@ - -if disable_posix_option - subdir_done() -endif -libc_sources += files( - 'generic/arpa-inet-stubs.cpp', - 'generic/dirent-stubs.cpp', - 'generic/dlfcn-stubs.cpp', - 'generic/fcntl-stubs.cpp', - 'generic/ftw-stubs.cpp', - 'generic/grp-stubs.cpp', - 'generic/langinfo-stubs.cpp', - 'generic/libgen-stubs.cpp', - 'generic/lookup.cpp', - 'generic/netdb-stubs.cpp', - 'generic/net-if-stubs.cpp', - 'generic/poll.cpp', - 'generic/posix_ctype.cpp', - 'generic/posix-file-io.cpp', - 'generic/posix_locale.cpp', - 'generic/posix_signal.cpp', - 'generic/posix_stdio.cpp', - 'generic/posix_stdlib.cpp', - 'generic/posix_string.cpp', - 'generic/posix_time.cpp', - 'generic/pthread-stubs.cpp', - 'generic/pwd-stubs.cpp', - 'generic/resolv_conf.cpp', - 'generic/sched-stubs.cpp', - 'generic/spawn-stubs.cpp', - 'generic/strings-stubs.cpp', - 'generic/services.cpp', - 'generic/sys-file-stubs.cpp', - 'generic/syslog-stubs.cpp', - 'generic/sys-mman-stubs.cpp', - 'generic/sys-resource-stubs.cpp', - 'generic/sys-select-stubs.cpp', - 'generic/sys-shm.cpp', - 'generic/sys-socket-stubs.cpp', - 'generic/sys-stat-stubs.cpp', - 'generic/sys-statvfs-stubs.cpp', - 'generic/sys-times.cpp', - 'generic/sys-time-stubs.cpp', - 'generic/sys-uio.cpp', - 'generic/sys-utsname.cpp', - 'generic/sys-wait-stubs.cpp', - 'generic/termios-stubs.cpp', - 'generic/unistd-stubs.cpp', - 'generic/utime-stubs.cpp', - 'generic/ucontext-stubs.cpp', - 'generic/semaphore-stubs.cpp', - 'generic/search.cpp', - 'generic/sys-msg.cpp', - 'generic/sys-sem.cpp', - 'generic/sys-ipc.cpp', - 'generic/time.cpp', - 'generic/wordexp-stubs.cpp', - 'generic/mqueue.cpp' -) - -if not headers_only - libc_sublibs += static_library('musl-generic-regex', - 'musl-generic-regex/fnmatch.c', - 'musl-generic-regex/glob.c', - 'musl-generic-regex/regcomp.c', - 'musl-generic-regex/regerror.c', - 'musl-generic-regex/regexec.c', - 'musl-generic-regex/tre-mem.c', - pic: true, - include_directories: libc_include_dirs, - dependencies: libc_deps, - c_args: ['-Wno-unused', '-Wno-implicit', '-Wno-parentheses', '-Wno-sign-compare', '-Wno-attributes', '-Wno-unknown-pragmas', '-Wno-implicit-fallthrough'] - ) -endif - -if not no_headers - install_headers( - 'include/byteswap.h', - 'include/dirent.h', - 'include/dlfcn.h', - 'include/fcntl.h', - 'include/fnmatch.h', - 'include/ftw.h', - 'include/glob.h', - 'include/grp.h', - 'include/langinfo.h', - 'include/libgen.h', - 'include/netdb.h', - 'include/nl_types.h', - 'include/pthread.h', - 'include/pwd.h', - 'include/poll.h', - 'include/regex.h', - 'include/sched.h', - 'include/search.h', - 'include/spawn.h', - 'include/strings.h', - 'include/syslog.h', - 'include/termios.h', - 'include/unistd.h', - 'include/utime.h', - 'include/ucontext.h', - 'include/wordexp.h', - 'include/semaphore.h', - 'include/mqueue.h', - ) - install_headers( - 'include/arpa/inet.h', - subdir: 'arpa' - ) - install_headers( - 'include/net/if.h', - 'include/net/if_arp.h', - subdir: 'net' - ) - install_headers( - 'include/netinet/in.h', - 'include/netinet/ip.h', - 'include/netinet/tcp.h', - 'include/netinet/icmp6.h', - 'include/netinet/if_ether.h', - 'include/netinet/udp.h', - 'include/netinet/ip6.h', - 'include/netinet/ip_icmp.h', - subdir: 'netinet' - ) - install_headers( - 'include/sys/file.h', - 'include/sys/ipc.h', - 'include/sys/mman.h', - 'include/sys/msg.h', - 'include/sys/param.h', - 'include/sys/poll.h', - 'include/sys/resource.h', - 'include/sys/select.h', - 'include/sys/sem.h', - 'include/sys/shm.h', - 'include/sys/socket.h', - 'include/sys/stat.h', - 'include/sys/statvfs.h', - 'include/sys/termios.h', - 'include/sys/time.h', - 'include/sys/times.h', - 'include/sys/ttydefaults.h', - 'include/sys/types.h', - 'include/sys/uio.h', - 'include/sys/un.h', - 'include/sys/utsname.h', - 'include/sys/wait.h', - 'include/sys/syslog.h', - subdir: 'sys' - ) - install_headers( - 'include/bits/posix/id_t.h', - 'include/bits/posix/in_addr_t.h', - 'include/bits/posix/in_port_t.h', - 'include/bits/posix/iovec.h', - 'include/bits/posix/locale_t.h', - 'include/bits/posix/posix_ctype.h', - 'include/bits/posix/posix_locale.h', - 'include/bits/posix/posix_signal.h', - 'include/bits/posix/posix_stdio.h', - 'include/bits/posix/posix_stdlib.h', - 'include/bits/posix/posix_string.h', - 'include/bits/posix/posix_time.h', - 'include/bits/posix/posix_wctype.h', - 'include/bits/posix/stat.h', - 'include/bits/posix/timeval.h', - 'include/bits/posix/fd_set.h', - 'include/bits/posix/pthread_t.h', - 'include/bits/posix/timer_t.h', - subdir: 'bits/posix' - ) -endif - diff --git a/lib/mlibc/options/posix/musl-generic-regex/fnmatch.c b/lib/mlibc/options/posix/musl-generic-regex/fnmatch.c deleted file mode 100644 index 0e6de47..0000000 --- a/lib/mlibc/options/posix/musl-generic-regex/fnmatch.c +++ /dev/null @@ -1,321 +0,0 @@ -/* - * An implementation of what I call the "Sea of Stars" algorithm for - * POSIX fnmatch(). The basic idea is that we factor the pattern into - * a head component (which we match first and can reject without ever - * measuring the length of the string), an optional tail component - * (which only exists if the pattern contains at least one star), and - * an optional "sea of stars", a set of star-separated components - * between the head and tail. After the head and tail matches have - * been removed from the input string, the components in the "sea of - * stars" are matched sequentially by searching for their first - * occurrence past the end of the previous match. - * - * - Rich Felker, April 2012 - */ - -#include <string.h> -#include <fnmatch.h> -#include <stdlib.h> -#include <wchar.h> -#include <wctype.h> -// #include "locale_impl.h" - -#define END 0 -#define UNMATCHABLE -2 -#define BRACKET -3 -#define QUESTION -4 -#define STAR -5 - -static int str_next(const char *str, size_t n, size_t *step) -{ - if (!n) { - *step = 0; - return 0; - } - if (str[0] >= 128U) { - wchar_t wc; - int k = mbtowc(&wc, str, n); - if (k<0) { - *step = 1; - return -1; - } - *step = k; - return wc; - } - *step = 1; - return str[0]; -} - -static int pat_next(const char *pat, size_t m, size_t *step, int flags) -{ - int esc = 0; - if (!m || !*pat) { - *step = 0; - return END; - } - *step = 1; - if (pat[0]=='\\' && pat[1] && !(flags & FNM_NOESCAPE)) { - *step = 2; - pat++; - esc = 1; - goto escaped; - } - if (pat[0]=='[') { - size_t k = 1; - if (k<m) if (pat[k] == '^' || pat[k] == '!') k++; - if (k<m) if (pat[k] == ']') k++; - for (; k<m && pat[k] && pat[k]!=']'; k++) { - if (k+1<m && pat[k+1] && pat[k]=='[' && (pat[k+1]==':' || pat[k+1]=='.' || pat[k+1]=='=')) { - int z = pat[k+1]; - k+=2; - if (k<m && pat[k]) k++; - while (k<m && pat[k] && (pat[k-1]!=z || pat[k]!=']')) k++; - if (k==m || !pat[k]) break; - } - } - if (k==m || !pat[k]) { - *step = 1; - return '['; - } - *step = k+1; - return BRACKET; - } - if (pat[0] == '*') - return STAR; - if (pat[0] == '?') - return QUESTION; -escaped: - if (pat[0] >= 128U) { - wchar_t wc; - int k = mbtowc(&wc, pat, m); - if (k<0) { - *step = 0; - return UNMATCHABLE; - } - *step = k + esc; - return wc; - } - return pat[0]; -} - -static int casefold(int k) -{ - int c = towupper(k); - return c == k ? towlower(k) : c; -} - -static int match_bracket(const char *p, int k, int kfold) -{ - wchar_t wc; - int inv = 0; - p++; - if (*p=='^' || *p=='!') { - inv = 1; - p++; - } - if (*p==']') { - if (k==']') return !inv; - p++; - } else if (*p=='-') { - if (k=='-') return !inv; - p++; - } - wc = p[-1]; - for (; *p != ']'; p++) { - if (p[0]=='-' && p[1]!=']') { - wchar_t wc2; - int l = mbtowc(&wc2, p+1, 4); - if (l < 0) return 0; - if (wc <= wc2) - if ((unsigned)k-wc <= wc2-wc || - (unsigned)kfold-wc <= wc2-wc) - return !inv; - p += l-1; - continue; - } - if (p[0]=='[' && (p[1]==':' || p[1]=='.' || p[1]=='=')) { - const char *p0 = p+2; - int z = p[1]; - p+=3; - while (p[-1]!=z || p[0]!=']') p++; - if (z == ':' && p-1-p0 < 16) { - char buf[16]; - memcpy(buf, p0, p-1-p0); - buf[p-1-p0] = 0; - if (iswctype(k, wctype(buf)) || - iswctype(kfold, wctype(buf))) - return !inv; - } - continue; - } - if (*p < 128U) { - wc = (unsigned char)*p; - } else { - int l = mbtowc(&wc, p, 4); - if (l < 0) return 0; - p += l-1; - } - if (wc==(wchar_t)k || wc==(wchar_t)kfold) return !inv; - } - return inv; -} - -static int fnmatch_internal(const char *pat, size_t m, const char *str, size_t n, int flags) -{ - const char *p, *ptail, *endpat; - const char *s, *stail, *endstr; - size_t pinc, sinc, tailcnt=0; - int c, k, kfold; - - if (flags & FNM_PERIOD) { - if (*str == '.' && *pat != '.') - return FNM_NOMATCH; - } - for (;;) { - switch ((c = pat_next(pat, m, &pinc, flags))) { - case UNMATCHABLE: - return FNM_NOMATCH; - case STAR: - pat++; - m--; - break; - default: - k = str_next(str, n, &sinc); - if (k <= 0) - return (c==END) ? 0 : FNM_NOMATCH; - str += sinc; - n -= sinc; - kfold = flags & FNM_CASEFOLD ? casefold(k) : k; - if (c == BRACKET) { - if (!match_bracket(pat, k, kfold)) - return FNM_NOMATCH; - } else if (c != QUESTION && k != c && kfold != c) { - return FNM_NOMATCH; - } - pat+=pinc; - m-=pinc; - continue; - } - break; - } - - /* Compute real pat length if it was initially unknown/-1 */ - m = strnlen(pat, m); - endpat = pat + m; - - /* Find the last * in pat and count chars needed after it */ - for (p=ptail=pat; p<endpat; p+=pinc) { - switch (pat_next(p, endpat-p, &pinc, flags)) { - case UNMATCHABLE: - return FNM_NOMATCH; - case STAR: - tailcnt=0; - ptail = p+1; - break; - default: - tailcnt++; - break; - } - } - - /* Past this point we need not check for UNMATCHABLE in pat, - * because all of pat has already been parsed once. */ - - /* Compute real str length if it was initially unknown/-1 */ - n = strnlen(str, n); - endstr = str + n; - if (n < tailcnt) return FNM_NOMATCH; - - /* Find the final tailcnt chars of str, accounting for UTF-8. - * On illegal sequences we may get it wrong, but in that case - * we necessarily have a matching failure anyway. */ - for (s=endstr; s>str && tailcnt; tailcnt--) { - if (s[-1] < 128U || MB_CUR_MAX==1) s--; - else while ((unsigned char)*--s-0x80U<0x40 && s>str); - } - if (tailcnt) return FNM_NOMATCH; - stail = s; - - /* Check that the pat and str tails match */ - p = ptail; - for (;;) { - c = pat_next(p, endpat-p, &pinc, flags); - p += pinc; - if ((k = str_next(s, endstr-s, &sinc)) <= 0) { - if (c != END) return FNM_NOMATCH; - break; - } - s += sinc; - kfold = flags & FNM_CASEFOLD ? casefold(k) : k; - if (c == BRACKET) { - if (!match_bracket(p-pinc, k, kfold)) - return FNM_NOMATCH; - } else if (c != QUESTION && k != c && kfold != c) { - return FNM_NOMATCH; - } - } - - /* We're all done with the tails now, so throw them out */ - endstr = stail; - endpat = ptail; - - /* Match pattern components until there are none left */ - while (pat<endpat) { - p = pat; - s = str; - for (;;) { - c = pat_next(p, endpat-p, &pinc, flags); - p += pinc; - /* Encountering * completes/commits a component */ - if (c == STAR) { - pat = p; - str = s; - break; - } - k = str_next(s, endstr-s, &sinc); - if (!k) - return FNM_NOMATCH; - kfold = flags & FNM_CASEFOLD ? casefold(k) : k; - if (c == BRACKET) { - if (!match_bracket(p-pinc, k, kfold)) - break; - } else if (c != QUESTION && k != c && kfold != c) { - break; - } - s += sinc; - } - if (c == STAR) continue; - /* If we failed, advance str, by 1 char if it's a valid - * char, or past all invalid bytes otherwise. */ - k = str_next(str, endstr-str, &sinc); - if (k > 0) str += sinc; - else for (str++; str_next(str, endstr-str, &sinc)<0; str++); - } - - return 0; -} - -int fnmatch(const char *pat, const char *str, int flags) -{ - const char *s, *p; - size_t inc; - int c; - if (flags & FNM_PATHNAME) for (;;) { - for (s=str; *s && *s!='/'; s++); - for (p=pat; (c=pat_next(p, -1, &inc, flags))!=END && c!='/'; p+=inc); - if (c!=*s && (!*s || !(flags & FNM_LEADING_DIR))) - return FNM_NOMATCH; - if (fnmatch_internal(pat, p-pat, str, s-str, flags)) - return FNM_NOMATCH; - if (!c) return 0; - str = s+1; - pat = p+inc; - } else if (flags & FNM_LEADING_DIR) { - for (s=str; *s; s++) { - if (*s != '/') continue; - if (!fnmatch_internal(pat, -1, str, s-str, flags)) - return 0; - } - } - return fnmatch_internal(pat, -1, str, -1, flags); -} diff --git a/lib/mlibc/options/posix/musl-generic-regex/glob.c b/lib/mlibc/options/posix/musl-generic-regex/glob.c deleted file mode 100644 index b57f2f3..0000000 --- a/lib/mlibc/options/posix/musl-generic-regex/glob.c +++ /dev/null @@ -1,311 +0,0 @@ -#define _BSD_SOURCE -#include <glob.h> -#include <fnmatch.h> -#include <sys/stat.h> -#include <dirent.h> -#include <limits.h> -#include <string.h> -#include <stdlib.h> -#include <errno.h> -#include <stddef.h> -#include <unistd.h> -#include <pwd.h> - -struct match -{ - struct match *next; - char name[]; -}; - -static int append(struct match **tail, const char *name, size_t len, int mark) -{ - struct match *new = malloc(sizeof(struct match) + len + 2); - if (!new) return -1; - (*tail)->next = new; - new->next = NULL; - memcpy(new->name, name, len+1); - if (mark && len && name[len-1]!='/') { - new->name[len] = '/'; - new->name[len+1] = 0; - } - *tail = new; - return 0; -} - -static int do_glob(char *buf, size_t pos, int type, char *pat, int flags, int (*errfunc)(const char *path, int err), struct match **tail) -{ - /* If GLOB_MARK is unused, we don't care about type. */ - if (!type && !(flags & GLOB_MARK)) type = DT_REG; - - /* Special-case the remaining pattern being all slashes, in - * which case we can use caller-passed type if it's a dir. */ - if (*pat && type!=DT_DIR) type = 0; - while (pos+1 < PATH_MAX && *pat=='/') buf[pos++] = *pat++; - - /* Consume maximal [escaped-]literal prefix of pattern, copying - * and un-escaping it to the running buffer as we go. */ - ptrdiff_t i=0, j=0; - int in_bracket = 0, overflow = 0; - for (; pat[i]!='*' && pat[i]!='?' && (!in_bracket || pat[i]!=']'); i++) { - if (!pat[i]) { - if (overflow) return 0; - pat += i; - pos += j; - i = j = 0; - break; - } else if (pat[i] == '[') { - in_bracket = 1; - } else if (pat[i] == '\\' && !(flags & GLOB_NOESCAPE)) { - /* Backslashes inside a bracket are (at least by - * our interpretation) non-special, so if next - * char is ']' we have a complete expression. */ - if (in_bracket && pat[i+1]==']') break; - /* Unpaired final backslash never matches. */ - if (!pat[i+1]) return 0; - i++; - } - if (pat[i] == '/') { - if (overflow) return 0; - in_bracket = 0; - pat += i+1; - i = -1; - pos += j+1; - j = -1; - } - /* Only store a character if it fits in the buffer, but if - * a potential bracket expression is open, the overflow - * must be remembered and handled later only if the bracket - * is unterminated (and thereby a literal), so as not to - * disallow long bracket expressions with short matches. */ - if (pos+(j+1) < PATH_MAX) { - buf[pos+j++] = pat[i]; - } else if (in_bracket) { - overflow = 1; - } else { - return 0; - } - /* If we consume any new components, the caller-passed type - * or dummy type from above is no longer valid. */ - type = 0; - } - buf[pos] = 0; - if (!*pat) { - /* If we consumed any components above, or if GLOB_MARK is - * requested and we don't yet know if the match is a dir, - * we must confirm the file exists and/or determine its type. - * - * If marking dirs, symlink type is inconclusive; we need the - * type for the symlink target, and therefore must try stat - * first unless type is known not to be a symlink. Otherwise, - * or if that fails, use lstat for determining existence to - * avoid false negatives in the case of broken symlinks. */ - struct stat st; - if ((flags & GLOB_MARK) && (!type||type==DT_LNK) && !stat(buf, &st)) { - if (S_ISDIR(st.st_mode)) type = DT_DIR; - else type = DT_REG; - } - if (!type && lstat(buf, &st)) { - if (errno!=ENOENT && (errfunc(buf, errno) || (flags & GLOB_ERR))) - return GLOB_ABORTED; - return 0; - } - if (append(tail, buf, pos, (flags & GLOB_MARK) && type==DT_DIR)) - return GLOB_NOSPACE; - return 0; - } - char *p2 = strchr(pat, '/'), saved_sep = '/'; - /* Check if the '/' was escaped and, if so, remove the escape char - * so that it will not be unpaired when passed to fnmatch. */ - if (p2 && !(flags & GLOB_NOESCAPE)) { - char *p; - for (p=p2; p>pat && p[-1]=='\\'; p--); - if ((p2-p)%2) { - p2--; - saved_sep = '\\'; - } - } - DIR *dir = opendir(pos ? buf : "."); - if (!dir) { - if (errfunc(buf, errno) || (flags & GLOB_ERR)) - return GLOB_ABORTED; - return 0; - } - int old_errno = errno; - struct dirent *de; - while (errno=0, de=readdir(dir)) { - /* Quickly skip non-directories when there's pattern left. */ - if (p2 && de->d_type && de->d_type!=DT_DIR && de->d_type!=DT_LNK) - continue; - - size_t l = strlen(de->d_name); - if (l >= PATH_MAX-pos) continue; - - if (p2) *p2 = 0; - - int fnm_flags= ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0) - | ((!(flags & GLOB_PERIOD)) ? FNM_PERIOD : 0); - - if (fnmatch(pat, de->d_name, fnm_flags)) - continue; - - /* With GLOB_PERIOD, don't allow matching . or .. unless - * fnmatch would match them with FNM_PERIOD rules in effect. */ - if (p2 && (flags & GLOB_PERIOD) && de->d_name[0]=='.' - && (!de->d_name[1] || de->d_name[1]=='.' && !de->d_name[2]) - && fnmatch(pat, de->d_name, fnm_flags | FNM_PERIOD)) - continue; - - memcpy(buf+pos, de->d_name, l+1); - if (p2) *p2 = saved_sep; - int r = do_glob(buf, pos+l, de->d_type, p2 ? p2 : "", flags, errfunc, tail); - if (r) { - closedir(dir); - return r; - } - } - int readerr = errno; - if (p2) *p2 = saved_sep; - closedir(dir); - if (readerr && (errfunc(buf, errno) || (flags & GLOB_ERR))) - return GLOB_ABORTED; - errno = old_errno; - return 0; -} - -static int ignore_err(const char *path, int err) -{ - return 0; -} - -static void freelist(struct match *head) -{ - struct match *match, *next; - for (match=head->next; match; match=next) { - next = match->next; - free(match); - } -} - -static int sort(const void *a, const void *b) -{ - return strcmp(*(const char **)a, *(const char **)b); -} - -static int expand_tilde(char **pat, char *buf, size_t *pos) -{ - char *p = *pat + 1; - size_t i = 0; - - char delim, *name_end = strchrnul(p, '/'); - if ((delim = *name_end)) *name_end++ = 0; - *pat = name_end; - - char *home = *p ? NULL : getenv("HOME"); - if (!home) { - struct passwd pw, *res; - switch (*p ? getpwnam_r(p, &pw, buf, PATH_MAX, &res) - : getpwuid_r(getuid(), &pw, buf, PATH_MAX, &res)) { - case ENOMEM: - return GLOB_NOSPACE; - case 0: - if (!res) - default: - return GLOB_NOMATCH; - } - home = pw.pw_dir; - } - while (i < PATH_MAX - 2 && *home) - buf[i++] = *home++; - if (*home) - return GLOB_NOMATCH; - if ((buf[i] = delim)) - buf[++i] = 0; - *pos = i; - return 0; -} - -int glob(const char *restrict pat, int flags, int (*errfunc)(const char *path, int err), glob_t *restrict g) -{ - struct match head = { .next = NULL }, *tail = &head; - size_t cnt, i; - size_t offs = (flags & GLOB_DOOFFS) ? g->gl_offs : 0; - int error = 0; - char buf[PATH_MAX]; - - if (!errfunc) errfunc = ignore_err; - - if (!(flags & GLOB_APPEND)) { - g->gl_offs = offs; - g->gl_pathc = 0; - g->gl_pathv = NULL; - } - - if (*pat) { - char *p = strdup(pat); - if (!p) return GLOB_NOSPACE; - buf[0] = 0; - size_t pos = 0; - char *s = p; - if ((flags & (GLOB_TILDE | GLOB_TILDE_CHECK)) && *p == '~') - error = expand_tilde(&s, buf, &pos); - if (!error) - error = do_glob(buf, pos, 0, s, flags, errfunc, &tail); - free(p); - } - - if (error == GLOB_NOSPACE) { - freelist(&head); - return error; - } - - for (cnt=0, tail=head.next; tail; tail=tail->next, cnt++); - if (!cnt) { - if (flags & GLOB_NOCHECK) { - tail = &head; - if (append(&tail, pat, strlen(pat), 0)) - return GLOB_NOSPACE; - cnt++; - } else - return GLOB_NOMATCH; - } - - if (flags & GLOB_APPEND) { - char **pathv = realloc(g->gl_pathv, (offs + g->gl_pathc + cnt + 1) * sizeof(char *)); - if (!pathv) { - freelist(&head); - return GLOB_NOSPACE; - } - g->gl_pathv = pathv; - offs += g->gl_pathc; - } else { - g->gl_pathv = malloc((offs + cnt + 1) * sizeof(char *)); - if (!g->gl_pathv) { - freelist(&head); - return GLOB_NOSPACE; - } - for (i=0; i<offs; i++) - g->gl_pathv[i] = NULL; - } - for (i=0, tail=head.next; i<cnt; tail=tail->next, i++) - g->gl_pathv[offs + i] = tail->name; - g->gl_pathv[offs + i] = NULL; - g->gl_pathc += cnt; - - if (!(flags & GLOB_NOSORT)) - qsort(g->gl_pathv+offs, cnt, sizeof(char *), sort); - - return error; -} - -void globfree(glob_t *g) -{ - size_t i; - for (i=0; i<g->gl_pathc; i++) - free(g->gl_pathv[g->gl_offs + i] - offsetof(struct match, name)); - free(g->gl_pathv); - g->gl_pathc = 0; - g->gl_pathv = NULL; -} - -// weak_alias(glob, glob64); -// weak_alias(globfree, globfree64); diff --git a/lib/mlibc/options/posix/musl-generic-regex/regcomp.c b/lib/mlibc/options/posix/musl-generic-regex/regcomp.c deleted file mode 100644 index ab03984..0000000 --- a/lib/mlibc/options/posix/musl-generic-regex/regcomp.c +++ /dev/null @@ -1,2953 +0,0 @@ -/* - regcomp.c - TRE POSIX compatible regex compilation functions. - - Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi> - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#include <string.h> -#include <stdlib.h> -#include <regex.h> -#include <limits.h> -#include <stdint.h> -#include <ctype.h> - -#include "tre.h" - -#include <assert.h> - -/*********************************************************************** - from tre-compile.h -***********************************************************************/ - -typedef struct { - int position; - int code_min; - int code_max; - int *tags; - int assertions; - tre_ctype_t class; - tre_ctype_t *neg_classes; - int backref; -} tre_pos_and_tags_t; - - -/*********************************************************************** - from tre-ast.c and tre-ast.h -***********************************************************************/ - -/* The different AST node types. */ -typedef enum { - LITERAL, - CATENATION, - ITERATION, - UNION -} tre_ast_type_t; - -/* Special subtypes of TRE_LITERAL. */ -#define EMPTY -1 /* Empty leaf (denotes empty string). */ -#define ASSERTION -2 /* Assertion leaf. */ -#define TAG -3 /* Tag leaf. */ -#define BACKREF -4 /* Back reference leaf. */ - -#define IS_SPECIAL(x) ((x)->code_min < 0) -#define IS_EMPTY(x) ((x)->code_min == EMPTY) -#define IS_ASSERTION(x) ((x)->code_min == ASSERTION) -#define IS_TAG(x) ((x)->code_min == TAG) -#define IS_BACKREF(x) ((x)->code_min == BACKREF) - - -/* A generic AST node. All AST nodes consist of this node on the top - level with `obj' pointing to the actual content. */ -typedef struct { - tre_ast_type_t type; /* Type of the node. */ - void *obj; /* Pointer to actual node. */ - int nullable; - int submatch_id; - int num_submatches; - int num_tags; - tre_pos_and_tags_t *firstpos; - tre_pos_and_tags_t *lastpos; -} tre_ast_node_t; - - -/* A "literal" node. These are created for assertions, back references, - tags, matching parameter settings, and all expressions that match one - character. */ -typedef struct { - long code_min; - long code_max; - int position; - tre_ctype_t class; - tre_ctype_t *neg_classes; -} tre_literal_t; - -/* A "catenation" node. These are created when two regexps are concatenated. - If there are more than one subexpressions in sequence, the `left' part - holds all but the last, and `right' part holds the last subexpression - (catenation is left associative). */ -typedef struct { - tre_ast_node_t *left; - tre_ast_node_t *right; -} tre_catenation_t; - -/* An "iteration" node. These are created for the "*", "+", "?", and "{m,n}" - operators. */ -typedef struct { - /* Subexpression to match. */ - tre_ast_node_t *arg; - /* Minimum number of consecutive matches. */ - int min; - /* Maximum number of consecutive matches. */ - int max; - /* If 0, match as many characters as possible, if 1 match as few as - possible. Note that this does not always mean the same thing as - matching as many/few repetitions as possible. */ - unsigned int minimal:1; -} tre_iteration_t; - -/* An "union" node. These are created for the "|" operator. */ -typedef struct { - tre_ast_node_t *left; - tre_ast_node_t *right; -} tre_union_t; - - -static tre_ast_node_t * -tre_ast_new_node(tre_mem_t mem, int type, void *obj) -{ - tre_ast_node_t *node = tre_mem_calloc(mem, sizeof *node); - if (!node || !obj) - return 0; - node->obj = obj; - node->type = type; - node->nullable = -1; - node->submatch_id = -1; - return node; -} - -static tre_ast_node_t * -tre_ast_new_literal(tre_mem_t mem, int code_min, int code_max, int position) -{ - tre_ast_node_t *node; - tre_literal_t *lit; - - lit = tre_mem_calloc(mem, sizeof *lit); - node = tre_ast_new_node(mem, LITERAL, lit); - if (!node) - return 0; - lit->code_min = code_min; - lit->code_max = code_max; - lit->position = position; - return node; -} - -static tre_ast_node_t * -tre_ast_new_iter(tre_mem_t mem, tre_ast_node_t *arg, int min, int max, int minimal) -{ - tre_ast_node_t *node; - tre_iteration_t *iter; - - iter = tre_mem_calloc(mem, sizeof *iter); - node = tre_ast_new_node(mem, ITERATION, iter); - if (!node) - return 0; - iter->arg = arg; - iter->min = min; - iter->max = max; - iter->minimal = minimal; - node->num_submatches = arg->num_submatches; - return node; -} - -static tre_ast_node_t * -tre_ast_new_union(tre_mem_t mem, tre_ast_node_t *left, tre_ast_node_t *right) -{ - tre_ast_node_t *node; - tre_union_t *un; - - if (!left) - return right; - un = tre_mem_calloc(mem, sizeof *un); - node = tre_ast_new_node(mem, UNION, un); - if (!node || !right) - return 0; - un->left = left; - un->right = right; - node->num_submatches = left->num_submatches + right->num_submatches; - return node; -} - -static tre_ast_node_t * -tre_ast_new_catenation(tre_mem_t mem, tre_ast_node_t *left, tre_ast_node_t *right) -{ - tre_ast_node_t *node; - tre_catenation_t *cat; - - if (!left) - return right; - cat = tre_mem_calloc(mem, sizeof *cat); - node = tre_ast_new_node(mem, CATENATION, cat); - if (!node) - return 0; - cat->left = left; - cat->right = right; - node->num_submatches = left->num_submatches + right->num_submatches; - return node; -} - - -/*********************************************************************** - from tre-stack.c and tre-stack.h -***********************************************************************/ - -typedef struct tre_stack_rec tre_stack_t; - -/* Creates a new stack object. `size' is initial size in bytes, `max_size' - is maximum size, and `increment' specifies how much more space will be - allocated with realloc() if all space gets used up. Returns the stack - object or NULL if out of memory. */ -static tre_stack_t * -tre_stack_new(int size, int max_size, int increment); - -/* Frees the stack object. */ -static void -tre_stack_destroy(tre_stack_t *s); - -/* Returns the current number of objects in the stack. */ -static int -tre_stack_num_objects(tre_stack_t *s); - -/* Each tre_stack_push_*(tre_stack_t *s, <type> value) function pushes - `value' on top of stack `s'. Returns REG_ESPACE if out of memory. - This tries to realloc() more space before failing if maximum size - has not yet been reached. Returns REG_OK if successful. */ -#define declare_pushf(typetag, type) \ - static reg_errcode_t tre_stack_push_ ## typetag(tre_stack_t *s, type value) - -declare_pushf(voidptr, void *); -declare_pushf(int, int); - -/* Each tre_stack_pop_*(tre_stack_t *s) function pops the topmost - element off of stack `s' and returns it. The stack must not be - empty. */ -#define declare_popf(typetag, type) \ - static type tre_stack_pop_ ## typetag(tre_stack_t *s) - -declare_popf(voidptr, void *); -declare_popf(int, int); - -/* Just to save some typing. */ -#define STACK_PUSH(s, typetag, value) \ - do \ - { \ - status = tre_stack_push_ ## typetag(s, value); \ - } \ - while (/*CONSTCOND*/0) - -#define STACK_PUSHX(s, typetag, value) \ - { \ - status = tre_stack_push_ ## typetag(s, value); \ - if (status != REG_OK) \ - break; \ - } - -#define STACK_PUSHR(s, typetag, value) \ - { \ - reg_errcode_t _status; \ - _status = tre_stack_push_ ## typetag(s, value); \ - if (_status != REG_OK) \ - return _status; \ - } - -union tre_stack_item { - void *voidptr_value; - int int_value; -}; - -struct tre_stack_rec { - int size; - int max_size; - int increment; - int ptr; - union tre_stack_item *stack; -}; - - -static tre_stack_t * -tre_stack_new(int size, int max_size, int increment) -{ - tre_stack_t *s; - - s = xmalloc(sizeof(*s)); - if (s != NULL) - { - s->stack = xmalloc(sizeof(*s->stack) * size); - if (s->stack == NULL) - { - xfree(s); - return NULL; - } - s->size = size; - s->max_size = max_size; - s->increment = increment; - s->ptr = 0; - } - return s; -} - -static void -tre_stack_destroy(tre_stack_t *s) -{ - xfree(s->stack); - xfree(s); -} - -static int -tre_stack_num_objects(tre_stack_t *s) -{ - return s->ptr; -} - -static reg_errcode_t -tre_stack_push(tre_stack_t *s, union tre_stack_item value) -{ - if (s->ptr < s->size) - { - s->stack[s->ptr] = value; - s->ptr++; - } - else - { - if (s->size >= s->max_size) - { - return REG_ESPACE; - } - else - { - union tre_stack_item *new_buffer; - int new_size; - new_size = s->size + s->increment; - if (new_size > s->max_size) - new_size = s->max_size; - new_buffer = xrealloc(s->stack, sizeof(*new_buffer) * new_size); - if (new_buffer == NULL) - { - return REG_ESPACE; - } - assert(new_size > s->size); - s->size = new_size; - s->stack = new_buffer; - tre_stack_push(s, value); - } - } - return REG_OK; -} - -#define define_pushf(typetag, type) \ - declare_pushf(typetag, type) { \ - union tre_stack_item item; \ - item.typetag ## _value = value; \ - return tre_stack_push(s, item); \ -} - -define_pushf(int, int) -define_pushf(voidptr, void *) - -#define define_popf(typetag, type) \ - declare_popf(typetag, type) { \ - return s->stack[--s->ptr].typetag ## _value; \ - } - -define_popf(int, int) -define_popf(voidptr, void *) - - -/*********************************************************************** - from tre-parse.c and tre-parse.h -***********************************************************************/ - -/* Parse context. */ -typedef struct { - /* Memory allocator. The AST is allocated using this. */ - tre_mem_t mem; - /* Stack used for keeping track of regexp syntax. */ - tre_stack_t *stack; - /* The parsed node after a parse function returns. */ - tre_ast_node_t *n; - /* Position in the regexp pattern after a parse function returns. */ - const char *s; - /* The first character of the last subexpression parsed. */ - const char *start; - /* Current submatch ID. */ - int submatch_id; - /* Current position (number of literal). */ - int position; - /* The highest back reference or -1 if none seen so far. */ - int max_backref; - /* Compilation flags. */ - int cflags; -} tre_parse_ctx_t; - -/* Some macros for expanding \w, \s, etc. */ -static const struct { - char c; - const char *expansion; -} tre_macros[] = { - {'t', "\t"}, {'n', "\n"}, {'r', "\r"}, - {'f', "\f"}, {'a', "\a"}, {'e', "\033"}, - {'w', "[[:alnum:]_]"}, {'W', "[^[:alnum:]_]"}, {'s', "[[:space:]]"}, - {'S', "[^[:space:]]"}, {'d', "[[:digit:]]"}, {'D', "[^[:digit:]]"}, - { 0, 0 } -}; - -/* Expands a macro delimited by `regex' and `regex_end' to `buf', which - must have at least `len' items. Sets buf[0] to zero if the there - is no match in `tre_macros'. */ -static const char *tre_expand_macro(const char *s) -{ - int i; - for (i = 0; tre_macros[i].c && tre_macros[i].c != *s; i++); - return tre_macros[i].expansion; -} - -static int -tre_compare_lit(const void *a, const void *b) -{ - const tre_literal_t *const *la = a; - const tre_literal_t *const *lb = b; - /* assumes the range of valid code_min is < INT_MAX */ - return la[0]->code_min - lb[0]->code_min; -} - -struct literals { - tre_mem_t mem; - tre_literal_t **a; - int len; - int cap; -}; - -static tre_literal_t *tre_new_lit(struct literals *p) -{ - tre_literal_t **a; - if (p->len >= p->cap) { - if (p->cap >= 1<<15) - return 0; - p->cap *= 2; - a = xrealloc(p->a, p->cap * sizeof *p->a); - if (!a) - return 0; - p->a = a; - } - a = p->a + p->len++; - *a = tre_mem_calloc(p->mem, sizeof **a); - return *a; -} - -static int add_icase_literals(struct literals *ls, int min, int max) -{ - tre_literal_t *lit; - int b, e, c; - for (c=min; c<=max; ) { - /* assumes islower(c) and isupper(c) are exclusive - and toupper(c)!=c if islower(c). - multiple opposite case characters are not supported */ - if (tre_islower(c)) { - b = e = tre_toupper(c); - for (c++, e++; c<=max; c++, e++) - if (tre_toupper(c) != e) break; - } else if (tre_isupper(c)) { - b = e = tre_tolower(c); - for (c++, e++; c<=max; c++, e++) - if (tre_tolower(c) != e) break; - } else { - c++; - continue; - } - lit = tre_new_lit(ls); - if (!lit) - return -1; - lit->code_min = b; - lit->code_max = e-1; - lit->position = -1; - } - return 0; -} - - -/* Maximum number of character classes in a negated bracket expression. */ -#define MAX_NEG_CLASSES 64 - -struct neg { - int negate; - int len; - tre_ctype_t a[MAX_NEG_CLASSES]; -}; - -// TODO: parse bracket into a set of non-overlapping [lo,hi] ranges - -/* -bracket grammar: -Bracket = '[' List ']' | '[^' List ']' -List = Term | List Term -Term = Char | Range | Chclass | Eqclass -Range = Char '-' Char | Char '-' '-' -Char = Coll | coll_single -Meta = ']' | '-' -Coll = '[.' coll_single '.]' | '[.' coll_multi '.]' | '[.' Meta '.]' -Eqclass = '[=' coll_single '=]' | '[=' coll_multi '=]' -Chclass = '[:' class ':]' - -coll_single is a single char collating element but it can be - '-' only at the beginning or end of a List and - ']' only at the beginning of a List and - '^' anywhere except after the openning '[' -*/ - -static reg_errcode_t parse_bracket_terms(tre_parse_ctx_t *ctx, const char *s, struct literals *ls, struct neg *neg) -{ - const char *start = s; - tre_ctype_t class; - int min, max; - wchar_t wc; - int len; - - for (;;) { - class = 0; - len = mbtowc(&wc, s, -1); - if (len <= 0) - return *s ? REG_BADPAT : REG_EBRACK; - if (*s == ']' && s != start) { - ctx->s = s+1; - return REG_OK; - } - if (*s == '-' && s != start && s[1] != ']' && - /* extension: [a-z--@] is accepted as [a-z]|[--@] */ - (s[1] != '-' || s[2] == ']')) - return REG_ERANGE; - if (*s == '[' && (s[1] == '.' || s[1] == '=')) - /* collating symbols and equivalence classes are not supported */ - return REG_ECOLLATE; - if (*s == '[' && s[1] == ':') { - char tmp[CHARCLASS_NAME_MAX+1]; - s += 2; - for (len=0; len < CHARCLASS_NAME_MAX && s[len]; len++) { - if (s[len] == ':') { - memcpy(tmp, s, len); - tmp[len] = 0; - class = tre_ctype(tmp); - break; - } - } - if (!class || s[len+1] != ']') - return REG_ECTYPE; - min = 0; - max = TRE_CHAR_MAX; - s += len+2; - } else { - min = max = wc; - s += len; - if (*s == '-' && s[1] != ']') { - s++; - len = mbtowc(&wc, s, -1); - max = wc; - /* XXX - Should use collation order instead of - encoding values in character ranges. */ - if (len <= 0 || min > max) - return REG_ERANGE; - s += len; - } - } - - if (class && neg->negate) { - if (neg->len >= MAX_NEG_CLASSES) - return REG_ESPACE; - neg->a[neg->len++] = class; - } else { - tre_literal_t *lit = tre_new_lit(ls); - if (!lit) - return REG_ESPACE; - lit->code_min = min; - lit->code_max = max; - lit->class = class; - lit->position = -1; - - /* Add opposite-case codepoints if REG_ICASE is present. - It seems that POSIX requires that bracket negation - should happen before case-folding, but most practical - implementations do it the other way around. Changing - the order would need efficient representation of - case-fold ranges and bracket range sets even with - simple patterns so this is ok for now. */ - if (ctx->cflags & REG_ICASE && !class) - if (add_icase_literals(ls, min, max)) - return REG_ESPACE; - } - } -} - -static reg_errcode_t parse_bracket(tre_parse_ctx_t *ctx, const char *s) -{ - int i, max, min, negmax, negmin; - tre_ast_node_t *node = 0, *n; - tre_ctype_t *nc = 0; - tre_literal_t *lit; - struct literals ls; - struct neg neg; - reg_errcode_t err; - - ls.mem = ctx->mem; - ls.len = 0; - ls.cap = 32; - ls.a = xmalloc(ls.cap * sizeof *ls.a); - if (!ls.a) - return REG_ESPACE; - neg.len = 0; - neg.negate = *s == '^'; - if (neg.negate) - s++; - - err = parse_bracket_terms(ctx, s, &ls, &neg); - if (err != REG_OK) - goto parse_bracket_done; - - if (neg.negate) { - /* - * With REG_NEWLINE, POSIX requires that newlines are not matched by - * any form of a non-matching list. - */ - if (ctx->cflags & REG_NEWLINE) { - lit = tre_new_lit(&ls); - if (!lit) { - err = REG_ESPACE; - goto parse_bracket_done; - } - lit->code_min = '\n'; - lit->code_max = '\n'; - lit->position = -1; - } - /* Sort the array if we need to negate it. */ - qsort(ls.a, ls.len, sizeof *ls.a, tre_compare_lit); - /* extra lit for the last negated range */ - lit = tre_new_lit(&ls); - if (!lit) { - err = REG_ESPACE; - goto parse_bracket_done; - } - lit->code_min = TRE_CHAR_MAX+1; - lit->code_max = TRE_CHAR_MAX+1; - lit->position = -1; - /* negated classes */ - if (neg.len) { - nc = tre_mem_alloc(ctx->mem, (neg.len+1)*sizeof *neg.a); - if (!nc) { - err = REG_ESPACE; - goto parse_bracket_done; - } - memcpy(nc, neg.a, neg.len*sizeof *neg.a); - nc[neg.len] = 0; - } - } - - /* Build a union of the items in the array, negated if necessary. */ - negmax = negmin = 0; - for (i = 0; i < ls.len; i++) { - lit = ls.a[i]; - min = lit->code_min; - max = lit->code_max; - if (neg.negate) { - if (min <= negmin) { - /* Overlap. */ - negmin = MAX(max + 1, negmin); - continue; - } - negmax = min - 1; - lit->code_min = negmin; - lit->code_max = negmax; - negmin = max + 1; - } - lit->position = ctx->position; - lit->neg_classes = nc; - n = tre_ast_new_node(ctx->mem, LITERAL, lit); - node = tre_ast_new_union(ctx->mem, node, n); - if (!node) { - err = REG_ESPACE; - break; - } - } - -parse_bracket_done: - xfree(ls.a); - ctx->position++; - ctx->n = node; - return err; -} - -static const char *parse_dup_count(const char *s, int *n) -{ - *n = -1; - if (!isdigit(*s)) - return s; - *n = 0; - for (;;) { - *n = 10 * *n + (*s - '0'); - s++; - if (!isdigit(*s) || *n > RE_DUP_MAX) - break; - } - return s; -} - -static const char *parse_dup(const char *s, int ere, int *pmin, int *pmax) -{ - int min, max; - - s = parse_dup_count(s, &min); - if (*s == ',') - s = parse_dup_count(s+1, &max); - else - max = min; - - if ( - (max < min && max >= 0) || - max > RE_DUP_MAX || - min > RE_DUP_MAX || - min < 0 || - (!ere && *s++ != '\\') || - *s++ != '}' - ) - return 0; - *pmin = min; - *pmax = max; - return s; -} - -static int hexval(unsigned c) -{ - if (c-'0'<10) return c-'0'; - c |= 32; - if (c-'a'<6) return c-'a'+10; - return -1; -} - -static reg_errcode_t marksub(tre_parse_ctx_t *ctx, tre_ast_node_t *node, int subid) -{ - if (node->submatch_id >= 0) { - tre_ast_node_t *n = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1); - if (!n) - return REG_ESPACE; - n = tre_ast_new_catenation(ctx->mem, n, node); - if (!n) - return REG_ESPACE; - n->num_submatches = node->num_submatches; - node = n; - } - node->submatch_id = subid; - node->num_submatches++; - ctx->n = node; - return REG_OK; -} - -/* -BRE grammar: -Regex = Branch | '^' | '$' | '^$' | '^' Branch | Branch '$' | '^' Branch '$' -Branch = Atom | Branch Atom -Atom = char | quoted_char | '.' | Bracket | Atom Dup | '\(' Branch '\)' | back_ref -Dup = '*' | '\{' Count '\}' | '\{' Count ',\}' | '\{' Count ',' Count '\}' - -(leading ^ and trailing $ in a sub expr may be an anchor or literal as well) - -ERE grammar: -Regex = Branch | Regex '|' Branch -Branch = Atom | Branch Atom -Atom = char | quoted_char | '.' | Bracket | Atom Dup | '(' Regex ')' | '^' | '$' -Dup = '*' | '+' | '?' | '{' Count '}' | '{' Count ',}' | '{' Count ',' Count '}' - -(a*+?, ^*, $+, \X, {, (|a) are unspecified) -*/ - -static reg_errcode_t parse_atom(tre_parse_ctx_t *ctx, const char *s) -{ - int len, ere = ctx->cflags & REG_EXTENDED; - const char *p; - tre_ast_node_t *node; - wchar_t wc; - switch (*s) { - case '[': - return parse_bracket(ctx, s+1); - case '\\': - p = tre_expand_macro(s+1); - if (p) { - /* assume \X expansion is a single atom */ - reg_errcode_t err = parse_atom(ctx, p); - ctx->s = s+2; - return err; - } - /* extensions: \b, \B, \<, \>, \xHH \x{HHHH} */ - switch (*++s) { - case 0: - return REG_EESCAPE; - case 'b': - node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_WB, -1); - break; - case 'B': - node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_WB_NEG, -1); - break; - case '<': - node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_BOW, -1); - break; - case '>': - node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_EOW, -1); - break; - case 'x': - s++; - int i, v = 0, c; - len = 2; - if (*s == '{') { - len = 8; - s++; - } - for (i=0; i<len && v<0x110000; i++) { - c = hexval(s[i]); - if (c < 0) break; - v = 16*v + c; - } - s += i; - if (len == 8) { - if (*s != '}') - return REG_EBRACE; - s++; - } - node = tre_ast_new_literal(ctx->mem, v, v, ctx->position++); - s--; - break; - case '{': - case '+': - case '?': - /* extension: treat \+, \? as repetitions in BRE */ - /* reject repetitions after empty expression in BRE */ - if (!ere) - return REG_BADRPT; - case '|': - /* extension: treat \| as alternation in BRE */ - if (!ere) { - node = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1); - s--; - goto end; - } - /* fallthrough */ - default: - if (!ere && (unsigned)*s-'1' < 9) { - /* back reference */ - int val = *s - '0'; - node = tre_ast_new_literal(ctx->mem, BACKREF, val, ctx->position++); - ctx->max_backref = MAX(val, ctx->max_backref); - } else { - /* extension: accept unknown escaped char - as a literal */ - goto parse_literal; - } - } - s++; - break; - case '.': - if (ctx->cflags & REG_NEWLINE) { - tre_ast_node_t *tmp1, *tmp2; - tmp1 = tre_ast_new_literal(ctx->mem, 0, '\n'-1, ctx->position++); - tmp2 = tre_ast_new_literal(ctx->mem, '\n'+1, TRE_CHAR_MAX, ctx->position++); - if (tmp1 && tmp2) - node = tre_ast_new_union(ctx->mem, tmp1, tmp2); - else - node = 0; - } else { - node = tre_ast_new_literal(ctx->mem, 0, TRE_CHAR_MAX, ctx->position++); - } - s++; - break; - case '^': - /* '^' has a special meaning everywhere in EREs, and at beginning of BRE. */ - if (!ere && s != ctx->start) - goto parse_literal; - node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_BOL, -1); - s++; - break; - case '$': - /* '$' is special everywhere in EREs, and at the end of a BRE subexpression. */ - if (!ere && s[1] && (s[1]!='\\'|| (s[2]!=')' && s[2]!='|'))) - goto parse_literal; - node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_EOL, -1); - s++; - break; - case '*': - case '{': - case '+': - case '?': - /* reject repetitions after empty expression in ERE */ - if (ere) - return REG_BADRPT; - case '|': - if (!ere) - goto parse_literal; - case 0: - node = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1); - break; - default: -parse_literal: - len = mbtowc(&wc, s, -1); - if (len < 0) - return REG_BADPAT; - if (ctx->cflags & REG_ICASE && (tre_isupper(wc) || tre_islower(wc))) { - tre_ast_node_t *tmp1, *tmp2; - /* multiple opposite case characters are not supported */ - tmp1 = tre_ast_new_literal(ctx->mem, tre_toupper(wc), tre_toupper(wc), ctx->position); - tmp2 = tre_ast_new_literal(ctx->mem, tre_tolower(wc), tre_tolower(wc), ctx->position); - if (tmp1 && tmp2) - node = tre_ast_new_union(ctx->mem, tmp1, tmp2); - else - node = 0; - } else { - node = tre_ast_new_literal(ctx->mem, wc, wc, ctx->position); - } - ctx->position++; - s += len; - break; - } -end: - if (!node) - return REG_ESPACE; - ctx->n = node; - ctx->s = s; - return REG_OK; -} - -#define PUSHPTR(err, s, v) do { \ - if ((err = tre_stack_push_voidptr(s, v)) != REG_OK) \ - return err; \ -} while(0) - -#define PUSHINT(err, s, v) do { \ - if ((err = tre_stack_push_int(s, v)) != REG_OK) \ - return err; \ -} while(0) - -static reg_errcode_t tre_parse(tre_parse_ctx_t *ctx) -{ - tre_ast_node_t *nbranch=0, *nunion=0; - int ere = ctx->cflags & REG_EXTENDED; - const char *s = ctx->start; - int subid = 0; - int depth = 0; - reg_errcode_t err; - tre_stack_t *stack = ctx->stack; - - PUSHINT(err, stack, subid++); - for (;;) { - if ((!ere && *s == '\\' && s[1] == '(') || - (ere && *s == '(')) { - PUSHPTR(err, stack, nunion); - PUSHPTR(err, stack, nbranch); - PUSHINT(err, stack, subid++); - s++; - if (!ere) - s++; - depth++; - nbranch = nunion = 0; - ctx->start = s; - continue; - } - if ((!ere && *s == '\\' && s[1] == ')') || - (ere && *s == ')' && depth)) { - ctx->n = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1); - if (!ctx->n) - return REG_ESPACE; - } else { - err = parse_atom(ctx, s); - if (err != REG_OK) - return err; - s = ctx->s; - } - - parse_iter: - for (;;) { - int min, max; - - if (*s!='\\' && *s!='*') { - if (!ere) - break; - if (*s!='+' && *s!='?' && *s!='{') - break; - } - if (*s=='\\' && ere) - break; - /* extension: treat \+, \? as repetitions in BRE */ - if (*s=='\\' && s[1]!='+' && s[1]!='?' && s[1]!='{') - break; - if (*s=='\\') - s++; - - /* handle ^* at the start of a BRE. */ - if (!ere && s==ctx->start+1 && s[-1]=='^') - break; - - /* extension: multiple consecutive *+?{,} is unspecified, - but (a+)+ has to be supported so accepting a++ makes - sense, note however that the RE_DUP_MAX limit can be - circumvented: (a{255}){255} uses a lot of memory.. */ - if (*s=='{') { - s = parse_dup(s+1, ere, &min, &max); - if (!s) - return REG_BADBR; - } else { - min=0; - max=-1; - if (*s == '+') - min = 1; - if (*s == '?') - max = 1; - s++; - } - if (max == 0) - ctx->n = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1); - else - ctx->n = tre_ast_new_iter(ctx->mem, ctx->n, min, max, 0); - if (!ctx->n) - return REG_ESPACE; - } - - nbranch = tre_ast_new_catenation(ctx->mem, nbranch, ctx->n); - if ((ere && *s == '|') || - (ere && *s == ')' && depth) || - (!ere && *s == '\\' && s[1] == ')') || - /* extension: treat \| as alternation in BRE */ - (!ere && *s == '\\' && s[1] == '|') || - !*s) { - /* extension: empty branch is unspecified (), (|a), (a|) - here they are not rejected but match on empty string */ - int c = *s; - nunion = tre_ast_new_union(ctx->mem, nunion, nbranch); - nbranch = 0; - - if (c == '\\' && s[1] == '|') { - s+=2; - ctx->start = s; - } else if (c == '|') { - s++; - ctx->start = s; - } else { - if (c == '\\') { - if (!depth) return REG_EPAREN; - s+=2; - } else if (c == ')') - s++; - depth--; - err = marksub(ctx, nunion, tre_stack_pop_int(stack)); - if (err != REG_OK) - return err; - if (!c && depth<0) { - ctx->submatch_id = subid; - return REG_OK; - } - if (!c || depth<0) - return REG_EPAREN; - nbranch = tre_stack_pop_voidptr(stack); - nunion = tre_stack_pop_voidptr(stack); - goto parse_iter; - } - } - } -} - - -/*********************************************************************** - from tre-compile.c -***********************************************************************/ - - -/* - TODO: - - Fix tre_ast_to_tnfa() to recurse using a stack instead of recursive - function calls. -*/ - -/* - Algorithms to setup tags so that submatch addressing can be done. -*/ - - -/* Inserts a catenation node to the root of the tree given in `node'. - As the left child a new tag with number `tag_id' to `node' is added, - and the right child is the old root. */ -static reg_errcode_t -tre_add_tag_left(tre_mem_t mem, tre_ast_node_t *node, int tag_id) -{ - tre_catenation_t *c; - - c = tre_mem_alloc(mem, sizeof(*c)); - if (c == NULL) - return REG_ESPACE; - c->left = tre_ast_new_literal(mem, TAG, tag_id, -1); - if (c->left == NULL) - return REG_ESPACE; - c->right = tre_mem_alloc(mem, sizeof(tre_ast_node_t)); - if (c->right == NULL) - return REG_ESPACE; - - c->right->obj = node->obj; - c->right->type = node->type; - c->right->nullable = -1; - c->right->submatch_id = -1; - c->right->firstpos = NULL; - c->right->lastpos = NULL; - c->right->num_tags = 0; - c->right->num_submatches = 0; - node->obj = c; - node->type = CATENATION; - return REG_OK; -} - -/* Inserts a catenation node to the root of the tree given in `node'. - As the right child a new tag with number `tag_id' to `node' is added, - and the left child is the old root. */ -static reg_errcode_t -tre_add_tag_right(tre_mem_t mem, tre_ast_node_t *node, int tag_id) -{ - tre_catenation_t *c; - - c = tre_mem_alloc(mem, sizeof(*c)); - if (c == NULL) - return REG_ESPACE; - c->right = tre_ast_new_literal(mem, TAG, tag_id, -1); - if (c->right == NULL) - return REG_ESPACE; - c->left = tre_mem_alloc(mem, sizeof(tre_ast_node_t)); - if (c->left == NULL) - return REG_ESPACE; - - c->left->obj = node->obj; - c->left->type = node->type; - c->left->nullable = -1; - c->left->submatch_id = -1; - c->left->firstpos = NULL; - c->left->lastpos = NULL; - c->left->num_tags = 0; - c->left->num_submatches = 0; - node->obj = c; - node->type = CATENATION; - return REG_OK; -} - -typedef enum { - ADDTAGS_RECURSE, - ADDTAGS_AFTER_ITERATION, - ADDTAGS_AFTER_UNION_LEFT, - ADDTAGS_AFTER_UNION_RIGHT, - ADDTAGS_AFTER_CAT_LEFT, - ADDTAGS_AFTER_CAT_RIGHT, - ADDTAGS_SET_SUBMATCH_END -} tre_addtags_symbol_t; - - -typedef struct { - int tag; - int next_tag; -} tre_tag_states_t; - - -/* Go through `regset' and set submatch data for submatches that are - using this tag. */ -static void -tre_purge_regset(int *regset, tre_tnfa_t *tnfa, int tag) -{ - int i; - - for (i = 0; regset[i] >= 0; i++) - { - int id = regset[i] / 2; - int start = !(regset[i] % 2); - if (start) - tnfa->submatch_data[id].so_tag = tag; - else - tnfa->submatch_data[id].eo_tag = tag; - } - regset[0] = -1; -} - - -/* Adds tags to appropriate locations in the parse tree in `tree', so that - subexpressions marked for submatch addressing can be traced. */ -static reg_errcode_t -tre_add_tags(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *tree, - tre_tnfa_t *tnfa) -{ - reg_errcode_t status = REG_OK; - tre_addtags_symbol_t symbol; - tre_ast_node_t *node = tree; /* Tree node we are currently looking at. */ - int bottom = tre_stack_num_objects(stack); - /* True for first pass (counting number of needed tags) */ - int first_pass = (mem == NULL || tnfa == NULL); - int *regset, *orig_regset; - int num_tags = 0; /* Total number of tags. */ - int num_minimals = 0; /* Number of special minimal tags. */ - int tag = 0; /* The tag that is to be added next. */ - int next_tag = 1; /* Next tag to use after this one. */ - int *parents; /* Stack of submatches the current submatch is - contained in. */ - int minimal_tag = -1; /* Tag that marks the beginning of a minimal match. */ - tre_tag_states_t *saved_states; - - tre_tag_direction_t direction = TRE_TAG_MINIMIZE; - if (!first_pass) - { - tnfa->end_tag = 0; - tnfa->minimal_tags[0] = -1; - } - - regset = xmalloc(sizeof(*regset) * ((tnfa->num_submatches + 1) * 2)); - if (regset == NULL) - return REG_ESPACE; - regset[0] = -1; - orig_regset = regset; - - parents = xmalloc(sizeof(*parents) * (tnfa->num_submatches + 1)); - if (parents == NULL) - { - xfree(regset); - return REG_ESPACE; - } - parents[0] = -1; - - saved_states = xmalloc(sizeof(*saved_states) * (tnfa->num_submatches + 1)); - if (saved_states == NULL) - { - xfree(regset); - xfree(parents); - return REG_ESPACE; - } - else - { - unsigned int i; - for (i = 0; i <= tnfa->num_submatches; i++) - saved_states[i].tag = -1; - } - - STACK_PUSH(stack, voidptr, node); - STACK_PUSH(stack, int, ADDTAGS_RECURSE); - - while (tre_stack_num_objects(stack) > bottom) - { - if (status != REG_OK) - break; - - symbol = (tre_addtags_symbol_t)tre_stack_pop_int(stack); - switch (symbol) - { - - case ADDTAGS_SET_SUBMATCH_END: - { - int id = tre_stack_pop_int(stack); - int i; - - /* Add end of this submatch to regset. */ - for (i = 0; regset[i] >= 0; i++); - regset[i] = id * 2 + 1; - regset[i + 1] = -1; - - /* Pop this submatch from the parents stack. */ - for (i = 0; parents[i] >= 0; i++); - parents[i - 1] = -1; - break; - } - - case ADDTAGS_RECURSE: - node = tre_stack_pop_voidptr(stack); - - if (node->submatch_id >= 0) - { - int id = node->submatch_id; - int i; - - - /* Add start of this submatch to regset. */ - for (i = 0; regset[i] >= 0; i++); - regset[i] = id * 2; - regset[i + 1] = -1; - - if (!first_pass) - { - for (i = 0; parents[i] >= 0; i++); - tnfa->submatch_data[id].parents = NULL; - if (i > 0) - { - int *p = xmalloc(sizeof(*p) * (i + 1)); - if (p == NULL) - { - status = REG_ESPACE; - break; - } - assert(tnfa->submatch_data[id].parents == NULL); - tnfa->submatch_data[id].parents = p; - for (i = 0; parents[i] >= 0; i++) - p[i] = parents[i]; - p[i] = -1; - } - } - - /* Add end of this submatch to regset after processing this - node. */ - STACK_PUSHX(stack, int, node->submatch_id); - STACK_PUSHX(stack, int, ADDTAGS_SET_SUBMATCH_END); - } - - switch (node->type) - { - case LITERAL: - { - tre_literal_t *lit = node->obj; - - if (!IS_SPECIAL(lit) || IS_BACKREF(lit)) - { - int i; - if (regset[0] >= 0) - { - /* Regset is not empty, so add a tag before the - literal or backref. */ - if (!first_pass) - { - status = tre_add_tag_left(mem, node, tag); - tnfa->tag_directions[tag] = direction; - if (minimal_tag >= 0) - { - for (i = 0; tnfa->minimal_tags[i] >= 0; i++); - tnfa->minimal_tags[i] = tag; - tnfa->minimal_tags[i + 1] = minimal_tag; - tnfa->minimal_tags[i + 2] = -1; - minimal_tag = -1; - num_minimals++; - } - tre_purge_regset(regset, tnfa, tag); - } - else - { - node->num_tags = 1; - } - - regset[0] = -1; - tag = next_tag; - num_tags++; - next_tag++; - } - } - else - { - assert(!IS_TAG(lit)); - } - break; - } - case CATENATION: - { - tre_catenation_t *cat = node->obj; - tre_ast_node_t *left = cat->left; - tre_ast_node_t *right = cat->right; - int reserved_tag = -1; - - - /* After processing right child. */ - STACK_PUSHX(stack, voidptr, node); - STACK_PUSHX(stack, int, ADDTAGS_AFTER_CAT_RIGHT); - - /* Process right child. */ - STACK_PUSHX(stack, voidptr, right); - STACK_PUSHX(stack, int, ADDTAGS_RECURSE); - - /* After processing left child. */ - STACK_PUSHX(stack, int, next_tag + left->num_tags); - if (left->num_tags > 0 && right->num_tags > 0) - { - /* Reserve the next tag to the right child. */ - reserved_tag = next_tag; - next_tag++; - } - STACK_PUSHX(stack, int, reserved_tag); - STACK_PUSHX(stack, int, ADDTAGS_AFTER_CAT_LEFT); - - /* Process left child. */ - STACK_PUSHX(stack, voidptr, left); - STACK_PUSHX(stack, int, ADDTAGS_RECURSE); - - } - break; - case ITERATION: - { - tre_iteration_t *iter = node->obj; - - if (first_pass) - { - STACK_PUSHX(stack, int, regset[0] >= 0 || iter->minimal); - } - else - { - STACK_PUSHX(stack, int, tag); - STACK_PUSHX(stack, int, iter->minimal); - } - STACK_PUSHX(stack, voidptr, node); - STACK_PUSHX(stack, int, ADDTAGS_AFTER_ITERATION); - - STACK_PUSHX(stack, voidptr, iter->arg); - STACK_PUSHX(stack, int, ADDTAGS_RECURSE); - - /* Regset is not empty, so add a tag here. */ - if (regset[0] >= 0 || iter->minimal) - { - if (!first_pass) - { - int i; - status = tre_add_tag_left(mem, node, tag); - if (iter->minimal) - tnfa->tag_directions[tag] = TRE_TAG_MAXIMIZE; - else - tnfa->tag_directions[tag] = direction; - if (minimal_tag >= 0) - { - for (i = 0; tnfa->minimal_tags[i] >= 0; i++); - tnfa->minimal_tags[i] = tag; - tnfa->minimal_tags[i + 1] = minimal_tag; - tnfa->minimal_tags[i + 2] = -1; - minimal_tag = -1; - num_minimals++; - } - tre_purge_regset(regset, tnfa, tag); - } - - regset[0] = -1; - tag = next_tag; - num_tags++; - next_tag++; - } - direction = TRE_TAG_MINIMIZE; - } - break; - case UNION: - { - tre_union_t *uni = node->obj; - tre_ast_node_t *left = uni->left; - tre_ast_node_t *right = uni->right; - int left_tag; - int right_tag; - - if (regset[0] >= 0) - { - left_tag = next_tag; - right_tag = next_tag + 1; - } - else - { - left_tag = tag; - right_tag = next_tag; - } - - /* After processing right child. */ - STACK_PUSHX(stack, int, right_tag); - STACK_PUSHX(stack, int, left_tag); - STACK_PUSHX(stack, voidptr, regset); - STACK_PUSHX(stack, int, regset[0] >= 0); - STACK_PUSHX(stack, voidptr, node); - STACK_PUSHX(stack, voidptr, right); - STACK_PUSHX(stack, voidptr, left); - STACK_PUSHX(stack, int, ADDTAGS_AFTER_UNION_RIGHT); - - /* Process right child. */ - STACK_PUSHX(stack, voidptr, right); - STACK_PUSHX(stack, int, ADDTAGS_RECURSE); - - /* After processing left child. */ - STACK_PUSHX(stack, int, ADDTAGS_AFTER_UNION_LEFT); - - /* Process left child. */ - STACK_PUSHX(stack, voidptr, left); - STACK_PUSHX(stack, int, ADDTAGS_RECURSE); - - /* Regset is not empty, so add a tag here. */ - if (regset[0] >= 0) - { - if (!first_pass) - { - int i; - status = tre_add_tag_left(mem, node, tag); - tnfa->tag_directions[tag] = direction; - if (minimal_tag >= 0) - { - for (i = 0; tnfa->minimal_tags[i] >= 0; i++); - tnfa->minimal_tags[i] = tag; - tnfa->minimal_tags[i + 1] = minimal_tag; - tnfa->minimal_tags[i + 2] = -1; - minimal_tag = -1; - num_minimals++; - } - tre_purge_regset(regset, tnfa, tag); - } - - regset[0] = -1; - tag = next_tag; - num_tags++; - next_tag++; - } - - if (node->num_submatches > 0) - { - /* The next two tags are reserved for markers. */ - next_tag++; - tag = next_tag; - next_tag++; - } - - break; - } - } - - if (node->submatch_id >= 0) - { - int i; - /* Push this submatch on the parents stack. */ - for (i = 0; parents[i] >= 0; i++); - parents[i] = node->submatch_id; - parents[i + 1] = -1; - } - - break; /* end case: ADDTAGS_RECURSE */ - - case ADDTAGS_AFTER_ITERATION: - { - int minimal = 0; - int enter_tag; - node = tre_stack_pop_voidptr(stack); - if (first_pass) - { - node->num_tags = ((tre_iteration_t *)node->obj)->arg->num_tags - + tre_stack_pop_int(stack); - minimal_tag = -1; - } - else - { - minimal = tre_stack_pop_int(stack); - enter_tag = tre_stack_pop_int(stack); - if (minimal) - minimal_tag = enter_tag; - } - - if (!first_pass) - { - if (minimal) - direction = TRE_TAG_MINIMIZE; - else - direction = TRE_TAG_MAXIMIZE; - } - break; - } - - case ADDTAGS_AFTER_CAT_LEFT: - { - int new_tag = tre_stack_pop_int(stack); - next_tag = tre_stack_pop_int(stack); - if (new_tag >= 0) - { - tag = new_tag; - } - break; - } - - case ADDTAGS_AFTER_CAT_RIGHT: - node = tre_stack_pop_voidptr(stack); - if (first_pass) - node->num_tags = ((tre_catenation_t *)node->obj)->left->num_tags - + ((tre_catenation_t *)node->obj)->right->num_tags; - break; - - case ADDTAGS_AFTER_UNION_LEFT: - /* Lift the bottom of the `regset' array so that when processing - the right operand the items currently in the array are - invisible. The original bottom was saved at ADDTAGS_UNION and - will be restored at ADDTAGS_AFTER_UNION_RIGHT below. */ - while (*regset >= 0) - regset++; - break; - - case ADDTAGS_AFTER_UNION_RIGHT: - { - int added_tags, tag_left, tag_right; - tre_ast_node_t *left = tre_stack_pop_voidptr(stack); - tre_ast_node_t *right = tre_stack_pop_voidptr(stack); - node = tre_stack_pop_voidptr(stack); - added_tags = tre_stack_pop_int(stack); - if (first_pass) - { - node->num_tags = ((tre_union_t *)node->obj)->left->num_tags - + ((tre_union_t *)node->obj)->right->num_tags + added_tags - + ((node->num_submatches > 0) ? 2 : 0); - } - regset = tre_stack_pop_voidptr(stack); - tag_left = tre_stack_pop_int(stack); - tag_right = tre_stack_pop_int(stack); - - /* Add tags after both children, the left child gets a smaller - tag than the right child. This guarantees that we prefer - the left child over the right child. */ - /* XXX - This is not always necessary (if the children have - tags which must be seen for every match of that child). */ - /* XXX - Check if this is the only place where tre_add_tag_right - is used. If so, use tre_add_tag_left (putting the tag before - the child as opposed after the child) and throw away - tre_add_tag_right. */ - if (node->num_submatches > 0) - { - if (!first_pass) - { - status = tre_add_tag_right(mem, left, tag_left); - tnfa->tag_directions[tag_left] = TRE_TAG_MAXIMIZE; - if (status == REG_OK) - status = tre_add_tag_right(mem, right, tag_right); - tnfa->tag_directions[tag_right] = TRE_TAG_MAXIMIZE; - } - num_tags += 2; - } - direction = TRE_TAG_MAXIMIZE; - break; - } - - default: - assert(0); - break; - - } /* end switch(symbol) */ - } /* end while(tre_stack_num_objects(stack) > bottom) */ - - if (!first_pass) - tre_purge_regset(regset, tnfa, tag); - - if (!first_pass && minimal_tag >= 0) - { - int i; - for (i = 0; tnfa->minimal_tags[i] >= 0; i++); - tnfa->minimal_tags[i] = tag; - tnfa->minimal_tags[i + 1] = minimal_tag; - tnfa->minimal_tags[i + 2] = -1; - minimal_tag = -1; - num_minimals++; - } - - assert(tree->num_tags == num_tags); - tnfa->end_tag = num_tags; - tnfa->num_tags = num_tags; - tnfa->num_minimals = num_minimals; - xfree(orig_regset); - xfree(parents); - xfree(saved_states); - return status; -} - - - -/* - AST to TNFA compilation routines. -*/ - -typedef enum { - COPY_RECURSE, - COPY_SET_RESULT_PTR -} tre_copyast_symbol_t; - -/* Flags for tre_copy_ast(). */ -#define COPY_REMOVE_TAGS 1 -#define COPY_MAXIMIZE_FIRST_TAG 2 - -static reg_errcode_t -tre_copy_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast, - int flags, int *pos_add, tre_tag_direction_t *tag_directions, - tre_ast_node_t **copy, int *max_pos) -{ - reg_errcode_t status = REG_OK; - int bottom = tre_stack_num_objects(stack); - int num_copied = 0; - int first_tag = 1; - tre_ast_node_t **result = copy; - tre_copyast_symbol_t symbol; - - STACK_PUSH(stack, voidptr, ast); - STACK_PUSH(stack, int, COPY_RECURSE); - - while (status == REG_OK && tre_stack_num_objects(stack) > bottom) - { - tre_ast_node_t *node; - if (status != REG_OK) - break; - - symbol = (tre_copyast_symbol_t)tre_stack_pop_int(stack); - switch (symbol) - { - case COPY_SET_RESULT_PTR: - result = tre_stack_pop_voidptr(stack); - break; - case COPY_RECURSE: - node = tre_stack_pop_voidptr(stack); - switch (node->type) - { - case LITERAL: - { - tre_literal_t *lit = node->obj; - int pos = lit->position; - int min = lit->code_min; - int max = lit->code_max; - if (!IS_SPECIAL(lit) || IS_BACKREF(lit)) - { - /* XXX - e.g. [ab] has only one position but two - nodes, so we are creating holes in the state space - here. Not fatal, just wastes memory. */ - pos += *pos_add; - num_copied++; - } - else if (IS_TAG(lit) && (flags & COPY_REMOVE_TAGS)) - { - /* Change this tag to empty. */ - min = EMPTY; - max = pos = -1; - } - else if (IS_TAG(lit) && (flags & COPY_MAXIMIZE_FIRST_TAG) - && first_tag) - { - /* Maximize the first tag. */ - tag_directions[max] = TRE_TAG_MAXIMIZE; - first_tag = 0; - } - *result = tre_ast_new_literal(mem, min, max, pos); - if (*result == NULL) - status = REG_ESPACE; - else { - tre_literal_t *p = (*result)->obj; - p->class = lit->class; - p->neg_classes = lit->neg_classes; - } - - if (pos > *max_pos) - *max_pos = pos; - break; - } - case UNION: - { - tre_union_t *uni = node->obj; - tre_union_t *tmp; - *result = tre_ast_new_union(mem, uni->left, uni->right); - if (*result == NULL) - { - status = REG_ESPACE; - break; - } - tmp = (*result)->obj; - result = &tmp->left; - STACK_PUSHX(stack, voidptr, uni->right); - STACK_PUSHX(stack, int, COPY_RECURSE); - STACK_PUSHX(stack, voidptr, &tmp->right); - STACK_PUSHX(stack, int, COPY_SET_RESULT_PTR); - STACK_PUSHX(stack, voidptr, uni->left); - STACK_PUSHX(stack, int, COPY_RECURSE); - break; - } - case CATENATION: - { - tre_catenation_t *cat = node->obj; - tre_catenation_t *tmp; - *result = tre_ast_new_catenation(mem, cat->left, cat->right); - if (*result == NULL) - { - status = REG_ESPACE; - break; - } - tmp = (*result)->obj; - tmp->left = NULL; - tmp->right = NULL; - result = &tmp->left; - - STACK_PUSHX(stack, voidptr, cat->right); - STACK_PUSHX(stack, int, COPY_RECURSE); - STACK_PUSHX(stack, voidptr, &tmp->right); - STACK_PUSHX(stack, int, COPY_SET_RESULT_PTR); - STACK_PUSHX(stack, voidptr, cat->left); - STACK_PUSHX(stack, int, COPY_RECURSE); - break; - } - case ITERATION: - { - tre_iteration_t *iter = node->obj; - STACK_PUSHX(stack, voidptr, iter->arg); - STACK_PUSHX(stack, int, COPY_RECURSE); - *result = tre_ast_new_iter(mem, iter->arg, iter->min, - iter->max, iter->minimal); - if (*result == NULL) - { - status = REG_ESPACE; - break; - } - iter = (*result)->obj; - result = &iter->arg; - break; - } - default: - assert(0); - break; - } - break; - } - } - *pos_add += num_copied; - return status; -} - -typedef enum { - EXPAND_RECURSE, - EXPAND_AFTER_ITER -} tre_expand_ast_symbol_t; - -/* Expands each iteration node that has a finite nonzero minimum or maximum - iteration count to a catenated sequence of copies of the node. */ -static reg_errcode_t -tre_expand_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast, - int *position, tre_tag_direction_t *tag_directions) -{ - reg_errcode_t status = REG_OK; - int bottom = tre_stack_num_objects(stack); - int pos_add = 0; - int pos_add_total = 0; - int max_pos = 0; - int iter_depth = 0; - - STACK_PUSHR(stack, voidptr, ast); - STACK_PUSHR(stack, int, EXPAND_RECURSE); - while (status == REG_OK && tre_stack_num_objects(stack) > bottom) - { - tre_ast_node_t *node; - tre_expand_ast_symbol_t symbol; - - if (status != REG_OK) - break; - - symbol = (tre_expand_ast_symbol_t)tre_stack_pop_int(stack); - node = tre_stack_pop_voidptr(stack); - switch (symbol) - { - case EXPAND_RECURSE: - switch (node->type) - { - case LITERAL: - { - tre_literal_t *lit= node->obj; - if (!IS_SPECIAL(lit) || IS_BACKREF(lit)) - { - lit->position += pos_add; - if (lit->position > max_pos) - max_pos = lit->position; - } - break; - } - case UNION: - { - tre_union_t *uni = node->obj; - STACK_PUSHX(stack, voidptr, uni->right); - STACK_PUSHX(stack, int, EXPAND_RECURSE); - STACK_PUSHX(stack, voidptr, uni->left); - STACK_PUSHX(stack, int, EXPAND_RECURSE); - break; - } - case CATENATION: - { - tre_catenation_t *cat = node->obj; - STACK_PUSHX(stack, voidptr, cat->right); - STACK_PUSHX(stack, int, EXPAND_RECURSE); - STACK_PUSHX(stack, voidptr, cat->left); - STACK_PUSHX(stack, int, EXPAND_RECURSE); - break; - } - case ITERATION: - { - tre_iteration_t *iter = node->obj; - STACK_PUSHX(stack, int, pos_add); - STACK_PUSHX(stack, voidptr, node); - STACK_PUSHX(stack, int, EXPAND_AFTER_ITER); - STACK_PUSHX(stack, voidptr, iter->arg); - STACK_PUSHX(stack, int, EXPAND_RECURSE); - /* If we are going to expand this node at EXPAND_AFTER_ITER - then don't increase the `pos' fields of the nodes now, it - will get done when expanding. */ - if (iter->min > 1 || iter->max > 1) - pos_add = 0; - iter_depth++; - break; - } - default: - assert(0); - break; - } - break; - case EXPAND_AFTER_ITER: - { - tre_iteration_t *iter = node->obj; - int pos_add_last; - pos_add = tre_stack_pop_int(stack); - pos_add_last = pos_add; - if (iter->min > 1 || iter->max > 1) - { - tre_ast_node_t *seq1 = NULL, *seq2 = NULL; - int j; - int pos_add_save = pos_add; - - /* Create a catenated sequence of copies of the node. */ - for (j = 0; j < iter->min; j++) - { - tre_ast_node_t *copy; - /* Remove tags from all but the last copy. */ - int flags = ((j + 1 < iter->min) - ? COPY_REMOVE_TAGS - : COPY_MAXIMIZE_FIRST_TAG); - pos_add_save = pos_add; - status = tre_copy_ast(mem, stack, iter->arg, flags, - &pos_add, tag_directions, ©, - &max_pos); - if (status != REG_OK) - return status; - if (seq1 != NULL) - seq1 = tre_ast_new_catenation(mem, seq1, copy); - else - seq1 = copy; - if (seq1 == NULL) - return REG_ESPACE; - } - - if (iter->max == -1) - { - /* No upper limit. */ - pos_add_save = pos_add; - status = tre_copy_ast(mem, stack, iter->arg, 0, - &pos_add, NULL, &seq2, &max_pos); - if (status != REG_OK) - return status; - seq2 = tre_ast_new_iter(mem, seq2, 0, -1, 0); - if (seq2 == NULL) - return REG_ESPACE; - } - else - { - for (j = iter->min; j < iter->max; j++) - { - tre_ast_node_t *tmp, *copy; - pos_add_save = pos_add; - status = tre_copy_ast(mem, stack, iter->arg, 0, - &pos_add, NULL, ©, &max_pos); - if (status != REG_OK) - return status; - if (seq2 != NULL) - seq2 = tre_ast_new_catenation(mem, copy, seq2); - else - seq2 = copy; - if (seq2 == NULL) - return REG_ESPACE; - tmp = tre_ast_new_literal(mem, EMPTY, -1, -1); - if (tmp == NULL) - return REG_ESPACE; - seq2 = tre_ast_new_union(mem, tmp, seq2); - if (seq2 == NULL) - return REG_ESPACE; - } - } - - pos_add = pos_add_save; - if (seq1 == NULL) - seq1 = seq2; - else if (seq2 != NULL) - seq1 = tre_ast_new_catenation(mem, seq1, seq2); - if (seq1 == NULL) - return REG_ESPACE; - node->obj = seq1->obj; - node->type = seq1->type; - } - - iter_depth--; - pos_add_total += pos_add - pos_add_last; - if (iter_depth == 0) - pos_add = pos_add_total; - - break; - } - default: - assert(0); - break; - } - } - - *position += pos_add_total; - - /* `max_pos' should never be larger than `*position' if the above - code works, but just an extra safeguard let's make sure - `*position' is set large enough so enough memory will be - allocated for the transition table. */ - if (max_pos > *position) - *position = max_pos; - - return status; -} - -static tre_pos_and_tags_t * -tre_set_empty(tre_mem_t mem) -{ - tre_pos_and_tags_t *new_set; - - new_set = tre_mem_calloc(mem, sizeof(*new_set)); - if (new_set == NULL) - return NULL; - - new_set[0].position = -1; - new_set[0].code_min = -1; - new_set[0].code_max = -1; - - return new_set; -} - -static tre_pos_and_tags_t * -tre_set_one(tre_mem_t mem, int position, int code_min, int code_max, - tre_ctype_t class, tre_ctype_t *neg_classes, int backref) -{ - tre_pos_and_tags_t *new_set; - - new_set = tre_mem_calloc(mem, sizeof(*new_set) * 2); - if (new_set == NULL) - return NULL; - - new_set[0].position = position; - new_set[0].code_min = code_min; - new_set[0].code_max = code_max; - new_set[0].class = class; - new_set[0].neg_classes = neg_classes; - new_set[0].backref = backref; - new_set[1].position = -1; - new_set[1].code_min = -1; - new_set[1].code_max = -1; - - return new_set; -} - -static tre_pos_and_tags_t * -tre_set_union(tre_mem_t mem, tre_pos_and_tags_t *set1, tre_pos_and_tags_t *set2, - int *tags, int assertions) -{ - int s1, s2, i, j; - tre_pos_and_tags_t *new_set; - int *new_tags; - int num_tags; - - for (num_tags = 0; tags != NULL && tags[num_tags] >= 0; num_tags++); - for (s1 = 0; set1[s1].position >= 0; s1++); - for (s2 = 0; set2[s2].position >= 0; s2++); - new_set = tre_mem_calloc(mem, sizeof(*new_set) * (s1 + s2 + 1)); - if (!new_set ) - return NULL; - - for (s1 = 0; set1[s1].position >= 0; s1++) - { - new_set[s1].position = set1[s1].position; - new_set[s1].code_min = set1[s1].code_min; - new_set[s1].code_max = set1[s1].code_max; - new_set[s1].assertions = set1[s1].assertions | assertions; - new_set[s1].class = set1[s1].class; - new_set[s1].neg_classes = set1[s1].neg_classes; - new_set[s1].backref = set1[s1].backref; - if (set1[s1].tags == NULL && tags == NULL) - new_set[s1].tags = NULL; - else - { - for (i = 0; set1[s1].tags != NULL && set1[s1].tags[i] >= 0; i++); - new_tags = tre_mem_alloc(mem, (sizeof(*new_tags) - * (i + num_tags + 1))); - if (new_tags == NULL) - return NULL; - for (j = 0; j < i; j++) - new_tags[j] = set1[s1].tags[j]; - for (i = 0; i < num_tags; i++) - new_tags[j + i] = tags[i]; - new_tags[j + i] = -1; - new_set[s1].tags = new_tags; - } - } - - for (s2 = 0; set2[s2].position >= 0; s2++) - { - new_set[s1 + s2].position = set2[s2].position; - new_set[s1 + s2].code_min = set2[s2].code_min; - new_set[s1 + s2].code_max = set2[s2].code_max; - /* XXX - why not | assertions here as well? */ - new_set[s1 + s2].assertions = set2[s2].assertions; - new_set[s1 + s2].class = set2[s2].class; - new_set[s1 + s2].neg_classes = set2[s2].neg_classes; - new_set[s1 + s2].backref = set2[s2].backref; - if (set2[s2].tags == NULL) - new_set[s1 + s2].tags = NULL; - else - { - for (i = 0; set2[s2].tags[i] >= 0; i++); - new_tags = tre_mem_alloc(mem, sizeof(*new_tags) * (i + 1)); - if (new_tags == NULL) - return NULL; - for (j = 0; j < i; j++) - new_tags[j] = set2[s2].tags[j]; - new_tags[j] = -1; - new_set[s1 + s2].tags = new_tags; - } - } - new_set[s1 + s2].position = -1; - return new_set; -} - -/* Finds the empty path through `node' which is the one that should be - taken according to POSIX.2 rules, and adds the tags on that path to - `tags'. `tags' may be NULL. If `num_tags_seen' is not NULL, it is - set to the number of tags seen on the path. */ -static reg_errcode_t -tre_match_empty(tre_stack_t *stack, tre_ast_node_t *node, int *tags, - int *assertions, int *num_tags_seen) -{ - tre_literal_t *lit; - tre_union_t *uni; - tre_catenation_t *cat; - tre_iteration_t *iter; - int i; - int bottom = tre_stack_num_objects(stack); - reg_errcode_t status = REG_OK; - if (num_tags_seen) - *num_tags_seen = 0; - - status = tre_stack_push_voidptr(stack, node); - - /* Walk through the tree recursively. */ - while (status == REG_OK && tre_stack_num_objects(stack) > bottom) - { - node = tre_stack_pop_voidptr(stack); - - switch (node->type) - { - case LITERAL: - lit = (tre_literal_t *)node->obj; - switch (lit->code_min) - { - case TAG: - if (lit->code_max >= 0) - { - if (tags != NULL) - { - /* Add the tag to `tags'. */ - for (i = 0; tags[i] >= 0; i++) - if (tags[i] == lit->code_max) - break; - if (tags[i] < 0) - { - tags[i] = lit->code_max; - tags[i + 1] = -1; - } - } - if (num_tags_seen) - (*num_tags_seen)++; - } - break; - case ASSERTION: - assert(lit->code_max >= 1 - || lit->code_max <= ASSERT_LAST); - if (assertions != NULL) - *assertions |= lit->code_max; - break; - case EMPTY: - break; - default: - assert(0); - break; - } - break; - - case UNION: - /* Subexpressions starting earlier take priority over ones - starting later, so we prefer the left subexpression over the - right subexpression. */ - uni = (tre_union_t *)node->obj; - if (uni->left->nullable) - STACK_PUSHX(stack, voidptr, uni->left) - else if (uni->right->nullable) - STACK_PUSHX(stack, voidptr, uni->right) - else - assert(0); - break; - - case CATENATION: - /* The path must go through both children. */ - cat = (tre_catenation_t *)node->obj; - assert(cat->left->nullable); - assert(cat->right->nullable); - STACK_PUSHX(stack, voidptr, cat->left); - STACK_PUSHX(stack, voidptr, cat->right); - break; - - case ITERATION: - /* A match with an empty string is preferred over no match at - all, so we go through the argument if possible. */ - iter = (tre_iteration_t *)node->obj; - if (iter->arg->nullable) - STACK_PUSHX(stack, voidptr, iter->arg); - break; - - default: - assert(0); - break; - } - } - - return status; -} - - -typedef enum { - NFL_RECURSE, - NFL_POST_UNION, - NFL_POST_CATENATION, - NFL_POST_ITERATION -} tre_nfl_stack_symbol_t; - - -/* Computes and fills in the fields `nullable', `firstpos', and `lastpos' for - the nodes of the AST `tree'. */ -static reg_errcode_t -tre_compute_nfl(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *tree) -{ - int bottom = tre_stack_num_objects(stack); - - STACK_PUSHR(stack, voidptr, tree); - STACK_PUSHR(stack, int, NFL_RECURSE); - - while (tre_stack_num_objects(stack) > bottom) - { - tre_nfl_stack_symbol_t symbol; - tre_ast_node_t *node; - - symbol = (tre_nfl_stack_symbol_t)tre_stack_pop_int(stack); - node = tre_stack_pop_voidptr(stack); - switch (symbol) - { - case NFL_RECURSE: - switch (node->type) - { - case LITERAL: - { - tre_literal_t *lit = (tre_literal_t *)node->obj; - if (IS_BACKREF(lit)) - { - /* Back references: nullable = false, firstpos = {i}, - lastpos = {i}. */ - node->nullable = 0; - node->firstpos = tre_set_one(mem, lit->position, 0, - TRE_CHAR_MAX, 0, NULL, -1); - if (!node->firstpos) - return REG_ESPACE; - node->lastpos = tre_set_one(mem, lit->position, 0, - TRE_CHAR_MAX, 0, NULL, - (int)lit->code_max); - if (!node->lastpos) - return REG_ESPACE; - } - else if (lit->code_min < 0) - { - /* Tags, empty strings, params, and zero width assertions: - nullable = true, firstpos = {}, and lastpos = {}. */ - node->nullable = 1; - node->firstpos = tre_set_empty(mem); - if (!node->firstpos) - return REG_ESPACE; - node->lastpos = tre_set_empty(mem); - if (!node->lastpos) - return REG_ESPACE; - } - else - { - /* Literal at position i: nullable = false, firstpos = {i}, - lastpos = {i}. */ - node->nullable = 0; - node->firstpos = - tre_set_one(mem, lit->position, (int)lit->code_min, - (int)lit->code_max, 0, NULL, -1); - if (!node->firstpos) - return REG_ESPACE; - node->lastpos = tre_set_one(mem, lit->position, - (int)lit->code_min, - (int)lit->code_max, - lit->class, lit->neg_classes, - -1); - if (!node->lastpos) - return REG_ESPACE; - } - break; - } - - case UNION: - /* Compute the attributes for the two subtrees, and after that - for this node. */ - STACK_PUSHR(stack, voidptr, node); - STACK_PUSHR(stack, int, NFL_POST_UNION); - STACK_PUSHR(stack, voidptr, ((tre_union_t *)node->obj)->right); - STACK_PUSHR(stack, int, NFL_RECURSE); - STACK_PUSHR(stack, voidptr, ((tre_union_t *)node->obj)->left); - STACK_PUSHR(stack, int, NFL_RECURSE); - break; - - case CATENATION: - /* Compute the attributes for the two subtrees, and after that - for this node. */ - STACK_PUSHR(stack, voidptr, node); - STACK_PUSHR(stack, int, NFL_POST_CATENATION); - STACK_PUSHR(stack, voidptr, ((tre_catenation_t *)node->obj)->right); - STACK_PUSHR(stack, int, NFL_RECURSE); - STACK_PUSHR(stack, voidptr, ((tre_catenation_t *)node->obj)->left); - STACK_PUSHR(stack, int, NFL_RECURSE); - break; - - case ITERATION: - /* Compute the attributes for the subtree, and after that for - this node. */ - STACK_PUSHR(stack, voidptr, node); - STACK_PUSHR(stack, int, NFL_POST_ITERATION); - STACK_PUSHR(stack, voidptr, ((tre_iteration_t *)node->obj)->arg); - STACK_PUSHR(stack, int, NFL_RECURSE); - break; - } - break; /* end case: NFL_RECURSE */ - - case NFL_POST_UNION: - { - tre_union_t *uni = (tre_union_t *)node->obj; - node->nullable = uni->left->nullable || uni->right->nullable; - node->firstpos = tre_set_union(mem, uni->left->firstpos, - uni->right->firstpos, NULL, 0); - if (!node->firstpos) - return REG_ESPACE; - node->lastpos = tre_set_union(mem, uni->left->lastpos, - uni->right->lastpos, NULL, 0); - if (!node->lastpos) - return REG_ESPACE; - break; - } - - case NFL_POST_ITERATION: - { - tre_iteration_t *iter = (tre_iteration_t *)node->obj; - - if (iter->min == 0 || iter->arg->nullable) - node->nullable = 1; - else - node->nullable = 0; - node->firstpos = iter->arg->firstpos; - node->lastpos = iter->arg->lastpos; - break; - } - - case NFL_POST_CATENATION: - { - int num_tags, *tags, assertions; - reg_errcode_t status; - tre_catenation_t *cat = node->obj; - node->nullable = cat->left->nullable && cat->right->nullable; - - /* Compute firstpos. */ - if (cat->left->nullable) - { - /* The left side matches the empty string. Make a first pass - with tre_match_empty() to get the number of tags and - parameters. */ - status = tre_match_empty(stack, cat->left, - NULL, NULL, &num_tags); - if (status != REG_OK) - return status; - /* Allocate arrays for the tags and parameters. */ - tags = xmalloc(sizeof(*tags) * (num_tags + 1)); - if (!tags) - return REG_ESPACE; - tags[0] = -1; - assertions = 0; - /* Second pass with tre_mach_empty() to get the list of - tags and parameters. */ - status = tre_match_empty(stack, cat->left, tags, - &assertions, NULL); - if (status != REG_OK) - { - xfree(tags); - return status; - } - node->firstpos = - tre_set_union(mem, cat->right->firstpos, cat->left->firstpos, - tags, assertions); - xfree(tags); - if (!node->firstpos) - return REG_ESPACE; - } - else - { - node->firstpos = cat->left->firstpos; - } - - /* Compute lastpos. */ - if (cat->right->nullable) - { - /* The right side matches the empty string. Make a first pass - with tre_match_empty() to get the number of tags and - parameters. */ - status = tre_match_empty(stack, cat->right, - NULL, NULL, &num_tags); - if (status != REG_OK) - return status; - /* Allocate arrays for the tags and parameters. */ - tags = xmalloc(sizeof(int) * (num_tags + 1)); - if (!tags) - return REG_ESPACE; - tags[0] = -1; - assertions = 0; - /* Second pass with tre_mach_empty() to get the list of - tags and parameters. */ - status = tre_match_empty(stack, cat->right, tags, - &assertions, NULL); - if (status != REG_OK) - { - xfree(tags); - return status; - } - node->lastpos = - tre_set_union(mem, cat->left->lastpos, cat->right->lastpos, - tags, assertions); - xfree(tags); - if (!node->lastpos) - return REG_ESPACE; - } - else - { - node->lastpos = cat->right->lastpos; - } - break; - } - - default: - assert(0); - break; - } - } - - return REG_OK; -} - - -/* Adds a transition from each position in `p1' to each position in `p2'. */ -static reg_errcode_t -tre_make_trans(tre_pos_and_tags_t *p1, tre_pos_and_tags_t *p2, - tre_tnfa_transition_t *transitions, - int *counts, int *offs) -{ - tre_pos_and_tags_t *orig_p2 = p2; - tre_tnfa_transition_t *trans; - int i, j, k, l, dup, prev_p2_pos; - - if (transitions != NULL) - while (p1->position >= 0) - { - p2 = orig_p2; - prev_p2_pos = -1; - while (p2->position >= 0) - { - /* Optimization: if this position was already handled, skip it. */ - if (p2->position == prev_p2_pos) - { - p2++; - continue; - } - prev_p2_pos = p2->position; - /* Set `trans' to point to the next unused transition from - position `p1->position'. */ - trans = transitions + offs[p1->position]; - while (trans->state != NULL) - { -#if 0 - /* If we find a previous transition from `p1->position' to - `p2->position', it is overwritten. This can happen only - if there are nested loops in the regexp, like in "((a)*)*". - In POSIX.2 repetition using the outer loop is always - preferred over using the inner loop. Therefore the - transition for the inner loop is useless and can be thrown - away. */ - /* XXX - The same position is used for all nodes in a bracket - expression, so this optimization cannot be used (it will - break bracket expressions) unless I figure out a way to - detect it here. */ - if (trans->state_id == p2->position) - { - break; - } -#endif - trans++; - } - - if (trans->state == NULL) - (trans + 1)->state = NULL; - /* Use the character ranges, assertions, etc. from `p1' for - the transition from `p1' to `p2'. */ - trans->code_min = p1->code_min; - trans->code_max = p1->code_max; - trans->state = transitions + offs[p2->position]; - trans->state_id = p2->position; - trans->assertions = p1->assertions | p2->assertions - | (p1->class ? ASSERT_CHAR_CLASS : 0) - | (p1->neg_classes != NULL ? ASSERT_CHAR_CLASS_NEG : 0); - if (p1->backref >= 0) - { - assert((trans->assertions & ASSERT_CHAR_CLASS) == 0); - assert(p2->backref < 0); - trans->u.backref = p1->backref; - trans->assertions |= ASSERT_BACKREF; - } - else - trans->u.class = p1->class; - if (p1->neg_classes != NULL) - { - for (i = 0; p1->neg_classes[i] != (tre_ctype_t)0; i++); - trans->neg_classes = - xmalloc(sizeof(*trans->neg_classes) * (i + 1)); - if (trans->neg_classes == NULL) - return REG_ESPACE; - for (i = 0; p1->neg_classes[i] != (tre_ctype_t)0; i++) - trans->neg_classes[i] = p1->neg_classes[i]; - trans->neg_classes[i] = (tre_ctype_t)0; - } - else - trans->neg_classes = NULL; - - /* Find out how many tags this transition has. */ - i = 0; - if (p1->tags != NULL) - while(p1->tags[i] >= 0) - i++; - j = 0; - if (p2->tags != NULL) - while(p2->tags[j] >= 0) - j++; - - /* If we are overwriting a transition, free the old tag array. */ - if (trans->tags != NULL) - xfree(trans->tags); - trans->tags = NULL; - - /* If there were any tags, allocate an array and fill it. */ - if (i + j > 0) - { - trans->tags = xmalloc(sizeof(*trans->tags) * (i + j + 1)); - if (!trans->tags) - return REG_ESPACE; - i = 0; - if (p1->tags != NULL) - while(p1->tags[i] >= 0) - { - trans->tags[i] = p1->tags[i]; - i++; - } - l = i; - j = 0; - if (p2->tags != NULL) - while (p2->tags[j] >= 0) - { - /* Don't add duplicates. */ - dup = 0; - for (k = 0; k < i; k++) - if (trans->tags[k] == p2->tags[j]) - { - dup = 1; - break; - } - if (!dup) - trans->tags[l++] = p2->tags[j]; - j++; - } - trans->tags[l] = -1; - } - - p2++; - } - p1++; - } - else - /* Compute a maximum limit for the number of transitions leaving - from each state. */ - while (p1->position >= 0) - { - p2 = orig_p2; - while (p2->position >= 0) - { - counts[p1->position]++; - p2++; - } - p1++; - } - return REG_OK; -} - -/* Converts the syntax tree to a TNFA. All the transitions in the TNFA are - labelled with one character range (there are no transitions on empty - strings). The TNFA takes O(n^2) space in the worst case, `n' is size of - the regexp. */ -static reg_errcode_t -tre_ast_to_tnfa(tre_ast_node_t *node, tre_tnfa_transition_t *transitions, - int *counts, int *offs) -{ - tre_union_t *uni; - tre_catenation_t *cat; - tre_iteration_t *iter; - reg_errcode_t errcode = REG_OK; - - /* XXX - recurse using a stack!. */ - switch (node->type) - { - case LITERAL: - break; - case UNION: - uni = (tre_union_t *)node->obj; - errcode = tre_ast_to_tnfa(uni->left, transitions, counts, offs); - if (errcode != REG_OK) - return errcode; - errcode = tre_ast_to_tnfa(uni->right, transitions, counts, offs); - break; - - case CATENATION: - cat = (tre_catenation_t *)node->obj; - /* Add a transition from each position in cat->left->lastpos - to each position in cat->right->firstpos. */ - errcode = tre_make_trans(cat->left->lastpos, cat->right->firstpos, - transitions, counts, offs); - if (errcode != REG_OK) - return errcode; - errcode = tre_ast_to_tnfa(cat->left, transitions, counts, offs); - if (errcode != REG_OK) - return errcode; - errcode = tre_ast_to_tnfa(cat->right, transitions, counts, offs); - break; - - case ITERATION: - iter = (tre_iteration_t *)node->obj; - assert(iter->max == -1 || iter->max == 1); - - if (iter->max == -1) - { - assert(iter->min == 0 || iter->min == 1); - /* Add a transition from each last position in the iterated - expression to each first position. */ - errcode = tre_make_trans(iter->arg->lastpos, iter->arg->firstpos, - transitions, counts, offs); - if (errcode != REG_OK) - return errcode; - } - errcode = tre_ast_to_tnfa(iter->arg, transitions, counts, offs); - break; - } - return errcode; -} - - -#define ERROR_EXIT(err) \ - do \ - { \ - errcode = err; \ - if (/*CONSTCOND*/1) \ - goto error_exit; \ - } \ - while (/*CONSTCOND*/0) - - -int -regcomp(regex_t *restrict preg, const char *restrict regex, int cflags) -{ - tre_stack_t *stack; - tre_ast_node_t *tree, *tmp_ast_l, *tmp_ast_r; - tre_pos_and_tags_t *p; - int *counts = NULL, *offs = NULL; - int i, add = 0; - tre_tnfa_transition_t *transitions, *initial; - tre_tnfa_t *tnfa = NULL; - tre_submatch_data_t *submatch_data; - tre_tag_direction_t *tag_directions = NULL; - reg_errcode_t errcode; - tre_mem_t mem; - - /* Parse context. */ - tre_parse_ctx_t parse_ctx; - - /* Allocate a stack used throughout the compilation process for various - purposes. */ - stack = tre_stack_new(512, 1024000, 128); - if (!stack) - return REG_ESPACE; - /* Allocate a fast memory allocator. */ - mem = tre_mem_new(); - if (!mem) - { - tre_stack_destroy(stack); - return REG_ESPACE; - } - - /* Parse the regexp. */ - memset(&parse_ctx, 0, sizeof(parse_ctx)); - parse_ctx.mem = mem; - parse_ctx.stack = stack; - parse_ctx.start = regex; - parse_ctx.cflags = cflags; - parse_ctx.max_backref = -1; - errcode = tre_parse(&parse_ctx); - if (errcode != REG_OK) - ERROR_EXIT(errcode); - preg->re_nsub = parse_ctx.submatch_id - 1; - tree = parse_ctx.n; - -#ifdef TRE_DEBUG - tre_ast_print(tree); -#endif /* TRE_DEBUG */ - - /* Referring to nonexistent subexpressions is illegal. */ - if (parse_ctx.max_backref > (int)preg->re_nsub) - ERROR_EXIT(REG_ESUBREG); - - /* Allocate the TNFA struct. */ - tnfa = xcalloc(1, sizeof(tre_tnfa_t)); - if (tnfa == NULL) - ERROR_EXIT(REG_ESPACE); - tnfa->have_backrefs = parse_ctx.max_backref >= 0; - tnfa->have_approx = 0; - tnfa->num_submatches = parse_ctx.submatch_id; - - /* Set up tags for submatch addressing. If REG_NOSUB is set and the - regexp does not have back references, this can be skipped. */ - if (tnfa->have_backrefs || !(cflags & REG_NOSUB)) - { - - /* Figure out how many tags we will need. */ - errcode = tre_add_tags(NULL, stack, tree, tnfa); - if (errcode != REG_OK) - ERROR_EXIT(errcode); - - if (tnfa->num_tags > 0) - { - tag_directions = xmalloc(sizeof(*tag_directions) - * (tnfa->num_tags + 1)); - if (tag_directions == NULL) - ERROR_EXIT(REG_ESPACE); - tnfa->tag_directions = tag_directions; - memset(tag_directions, -1, - sizeof(*tag_directions) * (tnfa->num_tags + 1)); - } - tnfa->minimal_tags = xcalloc((unsigned)tnfa->num_tags * 2 + 1, - sizeof(*tnfa->minimal_tags)); - if (tnfa->minimal_tags == NULL) - ERROR_EXIT(REG_ESPACE); - - submatch_data = xcalloc((unsigned)parse_ctx.submatch_id, - sizeof(*submatch_data)); - if (submatch_data == NULL) - ERROR_EXIT(REG_ESPACE); - tnfa->submatch_data = submatch_data; - - errcode = tre_add_tags(mem, stack, tree, tnfa); - if (errcode != REG_OK) - ERROR_EXIT(errcode); - - } - - /* Expand iteration nodes. */ - errcode = tre_expand_ast(mem, stack, tree, &parse_ctx.position, - tag_directions); - if (errcode != REG_OK) - ERROR_EXIT(errcode); - - /* Add a dummy node for the final state. - XXX - For certain patterns this dummy node can be optimized away, - for example "a*" or "ab*". Figure out a simple way to detect - this possibility. */ - tmp_ast_l = tree; - tmp_ast_r = tre_ast_new_literal(mem, 0, 0, parse_ctx.position++); - if (tmp_ast_r == NULL) - ERROR_EXIT(REG_ESPACE); - - tree = tre_ast_new_catenation(mem, tmp_ast_l, tmp_ast_r); - if (tree == NULL) - ERROR_EXIT(REG_ESPACE); - - errcode = tre_compute_nfl(mem, stack, tree); - if (errcode != REG_OK) - ERROR_EXIT(errcode); - - counts = xmalloc(sizeof(int) * parse_ctx.position); - if (counts == NULL) - ERROR_EXIT(REG_ESPACE); - - offs = xmalloc(sizeof(int) * parse_ctx.position); - if (offs == NULL) - ERROR_EXIT(REG_ESPACE); - - for (i = 0; i < parse_ctx.position; i++) - counts[i] = 0; - tre_ast_to_tnfa(tree, NULL, counts, NULL); - - add = 0; - for (i = 0; i < parse_ctx.position; i++) - { - offs[i] = add; - add += counts[i] + 1; - counts[i] = 0; - } - transitions = xcalloc((unsigned)add + 1, sizeof(*transitions)); - if (transitions == NULL) - ERROR_EXIT(REG_ESPACE); - tnfa->transitions = transitions; - tnfa->num_transitions = add; - - errcode = tre_ast_to_tnfa(tree, transitions, counts, offs); - if (errcode != REG_OK) - ERROR_EXIT(errcode); - - tnfa->firstpos_chars = NULL; - - p = tree->firstpos; - i = 0; - while (p->position >= 0) - { - i++; - p++; - } - - initial = xcalloc((unsigned)i + 1, sizeof(tre_tnfa_transition_t)); - if (initial == NULL) - ERROR_EXIT(REG_ESPACE); - tnfa->initial = initial; - - i = 0; - for (p = tree->firstpos; p->position >= 0; p++) - { - initial[i].state = transitions + offs[p->position]; - initial[i].state_id = p->position; - initial[i].tags = NULL; - /* Copy the arrays p->tags, and p->params, they are allocated - from a tre_mem object. */ - if (p->tags) - { - int j; - for (j = 0; p->tags[j] >= 0; j++); - initial[i].tags = xmalloc(sizeof(*p->tags) * (j + 1)); - if (!initial[i].tags) - ERROR_EXIT(REG_ESPACE); - memcpy(initial[i].tags, p->tags, sizeof(*p->tags) * (j + 1)); - } - initial[i].assertions = p->assertions; - i++; - } - initial[i].state = NULL; - - tnfa->num_transitions = add; - tnfa->final = transitions + offs[tree->lastpos[0].position]; - tnfa->num_states = parse_ctx.position; - tnfa->cflags = cflags; - - tre_mem_destroy(mem); - tre_stack_destroy(stack); - xfree(counts); - xfree(offs); - - preg->TRE_REGEX_T_FIELD = (void *)tnfa; - return REG_OK; - - error_exit: - /* Free everything that was allocated and return the error code. */ - tre_mem_destroy(mem); - if (stack != NULL) - tre_stack_destroy(stack); - if (counts != NULL) - xfree(counts); - if (offs != NULL) - xfree(offs); - preg->TRE_REGEX_T_FIELD = (void *)tnfa; - regfree(preg); - return errcode; -} - - - - -void -regfree(regex_t *preg) -{ - tre_tnfa_t *tnfa; - unsigned int i; - tre_tnfa_transition_t *trans; - - tnfa = (void *)preg->TRE_REGEX_T_FIELD; - if (!tnfa) - return; - - for (i = 0; i < tnfa->num_transitions; i++) - if (tnfa->transitions[i].state) - { - if (tnfa->transitions[i].tags) - xfree(tnfa->transitions[i].tags); - if (tnfa->transitions[i].neg_classes) - xfree(tnfa->transitions[i].neg_classes); - } - if (tnfa->transitions) - xfree(tnfa->transitions); - - if (tnfa->initial) - { - for (trans = tnfa->initial; trans->state; trans++) - { - if (trans->tags) - xfree(trans->tags); - } - xfree(tnfa->initial); - } - - if (tnfa->submatch_data) - { - for (i = 0; i < tnfa->num_submatches; i++) - if (tnfa->submatch_data[i].parents) - xfree(tnfa->submatch_data[i].parents); - xfree(tnfa->submatch_data); - } - - if (tnfa->tag_directions) - xfree(tnfa->tag_directions); - if (tnfa->firstpos_chars) - xfree(tnfa->firstpos_chars); - if (tnfa->minimal_tags) - xfree(tnfa->minimal_tags); - xfree(tnfa); -}
\ No newline at end of file diff --git a/lib/mlibc/options/posix/musl-generic-regex/regerror.c b/lib/mlibc/options/posix/musl-generic-regex/regerror.c deleted file mode 100644 index 41e9a36..0000000 --- a/lib/mlibc/options/posix/musl-generic-regex/regerror.c +++ /dev/null @@ -1,37 +0,0 @@ -#include <string.h> -#include <regex.h> -#include <stdio.h> -// #include "locale_impl.h" - -/* Error message strings for error codes listed in `regex.h'. This list - needs to be in sync with the codes listed there, naturally. */ - -/* Converted to single string by Rich Felker to remove the need for - * data relocations at runtime, 27 Feb 2006. */ - -static const char messages[] = { - "No error\0" - "No match\0" - "Invalid regexp\0" - "Unknown collating element\0" - "Unknown character class name\0" - "Trailing backslash\0" - "Invalid back reference\0" - "Missing ']'\0" - "Missing ')'\0" - "Missing '}'\0" - "Invalid contents of {}\0" - "Invalid character range\0" - "Out of memory\0" - "Repetition not preceded by valid expression\0" - "\0Unknown error" -}; - -size_t regerror(int e, const regex_t *restrict preg, char *restrict buf, size_t size) -{ - const char *s; - for (s=messages; e && *s; e--, s+=strlen(s)+1); - if (!*s) s++; - // s = LCTRANS_CUR(s); - return 1+snprintf(buf, size, "%s", s); -} diff --git a/lib/mlibc/options/posix/musl-generic-regex/regexec.c b/lib/mlibc/options/posix/musl-generic-regex/regexec.c deleted file mode 100644 index 1a169ab..0000000 --- a/lib/mlibc/options/posix/musl-generic-regex/regexec.c +++ /dev/null @@ -1,1028 +0,0 @@ -/* - regexec.c - TRE POSIX compatible matching functions (and more). - - Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi> - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#include <stdlib.h> -#include <string.h> -#include <wchar.h> -#include <wctype.h> -#include <limits.h> -#include <stdint.h> - -#include <regex.h> - -#include "tre.h" - -#include <assert.h> - -static void -tre_fill_pmatch(size_t nmatch, regmatch_t pmatch[], int cflags, - const tre_tnfa_t *tnfa, regoff_t *tags, regoff_t match_eo); - -/*********************************************************************** - from tre-match-utils.h -***********************************************************************/ - -#define GET_NEXT_WCHAR() do { \ - prev_c = next_c; pos += pos_add_next; \ - if ((pos_add_next = mbtowc(&next_c, str_byte, MB_LEN_MAX)) <= 0) { \ - if (pos_add_next < 0) { ret = REG_NOMATCH; goto error_exit; } \ - else pos_add_next++; \ - } \ - str_byte += pos_add_next; \ - } while (0) - -#define IS_WORD_CHAR(c) ((c) == L'_' || tre_isalnum(c)) - -#define CHECK_ASSERTIONS(assertions) \ - (((assertions & ASSERT_AT_BOL) \ - && (pos > 0 || reg_notbol) \ - && (prev_c != L'\n' || !reg_newline)) \ - || ((assertions & ASSERT_AT_EOL) \ - && (next_c != L'\0' || reg_noteol) \ - && (next_c != L'\n' || !reg_newline)) \ - || ((assertions & ASSERT_AT_BOW) \ - && (IS_WORD_CHAR(prev_c) || !IS_WORD_CHAR(next_c))) \ - || ((assertions & ASSERT_AT_EOW) \ - && (!IS_WORD_CHAR(prev_c) || IS_WORD_CHAR(next_c))) \ - || ((assertions & ASSERT_AT_WB) \ - && (pos != 0 && next_c != L'\0' \ - && IS_WORD_CHAR(prev_c) == IS_WORD_CHAR(next_c))) \ - || ((assertions & ASSERT_AT_WB_NEG) \ - && (pos == 0 || next_c == L'\0' \ - || IS_WORD_CHAR(prev_c) != IS_WORD_CHAR(next_c)))) - -#define CHECK_CHAR_CLASSES(trans_i, tnfa, eflags) \ - (((trans_i->assertions & ASSERT_CHAR_CLASS) \ - && !(tnfa->cflags & REG_ICASE) \ - && !tre_isctype((tre_cint_t)prev_c, trans_i->u.class)) \ - || ((trans_i->assertions & ASSERT_CHAR_CLASS) \ - && (tnfa->cflags & REG_ICASE) \ - && !tre_isctype(tre_tolower((tre_cint_t)prev_c),trans_i->u.class) \ - && !tre_isctype(tre_toupper((tre_cint_t)prev_c),trans_i->u.class)) \ - || ((trans_i->assertions & ASSERT_CHAR_CLASS_NEG) \ - && tre_neg_char_classes_match(trans_i->neg_classes,(tre_cint_t)prev_c,\ - tnfa->cflags & REG_ICASE))) - - - - -/* Returns 1 if `t1' wins `t2', 0 otherwise. */ -static int -tre_tag_order(int num_tags, tre_tag_direction_t *tag_directions, - regoff_t *t1, regoff_t *t2) -{ - int i; - for (i = 0; i < num_tags; i++) - { - if (tag_directions[i] == TRE_TAG_MINIMIZE) - { - if (t1[i] < t2[i]) - return 1; - if (t1[i] > t2[i]) - return 0; - } - else - { - if (t1[i] > t2[i]) - return 1; - if (t1[i] < t2[i]) - return 0; - } - } - /* assert(0);*/ - return 0; -} - -static int -tre_neg_char_classes_match(tre_ctype_t *classes, tre_cint_t wc, int icase) -{ - while (*classes != (tre_ctype_t)0) - if ((!icase && tre_isctype(wc, *classes)) - || (icase && (tre_isctype(tre_toupper(wc), *classes) - || tre_isctype(tre_tolower(wc), *classes)))) - return 1; /* Match. */ - else - classes++; - return 0; /* No match. */ -} - - -/*********************************************************************** - from tre-match-parallel.c -***********************************************************************/ - -/* - This algorithm searches for matches basically by reading characters - in the searched string one by one, starting at the beginning. All - matching paths in the TNFA are traversed in parallel. When two or - more paths reach the same state, exactly one is chosen according to - tag ordering rules; if returning submatches is not required it does - not matter which path is chosen. - - The worst case time required for finding the leftmost and longest - match, or determining that there is no match, is always linearly - dependent on the length of the text being searched. - - This algorithm cannot handle TNFAs with back referencing nodes. - See `tre-match-backtrack.c'. -*/ - -typedef struct { - tre_tnfa_transition_t *state; - regoff_t *tags; -} tre_tnfa_reach_t; - -typedef struct { - regoff_t pos; - regoff_t **tags; -} tre_reach_pos_t; - - -static reg_errcode_t -tre_tnfa_run_parallel(const tre_tnfa_t *tnfa, const void *string, - regoff_t *match_tags, int eflags, - regoff_t *match_end_ofs) -{ - /* State variables required by GET_NEXT_WCHAR. */ - tre_char_t prev_c = 0, next_c = 0; - const char *str_byte = string; - regoff_t pos = -1; - regoff_t pos_add_next = 1; -#ifdef TRE_MBSTATE - mbstate_t mbstate; -#endif /* TRE_MBSTATE */ - int reg_notbol = eflags & REG_NOTBOL; - int reg_noteol = eflags & REG_NOTEOL; - int reg_newline = tnfa->cflags & REG_NEWLINE; - reg_errcode_t ret; - - char *buf; - tre_tnfa_transition_t *trans_i; - tre_tnfa_reach_t *reach, *reach_next, *reach_i, *reach_next_i; - tre_reach_pos_t *reach_pos; - int *tag_i; - int num_tags, i; - - regoff_t match_eo = -1; /* end offset of match (-1 if no match found yet) */ - int new_match = 0; - regoff_t *tmp_tags = NULL; - regoff_t *tmp_iptr; - -#ifdef TRE_MBSTATE - memset(&mbstate, '\0', sizeof(mbstate)); -#endif /* TRE_MBSTATE */ - - if (!match_tags) - num_tags = 0; - else - num_tags = tnfa->num_tags; - - /* Allocate memory for temporary data required for matching. This needs to - be done for every matching operation to be thread safe. This allocates - everything in a single large block with calloc(). */ - { - size_t tbytes, rbytes, pbytes, xbytes, total_bytes; - char *tmp_buf; - - /* Ensure that tbytes and xbytes*num_states cannot overflow, and that - * they don't contribute more than 1/8 of SIZE_MAX to total_bytes. */ - if (num_tags > SIZE_MAX/(8 * sizeof(regoff_t) * tnfa->num_states)) - return REG_ESPACE; - - /* Likewise check rbytes. */ - if (tnfa->num_states+1 > SIZE_MAX/(8 * sizeof(*reach_next))) - return REG_ESPACE; - - /* Likewise check pbytes. */ - if (tnfa->num_states > SIZE_MAX/(8 * sizeof(*reach_pos))) - return REG_ESPACE; - - /* Compute the length of the block we need. */ - tbytes = sizeof(*tmp_tags) * num_tags; - rbytes = sizeof(*reach_next) * (tnfa->num_states + 1); - pbytes = sizeof(*reach_pos) * tnfa->num_states; - xbytes = sizeof(regoff_t) * num_tags; - total_bytes = - (sizeof(long) - 1) * 4 /* for alignment paddings */ - + (rbytes + xbytes * tnfa->num_states) * 2 + tbytes + pbytes; - - /* Allocate the memory. */ - buf = calloc(total_bytes, 1); - if (buf == NULL) - return REG_ESPACE; - - /* Get the various pointers within tmp_buf (properly aligned). */ - tmp_tags = (void *)buf; - tmp_buf = buf + tbytes; - tmp_buf += ALIGN(tmp_buf, long); - reach_next = (void *)tmp_buf; - tmp_buf += rbytes; - tmp_buf += ALIGN(tmp_buf, long); - reach = (void *)tmp_buf; - tmp_buf += rbytes; - tmp_buf += ALIGN(tmp_buf, long); - reach_pos = (void *)tmp_buf; - tmp_buf += pbytes; - tmp_buf += ALIGN(tmp_buf, long); - for (i = 0; i < tnfa->num_states; i++) - { - reach[i].tags = (void *)tmp_buf; - tmp_buf += xbytes; - reach_next[i].tags = (void *)tmp_buf; - tmp_buf += xbytes; - } - } - - for (i = 0; i < tnfa->num_states; i++) - reach_pos[i].pos = -1; - - GET_NEXT_WCHAR(); - pos = 0; - - reach_next_i = reach_next; - while (1) - { - /* If no match found yet, add the initial states to `reach_next'. */ - if (match_eo < 0) - { - trans_i = tnfa->initial; - while (trans_i->state != NULL) - { - if (reach_pos[trans_i->state_id].pos < pos) - { - if (trans_i->assertions - && CHECK_ASSERTIONS(trans_i->assertions)) - { - trans_i++; - continue; - } - - reach_next_i->state = trans_i->state; - for (i = 0; i < num_tags; i++) - reach_next_i->tags[i] = -1; - tag_i = trans_i->tags; - if (tag_i) - while (*tag_i >= 0) - { - if (*tag_i < num_tags) - reach_next_i->tags[*tag_i] = pos; - tag_i++; - } - if (reach_next_i->state == tnfa->final) - { - match_eo = pos; - new_match = 1; - for (i = 0; i < num_tags; i++) - match_tags[i] = reach_next_i->tags[i]; - } - reach_pos[trans_i->state_id].pos = pos; - reach_pos[trans_i->state_id].tags = &reach_next_i->tags; - reach_next_i++; - } - trans_i++; - } - reach_next_i->state = NULL; - } - else - { - if (num_tags == 0 || reach_next_i == reach_next) - /* We have found a match. */ - break; - } - - /* Check for end of string. */ - if (!next_c) break; - - GET_NEXT_WCHAR(); - - /* Swap `reach' and `reach_next'. */ - reach_i = reach; - reach = reach_next; - reach_next = reach_i; - - /* For each state in `reach', weed out states that don't fulfill the - minimal matching conditions. */ - if (tnfa->num_minimals && new_match) - { - new_match = 0; - reach_next_i = reach_next; - for (reach_i = reach; reach_i->state; reach_i++) - { - int skip = 0; - for (i = 0; tnfa->minimal_tags[i] >= 0; i += 2) - { - int end = tnfa->minimal_tags[i]; - int start = tnfa->minimal_tags[i + 1]; - if (end >= num_tags) - { - skip = 1; - break; - } - else if (reach_i->tags[start] == match_tags[start] - && reach_i->tags[end] < match_tags[end]) - { - skip = 1; - break; - } - } - if (!skip) - { - reach_next_i->state = reach_i->state; - tmp_iptr = reach_next_i->tags; - reach_next_i->tags = reach_i->tags; - reach_i->tags = tmp_iptr; - reach_next_i++; - } - } - reach_next_i->state = NULL; - - /* Swap `reach' and `reach_next'. */ - reach_i = reach; - reach = reach_next; - reach_next = reach_i; - } - - /* For each state in `reach' see if there is a transition leaving with - the current input symbol to a state not yet in `reach_next', and - add the destination states to `reach_next'. */ - reach_next_i = reach_next; - for (reach_i = reach; reach_i->state; reach_i++) - { - for (trans_i = reach_i->state; trans_i->state; trans_i++) - { - /* Does this transition match the input symbol? */ - if (trans_i->code_min <= (tre_cint_t)prev_c && - trans_i->code_max >= (tre_cint_t)prev_c) - { - if (trans_i->assertions - && (CHECK_ASSERTIONS(trans_i->assertions) - || CHECK_CHAR_CLASSES(trans_i, tnfa, eflags))) - { - continue; - } - - /* Compute the tags after this transition. */ - for (i = 0; i < num_tags; i++) - tmp_tags[i] = reach_i->tags[i]; - tag_i = trans_i->tags; - if (tag_i != NULL) - while (*tag_i >= 0) - { - if (*tag_i < num_tags) - tmp_tags[*tag_i] = pos; - tag_i++; - } - - if (reach_pos[trans_i->state_id].pos < pos) - { - /* Found an unvisited node. */ - reach_next_i->state = trans_i->state; - tmp_iptr = reach_next_i->tags; - reach_next_i->tags = tmp_tags; - tmp_tags = tmp_iptr; - reach_pos[trans_i->state_id].pos = pos; - reach_pos[trans_i->state_id].tags = &reach_next_i->tags; - - if (reach_next_i->state == tnfa->final - && (match_eo == -1 - || (num_tags > 0 - && reach_next_i->tags[0] <= match_tags[0]))) - { - match_eo = pos; - new_match = 1; - for (i = 0; i < num_tags; i++) - match_tags[i] = reach_next_i->tags[i]; - } - reach_next_i++; - - } - else - { - assert(reach_pos[trans_i->state_id].pos == pos); - /* Another path has also reached this state. We choose - the winner by examining the tag values for both - paths. */ - if (tre_tag_order(num_tags, tnfa->tag_directions, - tmp_tags, - *reach_pos[trans_i->state_id].tags)) - { - /* The new path wins. */ - tmp_iptr = *reach_pos[trans_i->state_id].tags; - *reach_pos[trans_i->state_id].tags = tmp_tags; - if (trans_i->state == tnfa->final) - { - match_eo = pos; - new_match = 1; - for (i = 0; i < num_tags; i++) - match_tags[i] = tmp_tags[i]; - } - tmp_tags = tmp_iptr; - } - } - } - } - } - reach_next_i->state = NULL; - } - - *match_end_ofs = match_eo; - ret = match_eo >= 0 ? REG_OK : REG_NOMATCH; -error_exit: - xfree(buf); - return ret; -} - - - -/*********************************************************************** - from tre-match-backtrack.c -***********************************************************************/ - -/* - This matcher is for regexps that use back referencing. Regexp matching - with back referencing is an NP-complete problem on the number of back - references. The easiest way to match them is to use a backtracking - routine which basically goes through all possible paths in the TNFA - and chooses the one which results in the best (leftmost and longest) - match. This can be spectacularly expensive and may run out of stack - space, but there really is no better known generic algorithm. Quoting - Henry Spencer from comp.compilers: - <URL: http://compilers.iecc.com/comparch/article/93-03-102> - - POSIX.2 REs require longest match, which is really exciting to - implement since the obsolete ("basic") variant also includes - \<digit>. I haven't found a better way of tackling this than doing - a preliminary match using a DFA (or simulation) on a modified RE - that just replicates subREs for \<digit>, and then doing a - backtracking match to determine whether the subRE matches were - right. This can be rather slow, but I console myself with the - thought that people who use \<digit> deserve very slow execution. - (Pun unintentional but very appropriate.) - -*/ - -typedef struct { - regoff_t pos; - const char *str_byte; - tre_tnfa_transition_t *state; - int state_id; - int next_c; - regoff_t *tags; -#ifdef TRE_MBSTATE - mbstate_t mbstate; -#endif /* TRE_MBSTATE */ -} tre_backtrack_item_t; - -typedef struct tre_backtrack_struct { - tre_backtrack_item_t item; - struct tre_backtrack_struct *prev; - struct tre_backtrack_struct *next; -} *tre_backtrack_t; - -#ifdef TRE_MBSTATE -#define BT_STACK_MBSTATE_IN stack->item.mbstate = (mbstate) -#define BT_STACK_MBSTATE_OUT (mbstate) = stack->item.mbstate -#else /* !TRE_MBSTATE */ -#define BT_STACK_MBSTATE_IN -#define BT_STACK_MBSTATE_OUT -#endif /* !TRE_MBSTATE */ - -#define tre_bt_mem_new tre_mem_new -#define tre_bt_mem_alloc tre_mem_alloc -#define tre_bt_mem_destroy tre_mem_destroy - - -#define BT_STACK_PUSH(_pos, _str_byte, _str_wide, _state, _state_id, _next_c, _tags, _mbstate) \ - do \ - { \ - int i; \ - if (!stack->next) \ - { \ - tre_backtrack_t s; \ - s = tre_bt_mem_alloc(mem, sizeof(*s)); \ - if (!s) \ - { \ - tre_bt_mem_destroy(mem); \ - if (tags) \ - xfree(tags); \ - if (pmatch) \ - xfree(pmatch); \ - if (states_seen) \ - xfree(states_seen); \ - return REG_ESPACE; \ - } \ - s->prev = stack; \ - s->next = NULL; \ - s->item.tags = tre_bt_mem_alloc(mem, \ - sizeof(*tags) * tnfa->num_tags); \ - if (!s->item.tags) \ - { \ - tre_bt_mem_destroy(mem); \ - if (tags) \ - xfree(tags); \ - if (pmatch) \ - xfree(pmatch); \ - if (states_seen) \ - xfree(states_seen); \ - return REG_ESPACE; \ - } \ - stack->next = s; \ - stack = s; \ - } \ - else \ - stack = stack->next; \ - stack->item.pos = (_pos); \ - stack->item.str_byte = (_str_byte); \ - stack->item.state = (_state); \ - stack->item.state_id = (_state_id); \ - stack->item.next_c = (_next_c); \ - for (i = 0; i < tnfa->num_tags; i++) \ - stack->item.tags[i] = (_tags)[i]; \ - BT_STACK_MBSTATE_IN; \ - } \ - while (0) - -#define BT_STACK_POP() \ - do \ - { \ - int i; \ - assert(stack->prev); \ - pos = stack->item.pos; \ - str_byte = stack->item.str_byte; \ - state = stack->item.state; \ - next_c = stack->item.next_c; \ - for (i = 0; i < tnfa->num_tags; i++) \ - tags[i] = stack->item.tags[i]; \ - BT_STACK_MBSTATE_OUT; \ - stack = stack->prev; \ - } \ - while (0) - -#undef MIN -#define MIN(a, b) ((a) <= (b) ? (a) : (b)) - -static reg_errcode_t -tre_tnfa_run_backtrack(const tre_tnfa_t *tnfa, const void *string, - regoff_t *match_tags, int eflags, regoff_t *match_end_ofs) -{ - /* State variables required by GET_NEXT_WCHAR. */ - tre_char_t prev_c = 0, next_c = 0; - const char *str_byte = string; - regoff_t pos = 0; - regoff_t pos_add_next = 1; -#ifdef TRE_MBSTATE - mbstate_t mbstate; -#endif /* TRE_MBSTATE */ - int reg_notbol = eflags & REG_NOTBOL; - int reg_noteol = eflags & REG_NOTEOL; - int reg_newline = tnfa->cflags & REG_NEWLINE; - - /* These are used to remember the necessary values of the above - variables to return to the position where the current search - started from. */ - int next_c_start; - const char *str_byte_start; - regoff_t pos_start = -1; -#ifdef TRE_MBSTATE - mbstate_t mbstate_start; -#endif /* TRE_MBSTATE */ - - /* End offset of best match so far, or -1 if no match found yet. */ - regoff_t match_eo = -1; - /* Tag arrays. */ - int *next_tags; - regoff_t *tags = NULL; - /* Current TNFA state. */ - tre_tnfa_transition_t *state; - int *states_seen = NULL; - - /* Memory allocator to for allocating the backtracking stack. */ - tre_mem_t mem = tre_bt_mem_new(); - - /* The backtracking stack. */ - tre_backtrack_t stack; - - tre_tnfa_transition_t *trans_i; - regmatch_t *pmatch = NULL; - int ret; - -#ifdef TRE_MBSTATE - memset(&mbstate, '\0', sizeof(mbstate)); -#endif /* TRE_MBSTATE */ - - if (!mem) - return REG_ESPACE; - stack = tre_bt_mem_alloc(mem, sizeof(*stack)); - if (!stack) - { - ret = REG_ESPACE; - goto error_exit; - } - stack->prev = NULL; - stack->next = NULL; - - if (tnfa->num_tags) - { - tags = xmalloc(sizeof(*tags) * tnfa->num_tags); - if (!tags) - { - ret = REG_ESPACE; - goto error_exit; - } - } - if (tnfa->num_submatches) - { - pmatch = xmalloc(sizeof(*pmatch) * tnfa->num_submatches); - if (!pmatch) - { - ret = REG_ESPACE; - goto error_exit; - } - } - if (tnfa->num_states) - { - states_seen = xmalloc(sizeof(*states_seen) * tnfa->num_states); - if (!states_seen) - { - ret = REG_ESPACE; - goto error_exit; - } - } - - retry: - { - int i; - for (i = 0; i < tnfa->num_tags; i++) - { - tags[i] = -1; - if (match_tags) - match_tags[i] = -1; - } - for (i = 0; i < tnfa->num_states; i++) - states_seen[i] = 0; - } - - state = NULL; - pos = pos_start; - GET_NEXT_WCHAR(); - pos_start = pos; - next_c_start = next_c; - str_byte_start = str_byte; -#ifdef TRE_MBSTATE - mbstate_start = mbstate; -#endif /* TRE_MBSTATE */ - - /* Handle initial states. */ - next_tags = NULL; - for (trans_i = tnfa->initial; trans_i->state; trans_i++) - { - if (trans_i->assertions && CHECK_ASSERTIONS(trans_i->assertions)) - { - continue; - } - if (state == NULL) - { - /* Start from this state. */ - state = trans_i->state; - next_tags = trans_i->tags; - } - else - { - /* Backtrack to this state. */ - BT_STACK_PUSH(pos, str_byte, 0, trans_i->state, - trans_i->state_id, next_c, tags, mbstate); - { - int *tmp = trans_i->tags; - if (tmp) - while (*tmp >= 0) - stack->item.tags[*tmp++] = pos; - } - } - } - - if (next_tags) - for (; *next_tags >= 0; next_tags++) - tags[*next_tags] = pos; - - - if (state == NULL) - goto backtrack; - - while (1) - { - tre_tnfa_transition_t *next_state; - int empty_br_match; - - if (state == tnfa->final) - { - if (match_eo < pos - || (match_eo == pos - && match_tags - && tre_tag_order(tnfa->num_tags, tnfa->tag_directions, - tags, match_tags))) - { - int i; - /* This match wins the previous match. */ - match_eo = pos; - if (match_tags) - for (i = 0; i < tnfa->num_tags; i++) - match_tags[i] = tags[i]; - } - /* Our TNFAs never have transitions leaving from the final state, - so we jump right to backtracking. */ - goto backtrack; - } - - /* Go to the next character in the input string. */ - empty_br_match = 0; - trans_i = state; - if (trans_i->state && trans_i->assertions & ASSERT_BACKREF) - { - /* This is a back reference state. All transitions leaving from - this state have the same back reference "assertion". Instead - of reading the next character, we match the back reference. */ - regoff_t so, eo; - int bt = trans_i->u.backref; - regoff_t bt_len; - int result; - - /* Get the substring we need to match against. Remember to - turn off REG_NOSUB temporarily. */ - tre_fill_pmatch(bt + 1, pmatch, tnfa->cflags & ~REG_NOSUB, - tnfa, tags, pos); - so = pmatch[bt].rm_so; - eo = pmatch[bt].rm_eo; - bt_len = eo - so; - - result = strncmp((const char*)string + so, str_byte - 1, - (size_t)bt_len); - - if (result == 0) - { - /* Back reference matched. Check for infinite loop. */ - if (bt_len == 0) - empty_br_match = 1; - if (empty_br_match && states_seen[trans_i->state_id]) - { - goto backtrack; - } - - states_seen[trans_i->state_id] = empty_br_match; - - /* Advance in input string and resync `prev_c', `next_c' - and pos. */ - str_byte += bt_len - 1; - pos += bt_len - 1; - GET_NEXT_WCHAR(); - } - else - { - goto backtrack; - } - } - else - { - /* Check for end of string. */ - if (next_c == L'\0') - goto backtrack; - - /* Read the next character. */ - GET_NEXT_WCHAR(); - } - - next_state = NULL; - for (trans_i = state; trans_i->state; trans_i++) - { - if (trans_i->code_min <= (tre_cint_t)prev_c - && trans_i->code_max >= (tre_cint_t)prev_c) - { - if (trans_i->assertions - && (CHECK_ASSERTIONS(trans_i->assertions) - || CHECK_CHAR_CLASSES(trans_i, tnfa, eflags))) - { - continue; - } - - if (next_state == NULL) - { - /* First matching transition. */ - next_state = trans_i->state; - next_tags = trans_i->tags; - } - else - { - /* Second matching transition. We may need to backtrack here - to take this transition instead of the first one, so we - push this transition in the backtracking stack so we can - jump back here if needed. */ - BT_STACK_PUSH(pos, str_byte, 0, trans_i->state, - trans_i->state_id, next_c, tags, mbstate); - { - int *tmp; - for (tmp = trans_i->tags; tmp && *tmp >= 0; tmp++) - stack->item.tags[*tmp] = pos; - } -#if 0 /* XXX - it's important not to look at all transitions here to keep - the stack small! */ - break; -#endif - } - } - } - - if (next_state != NULL) - { - /* Matching transitions were found. Take the first one. */ - state = next_state; - - /* Update the tag values. */ - if (next_tags) - while (*next_tags >= 0) - tags[*next_tags++] = pos; - } - else - { - backtrack: - /* A matching transition was not found. Try to backtrack. */ - if (stack->prev) - { - if (stack->item.state->assertions & ASSERT_BACKREF) - { - states_seen[stack->item.state_id] = 0; - } - - BT_STACK_POP(); - } - else if (match_eo < 0) - { - /* Try starting from a later position in the input string. */ - /* Check for end of string. */ - if (next_c == L'\0') - { - break; - } - next_c = next_c_start; -#ifdef TRE_MBSTATE - mbstate = mbstate_start; -#endif /* TRE_MBSTATE */ - str_byte = str_byte_start; - goto retry; - } - else - { - break; - } - } - } - - ret = match_eo >= 0 ? REG_OK : REG_NOMATCH; - *match_end_ofs = match_eo; - - error_exit: - tre_bt_mem_destroy(mem); -#ifndef TRE_USE_ALLOCA - if (tags) - xfree(tags); - if (pmatch) - xfree(pmatch); - if (states_seen) - xfree(states_seen); -#endif /* !TRE_USE_ALLOCA */ - - return ret; -} - -/*********************************************************************** - from regexec.c -***********************************************************************/ - -/* Fills the POSIX.2 regmatch_t array according to the TNFA tag and match - endpoint values. */ -static void -tre_fill_pmatch(size_t nmatch, regmatch_t pmatch[], int cflags, - const tre_tnfa_t *tnfa, regoff_t *tags, regoff_t match_eo) -{ - tre_submatch_data_t *submatch_data; - unsigned int i, j; - int *parents; - - i = 0; - if (match_eo >= 0 && !(cflags & REG_NOSUB)) - { - /* Construct submatch offsets from the tags. */ - submatch_data = tnfa->submatch_data; - while (i < tnfa->num_submatches && i < nmatch) - { - if (submatch_data[i].so_tag == tnfa->end_tag) - pmatch[i].rm_so = match_eo; - else - pmatch[i].rm_so = tags[submatch_data[i].so_tag]; - - if (submatch_data[i].eo_tag == tnfa->end_tag) - pmatch[i].rm_eo = match_eo; - else - pmatch[i].rm_eo = tags[submatch_data[i].eo_tag]; - - /* If either of the endpoints were not used, this submatch - was not part of the match. */ - if (pmatch[i].rm_so == -1 || pmatch[i].rm_eo == -1) - pmatch[i].rm_so = pmatch[i].rm_eo = -1; - - i++; - } - /* Reset all submatches that are not within all of their parent - submatches. */ - i = 0; - while (i < tnfa->num_submatches && i < nmatch) - { - if (pmatch[i].rm_eo == -1) - assert(pmatch[i].rm_so == -1); - assert(pmatch[i].rm_so <= pmatch[i].rm_eo); - - parents = submatch_data[i].parents; - if (parents != NULL) - for (j = 0; parents[j] >= 0; j++) - { - if (pmatch[i].rm_so < pmatch[parents[j]].rm_so - || pmatch[i].rm_eo > pmatch[parents[j]].rm_eo) - pmatch[i].rm_so = pmatch[i].rm_eo = -1; - } - i++; - } - } - - while (i < nmatch) - { - pmatch[i].rm_so = -1; - pmatch[i].rm_eo = -1; - i++; - } -} - - -/* - Wrapper functions for POSIX compatible regexp matching. -*/ - -int -regexec(const regex_t *restrict preg, const char *restrict string, - size_t nmatch, regmatch_t pmatch[restrict], int eflags) -{ - tre_tnfa_t *tnfa = (void *)preg->TRE_REGEX_T_FIELD; - reg_errcode_t status; - regoff_t *tags = NULL, eo; - if (tnfa->cflags & REG_NOSUB) nmatch = 0; - if (tnfa->num_tags > 0 && nmatch > 0) - { - tags = xmalloc(sizeof(*tags) * tnfa->num_tags); - if (tags == NULL) - return REG_ESPACE; - } - - /* Dispatch to the appropriate matcher. */ - if (tnfa->have_backrefs) - { - /* The regex has back references, use the backtracking matcher. */ - status = tre_tnfa_run_backtrack(tnfa, string, tags, eflags, &eo); - } - else - { - /* Exact matching, no back references, use the parallel matcher. */ - status = tre_tnfa_run_parallel(tnfa, string, tags, eflags, &eo); - } - - if (status == REG_OK) - /* A match was found, so fill the submatch registers. */ - tre_fill_pmatch(nmatch, pmatch, tnfa->cflags, tnfa, tags, eo); - if (tags) - xfree(tags); - return status; -}
\ No newline at end of file diff --git a/lib/mlibc/options/posix/musl-generic-regex/tre-mem.c b/lib/mlibc/options/posix/musl-generic-regex/tre-mem.c deleted file mode 100644 index a3df685..0000000 --- a/lib/mlibc/options/posix/musl-generic-regex/tre-mem.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - tre-mem.c - TRE memory allocator - - Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi> - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -/* - This memory allocator is for allocating small memory blocks efficiently - in terms of memory overhead and execution speed. The allocated blocks - cannot be freed individually, only all at once. There can be multiple - allocators, though. -*/ - -#include <stdlib.h> -#include <string.h> - -#include "tre.h" - -/* - This memory allocator is for allocating small memory blocks efficiently - in terms of memory overhead and execution speed. The allocated blocks - cannot be freed individually, only all at once. There can be multiple - allocators, though. -*/ - -/* Returns a new memory allocator or NULL if out of memory. */ -tre_mem_t -tre_mem_new_impl(int provided, void *provided_block) -{ - tre_mem_t mem; - if (provided) - { - mem = provided_block; - memset(mem, 0, sizeof(*mem)); - } - else - mem = xcalloc(1, sizeof(*mem)); - if (mem == NULL) - return NULL; - return mem; -} - - -/* Frees the memory allocator and all memory allocated with it. */ -void -tre_mem_destroy(tre_mem_t mem) -{ - tre_list_t *tmp, *l = mem->blocks; - - while (l != NULL) - { - xfree(l->data); - tmp = l->next; - xfree(l); - l = tmp; - } - xfree(mem); -} - - -/* Allocates a block of `size' bytes from `mem'. Returns a pointer to the - allocated block or NULL if an underlying malloc() failed. */ -void * -tre_mem_alloc_impl(tre_mem_t mem, int provided, void *provided_block, - int zero, size_t size) -{ - void *ptr; - - if (mem->failed) - { - return NULL; - } - - if (mem->n < size) - { - /* We need more memory than is available in the current block. - Allocate a new block. */ - tre_list_t *l; - if (provided) - { - if (provided_block == NULL) - { - mem->failed = 1; - return NULL; - } - mem->ptr = provided_block; - mem->n = TRE_MEM_BLOCK_SIZE; - } - else - { - int block_size; - if (size * 8 > TRE_MEM_BLOCK_SIZE) - block_size = size * 8; - else - block_size = TRE_MEM_BLOCK_SIZE; - l = xmalloc(sizeof(*l)); - if (l == NULL) - { - mem->failed = 1; - return NULL; - } - l->data = xmalloc(block_size); - if (l->data == NULL) - { - xfree(l); - mem->failed = 1; - return NULL; - } - l->next = NULL; - if (mem->current != NULL) - mem->current->next = l; - if (mem->blocks == NULL) - mem->blocks = l; - mem->current = l; - mem->ptr = l->data; - mem->n = block_size; - } - } - - /* Make sure the next pointer will be aligned. */ - size += ALIGN(mem->ptr + size, long); - - /* Allocate from current block. */ - ptr = mem->ptr; - mem->ptr += size; - mem->n -= size; - - /* Set to zero if needed. */ - if (zero) - memset(ptr, 0, size); - - return ptr; -}
\ No newline at end of file diff --git a/lib/mlibc/options/posix/musl-generic-regex/tre.h b/lib/mlibc/options/posix/musl-generic-regex/tre.h deleted file mode 100644 index 5891f75..0000000 --- a/lib/mlibc/options/posix/musl-generic-regex/tre.h +++ /dev/null @@ -1,241 +0,0 @@ -// Taken from musl tre.h -/* - tre-internal.h - TRE internal definitions - - Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi> - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#include <regex.h> -#include <wchar.h> -#include <wctype.h> - -#define hidden __attribute__((__visibility__("hidden"))) - -// TODO: These should probably go in limits.h -#define CHARCLASS_NAME_MAX 14 -#define RE_DUP_MAX 255 - -#undef TRE_MBSTATE - -#define NDEBUG - -#define TRE_REGEX_T_FIELD __opaque -typedef int reg_errcode_t; - -typedef wchar_t tre_char_t; - -#define DPRINT(msg) do { } while(0) - -#define elementsof(x) ( sizeof(x) / sizeof(x[0]) ) - -#define tre_mbrtowc(pwc, s, n, ps) (mbtowc((pwc), (s), (n))) - -/* Wide characters. */ -typedef wint_t tre_cint_t; -#define TRE_CHAR_MAX 0x10ffff - -#define tre_isalnum iswalnum -#define tre_isalpha iswalpha -#define tre_isblank iswblank -#define tre_iscntrl iswcntrl -#define tre_isdigit iswdigit -#define tre_isgraph iswgraph -#define tre_islower iswlower -#define tre_isprint iswprint -#define tre_ispunct iswpunct -#define tre_isspace iswspace -#define tre_isupper iswupper -#define tre_isxdigit iswxdigit - -#define tre_tolower towlower -#define tre_toupper towupper -#define tre_strlen wcslen - -/* Use system provided iswctype() and wctype(). */ -typedef wctype_t tre_ctype_t; -#define tre_isctype iswctype -#define tre_ctype wctype - -/* Returns number of bytes to add to (char *)ptr to make it - properly aligned for the type. */ -#define ALIGN(ptr, type) \ - ((((long)ptr) % sizeof(type)) \ - ? (sizeof(type) - (((long)ptr) % sizeof(type))) \ - : 0) - -#undef MAX -#undef MIN -#define MAX(a, b) (((a) >= (b)) ? (a) : (b)) -#define MIN(a, b) (((a) <= (b)) ? (a) : (b)) - -/* TNFA transition type. A TNFA state is an array of transitions, - the terminator is a transition with NULL `state'. */ -typedef struct tnfa_transition tre_tnfa_transition_t; - -struct tnfa_transition { - /* Range of accepted characters. */ - tre_cint_t code_min; - tre_cint_t code_max; - /* Pointer to the destination state. */ - tre_tnfa_transition_t *state; - /* ID number of the destination state. */ - int state_id; - /* -1 terminated array of tags (or NULL). */ - int *tags; - /* Assertion bitmap. */ - int assertions; - /* Assertion parameters. */ - union { - /* Character class assertion. */ - tre_ctype_t class; - /* Back reference assertion. */ - int backref; - } u; - /* Negative character class assertions. */ - tre_ctype_t *neg_classes; -}; - - -/* Assertions. */ -#define ASSERT_AT_BOL 1 /* Beginning of line. */ -#define ASSERT_AT_EOL 2 /* End of line. */ -#define ASSERT_CHAR_CLASS 4 /* Character class in `class'. */ -#define ASSERT_CHAR_CLASS_NEG 8 /* Character classes in `neg_classes'. */ -#define ASSERT_AT_BOW 16 /* Beginning of word. */ -#define ASSERT_AT_EOW 32 /* End of word. */ -#define ASSERT_AT_WB 64 /* Word boundary. */ -#define ASSERT_AT_WB_NEG 128 /* Not a word boundary. */ -#define ASSERT_BACKREF 256 /* A back reference in `backref'. */ -#define ASSERT_LAST 256 - -/* Tag directions. */ -typedef enum { - TRE_TAG_MINIMIZE = 0, - TRE_TAG_MAXIMIZE = 1 -} tre_tag_direction_t; - -/* Instructions to compute submatch register values from tag values - after a successful match. */ -struct tre_submatch_data { - /* Tag that gives the value for rm_so (submatch start offset). */ - int so_tag; - /* Tag that gives the value for rm_eo (submatch end offset). */ - int eo_tag; - /* List of submatches this submatch is contained in. */ - int *parents; -}; - -typedef struct tre_submatch_data tre_submatch_data_t; - - -/* TNFA definition. */ -typedef struct tnfa tre_tnfa_t; - -struct tnfa { - tre_tnfa_transition_t *transitions; - unsigned int num_transitions; - tre_tnfa_transition_t *initial; - tre_tnfa_transition_t *final; - tre_submatch_data_t *submatch_data; - char *firstpos_chars; - int first_char; - unsigned int num_submatches; - tre_tag_direction_t *tag_directions; - int *minimal_tags; - int num_tags; - int num_minimals; - int end_tag; - int num_states; - int cflags; - int have_backrefs; - int have_approx; -}; - -/* from tre-mem.h: */ - -#define TRE_MEM_BLOCK_SIZE 1024 - -typedef struct tre_list { - void *data; - struct tre_list *next; -} tre_list_t; - -typedef struct tre_mem_struct { - tre_list_t *blocks; - tre_list_t *current; - char *ptr; - size_t n; - int failed; - void **provided; -} *tre_mem_t; - -#ifndef __MLIBC_ABI_ONLY - -#define tre_mem_new_impl __tre_mem_new_impl -#define tre_mem_alloc_impl __tre_mem_alloc_impl -#define tre_mem_destroy __tre_mem_destroy - -hidden tre_mem_t tre_mem_new_impl(int provided, void *provided_block); -hidden void *tre_mem_alloc_impl(tre_mem_t mem, int provided, void *provided_block, - int zero, size_t size); - -/* Returns a new memory allocator or NULL if out of memory. */ -#define tre_mem_new() tre_mem_new_impl(0, NULL) - -/* Allocates a block of `size' bytes from `mem'. Returns a pointer to the - allocated block or NULL if an underlying malloc() failed. */ -#define tre_mem_alloc(mem, size) tre_mem_alloc_impl(mem, 0, NULL, 0, size) - -/* Allocates a block of `size' bytes from `mem'. Returns a pointer to the - allocated block or NULL if an underlying malloc() failed. The memory - is set to zero. */ -#define tre_mem_calloc(mem, size) tre_mem_alloc_impl(mem, 0, NULL, 1, size) - -#ifdef TRE_USE_ALLOCA -/* alloca() versions. Like above, but memory is allocated with alloca() - instead of malloc(). */ - -#define tre_mem_newa() \ - tre_mem_new_impl(1, alloca(sizeof(struct tre_mem_struct))) - -#define tre_mem_alloca(mem, size) \ - ((mem)->n >= (size) \ - ? tre_mem_alloc_impl((mem), 1, NULL, 0, (size)) \ - : tre_mem_alloc_impl((mem), 1, alloca(TRE_MEM_BLOCK_SIZE), 0, (size))) -#endif /* TRE_USE_ALLOCA */ - - -/* Frees the memory allocator and all memory allocated with it. */ -hidden void tre_mem_destroy(tre_mem_t mem); - -#define xmalloc malloc -#define xcalloc calloc -#define xfree free -#define xrealloc realloc - -#endif /* !__MLIBC_ABI_ONLY */ |