mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
350 lines
11 KiB
Diff
350 lines
11 KiB
Diff
diff --git mlibc-clean/options/glibc/generic/stdio_ext.cpp mlibc-workdir/options/glibc/generic/stdio_ext.cpp
|
|
index ccb37257..3dfa27af 100644
|
|
--- mlibc-clean/options/glibc/generic/stdio_ext.cpp
|
|
+++ mlibc-workdir/options/glibc/generic/stdio_ext.cpp
|
|
@@ -71,14 +71,38 @@ size_t __freadahead(FILE *file_base) {
|
|
return file_base->__valid_limit - file_base->__offset;
|
|
}
|
|
|
|
-const char *__freadptr(FILE *, size_t *) {
|
|
- __ensure(!"Not implemented");
|
|
- __builtin_unreachable();
|
|
+const char *__freadptr(FILE *file_base, size_t *size) {
|
|
+ if(file_base->__io_mode != 0) {
|
|
+ mlibc::infoLogger() << "mlibc: __freadptr() called but file is not open for reading" << frg::endlog;
|
|
+ *size = 0;
|
|
+ return nullptr;
|
|
+ }
|
|
+
|
|
+ if(file_base->__unget_ptr != file_base->__buffer_ptr) {
|
|
+ *size = file_base->__buffer_ptr - file_base->__unget_ptr;
|
|
+ return file_base->__unget_ptr;
|
|
+ }
|
|
+
|
|
+ if(file_base->__offset == file_base->__valid_limit) {
|
|
+ *size = 0;
|
|
+ return nullptr;
|
|
+ }
|
|
+
|
|
+ *size = file_base->__valid_limit - file_base->__offset;
|
|
+ return file_base->__buffer_ptr + file_base->__offset;
|
|
}
|
|
|
|
-void __freadptrinc(FILE *, size_t) {
|
|
- __ensure(!"Not implemented");
|
|
- __builtin_unreachable();
|
|
+void __freadptrinc(FILE *file_base, size_t increment) {
|
|
+ size_t unget_size = file_base->__buffer_ptr ? file_base->__buffer_ptr - file_base->__unget_ptr : 0;
|
|
+ if(increment <= unget_size) {
|
|
+ file_base->__unget_ptr += increment;
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ increment -= unget_size;
|
|
+ file_base->__unget_ptr = file_base->__buffer_ptr;
|
|
+ __ensure(file_base->__offset + increment <= file_base->__valid_limit);
|
|
+ file_base->__offset += increment;
|
|
}
|
|
|
|
void __fseterr(FILE *file_base) {
|
|
@@ -87,4 +111,3 @@ void __fseterr(FILE *file_base) {
|
|
// set the error indicator for the stream
|
|
file->__status_bits |= __MLIBC_ERROR_BIT;
|
|
}
|
|
-
|
|
diff --git mlibc-clean/options/internal/generic/threads.cpp mlibc-workdir/options/internal/generic/threads.cpp
|
|
index 2b9abbc0..0be01957 100644
|
|
--- mlibc-clean/options/internal/generic/threads.cpp
|
|
+++ mlibc-workdir/options/internal/generic/threads.cpp
|
|
@@ -269,11 +269,16 @@ int thread_mutex_destroy(struct __mlibc_mutex *mutex) {
|
|
int thread_mutex_timedlock(struct __mlibc_mutex *mutex, const struct timespec *__restrict abstime, clockid_t clockid) {
|
|
unsigned int this_tid = mlibc::this_tid();
|
|
unsigned int expected = 0;
|
|
+ bool contended = false;
|
|
while(true) {
|
|
if(!expected) {
|
|
// Try to take the mutex here.
|
|
+ unsigned int desired = this_tid;
|
|
+ // Preserve the waiters bit after contention, as other waiters may still be asleep.
|
|
+ if(contended)
|
|
+ desired |= __mlibc_mutex::mutex_waiters_bit;
|
|
if(__atomic_compare_exchange_n(&mutex->__mlibc_state,
|
|
- &expected, this_tid | __mlibc_mutex::mutex_waiters_bit, false, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE)) {
|
|
+ &expected, desired, false, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE)) {
|
|
__ensure(!mutex->__mlibc_recursion);
|
|
mutex->__mlibc_recursion = 1;
|
|
return 0;
|
|
@@ -289,6 +294,8 @@ int thread_mutex_timedlock(struct __mlibc_mutex *mutex, const struct timespec *_
|
|
}
|
|
}
|
|
|
|
+ contended = true;
|
|
+
|
|
// Wait on the futex if the waiters flag is set.
|
|
if(expected & __mlibc_mutex::mutex_waiters_bit) {
|
|
int e;
|
|
diff --git mlibc-clean/options/internal/include/mlibc/allocator.hpp mlibc-workdir/options/internal/include/mlibc/allocator.hpp
|
|
index d5496df8..4dac6dbd 100644
|
|
--- mlibc-clean/options/internal/include/mlibc/allocator.hpp
|
|
+++ mlibc-workdir/options/internal/include/mlibc/allocator.hpp
|
|
@@ -11,6 +11,8 @@
|
|
|
|
struct VirtualAllocator {
|
|
public:
|
|
+ static constexpr size_t num_buckets = 14;
|
|
+
|
|
uintptr_t map(size_t length);
|
|
|
|
void unmap(uintptr_t address, size_t length);
|
|
diff --git mlibc-clean/options/linux/generic/malloc.cpp mlibc-workdir/options/linux/generic/malloc.cpp
|
|
index 065de6c1..10c73955 100644
|
|
--- mlibc-clean/options/linux/generic/malloc.cpp
|
|
+++ mlibc-workdir/options/linux/generic/malloc.cpp
|
|
@@ -1,7 +1,13 @@
|
|
-#include <bits/ensure.h>
|
|
+#include <errno.h>
|
|
#include <malloc.h>
|
|
+#include <stdlib.h>
|
|
|
|
-void *memalign(size_t, size_t) {
|
|
- __ensure(!"Not implemented");
|
|
- __builtin_unreachable();
|
|
+void *memalign(size_t alignment, size_t size) {
|
|
+ void *ptr;
|
|
+ int ret = posix_memalign(&ptr, alignment, size);
|
|
+ if(ret) {
|
|
+ errno = ret;
|
|
+ return nullptr;
|
|
+ }
|
|
+ return ptr;
|
|
}
|
|
diff --git mlibc-clean/options/posix/generic/monetary.cpp mlibc-workdir/options/posix/generic/monetary.cpp
|
|
index 55a567aa..d1d77873 100644
|
|
--- mlibc-clean/options/posix/generic/monetary.cpp
|
|
+++ mlibc-workdir/options/posix/generic/monetary.cpp
|
|
@@ -389,6 +389,8 @@ ssize_t strfmon_internal(char *__restrict s, size_t maxsize, mlibc::localeinfo *
|
|
false,
|
|
false,
|
|
false,
|
|
+ false,
|
|
+ false,
|
|
opts
|
|
);
|
|
|
|
diff --git mlibc-clean/options/posix/include/bits/posix/posix_stdio.h mlibc-workdir/options/posix/include/bits/posix/posix_stdio.h
|
|
index f0d6edd1..ab57b6b1 100644
|
|
--- mlibc-clean/options/posix/include/bits/posix/posix_stdio.h
|
|
+++ mlibc-workdir/options/posix/include/bits/posix/posix_stdio.h
|
|
@@ -63,6 +63,7 @@ char *fgetln(FILE *__stream, size_t *__size);
|
|
#endif /* !__MLIBC_ABI_ONLY */
|
|
|
|
#if defined(_GNU_SOURCE)
|
|
+#define RENAME_NOREPLACE (1 << 0)
|
|
#define RENAME_EXCHANGE (1 << 1)
|
|
|
|
/* GNU extensions */
|
|
@@ -97,4 +98,3 @@ FILE *fopencookie(void *__restrict __cookie, const char *__restrict __mode, cook
|
|
|
|
#endif /* _MLIBC_POSIX_STDIO_H */
|
|
|
|
-
|
|
diff --git mlibc-clean/options/posix/musl-generic-regex/glob.c mlibc-workdir/options/posix/musl-generic-regex/glob.c
|
|
index 411f6a84..cbf0fd26 100644
|
|
--- mlibc-clean/options/posix/musl-generic-regex/glob.c
|
|
+++ mlibc-workdir/options/posix/musl-generic-regex/glob.c
|
|
@@ -18,6 +18,58 @@ struct match
|
|
char name[];
|
|
};
|
|
|
|
+struct glob_context
|
|
+{
|
|
+ int (*errfunc)(const char *path, int err);
|
|
+ __typeof__(((glob_t *)0)->gl_opendir) opendir;
|
|
+ __typeof__(((glob_t *)0)->gl_readdir) readdir;
|
|
+ __typeof__(((glob_t *)0)->gl_closedir) closedir;
|
|
+ __typeof__(((glob_t *)0)->gl_stat) stat;
|
|
+ __typeof__(((glob_t *)0)->gl_lstat) lstat;
|
|
+};
|
|
+
|
|
+static void *default_opendir(const char *path)
|
|
+{
|
|
+ return opendir(path);
|
|
+}
|
|
+
|
|
+#if defined(_GNU_SOURCE)
|
|
+static struct dirent *default_readdir(void *dir)
|
|
+{
|
|
+ return readdir(dir);
|
|
+}
|
|
+
|
|
+static int default_stat(const char *path, struct stat *st)
|
|
+{
|
|
+ return stat(path, st);
|
|
+}
|
|
+
|
|
+static int default_lstat(const char *path, struct stat *st)
|
|
+{
|
|
+ return lstat(path, st);
|
|
+}
|
|
+#else
|
|
+static void *default_readdir(void *dir)
|
|
+{
|
|
+ return readdir(dir);
|
|
+}
|
|
+
|
|
+static int default_stat(const char *path, void *st)
|
|
+{
|
|
+ return stat(path, st);
|
|
+}
|
|
+
|
|
+static int default_lstat(const char *path, void *st)
|
|
+{
|
|
+ return lstat(path, st);
|
|
+}
|
|
+#endif
|
|
+
|
|
+static void default_closedir(void *dir)
|
|
+{
|
|
+ closedir(dir);
|
|
+}
|
|
+
|
|
static int append(struct match **tail, const char *name, size_t len, int mark)
|
|
{
|
|
struct match *new = malloc(sizeof(struct match) + len + 2);
|
|
@@ -33,7 +85,7 @@ static int append(struct match **tail, const char *name, size_t len, int mark)
|
|
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)
|
|
+static int do_glob(char *buf, size_t pos, int type, char *pat, int flags, struct glob_context *context, struct match **tail)
|
|
{
|
|
/* If GLOB_MARK is unused, we don't care about type. */
|
|
if (!type && !(flags & GLOB_MARK)) type = DT_REG;
|
|
@@ -101,12 +153,12 @@ static int do_glob(char *buf, size_t pos, int type, char *pat, int flags, int (*
|
|
* 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 ((flags & GLOB_MARK) && (!type||type==DT_LNK) && !context->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)))
|
|
+ if (!type && context->lstat(buf, &st)) {
|
|
+ if (errno!=ENOENT && (context->errfunc(buf, errno) || (flags & GLOB_ERR)))
|
|
return GLOB_ABORTED;
|
|
return 0;
|
|
}
|
|
@@ -125,15 +177,15 @@ static int do_glob(char *buf, size_t pos, int type, char *pat, int flags, int (*
|
|
saved_sep = '\\';
|
|
}
|
|
}
|
|
- DIR *dir = opendir(pos ? buf : ".");
|
|
+ void *dir = context->opendir(pos ? buf : ".");
|
|
if (!dir) {
|
|
- if (errfunc(buf, errno) || (flags & GLOB_ERR))
|
|
+ if (context->errfunc(buf, errno) || (flags & GLOB_ERR))
|
|
return GLOB_ABORTED;
|
|
return 0;
|
|
}
|
|
int old_errno = errno;
|
|
struct dirent *de;
|
|
- while (errno=0, de=readdir(dir)) {
|
|
+ while (errno=0, de=context->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;
|
|
@@ -158,16 +210,16 @@ static int do_glob(char *buf, size_t pos, int type, char *pat, int flags, int (*
|
|
|
|
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);
|
|
+ int r = do_glob(buf, pos+l, de->d_type, p2 ? p2 : "", flags, context, tail);
|
|
if (r) {
|
|
- closedir(dir);
|
|
+ context->closedir(dir);
|
|
return r;
|
|
}
|
|
}
|
|
int readerr = errno;
|
|
if (p2) *p2 = saved_sep;
|
|
- closedir(dir);
|
|
- if (readerr && (errfunc(buf, errno) || (flags & GLOB_ERR)))
|
|
+ context->closedir(dir);
|
|
+ if (readerr && (context->errfunc(buf, errno) || (flags & GLOB_ERR)))
|
|
return GLOB_ABORTED;
|
|
errno = old_errno;
|
|
return 0;
|
|
@@ -228,13 +280,19 @@ static int expand_tilde(char **pat, char *buf, size_t *pos)
|
|
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;
|
|
+ struct glob_context context = {
|
|
+ .errfunc = errfunc ? errfunc : ignore_err,
|
|
+ .opendir = (flags & GLOB_ALTDIRFUNC) ? g->gl_opendir : default_opendir,
|
|
+ .readdir = (flags & GLOB_ALTDIRFUNC) ? g->gl_readdir : default_readdir,
|
|
+ .closedir = (flags & GLOB_ALTDIRFUNC) ? g->gl_closedir : default_closedir,
|
|
+ .stat = (flags & GLOB_ALTDIRFUNC) ? g->gl_stat : default_stat,
|
|
+ .lstat = (flags & GLOB_ALTDIRFUNC) ? g->gl_lstat : default_lstat,
|
|
+ };
|
|
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;
|
|
@@ -250,7 +308,7 @@ int glob(const char *restrict pat, int flags, int (*errfunc)(const char *path, i
|
|
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);
|
|
+ error = do_glob(buf, pos, 0, s, flags, &context, &tail);
|
|
free(p);
|
|
}
|
|
|
|
diff --git mlibc-workdir/tests/glibc/memalign.c mlibc-workdir/tests/glibc/memalign.c
|
|
new file mode 100644
|
|
index 00000000..0b3a1581
|
|
--- /dev/null
|
|
+++ mlibc-workdir/tests/glibc/memalign.c
|
|
@@ -0,0 +1,22 @@
|
|
+#include <assert.h>
|
|
+#include <errno.h>
|
|
+#include <malloc.h>
|
|
+#include <stdint.h>
|
|
+#include <stdlib.h>
|
|
+
|
|
+int main(void) {
|
|
+ void *p;
|
|
+
|
|
+ errno = 0;
|
|
+ p = memalign(256, 1);
|
|
+ assert(p != NULL);
|
|
+ assert((uintptr_t)p % 256 == 0);
|
|
+ free(p);
|
|
+
|
|
+ errno = 0;
|
|
+ p = memalign(3, 1);
|
|
+ assert(p == NULL);
|
|
+ assert(errno == EINVAL);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
diff --git mlibc-clean/tests/meson.build mlibc-workdir/tests/meson.build
|
|
index 85b967c9..f555a1ec 100644
|
|
--- mlibc-clean/tests/meson.build
|
|
+++ mlibc-workdir/tests/meson.build
|
|
@@ -190,6 +190,7 @@ all_test_cases = [
|
|
'glibc/rpmatch',
|
|
'glibc/strverscmp',
|
|
'glibc/memmem',
|
|
+ 'glibc/memalign',
|
|
'glibc/stdio_ext',
|
|
'glibc/_dl_find_object',
|
|
'glibc/shadow',
|