summaryrefslogtreecommitdiff
path: root/lib/mlibc/options/glibc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mlibc/options/glibc')
-rw-r--r--lib/mlibc/options/glibc/generic/err.cpp64
-rw-r--r--lib/mlibc/options/glibc/generic/error.cpp65
-rw-r--r--lib/mlibc/options/glibc/generic/execinfo.cpp17
-rw-r--r--lib/mlibc/options/glibc/generic/getopt-stubs.cpp253
-rw-r--r--lib/mlibc/options/glibc/generic/glibc-assert.cpp14
-rw-r--r--lib/mlibc/options/glibc/generic/glibc-signal.cpp14
-rw-r--r--lib/mlibc/options/glibc/generic/gshadow.cpp7
-rw-r--r--lib/mlibc/options/glibc/generic/malloc.cpp6
-rw-r--r--lib/mlibc/options/glibc/generic/personality.cpp15
-rw-r--r--lib/mlibc/options/glibc/generic/printf.cpp7
-rw-r--r--lib/mlibc/options/glibc/generic/resolv-stubs.cpp36
-rw-r--r--lib/mlibc/options/glibc/generic/shadow-stubs.cpp217
-rw-r--r--lib/mlibc/options/glibc/generic/stdio_ext-stubs.cpp64
-rw-r--r--lib/mlibc/options/glibc/generic/string.cpp32
-rw-r--r--lib/mlibc/options/glibc/generic/sys-io.cpp25
-rw-r--r--lib/mlibc/options/glibc/generic/sys-ioctl.cpp21
-rw-r--r--lib/mlibc/options/glibc/generic/sys-timex.cpp17
-rw-r--r--lib/mlibc/options/glibc/include/ar.h27
-rw-r--r--lib/mlibc/options/glibc/include/bits/glibc/glibc_assert.h32
-rw-r--r--lib/mlibc/options/glibc/include/bits/glibc/glibc_icmp6.h21
-rw-r--r--lib/mlibc/options/glibc/include/bits/glibc/glibc_malloc.h17
-rw-r--r--lib/mlibc/options/glibc/include/bits/glibc/glibc_signal.h24
-rw-r--r--lib/mlibc/options/glibc/include/endian.h54
-rw-r--r--lib/mlibc/options/glibc/include/err.h29
-rw-r--r--lib/mlibc/options/glibc/include/error.h25
-rw-r--r--lib/mlibc/options/glibc/include/execinfo.h20
-rw-r--r--lib/mlibc/options/glibc/include/features.h6
-rw-r--r--lib/mlibc/options/glibc/include/getopt.h44
-rw-r--r--lib/mlibc/options/glibc/include/gshadow.h30
-rw-r--r--lib/mlibc/options/glibc/include/memory.h6
-rw-r--r--lib/mlibc/options/glibc/include/mlibc/glibc-sysdeps.hpp16
-rw-r--r--lib/mlibc/options/glibc/include/net/ethernet.h42
-rw-r--r--lib/mlibc/options/glibc/include/net/if_ppp.h23
-rw-r--r--lib/mlibc/options/glibc/include/net/route.h35
-rw-r--r--lib/mlibc/options/glibc/include/netax25/ax25.h51
-rw-r--r--lib/mlibc/options/glibc/include/netinet/in_systm.h7
-rw-r--r--lib/mlibc/options/glibc/include/netipx/ipx.h35
-rw-r--r--lib/mlibc/options/glibc/include/netrom/netrom.h27
-rw-r--r--lib/mlibc/options/glibc/include/paths.h41
-rw-r--r--lib/mlibc/options/glibc/include/printf.h41
-rw-r--r--lib/mlibc/options/glibc/include/resolv.h73
-rw-r--r--lib/mlibc/options/glibc/include/shadow.h42
-rw-r--r--lib/mlibc/options/glibc/include/stdio_ext.h41
-rw-r--r--lib/mlibc/options/glibc/include/sys/dir.h8
-rw-r--r--lib/mlibc/options/glibc/include/sys/endian.h0
-rw-r--r--lib/mlibc/options/glibc/include/sys/errno.h1
-rw-r--r--lib/mlibc/options/glibc/include/sys/io.h108
-rw-r--r--lib/mlibc/options/glibc/include/sys/ioctl.h44
-rw-r--r--lib/mlibc/options/glibc/include/sys/kd.h17
-rw-r--r--lib/mlibc/options/glibc/include/sys/mtio.h103
-rw-r--r--lib/mlibc/options/glibc/include/sys/personality.h58
-rw-r--r--lib/mlibc/options/glibc/include/sys/procfs.h54
-rw-r--r--lib/mlibc/options/glibc/include/sys/reg.h36
-rw-r--r--lib/mlibc/options/glibc/include/sys/signal.h1
-rw-r--r--lib/mlibc/options/glibc/include/sys/timeb.h14
-rw-r--r--lib/mlibc/options/glibc/include/sys/timex.h78
-rw-r--r--lib/mlibc/options/glibc/include/sys/ucontext.h14
-rw-r--r--lib/mlibc/options/glibc/include/sys/user.h49
-rw-r--r--lib/mlibc/options/glibc/include/sysexits.h24
-rw-r--r--lib/mlibc/options/glibc/meson.build90
60 files changed, 2382 insertions, 0 deletions
diff --git a/lib/mlibc/options/glibc/generic/err.cpp b/lib/mlibc/options/glibc/generic/err.cpp
new file mode 100644
index 0000000..042c1d8
--- /dev/null
+++ b/lib/mlibc/options/glibc/generic/err.cpp
@@ -0,0 +1,64 @@
+#include <err.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+// va_list
+
+void vwarn(const char *fmt, va_list params) {
+ fprintf(stderr, "%s: ", program_invocation_short_name);
+ if (fmt) {
+ vfprintf(stderr, fmt, params);
+ fwrite(": ", 1, 2, stderr);
+ }
+ perror(NULL);
+}
+
+void vwarnx(const char *fmt, va_list params) {
+ fprintf(stderr, "%s: ", program_invocation_short_name);
+ if (fmt) {
+ vfprintf(stderr, fmt, params);
+ }
+ putc('\n', stderr);
+}
+
+__attribute__((__noreturn__)) void verr(int status, const char *fmt, va_list params) {
+ vwarn(fmt, params);
+ exit(status);
+}
+
+__attribute__((__noreturn__)) void verrx(int status, const char *fmt, va_list params) {
+ vwarnx(fmt, params);
+ exit(status);
+}
+
+// variadic
+
+void warn(const char *fmt, ...) {
+ va_list params;
+ va_start(params, fmt);
+ vwarn(fmt, params);
+ va_end(params);
+}
+
+void warnx(const char *fmt, ...) {
+ va_list params;
+ va_start(params, fmt);
+ vwarnx(fmt, params);
+ va_end(params);
+}
+
+__attribute__((__noreturn__)) void err(int status, const char *fmt, ...) {
+ va_list params;
+ va_start(params, fmt);
+ verr(status, fmt, params);
+ va_end(params);
+}
+
+__attribute__((__noreturn__)) void errx(int status, const char *fmt, ...) {
+ va_list params;
+ va_start(params, fmt);
+ verrx(status, fmt, params);
+ va_end(params);
+}
diff --git a/lib/mlibc/options/glibc/generic/error.cpp b/lib/mlibc/options/glibc/generic/error.cpp
new file mode 100644
index 0000000..45203b2
--- /dev/null
+++ b/lib/mlibc/options/glibc/generic/error.cpp
@@ -0,0 +1,65 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <error.h>
+
+unsigned int error_message_count = 0;
+int error_one_per_line = 0;
+void (*error_print_progname)(void) = NULL;
+
+void error(int status, int errnum, const char *format, ...) {
+ va_list args;
+ va_start(args, format);
+
+ error_message_count++;
+
+ fflush(stdout);
+ if(error_print_progname) {
+ error_print_progname();
+ } else {
+ fprintf(stderr, "%s: ", program_invocation_name);
+ }
+ vfprintf(stderr, format, args);
+ va_end(args);
+
+ if(errnum) {
+ fprintf(stderr, ": %s\n", strerror(errnum));
+ }
+
+ if(status) {
+ exit(status);
+ }
+}
+
+void error_at_line(int status, int errnum, const char *filename, unsigned int linenum, const char *format, ...) {
+ va_list args;
+ va_start(args, format);
+
+ static bool first_call = true;
+ static unsigned int last_line = 0;
+ if(!(last_line == linenum && error_one_per_line && !first_call)) {
+ first_call = false;
+ last_line = linenum;
+ error_message_count++;
+
+ fflush(stdout);
+ if(error_print_progname) {
+ error_print_progname();
+ } else {
+ fprintf(stderr, "%s:", program_invocation_name);
+ }
+ fprintf(stderr, "%s:%u: ", filename, linenum);
+ vfprintf(stderr, format, args);
+
+ if(errnum) {
+ fprintf(stderr, ": %s\n", strerror(errnum));
+ }
+ }
+ va_end(args);
+
+ if(status) {
+ exit(status);
+ }
+}
diff --git a/lib/mlibc/options/glibc/generic/execinfo.cpp b/lib/mlibc/options/glibc/generic/execinfo.cpp
new file mode 100644
index 0000000..3474615
--- /dev/null
+++ b/lib/mlibc/options/glibc/generic/execinfo.cpp
@@ -0,0 +1,17 @@
+#include <execinfo.h>
+#include <bits/ensure.h>
+
+int backtrace(void **, int) {
+ __ensure(!"Not implemented");
+ __builtin_unreachable();
+}
+
+char **backtrace_symbols(void *const *, int) {
+ __ensure(!"Not implemented");
+ __builtin_unreachable();
+}
+
+void backtrace_symbols_fd(void *const *, int, int) {
+ __ensure(!"Not implemented");
+ __builtin_unreachable();
+}
diff --git a/lib/mlibc/options/glibc/generic/getopt-stubs.cpp b/lib/mlibc/options/glibc/generic/getopt-stubs.cpp
new file mode 100644
index 0000000..d13d4eb
--- /dev/null
+++ b/lib/mlibc/options/glibc/generic/getopt-stubs.cpp
@@ -0,0 +1,253 @@
+#include <assert.h>
+#include <bits/ensure.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <frg/optional.hpp>
+#include <mlibc/debug.hpp>
+
+char *optarg;
+int optind = 1;
+int opterr = 1;
+int optopt;
+
+namespace {
+
+int __optpos = 1;
+
+enum GetoptMode {
+ Short,
+ Long,
+ LongOnly,
+};
+
+int getopt_common(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex, enum GetoptMode mode) {
+ auto longopt_consume = [&](const char *arg, char *s, int k, bool colon) -> frg::optional<int> {
+ // Consume the option and its argument.
+ if(longopts[k].has_arg == required_argument) {
+ if(s) {
+ // Consume the long option and its argument.
+ optarg = s + 1;
+ optind++;
+ }else if(argv[optind + 1]) {
+ // Consume the long option.
+ optind++;
+
+ // Consume the option's argument.
+ optarg = argv[optind];
+ optind++;
+ }else{
+ /* If an error was detected, and the first character of optstring is not a colon,
+ and the external variable opterr is nonzero (which is the default),
+ getopt() prints an error message. */
+ if(!colon && opterr)
+ fprintf(stderr, "--%s requires an argument.\n", arg);
+ /* If the first character of optstring is a colon (':'), then getopt()
+ returns ':' instead of '?' to indicate a missing option argument. */
+ return colon ? ':' : '?';
+ }
+ }else if(longopts[k].has_arg == optional_argument) {
+ if(s) {
+ // Consume the long option and its argument.
+ optarg = s + 1;
+ optind++;
+ }else{
+ // Consume the long option.
+ optarg = nullptr;
+ optind++;
+ }
+ }else{
+ __ensure(longopts[k].has_arg == no_argument);
+
+ // Consume the long option.
+ optind++;
+ }
+
+ return frg::null_opt;
+ };
+
+ bool colon = optstring[0] == ':';
+ bool stop_at_first_nonarg = (optstring[0] == '+' || getenv("POSIXLY_CORRECT"));
+
+ // glibc extension: Setting optind to zero causes a full reset.
+ // TODO: Should we really reset opterr and the other flags?
+ if(!optind
+#if __MLIBC_BSD_OPTION
+ || optreset
+#endif //__MLIBC_BSD_OPTION
+ ) {
+ optarg = nullptr;
+ optind = 1;
+ opterr = 1;
+ optopt = 0;
+ __optpos = 1;
+#if __MLIBC_BSD_OPTION
+ optreset = 0;
+#endif //__MLIBC_BSD_OPTION
+ }
+
+ auto isOptionArg = [](char *arg){
+ // If the first character of arg '-', and the arg is not exactly
+ // equal to "-" or "--", then the arg is an option argument.
+ return arg[0] == '-' && strcmp(arg, "-") && strcmp(arg, "--");
+ };
+
+ while(optind < argc) {
+ char *arg = argv[optind];
+ if(!isOptionArg(arg)) {
+ if(stop_at_first_nonarg) {
+ return -1;
+ }
+
+ bool further_options = false;
+ int skip = optind;
+
+ for(; skip < argc; ++skip) {
+ if(isOptionArg(argv[skip])) {
+ further_options = true;
+ break;
+ }
+ }
+
+ if(further_options) {
+ optind += skip - optind;
+ continue;
+ } else {
+ optarg = nullptr;
+ return -1;
+ }
+ }
+
+ if(arg[1] == '-') {
+ arg += 2;
+
+ // Determine the end of the option name (vs. the start of the argument).
+ auto s = strchr(arg, '=');
+ size_t n = s ? (s - arg) : strlen(arg);
+
+ int k = -1;
+ for(int i = 0; longopts[i].name; i++) {
+ if(strncmp(arg, longopts[i].name, n) || longopts[i].name[n])
+ continue;
+
+ if(k >= 0) {
+ if(opterr)
+ fprintf(stderr, "Multiple option declaration detected: %s\n", arg);
+ return '?';
+ }
+ k = i;
+ }
+
+ if(k == -1) {
+ if(opterr)
+ fprintf(stderr, "--%s is not a valid option.\n", arg);
+ return '?';
+ }
+
+ if(longindex)
+ *longindex = k;
+
+ if(auto r = longopt_consume(arg, s, k, colon); r)
+ return r.value();
+
+ if(!longopts[k].flag) {
+ return longopts[k].val;
+ }else{
+ *longopts[k].flag = longopts[k].val;
+ return 0;
+ }
+ }else{
+ /* handle short options, i.e. options with only one dash prefixed; e.g. `program -s` */
+ unsigned int i = __optpos;
+ while(true) {
+ if(mode == GetoptMode::LongOnly) {
+ const char *lo_arg = &arg[1];
+ auto s = strchr(lo_arg, '=');
+ size_t n = s ? (s - lo_arg) : strlen(lo_arg);
+ int k = -1;
+
+ for(int longopt = 0; longopts[longopt].name; longopt++) {
+ if(strncmp(lo_arg, longopts[longopt].name, n) || longopts[longopt].name[n])
+ continue;
+
+ if(k >= 0) {
+ if(opterr)
+ fprintf(stderr, "Multiple option declaration detected: %s\n", arg);
+ return '?';
+ }
+
+ k = longopt;
+ }
+
+ if(k != -1) {
+ if(auto r = longopt_consume(lo_arg, s, k, colon); r)
+ return r.value();
+
+ if(!longopts[k].flag) {
+ return longopts[k].val;
+ }else{
+ *longopts[k].flag = longopts[k].val;
+ return 0;
+ }
+ }
+ }
+
+ auto opt = strchr(optstring, arg[i]);
+ if(opt) {
+ if(opt[1] == ':') {
+ bool required = (opt[2] != ':');
+
+ if(arg[i+1]) {
+ optarg = arg + i + 1;
+ } else if(optind + 1 < argc && argv[optind + 1] && (required || argv[optind + 1][0] != '-')) {
+ /* there is an argument to this short option, separated by a space */
+ optarg = argv[optind + 1];
+ optind++;
+ __optpos = 1;
+ } else if(!required) {
+ optarg = nullptr;
+ } else {
+ __optpos = 1;
+ optopt = arg[i];
+ return colon ? ':' : '?';
+ }
+ optind++;
+ } else {
+ if(arg[i+1]) {
+ __optpos++;
+ } else if(arg[i]) {
+ optind++;
+ } else {
+ return -1;
+ }
+ }
+
+ return arg[i];
+ } else {
+ /* If getopt() does not recognize an option character, it prints an error message to stderr,
+ stores the character in optopt, and returns '?'. The calling program may prevent
+ the error message by setting opterr to 0. */
+ optopt = arg[1];
+ if(opterr)
+ fprintf(stderr, "%s is not a valid option.\n", arg);
+ return '?';
+ }
+ }
+ }
+ }
+ return -1;
+}
+
+}
+
+int getopt_long(int argc, char * const argv[], const char *optstring,
+ const struct option *longopts, int *longindex) {
+ return getopt_common(argc, argv, optstring, longopts, longindex, GetoptMode::Long);
+}
+
+int getopt_long_only(int argc, char * const argv[], const char *optstring,
+ const struct option *longopts, int *longindex) {
+ return getopt_common(argc, argv, optstring, longopts, longindex, GetoptMode::LongOnly);
+}
diff --git a/lib/mlibc/options/glibc/generic/glibc-assert.cpp b/lib/mlibc/options/glibc/generic/glibc-assert.cpp
new file mode 100644
index 0000000..77cd498
--- /dev/null
+++ b/lib/mlibc/options/glibc/generic/glibc-assert.cpp
@@ -0,0 +1,14 @@
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <bits/ensure.h>
+
+[[gnu::noreturn]] void __assert_fail_perror(int errno, const char *file, unsigned int line,
+ const char *function) {
+ char *errormsg = strerror(errno);
+ fprintf(stderr, "In function %s, file %s:%d: Errno '%s' failed!\n",
+ function, file, line, errormsg);
+ abort();
+}
diff --git a/lib/mlibc/options/glibc/generic/glibc-signal.cpp b/lib/mlibc/options/glibc/generic/glibc-signal.cpp
new file mode 100644
index 0000000..41bc455
--- /dev/null
+++ b/lib/mlibc/options/glibc/generic/glibc-signal.cpp
@@ -0,0 +1,14 @@
+#include <errno.h>
+#include <signal.h>
+#include <bits/ensure.h>
+#include <mlibc/debug.hpp>
+#include <mlibc/glibc-sysdeps.hpp>
+
+int tgkill(int tgid, int tid, int sig) {
+ MLIBC_CHECK_OR_ENOSYS(mlibc::sys_tgkill, -1);
+ if(int e = mlibc::sys_tgkill(tgid, tid, sig); e) {
+ errno = e;
+ return -1;
+ }
+ return 0;
+}
diff --git a/lib/mlibc/options/glibc/generic/gshadow.cpp b/lib/mlibc/options/glibc/generic/gshadow.cpp
new file mode 100644
index 0000000..f93a47d
--- /dev/null
+++ b/lib/mlibc/options/glibc/generic/gshadow.cpp
@@ -0,0 +1,7 @@
+#include <gshadow.h>
+#include <bits/ensure.h>
+
+int getsgnam_r(const char *, struct sgrp *, char *, size_t, struct sgrp **) {
+ __ensure(!"Not implemented");
+ __builtin_unreachable();
+}
diff --git a/lib/mlibc/options/glibc/generic/malloc.cpp b/lib/mlibc/options/glibc/generic/malloc.cpp
new file mode 100644
index 0000000..b5a4daf
--- /dev/null
+++ b/lib/mlibc/options/glibc/generic/malloc.cpp
@@ -0,0 +1,6 @@
+#include <bits/glibc/glibc_malloc.h>
+#include <mlibc/allocator.hpp>
+
+size_t malloc_usable_size(void *p) {
+ return getAllocator().get_size(p);
+}
diff --git a/lib/mlibc/options/glibc/generic/personality.cpp b/lib/mlibc/options/glibc/generic/personality.cpp
new file mode 100644
index 0000000..3bfd9aa
--- /dev/null
+++ b/lib/mlibc/options/glibc/generic/personality.cpp
@@ -0,0 +1,15 @@
+#include <bits/ensure.h>
+#include <errno.h>
+#include <mlibc/glibc-sysdeps.hpp>
+#include <sys/personality.h>
+
+int personality(unsigned long persona) {
+ int out = 0;
+ auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_personality, -1);
+
+ if(int e = sysdep(persona, &out); e) {
+ errno = e;
+ return -1;
+ }
+ return out;
+}
diff --git a/lib/mlibc/options/glibc/generic/printf.cpp b/lib/mlibc/options/glibc/generic/printf.cpp
new file mode 100644
index 0000000..4abb00d
--- /dev/null
+++ b/lib/mlibc/options/glibc/generic/printf.cpp
@@ -0,0 +1,7 @@
+#include <bits/ensure.h>
+#include <printf.h>
+
+size_t parse_printf_format(const char * __restrict, size_t, int * __restrict) {
+ __ensure(!"Not implemented");
+ __builtin_unreachable();
+}
diff --git a/lib/mlibc/options/glibc/generic/resolv-stubs.cpp b/lib/mlibc/options/glibc/generic/resolv-stubs.cpp
new file mode 100644
index 0000000..7c0723e
--- /dev/null
+++ b/lib/mlibc/options/glibc/generic/resolv-stubs.cpp
@@ -0,0 +1,36 @@
+#include <resolv.h>
+#include <bits/ensure.h>
+#include <mlibc/debug.hpp>
+
+int dn_expand(const unsigned char *, const unsigned char *,
+ const unsigned char *, char *, int) {
+ __ensure(!"Not implemented");
+ __builtin_unreachable();
+}
+
+int res_query(const char *, int, int, unsigned char *, int) {
+ __ensure(!"Not implemented");
+ __builtin_unreachable();
+}
+
+int res_init() {
+ mlibc::infoLogger() << "mlibc: res_init is a stub!" << frg::endlog;
+ return 0;
+}
+
+int res_ninit(res_state) {
+ mlibc::infoLogger() << "mlibc: res_ninit is a stub!" << frg::endlog;
+ return 0;
+}
+
+void res_nclose(res_state) {
+ mlibc::infoLogger() << "mlibc: res_nclose is a stub!" << frg::endlog;
+ return;
+}
+
+/* This is completely unused, and exists purely to satisfy broken apps. */
+
+struct __res_state *__res_state() {
+ static struct __res_state res;
+ return &res;
+}
diff --git a/lib/mlibc/options/glibc/generic/shadow-stubs.cpp b/lib/mlibc/options/glibc/generic/shadow-stubs.cpp
new file mode 100644
index 0000000..9ce6584
--- /dev/null
+++ b/lib/mlibc/options/glibc/generic/shadow-stubs.cpp
@@ -0,0 +1,217 @@
+#include <shadow.h>
+#include <errno.h>
+#include <limits.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include <bits/ensure.h>
+#include <mlibc/debug.hpp>
+
+/*
+ * The code in this file is largely based on or taken from musl.
+ * This includes:
+ * - xatol
+ * - __parsespent
+ * - cleanup
+ * - getspnam_r
+ * - getspnam
+ */
+#define NUM(n) ((n) == -1 ? 0 : -1), ((n) == -1 ? 0 : (n))
+
+int putspent(const struct spwd *sp, FILE *f) {
+ auto str = [] (char *s) {
+ return ((s) ? (s) : "");
+ };
+ return fprintf(f, "%s:%s:%.*d:%.*d:%.*d:%.*d:%.*d:%.*d:%.*u\n",
+ str(sp->sp_namp), str(sp->sp_pwdp), NUM(sp->sp_lstchg),
+ NUM(sp->sp_min), NUM(sp->sp_max), NUM(sp->sp_warn),
+ NUM(sp->sp_inact), NUM(sp->sp_expire), NUM((int)sp->sp_flag)) < 0 ? -1 : 0;
+}
+#undef NUM
+
+static long xatol(char **s) {
+ long x;
+ if(**s == ':' || **s == '\n') {
+ return -1;
+ }
+ for(x = 0; (unsigned int)**s - '0' < 10U; ++*s) {
+ x = 10 * x + (**s - '0');
+ }
+ return x;
+}
+
+static int __parsespent(char *s, struct spwd *sp) {
+ sp->sp_namp = s;
+ if(!(s = strchr(s, ':'))) {
+ return -1;
+ }
+ *s = 0;
+
+ sp->sp_pwdp = ++s;
+ if(!(s = strchr(s, ':'))) {
+ return -1;
+ }
+ *s = 0;
+
+ s++;
+ sp->sp_lstchg = xatol(&s);
+ if(*s != ':') {
+ return -1;
+ }
+
+ s++;
+ sp->sp_min = xatol(&s);
+ if(*s != ':') {
+ return -1;
+ }
+
+ s++;
+ sp->sp_max = xatol(&s);
+ if(*s != ':') {
+ return -1;
+ }
+
+ s++;
+ sp->sp_warn = xatol(&s);
+ if(*s != ':') {
+ return -1;
+ }
+
+ s++;
+ sp->sp_inact = xatol(&s);
+ if(*s != ':') {
+ return -1;
+ }
+
+ s++;
+ sp->sp_expire = xatol(&s);
+ if(*s != ':') {
+ return -1;
+ }
+
+ s++;
+ sp->sp_flag = xatol(&s);
+ if(*s != '\n') {
+ return -1;
+ }
+ return 0;
+}
+
+static void cleanup(void *p) {
+ fclose((FILE *)p);
+}
+
+int getspnam_r(const char *name, struct spwd *sp, char *buf, size_t size, struct spwd **res) {
+ char path[20 + NAME_MAX];
+ FILE *f = 0;
+ int rv = 0;
+ int fd;
+ size_t k, l = strlen(name);
+ int skip = 0;
+ int cs;
+ int orig_errno = errno;
+
+ *res = 0;
+
+ /* Disallow potentially-malicious user names */
+ if(*name=='.' || strchr(name, '/') || !l) {
+ return errno = EINVAL;
+ }
+
+ /* Buffer size must at least be able to hold name, plus some.. */
+ if(size < l + 100) {
+ return errno = ERANGE;
+ }
+
+ /* Protect against truncation */
+ if(snprintf(path, sizeof path, "/etc/tcb/%s/shadow", name) >= (int)sizeof path) {
+ return errno = EINVAL;
+ }
+
+ fd = open(path, O_RDONLY|O_NOFOLLOW|O_NONBLOCK|O_CLOEXEC);
+ if(fd >= 0) {
+ struct stat st = {};
+ errno = EINVAL;
+ if(fstat(fd, &st) || !S_ISREG(st.st_mode) || !(f = fdopen(fd, "rb"))) {
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+ close(fd);
+ pthread_setcancelstate(cs, 0);
+ return errno;
+ }
+ } else {
+ if(errno != ENOENT && errno != ENOTDIR) {
+ return errno;
+ }
+ f = fopen("/etc/shadow", "rbe");
+ if(!f) {
+ if(errno != ENOENT && errno != ENOTDIR) {
+ return errno;
+ }
+ return 0;
+ }
+ }
+
+ pthread_cleanup_push(cleanup, f);
+ while(fgets(buf, size, f) && (k = strlen(buf)) > 0) {
+ if(skip || strncmp(name, buf, l) || buf[l] != ':') {
+ skip = buf[k - 1] != '\n';
+ continue;
+ }
+ if(buf[k - 1] != '\n') {
+ rv = ERANGE;
+ break;
+ }
+
+ if(__parsespent(buf, sp) < 0) {
+ continue;
+ }
+ *res = sp;
+ break;
+ }
+ pthread_cleanup_pop(1);
+ errno = rv ? rv : orig_errno;
+ return rv;
+}
+
+int lckpwdf(void) {
+ mlibc::infoLogger() << "mlibc: lckpwdf is unimplemented like musl" << frg::endlog;
+ return 0;
+}
+
+int ulckpwdf(void) {
+ mlibc::infoLogger() << "mlibc: ulckpwdf is unimplemented like musl" << frg::endlog;
+ return 0;
+}
+
+// Musl defines LINE_LIM to 256
+#define LINE_LIM 256
+
+struct spwd *getspnam(const char *name) {
+ static struct spwd sp;
+ static char *line;
+ struct spwd *res;
+ int e;
+ int orig_errno = errno;
+
+ if(!line) {
+ line = (char *)malloc(LINE_LIM);
+ }
+ if(!line) {
+ return 0;
+ }
+ e = getspnam_r(name, &sp, line, LINE_LIM, &res);
+ errno = e ? e : orig_errno;
+ return res;
+}
+
+struct spwd *fgetspent(FILE *) {
+ __ensure(!"Not implemented");
+ __builtin_unreachable();
+}
+
+void endspent(void) {
+ mlibc::infoLogger() << "mlibc: endspent is a stub" << frg::endlog;
+}
diff --git a/lib/mlibc/options/glibc/generic/stdio_ext-stubs.cpp b/lib/mlibc/options/glibc/generic/stdio_ext-stubs.cpp
new file mode 100644
index 0000000..b9b61fc
--- /dev/null
+++ b/lib/mlibc/options/glibc/generic/stdio_ext-stubs.cpp
@@ -0,0 +1,64 @@
+
+#include <stdio_ext.h>
+#include <bits/ensure.h>
+#include <mlibc/debug.hpp>
+
+size_t __fbufsize(FILE *) {
+ __ensure(!"Not implemented");
+ __builtin_unreachable();
+}
+
+size_t __fpending(FILE *file_base) {
+ __ensure(file_base->__dirty_end >= file_base->__dirty_begin);
+ return file_base->__dirty_end - file_base->__dirty_begin;
+}
+
+int __flbf(FILE *) {
+ __ensure(!"Not implemented");
+ __builtin_unreachable();
+}
+int __freadable(FILE *) {
+ __ensure(!"Not implemented");
+ __builtin_unreachable();
+}
+int __fwritable(FILE *) {
+ __ensure(!"Not implemented");
+ __builtin_unreachable();
+}
+
+int __freading(FILE *file_base) {
+ return file_base->__io_mode == 0;
+}
+
+int __fwriting(FILE *file_base) {
+ return file_base->__io_mode == 1;
+}
+
+int __fsetlocking(FILE *, int) {
+ mlibc::infoLogger() << "mlibc: __fsetlocking() is a no-op" << frg::endlog;
+ return FSETLOCKING_INTERNAL;
+}
+
+void _flushlbf(void) {
+ __ensure(!"Not implemented");
+ __builtin_unreachable();
+}
+
+// The following functions are defined by musl.
+
+size_t __freadahead(FILE *file_base) {
+ if(file_base->__io_mode != 0) {
+ mlibc::infoLogger() << "mlibc: __freadahead() called but file is not open for reading" << frg::endlog;
+ return 0;
+ }
+ return file_base->__valid_limit - file_base->__offset;
+}
+const char *__freadptr(FILE *, size_t *) {
+ __ensure(!"Not implemented");
+ __builtin_unreachable();
+}
+void __fseterr(FILE *) {
+ __ensure(!"Not implemented");
+ __builtin_unreachable();
+}
+
diff --git a/lib/mlibc/options/glibc/generic/string.cpp b/lib/mlibc/options/glibc/generic/string.cpp
new file mode 100644
index 0000000..19f77c7
--- /dev/null
+++ b/lib/mlibc/options/glibc/generic/string.cpp
@@ -0,0 +1,32 @@
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
+#include <type_traits>
+#include <string.h>
+
+/* This is a bit of a weird detail of the GNU implementation and C's lack of
+ * overloading and strictness: GNU takes const char * and returns a char * so
+ * that it autocasts to your desired constness, this function never actually
+ * modifies the string.
+ */
+char *__mlibc_gnu_basename_c(const char *path) {
+ char *basename_component = strrchr(path, '/');
+ if (!basename_component) {
+ return const_cast<char *>(path);
+ }
+ return basename_component + 1;
+}
+
+
+/* GNU exposes these overloads, and as a result, we should probably have them
+ * checked, to make sure we actually match expectations.
+ */
+static_assert(
+ std::is_same_v<decltype(basename((const char *)nullptr)), const char*>,
+ "C++ overloads broken"
+);
+
+static_assert(
+ std::is_same_v<decltype(basename((char *)nullptr)), char*>,
+ "C++ overloads broken"
+);
diff --git a/lib/mlibc/options/glibc/generic/sys-io.cpp b/lib/mlibc/options/glibc/generic/sys-io.cpp
new file mode 100644
index 0000000..fbd9070
--- /dev/null
+++ b/lib/mlibc/options/glibc/generic/sys-io.cpp
@@ -0,0 +1,25 @@
+#include <errno.h>
+#include <sys/io.h>
+
+#include <bits/ensure.h>
+#include <mlibc/glibc-sysdeps.hpp>
+
+int ioperm(unsigned long int from, unsigned long int num, int turn_on) {
+ auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_ioperm, -1);
+
+ if(int e = sysdep(from, num, turn_on); e) {
+ errno = e;
+ return -1;
+ }
+ return 0;
+}
+
+int iopl(int level) {
+ auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_iopl, -1);
+
+ if(int e = sysdep(level); e) {
+ errno = e;
+ return -1;
+ }
+ return 0;
+}
diff --git a/lib/mlibc/options/glibc/generic/sys-ioctl.cpp b/lib/mlibc/options/glibc/generic/sys-ioctl.cpp
new file mode 100644
index 0000000..021d2a3
--- /dev/null
+++ b/lib/mlibc/options/glibc/generic/sys-ioctl.cpp
@@ -0,0 +1,21 @@
+
+#include <errno.h>
+#include <sys/ioctl.h>
+
+#include <bits/ensure.h>
+#include <mlibc/debug.hpp>
+#include <mlibc/glibc-sysdeps.hpp>
+
+int ioctl(int fd, unsigned long request, ...) {
+ va_list args;
+ va_start(args, request);
+ int result;
+ MLIBC_CHECK_OR_ENOSYS(mlibc::sys_ioctl, -1);
+ void *arg = va_arg(args, void *);
+ if(int e = mlibc::sys_ioctl(fd, request, arg, &result); e) {
+ errno = e;
+ return -1;
+ }
+ return result;
+}
+
diff --git a/lib/mlibc/options/glibc/generic/sys-timex.cpp b/lib/mlibc/options/glibc/generic/sys-timex.cpp
new file mode 100644
index 0000000..6173399
--- /dev/null
+++ b/lib/mlibc/options/glibc/generic/sys-timex.cpp
@@ -0,0 +1,17 @@
+#include <bits/ensure.h>
+#include <sys/timex.h>
+
+int adjtimex(struct timex *) {
+ __ensure(!"Not implemented");
+ __builtin_unreachable();
+}
+
+int clock_adjtime(clockid_t, struct timex *) {
+ __ensure(!"Not implemented");
+ __builtin_unreachable();
+}
+
+int ntp_adjtime(struct timex *) {
+ __ensure(!"Not implemented");
+ __builtin_unreachable();
+}
diff --git a/lib/mlibc/options/glibc/include/ar.h b/lib/mlibc/options/glibc/include/ar.h
new file mode 100644
index 0000000..c7a9f38
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/ar.h
@@ -0,0 +1,27 @@
+
+#ifndef _AR_H
+#define _AR_H
+
+#define ARMAG "!<arch>\n"
+#define SARMAG 8
+#define ARFMAG "`\n"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ar_hdr {
+ char ar_name[16];
+ char ar_date[12];
+ char ar_uid[6];
+ char ar_gid[6];
+ char ar_mode[8];
+ char ar_size[10];
+ char ar_fmag[2];
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/mlibc/options/glibc/include/bits/glibc/glibc_assert.h b/lib/mlibc/options/glibc/include/bits/glibc/glibc_assert.h
new file mode 100644
index 0000000..4461c5e
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/bits/glibc/glibc_assert.h
@@ -0,0 +1,32 @@
+#ifndef MLIBC_GLIBC_ASSERT_H
+#define MLIBC_GLIBC_ASSERT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __MLIBC_ABI_ONLY
+
+__attribute__ ((__noreturn__)) void __assert_fail_perror(int errno, const char *file, unsigned int line,
+ const char *function);
+
+#endif /* !__MLIBC_ABI_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MLIBC_GLIBC_ASSERT_H */
+
+#ifdef NDEBUG
+
+#undef assert_perror
+#define assert_perror(ignore) ((void)0)
+
+#else /* NDEBUG */
+
+#undef assert_perror
+#define assert_perror(errno) (!(errno) \
+ || (__assert_fail_perror((errno), __FILE__, __LINE__, __func__), 0))
+
+#endif /* NDEBUG */
diff --git a/lib/mlibc/options/glibc/include/bits/glibc/glibc_icmp6.h b/lib/mlibc/options/glibc/include/bits/glibc/glibc_icmp6.h
new file mode 100644
index 0000000..eafde16
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/bits/glibc/glibc_icmp6.h
@@ -0,0 +1,21 @@
+#ifndef _GLIBC_NETINET_ICMP6_H
+#define _GLIBC_NETINET_ICMP6_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#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
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GLIBC_NETINET_ICMP6_H */
+
diff --git a/lib/mlibc/options/glibc/include/bits/glibc/glibc_malloc.h b/lib/mlibc/options/glibc/include/bits/glibc/glibc_malloc.h
new file mode 100644
index 0000000..7ce6c5e
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/bits/glibc/glibc_malloc.h
@@ -0,0 +1,17 @@
+#ifndef _GLIBC_MALLOC_H
+#define _GLIBC_MALLOC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <bits/size_t.h>
+
+size_t malloc_usable_size(void *ptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GLIBC_MALLOC_H */
+
diff --git a/lib/mlibc/options/glibc/include/bits/glibc/glibc_signal.h b/lib/mlibc/options/glibc/include/bits/glibc/glibc_signal.h
new file mode 100644
index 0000000..4d34e20
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/bits/glibc/glibc_signal.h
@@ -0,0 +1,24 @@
+#ifndef MLIBC_GLIBC_SIGNAL_H
+#define MLIBC_GLIBC_SIGNAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __MLIBC_ABI_ONLY
+
+int tgkill(int, int, int);
+
+#if defined(_GNU_SOURCE)
+
+typedef void (*sighandler_t)(int);
+
+#endif
+
+#endif /* !__MLIBC_ABI_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // MLIBC_GLIBC_SIGNAL_H
diff --git a/lib/mlibc/options/glibc/include/endian.h b/lib/mlibc/options/glibc/include/endian.h
new file mode 100644
index 0000000..00d5ee1
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/endian.h
@@ -0,0 +1,54 @@
+#ifndef _ENDIAN_H
+#define _ENDIAN_H
+
+#include <byteswap.h>
+
+#ifdef __GNUC__
+# define BYTE_ORDER __BYTE_ORDER__
+# define LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__
+# define BIG_ENDIAN __ORDER_BIG_ENDIAN__
+# define PDP_ENDIAN __ORDER_PDP_ENDIAN__
+
+# define __BYTE_ORDER __BYTE_ORDER__
+#ifndef __LITTLE_ENDIAN // Linux kernel headers define this already
+# define __LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__
+#endif
+# define __BIG_ENDIAN __ORDER_BIG_ENDIAN__
+# define __PDP_ENDIAN __ORDER_PDP_ENDIAN__
+#else
+# error "Unsupported compiler"
+#endif
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+# define htobe16(x) __bswap_16(x)
+# define htole16(x) (uint16_t)(x)
+# define be16toh(x) __bswap_16(x)
+# define le16toh(x) (uint16_t)(x)
+
+# define htobe32(x) __bswap_32(x)
+# define htole32(x) (uint32_t)(x)
+# define be32toh(x) __bswap_32(x)
+# define le32toh(x) (uint32_t)(x)
+
+# define htobe64(x) __bswap_64(x)
+# define htole64(x) (uint64_t)(x)
+# define be64toh(x) __bswap_64(x)
+# define le64toh(x) (uint64_t)(x)
+#else
+# define htobe16(x) (uint16_t)(x)
+# define htole16(x) __bswap_16(x)
+# define be16toh(x) (uint16_t)(x)
+# define le16toh(x) __bswap_16(x)
+
+# define htobe32(x) (uint32_t)(x)
+# define htole32(x) __bswap_32(x)
+# define be32toh(x) (uint32_t)(x)
+# define le32toh(x) __bswap_32(x)
+
+# define htobe64(x) (uint64_t)(x)
+# define htole64(x) __bswap_64(x)
+# define be64toh(x) (uint64_t)(x)
+# define le64toh(x) __bswap_64(x)
+#endif
+
+#endif // _ENDIAN_H
diff --git a/lib/mlibc/options/glibc/include/err.h b/lib/mlibc/options/glibc/include/err.h
new file mode 100644
index 0000000..c3757ab
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/err.h
@@ -0,0 +1,29 @@
+#ifndef _ERR_H
+#define _ERR_H
+
+#include <stdarg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __MLIBC_ABI_ONLY
+
+void warn(const char *, ...);
+void vwarn(const char *, va_list);
+void warnx(const char *, ...);
+void vwarnx(const char *, va_list);
+
+__attribute__((__noreturn__)) void err(int, const char *, ...);
+__attribute__((__noreturn__)) void verr(int, const char *, va_list);
+__attribute__((__noreturn__)) void errx(int, const char *, ...);
+__attribute__((__noreturn__)) void verrx(int, const char *, va_list);
+
+#endif /* !__MLIBC_ABI_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _ERR_H
+
diff --git a/lib/mlibc/options/glibc/include/error.h b/lib/mlibc/options/glibc/include/error.h
new file mode 100644
index 0000000..782101d
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/error.h
@@ -0,0 +1,25 @@
+#ifndef _ERROR_H
+#define _ERROR_H
+
+#include <stdarg.h>
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+#ifndef __MLIBC_ABI_ONLY
+
+void error(int status, int errnum, const char *format, ...);
+void error_at_line(int status, int errnum, const char *filename, unsigned int linenum, const char *format, ...);
+
+extern unsigned int error_message_count;
+extern int error_one_per_line;
+extern void (*error_print_progname)(void);
+
+#endif /* !__MLIBC_ABI_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ERROR_H */
diff --git a/lib/mlibc/options/glibc/include/execinfo.h b/lib/mlibc/options/glibc/include/execinfo.h
new file mode 100644
index 0000000..addbc4e
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/execinfo.h
@@ -0,0 +1,20 @@
+#ifndef _EXECINFO_H
+#define _EXECINFO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __MLIBC_ABI_ONLY
+
+int backtrace(void **, int);
+char **backtrace_symbols(void *const *, int);
+void backtrace_symbols_fd(void *const *, int, int);
+
+#endif /* !__MLIBC_ABI_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/mlibc/options/glibc/include/features.h b/lib/mlibc/options/glibc/include/features.h
new file mode 100644
index 0000000..382b684
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/features.h
@@ -0,0 +1,6 @@
+#ifndef FEATURES_H
+#define FEATURES_H
+
+// This header is a stub
+
+#endif
diff --git a/lib/mlibc/options/glibc/include/getopt.h b/lib/mlibc/options/glibc/include/getopt.h
new file mode 100644
index 0000000..5b24cc8
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/getopt.h
@@ -0,0 +1,44 @@
+
+#ifndef _GETOPT_H
+#define _GETOPT_H
+
+#include <mlibc-config.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct option {
+ const char *name;
+ int has_arg;
+ int *flag;
+ int val;
+};
+
+#ifndef __MLIBC_ABI_ONLY
+
+extern char **environ;
+extern char *optarg;
+extern int optind;
+extern int opterr;
+extern int optopt;
+#if __MLIBC_BSD_OPTION
+extern int optreset;
+#endif //__MLIBC_BSD_OPTION
+
+int getopt(int, char *const [], const char *);
+int getopt_long(int, char *const[], const char *, const struct option *, int *);
+int getopt_long_only(int, char *const[], const char *, const struct option *, int *);
+
+#endif /* !__MLIBC_ABI_ONLY */
+
+#define no_argument 0
+#define required_argument 1
+#define optional_argument 2
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _GETOPT_H
+
diff --git a/lib/mlibc/options/glibc/include/gshadow.h b/lib/mlibc/options/glibc/include/gshadow.h
new file mode 100644
index 0000000..61ec91f
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/gshadow.h
@@ -0,0 +1,30 @@
+#ifndef _GSHADOW_H
+#define _GSHADOW_H
+
+#include <paths.h>
+#include <bits/size_t.h>
+
+#define GSHADOW _PATH_GSHADOW
+
+struct sgrp {
+ char *sg_namp;
+ char *sg_passwd;
+ char **sg_adm;
+ char **sg_mem;
+};
+
+#ifndef __MLIBC_ABI_ONLY
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int getsgnam_r(const char *name, struct sgrp *result_buf, char *buffer, size_t len, struct sgrp **result);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !__MLIBC_ABI_ONLY */
+
+#endif
diff --git a/lib/mlibc/options/glibc/include/memory.h b/lib/mlibc/options/glibc/include/memory.h
new file mode 100644
index 0000000..39adee7
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/memory.h
@@ -0,0 +1,6 @@
+#ifndef _MEMORY_H
+#define _MEMORY_H
+
+#include <string.h>
+
+#endif
diff --git a/lib/mlibc/options/glibc/include/mlibc/glibc-sysdeps.hpp b/lib/mlibc/options/glibc/include/mlibc/glibc-sysdeps.hpp
new file mode 100644
index 0000000..a3888ce
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/mlibc/glibc-sysdeps.hpp
@@ -0,0 +1,16 @@
+#ifndef MLIBC_GLIBC_SYSDEPS
+#define MLIBC_GLIBC_SYSDEPS
+
+namespace [[gnu::visibility("hidden")]] mlibc {
+
+[[gnu::weak]] int sys_ioctl(int fd, unsigned long request, void *arg, int *result);
+[[gnu::weak]] int sys_tgkill(int tgid, int tid, int sig);
+
+[[gnu::weak]] int sys_personality(unsigned long persona, int *out);
+
+[[gnu::weak]] int sys_ioperm(unsigned long int from, unsigned long int num, int turn_on);
+[[gnu::weak]] int sys_iopl(int level);
+
+} // namespace mlibc
+
+#endif // MLIBC_GLIBC_SYSDEPS
diff --git a/lib/mlibc/options/glibc/include/net/ethernet.h b/lib/mlibc/options/glibc/include/net/ethernet.h
new file mode 100644
index 0000000..8dac98a
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/net/ethernet.h
@@ -0,0 +1,42 @@
+#ifndef _NET_ETHERNET_H
+#define _NET_ETHERNET_H
+
+#include <bits/ether_addr.h>
+#include <stdint.h>
+#include <mlibc-config.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if __MLIBC_LINUX_OPTION
+# include <linux/if_ether.h>
+#endif /* __MLIBC_LINUX_OPTION */
+
+#define ETHERTYPE_PUP 0x0200
+#define ETHERTYPE_SPRITE 0x0500
+#define ETHERTYPE_IP 0x0800
+#define ETHERTYPE_ARP 0x0806
+#define ETHERTYPE_REVARP 0x8035
+#define ETHERTYPE_AT 0x809B
+#define ETHERTYPE_AARP 0x80F3
+#define ETHERTYPE_VLAN 0x8100
+#define ETHERTYPE_IPX 0x8137
+#define ETHERTYPE_IPV6 0x86dd
+#define ETHERTYPE_LOOPBACK 0x9000
+
+struct ether_header {
+ uint8_t ether_dhost[6];
+ uint8_t ether_shost[6];
+ uint16_t ether_type;
+};
+
+#define ETHER_ADDR_LEN 6
+
+#define ETHERTYPE_IP 0x0800
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/mlibc/options/glibc/include/net/if_ppp.h b/lib/mlibc/options/glibc/include/net/if_ppp.h
new file mode 100644
index 0000000..55f46b5
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/net/if_ppp.h
@@ -0,0 +1,23 @@
+#ifndef _NET_IF_PPP_H
+#define _NET_IF_PPP_H
+
+#include <mlibc-config.h>
+
+#if __MLIBC_LINUX_OPTION
+#include <asm/ioctl.h>
+#include <linux/ppp_defs.h>
+
+#define PPPIOCGFLAGS _IOR('t', 90, int)
+#define PPPIOCSFLAGS _IOW('t', 89, int)
+#define PPPIOCGASYNCMAP _IOR('t', 88, int)
+#define PPPIOCSASYNCMAP _IOW('t', 87, int)
+#define PPPIOCGUNIT _IOR('t', 86, int)
+#define PPPIOCSMRU _IOW('t', 82, int)
+#define PPPIOCSMAXCID _IOW('t', 81, int)
+#define PPPIOCGXASYNCMAP _IOR('t', 80, ext_accm)
+#define PPPIOCSXASYNCMAP _IOW('t', 79, ext_accm)
+#define PPPIOCGDEBUG _IOR('t', 65, int)
+#define PPPIOCSDEBUG _IOW('t', 64, int)
+#endif
+
+#endif /* _NET_IF_PPP_H */
diff --git a/lib/mlibc/options/glibc/include/net/route.h b/lib/mlibc/options/glibc/include/net/route.h
new file mode 100644
index 0000000..7537241
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/net/route.h
@@ -0,0 +1,35 @@
+#ifndef _NET_ROUTE_H
+#define _NET_ROUTE_H
+
+#include <sys/socket.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RTF_HOST 0x0004
+#define RTF_REJECT 0x0200
+
+struct rtentry {
+ unsigned long int rt_pad1;
+ struct sockaddr rt_dst;
+ struct sockaddr rt_gateway;
+ struct sockaddr rt_genmask;
+ unsigned short int rt_flags;
+ short int rt_pad2;
+ unsigned long int rt_pad3;
+ unsigned char rt_tos;
+ unsigned char rt_class;
+ short int rt_pad4[3];
+ short int rt_metric;
+ char *rt_dev;
+ unsigned long int rt_mtu;
+ unsigned long int rt_window;
+ unsigned short int rt_irtt;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _NET_ROUTE_H */
diff --git a/lib/mlibc/options/glibc/include/netax25/ax25.h b/lib/mlibc/options/glibc/include/netax25/ax25.h
new file mode 100644
index 0000000..3fb82da
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/netax25/ax25.h
@@ -0,0 +1,51 @@
+#ifndef _NETAX25_AX25_H
+#define _NETAX25_AX25_H
+
+#include <mlibc-config.h>
+#include <sys/socket.h>
+
+#define AX25_VALUES_IPDEFMODE 0
+#define AX25_VALUES_AXDEFMODE 1
+#define AX25_VALUES_NETROM 2
+#define AX25_VALUES_TEXT 3
+#define AX25_VALUES_BACKOFF 4
+#define AX25_VALUES_CONMODE 5
+#define AX25_VALUES_WINDOW 6
+#define AX25_VALUES_EWINDOW 7
+#define AX25_VALUES_T1 8
+#define AX25_VALUES_T2 9
+#define AX25_VALUES_T3 10
+#define AX25_VALUES_N2 11
+#define AX25_VALUES_DIGI 12
+#define AX25_VALUES_IDLE 13
+#define AX25_VALUES_PACLEN 14
+#define AX25_VALUES_IPMAXQUEUE 15
+#define AX25_MAX_VALUES 20
+
+typedef struct {
+ char ax25_call[7];
+} ax25_address;
+
+struct sockaddr_ax25 {
+ sa_family_t sax25_family;
+ ax25_address sax25_call;
+ int sax25_ndigis;
+};
+
+struct ax25_parms_struct {
+ ax25_address port_addr;
+ unsigned short values[AX25_MAX_VALUES];
+};
+
+#if __MLIBC_LINUX_OPTION
+#include <abi-bits/ioctls.h>
+
+#define SIOCAX25GETUID (SIOCPROTOPRIVATE)
+#define SIOCAX25ADDUID (SIOCPROTOPRIVATE + 1)
+#define SIOCAX25DELUID (SIOCPROTOPRIVATE + 2)
+#define SIOCAX25NOUID (SIOCPROTOPRIVATE + 3)
+#define SIOCAX25GETPARMS (SIOCPROTOPRIVATE + 5)
+#define SIOCAX25SETPARMS (SIOCPROTOPRIVATE + 6)
+#endif /* __MLIBC_LINUX_OPTION */
+
+#endif /* _NETAX25_AX25_H */
diff --git a/lib/mlibc/options/glibc/include/netinet/in_systm.h b/lib/mlibc/options/glibc/include/netinet/in_systm.h
new file mode 100644
index 0000000..c98298f
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/netinet/in_systm.h
@@ -0,0 +1,7 @@
+
+#ifndef _NETINET_IN_SYSTM_H
+#define _NETINET_IN_SYSTM_H
+
+
+
+#endif // _NETINET_IN_SYSTM_H
diff --git a/lib/mlibc/options/glibc/include/netipx/ipx.h b/lib/mlibc/options/glibc/include/netipx/ipx.h
new file mode 100644
index 0000000..7b5c774
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/netipx/ipx.h
@@ -0,0 +1,35 @@
+#ifndef _NETIPX_IPX_H
+#define _NETIPX_IPX_H
+
+#include <mlibc-config.h>
+#include <sys/socket.h>
+#include <stdint.h>
+
+typedef struct ipx_config_data {
+ unsigned char ipxcfg_auto_select_primary;
+ unsigned char ipxcfg_auto_create_interfaces;
+} ipx_config_data;
+
+#define IPX_TYPE 1
+#define IPX_NODE_LEN 6
+
+struct sockaddr_ipx {
+ sa_family_t sipx_family;
+ uint16_t sipx_port;
+ uint32_t sipx_network;
+ unsigned char sipx_node[IPX_NODE_LEN];
+ uint8_t sipx_type;
+ unsigned char sipx_zero;
+};
+
+#define SOL_IPX 256
+
+#if __MLIBC_LINUX_OPTION
+#include <abi-bits/ioctls.h>
+
+#define SIOCAIPXITFCRT (SIOCPROTOPRIVATE)
+#define SIOCAIPXPRISLT (SIOCPROTOPRIVATE + 1)
+#define SIOCIPXCFGDATA (SIOCPROTOPRIVATE + 2)
+#endif
+
+#endif /* _NETIPX_IPX_H */
diff --git a/lib/mlibc/options/glibc/include/netrom/netrom.h b/lib/mlibc/options/glibc/include/netrom/netrom.h
new file mode 100644
index 0000000..69497d9
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/netrom/netrom.h
@@ -0,0 +1,27 @@
+#ifndef _NETROM_NETROM_H
+#define _NETROM_NETROM_H
+
+#include <mlibc-config.h>
+
+struct nr_parms_struct {
+ unsigned int quality;
+ unsigned int obs_count;
+ unsigned int ttl;
+ unsigned int timeout;
+ unsigned int ack_delay;
+ unsigned int busy_delay;
+ unsigned int tries;
+ unsigned int window;
+ unsigned int paclen;
+};
+
+#if __MLIBC_LINUX_OPTION
+#include <abi-bits/ioctls.h>
+
+#define SIOCNRGETPARMS (SIOCPROTOPRIVATE)
+#define SIOCNRSETPARMS (SIOCPROTOPRIVATE + 1)
+#define SIOCNRDECOBS (SIOCPROTOPRIVATE + 2)
+#define SIOCNRRTCTL (SIOCPROTOPRIVATE + 3)
+#endif
+
+#endif /* _NETROM_NETROM_H */
diff --git a/lib/mlibc/options/glibc/include/paths.h b/lib/mlibc/options/glibc/include/paths.h
new file mode 100644
index 0000000..3d8a4a6
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/paths.h
@@ -0,0 +1,41 @@
+// This file is taken from musl
+// Path to original: include/paths.h
+
+#ifndef _PATHS_H
+#define _PATHS_H
+
+#define _PATH_DEFPATH "/usr/local/bin:/bin:/usr/bin"
+#define _PATH_STDPATH "/bin:/usr/bin:/sbin:/usr/sbin"
+
+#define _PATH_BSHELL "/bin/sh"
+#define _PATH_CONSOLE "/dev/console"
+#define _PATH_DEVNULL "/dev/null"
+#define _PATH_GSHADOW "/etc/gshadow"
+#define _PATH_KLOG "/proc/kmsg"
+#define _PATH_LASTLOG "/var/log/lastlog"
+#define _PATH_MAILDIR "/var/mail"
+#define _PATH_MAN "/usr/share/man"
+#define _PATH_MNTTAB "/etc/fstab"
+#define _PATH_MOUNTED "/etc/mtab"
+#define _PATH_NOLOGIN "/etc/nologin"
+#define _PATH_PRESERVE "/var/lib"
+#define _PATH_SENDMAIL "/usr/sbin/sendmail"
+#define _PATH_SHADOW "/etc/shadow"
+#define _PATH_SHELLS "/etc/shells"
+#define _PATH_TTY "/dev/tty"
+#define _PATH_UTMP "/dev/null/utmp"
+#define _PATH_VI "/usr/bin/vi"
+#define _PATH_WTMP "/dev/null/wtmp"
+
+#define _PATH_DEV "/dev/"
+#define _PATH_TMP "/tmp/"
+#define _PATH_VARDB "/var/lib/misc/"
+#define _PATH_VARRUN "/var/run/"
+#define _PATH_VARTMP "/var/tmp/"
+
+#ifdef _GNU_SOURCE
+#define _PATH_UTMPX _PATH_UTMP
+#define _PATH_WTMPX _PATH_WTMP
+#endif
+
+#endif // _PATHS_H
diff --git a/lib/mlibc/options/glibc/include/printf.h b/lib/mlibc/options/glibc/include/printf.h
new file mode 100644
index 0000000..e7dd0d8
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/printf.h
@@ -0,0 +1,41 @@
+#ifndef _PRINTF_H
+#define _PRINTF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+#include <stdarg.h>
+
+#ifndef __MLIBC_ABI_ONLY
+
+// This seems to be a glibc thing, so constants are from glibc
+size_t parse_printf_format(const char * __restrict, size_t, int * __restrict);
+
+#endif /* !__MLIBC_ABI_ONLY */
+
+enum {
+ PA_INT,
+ PA_CHAR,
+ PA_WCHAR,
+ PA_STRING,
+ PA_WSTRING,
+ PA_POINTER,
+ PA_FLOAT,
+ PA_DOUBLE,
+ PA_LAST
+};
+
+#define PA_FLAG_MASK 0xff00
+#define PA_FLAG_LONG_LONG (1 << 8)
+#define PA_FLAG_LONG_DOUBLE PA_FLAG_LONG_LONG
+#define PA_FLAG_LONG (1 << 9)
+#define PA_FLAG_SHORT (1 << 10)
+#define PA_FLAG_PTR (1 << 11)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/mlibc/options/glibc/include/resolv.h b/lib/mlibc/options/glibc/include/resolv.h
new file mode 100644
index 0000000..71b4fe5
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/resolv.h
@@ -0,0 +1,73 @@
+#ifndef _RESOLV_H
+#define _RESOLV_H
+
+#include <netinet/in.h>
+
+#define RES_INIT 0x00000001
+#define RES_DEBUG 0x00000002
+#define RES_USEVC 0x00000008
+#define RES_IGNTC 0x00000020
+#define RES_RECURSE 0x00000040
+#define RES_DEFNAMES 0x00000080
+#define RES_STAYOPEN 0x00000100
+#define RES_DNSRCH 0x00000200
+
+#define MAXNS 3
+#define MAXDNSRCH 6
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __MLIBC_ABI_ONLY
+
+int dn_expand(const unsigned char *, const unsigned char *,
+ const unsigned char *, char *, int);
+
+int res_query(const char *, int, int, unsigned char *, int);
+
+int res_init(void);
+
+#endif /* !__MLIBC_ABI_ONLY */
+
+/* From musl: Unused; purely for broken apps
+ * To avoid an massive struct, only add the items requested. */
+typedef struct __res_state {
+ int retrans;
+ int retry;
+ unsigned long options;
+ int nscount;
+ struct sockaddr_in nsaddr_list[MAXNS];
+ char *dnsrch[MAXDNSRCH + 1];
+ char defdname[256];
+ unsigned ndots:4;
+ unsigned nsort:4;
+ union {
+ char pad[52];
+ struct {
+ uint16_t nscount;
+ uint16_t nsmap[MAXNS];
+ int nssocks[MAXNS];
+ uint16_t nscount6;
+ uint16_t nsinit;
+ struct sockaddr_in6 *nsaddrs[MAXNS];
+ unsigned int _initstamp[2];
+ } _ext;
+ } _u;
+} *res_state;
+
+#ifndef __MLIBC_ABI_ONLY
+
+struct __res_state *__res_state(void);
+#define _res (*__res_state())
+
+int res_ninit(res_state);
+void res_nclose(res_state);
+
+#endif /* !__MLIBC_ABI_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _RESOLV_H
diff --git a/lib/mlibc/options/glibc/include/shadow.h b/lib/mlibc/options/glibc/include/shadow.h
new file mode 100644
index 0000000..caad9cf
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/shadow.h
@@ -0,0 +1,42 @@
+#ifndef _SHADOW_H
+#define _SHADOW_H
+
+#include <stdint.h>
+#include <stdio.h>
+#include <paths.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct spwd {
+ char *sp_namp;
+ char *sp_pwdp;
+ int32_t sp_lstchg;
+ int32_t sp_min;
+ int32_t sp_max;
+ int32_t sp_warn;
+ int32_t sp_inact;
+ int32_t sp_expire;
+ uint32_t sp_flag;
+};
+
+#define SHADOW _PATH_SHADOW
+
+#ifndef __MLIBC_ABI_ONLY
+
+int putspent(const struct spwd *, FILE *);
+int lckpwdf(void);
+int ulckpwdf(void);
+struct spwd *getspnam(const char *);
+int getspnam_r(const char *, struct spwd *, char *, size_t, struct spwd **);
+struct spwd *fgetspent(FILE *);
+void endspent(void);
+
+#endif /* !__MLIBC_ABI_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/mlibc/options/glibc/include/stdio_ext.h b/lib/mlibc/options/glibc/include/stdio_ext.h
new file mode 100644
index 0000000..f22e05d
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/stdio_ext.h
@@ -0,0 +1,41 @@
+#ifndef _STDIO_EXT_H
+#define _STDIO_EXT_H
+
+#include <stddef.h>
+#include <stdio.h>
+
+#define FSETLOCKING_INTERNAL 1
+#define FSETLOCKING_BYCALLER 2
+#define FSETLOCKING_QUERY 3
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __MLIBC_ABI_ONLY
+
+size_t __fbufsize(FILE *);
+size_t __fpending(FILE *);
+int __flbf(FILE *);
+int __freadable(FILE *);
+int __fwritable(FILE *);
+int __freading(FILE *);
+int __fwriting(FILE *);
+int __fsetlocking(FILE *, int);
+void __fpurge(FILE *);
+
+void _flushlbf(void);
+
+// The following functions are defined by musl.
+
+size_t __freadahead(FILE *);
+const char *__freadptr(FILE *, size_t *);
+void __fseterr(FILE *);
+
+#endif /* !__MLIBC_ABI_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _STDIO_EXT_H
diff --git a/lib/mlibc/options/glibc/include/sys/dir.h b/lib/mlibc/options/glibc/include/sys/dir.h
new file mode 100644
index 0000000..eff112c
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/sys/dir.h
@@ -0,0 +1,8 @@
+#ifndef _SYS_DIR_H
+#define _SYS_DIR_H
+
+#include <dirent.h>
+
+#define direct dirent
+
+#endif
diff --git a/lib/mlibc/options/glibc/include/sys/endian.h b/lib/mlibc/options/glibc/include/sys/endian.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/sys/endian.h
diff --git a/lib/mlibc/options/glibc/include/sys/errno.h b/lib/mlibc/options/glibc/include/sys/errno.h
new file mode 100644
index 0000000..339f4fc
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/sys/errno.h
@@ -0,0 +1 @@
+#include <errno.h>
diff --git a/lib/mlibc/options/glibc/include/sys/io.h b/lib/mlibc/options/glibc/include/sys/io.h
new file mode 100644
index 0000000..311b25f
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/sys/io.h
@@ -0,0 +1,108 @@
+#ifndef _SYS_IO_H
+#define _SYS_IO_H
+
+#include <bits/inline-definition.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __MLIBC_ABI_ONLY
+
+int ioperm(unsigned long int from, unsigned long int num, int turn_on);
+
+__attribute__((deprecated)) int iopl(int level);
+
+#endif /* !__MLIBC_ABI_ONLY */
+
+#ifdef __x86_64__
+__MLIBC_INLINE_DEFINITION unsigned char inb(unsigned short int port) {
+ unsigned char _v;
+ __asm__ __volatile__ ("inb %w1,%0":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+__MLIBC_INLINE_DEFINITION unsigned char inb_p(unsigned short int port) {
+ unsigned char _v;
+ __asm__ __volatile__ ("inb %w1,%0\noutb %%al,$0x80":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+__MLIBC_INLINE_DEFINITION unsigned short int inw(unsigned short int port) {
+ unsigned short _v;
+ __asm__ __volatile__ ("inw %w1,%0":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+__MLIBC_INLINE_DEFINITION unsigned short int inw_p(unsigned short int port) {
+ unsigned short int _v;
+ __asm__ __volatile__ ("inw %w1,%0\noutb %%al,$0x80":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+__MLIBC_INLINE_DEFINITION unsigned int inl(unsigned short int port) {
+ unsigned int _v;
+ __asm__ __volatile__ ("inl %w1,%0":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+__MLIBC_INLINE_DEFINITION unsigned int inl_p(unsigned short int port) {
+ unsigned int _v;
+ __asm__ __volatile__ ("inl %w1,%0\noutb %%al,$0x80":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+__MLIBC_INLINE_DEFINITION void outb(unsigned char value, unsigned short int port) {
+ __asm__ __volatile__ ("outb %b0,%w1": :"a" (value), "Nd" (port));
+}
+
+__MLIBC_INLINE_DEFINITION void outb_p(unsigned char value, unsigned short int port) {
+ __asm__ __volatile__ ("outb %b0,%w1\noutb %%al,$0x80": :"a" (value), "Nd" (port));
+}
+
+__MLIBC_INLINE_DEFINITION void outw(unsigned short int value, unsigned short int port) {
+ __asm__ __volatile__ ("outw %w0,%w1": :"a" (value), "Nd" (port));
+}
+
+__MLIBC_INLINE_DEFINITION void outw_p(unsigned short int value, unsigned short int port) {
+ __asm__ __volatile__ ("outw %w0,%w1\noutb %%al,$0x80": :"a" (value), "Nd" (port));
+}
+
+__MLIBC_INLINE_DEFINITION void outl(unsigned int value, unsigned short int port) {
+ __asm__ __volatile__ ("outl %0,%w1": :"a" (value), "Nd" (port));
+}
+
+__MLIBC_INLINE_DEFINITION void outl_p(unsigned int value, unsigned short int port) {
+ __asm__ __volatile__ ("outl %0,%w1\noutb %%al,$0x80": :"a" (value), "Nd" (port));
+}
+
+__MLIBC_INLINE_DEFINITION void insb(unsigned short int port, void *addr, unsigned long int count) {
+ __asm__ __volatile__ ("cld ; rep ; insb":"=D" (addr), "=c" (count) :"d" (port), "0" (addr), "1" (count));
+}
+
+__MLIBC_INLINE_DEFINITION void insw(unsigned short int port, void *addr, unsigned long int count) {
+ __asm__ __volatile__ ("cld ; rep ; insw":"=D" (addr), "=c" (count) :"d" (port), "0" (addr), "1" (count));
+}
+
+__MLIBC_INLINE_DEFINITION void insl(unsigned short int port, void *addr, unsigned long int count) {
+ __asm__ __volatile__ ("cld ; rep ; insl":"=D" (addr), "=c" (count) :"d" (port), "0" (addr), "1" (count));
+}
+
+__MLIBC_INLINE_DEFINITION void outsb(unsigned short int port, const void *addr, unsigned long int count) {
+ __asm__ __volatile__ ("cld ; rep ; outsb":"=S" (addr), "=c" (count) :"d" (port), "0" (addr), "1" (count));
+}
+
+__MLIBC_INLINE_DEFINITION void outsw(unsigned short int port, const void *addr, unsigned long int count) {
+ __asm__ __volatile__ ("cld ; rep ; outsw":"=S" (addr), "=c" (count) :"d" (port), "0" (addr), "1" (count));
+}
+
+__MLIBC_INLINE_DEFINITION void outsl(unsigned short int port, const void *addr, unsigned long int count) {
+ __asm__ __volatile__ ("cld ; rep ; outsl":"=S" (addr), "=c" (count) :"d" (port), "0" (addr), "1" (count));
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_IO_H */
diff --git a/lib/mlibc/options/glibc/include/sys/ioctl.h b/lib/mlibc/options/glibc/include/sys/ioctl.h
new file mode 100644
index 0000000..6121446
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/sys/ioctl.h
@@ -0,0 +1,44 @@
+#ifndef _SYS_IOCTL_H
+#define _SYS_IOCTL_H
+
+#include <mlibc-config.h>
+#include <abi-bits/ioctls.h>
+
+// On Linux, sys/ioctl.h includes the termios ioctls.
+#if __MLIBC_LINUX_OPTION
+# include <asm/ioctls.h>
+# include <bits/winsize.h>
+# include <sys/ttydefaults.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __MLIBC_ABI_ONLY
+
+int ioctl(int fd, unsigned long request, ...);
+
+#endif /* !__MLIBC_ABI_ONLY */
+
+#define FIONREAD 0x541B
+#define FIONBIO 0x5421
+#define FIONCLEX 0x5450
+#define FIOCLEX 0x5451
+
+#define SIOCGIFNAME 0x8910
+#define SIOCGIFCONF 0x8912
+#define SIOCGIFFLAGS 0x8913
+#define SIOCSIFFLAGS 0x8914
+#define SIOCGIFMTU 0x8921
+#define SIOCSIFMTU 0x8922
+#define SIOCGIFINDEX 0x8933
+
+#define SIOCPROTOPRIVATE 0x89E0
+#define SIOCDEVPRIVATE 0x89F0
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _SYS_IOCTL_H
diff --git a/lib/mlibc/options/glibc/include/sys/kd.h b/lib/mlibc/options/glibc/include/sys/kd.h
new file mode 100644
index 0000000..285c694
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/sys/kd.h
@@ -0,0 +1,17 @@
+#ifndef _SYS_KD_H
+#define _SYS_KD_H
+
+/* Make sure the <linux/types.h> header is not loaded. */
+#ifndef _LINUX_TYPES_H
+# define _LINUX_TYPES_H 1
+# define __undef_LINUX_TYPES_H
+#endif
+
+#include <linux/kd.h>
+
+#ifdef __undef_LINUX_TYPES_H
+# undef _LINUX_TYPES_H
+# undef __undef_LINUX_TYPES_H
+#endif
+
+#endif /* _SYS_KD_H */
diff --git a/lib/mlibc/options/glibc/include/sys/mtio.h b/lib/mlibc/options/glibc/include/sys/mtio.h
new file mode 100644
index 0000000..c2f9d98
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/sys/mtio.h
@@ -0,0 +1,103 @@
+#ifndef _SYS_MTIO_H
+#define _SYS_MTIO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <mlibc-config.h>
+
+struct mtop {
+ short int mt_op;
+ int mt_count;
+};
+
+struct mtget {
+ long int mt_type;
+ long int mt_resid;
+ long int mt_dsreg;
+ long int mt_gstat;
+ long int mt_erreg;
+ int mt_fileno;
+ int mt_blkno;
+};
+
+struct mtpos {
+ long int mt_blkno;
+};
+
+struct mtconfiginfo {
+ long int mt_type;
+ long int ifc_type;
+ unsigned short int irqnr;
+ unsigned short int dmanr;
+ unsigned short int port;
+
+ unsigned long int debug;
+
+ unsigned have_dens:1;
+ unsigned have_bsf:1;
+ unsigned have_fsr:1;
+ unsigned have_bsr:1;
+ unsigned have_eod:1;
+ unsigned have_seek:1;
+ unsigned have_tell:1;
+ unsigned have_ras1:1;
+ unsigned have_ras2:1;
+ unsigned have_ras3:1;
+ unsigned have_qfa:1;
+
+ unsigned pad1:5;
+ char reserved[10];
+};
+
+#define MTRESET 0
+#define MTFSF 1
+#define MTBSF 2
+#define MTFSR 3
+#define MTBSR 4
+#define MTWEOF 5
+#define MTREW 6
+#define MTOFFL 7
+#define MTNOP 8
+#define MTRETEN 9
+#define MTBSFM 10
+#define MTFSFM 11
+#define MTEOM 12
+#define MTERASE 13
+#define MTRAS1 14
+#define MTRAS2 15
+#define MTRAS3 16
+#define MTSETBLK 20
+#define MTSETDENSITY 21
+#define MTSEEK 22
+#define MTTELL 23
+#define MTSETDRVBUFFER 24
+#define MTFSS 25
+#define MTBSS 26
+#define MTWSM 27
+#define MTLOCK 28
+#define MTUNLOCK 29
+#define MTLOAD 30
+#define MTUNLOAD 31
+#define MTCOMPRESSION 32
+#define MTSETPART 33
+#define MTMKPART 34
+
+#define GMT_WR_PROT(x) ((x) & 0x04000000)
+
+#if __MLIBC_LINUX_OPTION
+#include <asm/ioctl.h>
+
+#define MTIOCTOP _IOR('m', 1, struct mtop)
+#define MTIOCGET _IOR('m', 2, struct mtget)
+#define MTIOCPOS _IOR('m', 3, struct mtpos)
+#define MTIOCGETCONFIG _IOR('m', 4, struct mtconfiginfo)
+#define MTIOCSETCONFIG _IOR('m', 5, struct mtconfiginfo)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_MTIO_H */
diff --git a/lib/mlibc/options/glibc/include/sys/personality.h b/lib/mlibc/options/glibc/include/sys/personality.h
new file mode 100644
index 0000000..04563a0
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/sys/personality.h
@@ -0,0 +1,58 @@
+#ifndef _SYS_PERSONALITY_H
+#define _SYS_PERSONALITY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+ UNAME26 = 0x0020000,
+ ADDR_NO_RANDOMIZE = 0x0040000,
+ FDPIC_FUNCPTRS = 0x0080000,
+ MMAP_PAGE_ZERO = 0x0100000,
+ ADDR_COMPAT_LAYOUT = 0x0200000,
+ READ_IMPLIES_EXEC = 0x0400000,
+ ADDR_LIMIT_32BIT = 0x0800000,
+ SHORT_INODE = 0x1000000,
+ WHOLE_SECONDS = 0x2000000,
+ STICKY_TIMEOUTS = 0x4000000,
+ ADDR_LIMIT_3GB = 0x8000000,
+};
+
+enum {
+ PER_LINUX = 0x0000,
+ PER_LINUX_32BIT = 0x0000 | ADDR_LIMIT_32BIT,
+ PER_LINUX_FDPIC = 0x0000 | FDPIC_FUNCPTRS,
+ PER_SVR4 = 0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
+ PER_SVR3 = 0x0002 | STICKY_TIMEOUTS | SHORT_INODE,
+ PER_SCOSVR3 = 0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS | SHORT_INODE,
+ PER_OSR5 = 0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS,
+ PER_WYSEV386 = 0x0004 | STICKY_TIMEOUTS | SHORT_INODE,
+ PER_ISCR4 = 0x0005 | STICKY_TIMEOUTS,
+ PER_BSD = 0x0006,
+ PER_SUNOS = 0x0006 | STICKY_TIMEOUTS,
+ PER_XENIX = 0x0007 | STICKY_TIMEOUTS | SHORT_INODE,
+ PER_LINUX32 = 0x0008,
+ PER_LINUX32_3GB = 0x0008 | ADDR_LIMIT_3GB,
+ PER_IRIX32 = 0x0009 | STICKY_TIMEOUTS,
+ PER_IRIXN32 = 0x000a | STICKY_TIMEOUTS,
+ PER_IRIX64 = 0x000b | STICKY_TIMEOUTS,
+ PER_RISCOS = 0x000c,
+ PER_SOLARIS = 0x000d | STICKY_TIMEOUTS,
+ PER_UW7 = 0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
+ PER_OSF4 = 0x000f,
+ PER_HPUX = 0x0010,
+ PER_MASK = 0x00ff,
+};
+
+#ifndef __MLIBC_ABI_ONLY
+
+int personality(unsigned long persona);
+
+#endif /* !__MLIBC_ABI_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _SYS_PERSONALITY_H
diff --git a/lib/mlibc/options/glibc/include/sys/procfs.h b/lib/mlibc/options/glibc/include/sys/procfs.h
new file mode 100644
index 0000000..b13a81d
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/sys/procfs.h
@@ -0,0 +1,54 @@
+#ifndef _SYS_PROCFS_H
+#define _SYS_PROCFS_H
+
+#include <sys/user.h>
+#include <sys/time.h>
+#include <abi-bits/pid_t.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef unsigned long long elf_greg_t;
+
+#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof (elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct user_fpregs_struct elf_fpregset_t;
+typedef struct user_regs_struct prgregset_t;
+typedef struct user_fpregs_struct prfpregset_t;
+
+#define ELF_PRARGSZ 80
+
+struct elf_siginfo {
+ int si_signo;
+ int si_code;
+ int si_errno;
+};
+
+struct elf_prstatus {
+ struct elf_siginfo pr_info;
+ short int pr_cursig;
+ unsigned long int pr_sigpend;
+ unsigned long int pr_sighold;
+ pid_t pr_pid;
+ pid_t pr_ppid;
+ pid_t pr_pgrp;
+ pid_t pr_sid;
+ struct timeval pr_utime;
+ struct timeval pr_stime;
+ struct timeval pr_cutime;
+ struct timeval pr_cstime;
+ elf_gregset_t pr_reg;
+ int pr_fpvalid;
+};
+
+typedef pid_t lwpid_t;
+typedef void *psaddr_t;
+typedef struct elf_prstatus prstatus_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/mlibc/options/glibc/include/sys/reg.h b/lib/mlibc/options/glibc/include/sys/reg.h
new file mode 100644
index 0000000..c6e3429
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/sys/reg.h
@@ -0,0 +1,36 @@
+#ifndef _SYS_REG_H
+#define _SYS_REG_H
+
+#ifdef __x86_64__
+#define R15 0
+#define R14 1
+#define R13 2
+#define R12 3
+#define RBP 4
+#define RBX 5
+#define R11 6
+#define R10 7
+#define R9 8
+#define R8 9
+#define RAX 10
+#define RCX 11
+#define RDX 12
+#define RSI 13
+#define RDI 14
+#define ORIG_RAX 15
+#define RIP 16
+#define CS 17
+#define EFLAGS 18
+#define RSP 19
+#define SS 20
+#define FS_BASE 21
+#define GS_BASE 22
+#define DS 23
+#define ES 24
+#define FS 25
+#define GS 26
+#else
+#error "Add architecture specific code here"
+#endif
+
+#endif
diff --git a/lib/mlibc/options/glibc/include/sys/signal.h b/lib/mlibc/options/glibc/include/sys/signal.h
new file mode 100644
index 0000000..2e602da
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/sys/signal.h
@@ -0,0 +1 @@
+#include <signal.h>
diff --git a/lib/mlibc/options/glibc/include/sys/timeb.h b/lib/mlibc/options/glibc/include/sys/timeb.h
new file mode 100644
index 0000000..d27173b
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/sys/timeb.h
@@ -0,0 +1,14 @@
+#ifndef _SYS_TIMEB_H
+#define _SYS_TIMEB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _SYS_TIMEB_H
diff --git a/lib/mlibc/options/glibc/include/sys/timex.h b/lib/mlibc/options/glibc/include/sys/timex.h
new file mode 100644
index 0000000..97153ad
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/sys/timex.h
@@ -0,0 +1,78 @@
+#ifndef _SYS_TIMEX_H
+#define _SYS_TIMEX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <abi-bits/clockid_t.h>
+#include <bits/posix/timeval.h>
+
+struct timex {
+ int modes;
+ long offset;
+ long freq;
+ long maxerror;
+ long esterror;
+ int status;
+ long constant;
+ long precision;
+ long tolerance;
+ struct timeval time;
+ long tick;
+ long ppsfreq;
+ long jitter;
+ int shift;
+ long stabil;
+ long jitcnt;
+ long calcnt;
+ long errcnt;
+ long stbcnt;
+ int tai;
+ int __padding[11];
+};
+
+#define ADJ_OFFSET 0x0001
+#define ADJ_FREQUENCY 0x0002
+#define ADJ_MAXERROR 0x0004
+#define ADJ_ESTERROR 0x0008
+#define ADJ_STATUS 0x0010
+#define ADJ_TIMECONST 0x0020
+#define ADJ_TAI 0x0080
+#define ADJ_SETOFFSET 0x0100
+#define ADJ_MICRO 0x1000
+#define ADJ_NANO 0x2000
+#define ADJ_TICK 0x4000
+#define ADJ_OFFSET_SINGLESHOT 0x8001
+#define ADJ_OFFSET_SS_READ 0xa001
+
+#define STA_PLL 0x0001
+#define STA_PPSFREQ 0x0002
+#define STA_PPSTIME 0x0004
+#define STA_FLL 0x0008
+#define STA_INS 0x0010
+#define STA_DEL 0x0020
+#define STA_UNSYNC 0x0040
+#define STA_FREQHOLD 0x0080
+#define STA_PPSSIGNAL 0x0100
+#define STA_PPSJITTER 0x0200
+#define STA_PPSWANDER 0x0400
+#define STA_PPSERROR 0x0800
+#define STA_CLOCKERR 0x1000
+#define STA_NANO 0x2000
+#define STA_MODE 0x4000
+#define STA_CLK 0x8000
+
+#ifndef __MLIBC_ABI_ONLY
+
+int adjtimex(struct timex *);
+int clock_adjtime(clockid_t clk_id, struct timex *buf);
+int ntp_adjtime(struct timex *);
+
+#endif /* !__MLIBC_ABI_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _SYS_TIMEX_H
diff --git a/lib/mlibc/options/glibc/include/sys/ucontext.h b/lib/mlibc/options/glibc/include/sys/ucontext.h
new file mode 100644
index 0000000..b4798ee
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/sys/ucontext.h
@@ -0,0 +1,14 @@
+#ifndef _SYS_UCONTEXT_H
+#define _SYS_UCONTEXT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _SYS_UCONTEXT_H
diff --git a/lib/mlibc/options/glibc/include/sys/user.h b/lib/mlibc/options/glibc/include/sys/user.h
new file mode 100644
index 0000000..9a07ac6
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/sys/user.h
@@ -0,0 +1,49 @@
+#ifndef _SYS_USER_H
+#define _SYS_USER_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct user_fpregs_struct {
+ uint16_t cwd, swd, ftw, fop;
+ uint64_t rip, rdp;
+ uint32_t mxcsr, mxcr_mask;
+ uint32_t st_space[32], xmm_space[64], padding[24];
+} elf_fpregset_t;
+
+struct user_regs_struct {
+ unsigned long r15, r14, r13, r12, rbp, rbx, r11, r10, r9, r8;
+ unsigned long rax, rcx, rdx, rsi, rdi, orig_rax, rip;
+ unsigned long cs, eflags, rsp, ss, fs_base, gs_base, ds, es, fs, gs;
+};
+
+struct user {
+ struct user_regs_struct regs;
+ int u_fpvalid;
+ struct user_fpregs_struct i387;
+ unsigned long u_tsize;
+ unsigned long u_dsize;
+ unsigned long u_ssize;
+ unsigned long start_code;
+ unsigned long start_stack;
+ long signal;
+ int reserved;
+ struct user_regs_struct *u_ar0;
+ struct user_fpregs_struct *u_fpstate;
+ unsigned long magic;
+ char u_comm[32];
+ unsigned long u_debugreg[8];
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#define PAGE_SHIFT 12
+#define PAGE_SIZE (1UL << PAGE_SHIFT)
+#define PAGE_MASK (~(PAGE_SIZE - 1))
+
+#endif
diff --git a/lib/mlibc/options/glibc/include/sysexits.h b/lib/mlibc/options/glibc/include/sysexits.h
new file mode 100644
index 0000000..f3bde25
--- /dev/null
+++ b/lib/mlibc/options/glibc/include/sysexits.h
@@ -0,0 +1,24 @@
+#ifndef _SYSEXITS_H
+#define _SYSEXITS_H
+
+#define EX_OK 0
+#define EX_USAGE 64
+#define EX_DATAERR 65
+#define EX_NOINPUT 66
+#define EX_NOUSER 67
+#define EX_NOHOST 68
+#define EX_UNAVAILABLE 69
+#define EX_SOFTWARE 70
+#define EX_OSERR 71
+#define EX_OSFILE 72
+#define EX_CANTCREAT 73
+#define EX_IOERR 74
+#define EX_TEMPFAIL 75
+#define EX_PROTOCOL 76
+#define EX_NOPERM 77
+#define EX_CONFIG 78
+
+#define EX__BASE 64
+#define EX__MAX 78
+
+#endif // _SYSEXITS_H
diff --git a/lib/mlibc/options/glibc/meson.build b/lib/mlibc/options/glibc/meson.build
new file mode 100644
index 0000000..93bad85
--- /dev/null
+++ b/lib/mlibc/options/glibc/meson.build
@@ -0,0 +1,90 @@
+if disable_glibc_option
+ subdir_done()
+endif
+libc_sources += files(
+ 'generic/getopt-stubs.cpp',
+ 'generic/stdio_ext-stubs.cpp',
+ 'generic/sys-ioctl.cpp',
+ 'generic/err.cpp',
+ 'generic/error.cpp',
+ 'generic/resolv-stubs.cpp',
+ 'generic/shadow-stubs.cpp',
+ 'generic/printf.cpp',
+ 'generic/glibc-signal.cpp',
+ 'generic/execinfo.cpp',
+ 'generic/string.cpp',
+ 'generic/personality.cpp',
+ 'generic/gshadow.cpp',
+ 'generic/sys-timex.cpp',
+ 'generic/glibc-assert.cpp',
+ 'generic/malloc.cpp',
+ 'generic/sys-io.cpp',
+)
+
+if not no_headers
+ install_headers(
+ 'include/getopt.h',
+ 'include/stdio_ext.h',
+ 'include/err.h',
+ 'include/error.h',
+ 'include/paths.h',
+ 'include/sysexits.h',
+ 'include/resolv.h',
+ 'include/endian.h',
+ 'include/ar.h',
+ 'include/shadow.h',
+ 'include/memory.h',
+ 'include/printf.h',
+ 'include/gshadow.h',
+ 'include/execinfo.h',
+ 'include/features.h'
+ )
+ install_headers(
+ 'include/sys/dir.h',
+ 'include/sys/ioctl.h',
+ 'include/sys/user.h',
+ 'include/sys/procfs.h',
+ 'include/sys/reg.h',
+ 'include/sys/errno.h',
+ 'include/sys/signal.h',
+ 'include/sys/ucontext.h',
+ 'include/sys/personality.h',
+ 'include/sys/timeb.h',
+ 'include/sys/mtio.h',
+ 'include/sys/endian.h',
+ 'include/sys/timex.h',
+ 'include/sys/kd.h',
+ 'include/sys/io.h',
+ subdir: 'sys'
+ )
+ install_headers(
+ 'include/net/ethernet.h',
+ 'include/net/route.h',
+ 'include/net/if_ppp.h',
+ subdir: 'net'
+ )
+ install_headers(
+ 'include/netax25/ax25.h',
+ subdir: 'netax25'
+ )
+ install_headers(
+ 'include/netipx/ipx.h',
+ subdir: 'netipx'
+ )
+ install_headers(
+ 'include/netrom/netrom.h',
+ subdir: 'netrom'
+ )
+ install_headers(
+ 'include/netinet/in_systm.h',
+ subdir: 'netinet'
+ )
+ install_headers(
+ 'include/bits/glibc/glibc_signal.h',
+ 'include/bits/glibc/glibc_assert.h',
+ 'include/bits/glibc/glibc_malloc.h',
+ 'include/bits/glibc/glibc_icmp6.h',
+ subdir: 'bits/glibc'
+ )
+endif
+