diff --git mlibc-clean/options/ansi/generic/stdio.cpp mlibc-workdir/options/ansi/generic/stdio.cpp index 71033d0..4d40869 100644 --- mlibc-clean/options/ansi/generic/stdio.cpp +++ mlibc-workdir/options/ansi/generic/stdio.cpp @@ -1224,6 +1224,8 @@ int do_scanf(H &handler, const Char *fmt, __builtin_va_list args) { if (tolower(c) == 'x') { handler.consume(); c = handler.look_ahead(); + } else { + ++count; } } while (true) { diff --git mlibc-clean/options/glibc/generic/execinfo.cpp mlibc-workdir/options/glibc/generic/execinfo.cpp index 1ed110d..ded9114 100644 --- mlibc-clean/options/glibc/generic/execinfo.cpp +++ mlibc-workdir/options/glibc/generic/execinfo.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -52,29 +53,7 @@ _Unwind_Reason_Code trace(_Unwind_Context *context, void *arg) { } // namespace int backtrace(void **buffer, int size) { - if (size <= 0) - return 0; - - if (!libgccHandle) { - libgccHandle = dlopen("libgcc_s.so.1", RTLD_LAZY | RTLD_LOCAL); - if (!libgccHandle || libgccHandle.value() == nullptr) { - auto error = dlerror(); - mlibc::infoLogger() << "Failed to load libgcc_s.so.1: " << (error ? error : "") << frg::endlog; - return 0; - } - - unwindBacktrace = reinterpret_cast(dlsym(libgccHandle.value(), "_Unwind_Backtrace")); - unwindGetIP = reinterpret_cast(dlsym(libgccHandle.value(), "_Unwind_GetIP")); - - if (!unwindBacktrace || !unwindGetIP) { - mlibc::infoLogger() << "Failed to find unwind functions in libgcc_s.so.1: " << dlerror() << frg::endlog; - return 0; - } - } - - UnwindState state{buffer, size}; - unwindBacktrace(trace, &state); - return state.current_frame; + return ENOSYS; } char **backtrace_symbols(void *const *, int) { @@ -82,25 +61,5 @@ char **backtrace_symbols(void *const *, int) { __builtin_unreachable(); } -void backtrace_symbols_fd(void *const *buffer, int size, int fd) { - if (size <= 0 || fd < 0) - return; - - for (int frame_num = 0; frame_num < size; frame_num++) { - Dl_info info; - if (dladdr(buffer[frame_num], &info) != 0) { - if (info.dli_fname != nullptr) - write(fd, info.dli_fname, strlen(info.dli_fname)); - - if (info.dli_sname != nullptr) - dprintf(fd, "(%s+0x%" PRIxPTR ") ", info.dli_sname, - reinterpret_cast(buffer[frame_num]) - reinterpret_cast(info.dli_saddr)); - else if(info.dli_saddr) - dprintf(fd, "(+%p) ", info.dli_saddr); - else - dprintf(fd, "() "); - } - - dprintf(fd, "[%p]\n", buffer[frame_num]); - } +void backtrace_symbols_fd(void *const *, int, int) { } diff --git mlibc-clean/options/glibc/generic/stdio_ext.cpp mlibc-workdir/options/glibc/generic/stdio_ext.cpp index ccb3725..3dfa27a 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/global-config.cpp mlibc-workdir/options/internal/generic/global-config.cpp index 3b7b862..3d86e7a 100644 --- mlibc-clean/options/internal/generic/global-config.cpp +++ mlibc-workdir/options/internal/generic/global-config.cpp @@ -1,9 +1,15 @@ #include -#include +#include #include namespace mlibc { +namespace { + +constinit mlibc::lazy_eternal globalConfigInstance; + +} // namespace + struct GlobalConfigGuard { GlobalConfigGuard(); }; @@ -12,7 +18,7 @@ GlobalConfigGuard guard; GlobalConfigGuard::GlobalConfigGuard() { // Force the config to be created during initialization of libc.so. - mlibc::globalConfig(); + globalConfigInstance.get(); } static bool envEnabled(const char *env) { @@ -29,4 +35,8 @@ GlobalConfig::GlobalConfig() { debugMonetaryLengths = envEnabled("MLIBC_DEBUG_MONETARY_LENGTHS"); } +const GlobalConfig &globalConfig() { + return globalConfigInstance.get(); +} + } // namespace mlibc diff --git mlibc-clean/options/internal/include/mlibc/allocator.hpp mlibc-workdir/options/internal/include/mlibc/allocator.hpp index 852620a..a1bfb0a 100644 --- mlibc-clean/options/internal/include/mlibc/allocator.hpp +++ mlibc-workdir/options/internal/include/mlibc/allocator.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -35,4 +36,34 @@ MemoryAllocator &getAllocator(); #endif // !MLIBC_DEBUG_ALLOCATOR +namespace mlibc { + +template +struct lazy_eternal { + constexpr lazy_eternal() = default; + + template + auto &get(this Self &&self) { + if (__atomic_load_n(&self.initialized_, __ATOMIC_ACQUIRE)) + return *self.box_.get(); + + { + frg::unique_lock lock{self.lock_}; + if (!__atomic_load_n(&self.initialized_, __ATOMIC_RELAXED)) { + self.box_.initialize(); + __atomic_store_n(&self.initialized_, 1, __ATOMIC_RELEASE); + } + } + + return *self.box_.get(); + } + +private: + mutable uint32_t initialized_ = 0; + mutable FutexLock lock_; + mutable frg::manual_box box_; +}; + +} // namespace mlibc + #endif // MLIBC_FRIGG_ALLOC diff --git mlibc-clean/options/internal/include/mlibc/global-config.hpp mlibc-workdir/options/internal/include/mlibc/global-config.hpp index 0235c54..3fad411 100644 --- mlibc-clean/options/internal/include/mlibc/global-config.hpp +++ mlibc-workdir/options/internal/include/mlibc/global-config.hpp @@ -14,11 +14,8 @@ struct GlobalConfig { bool debugMonetaryLengths; }; -inline const GlobalConfig &globalConfig() { - static GlobalConfig cached; - return cached; -} +const GlobalConfig &globalConfig(); -} +} // namespace mlibc #endif // MLIBC_GLOBAL_CONFIG diff --git mlibc-clean/options/internal/include/mlibc/lock.hpp mlibc-workdir/options/internal/include/mlibc/lock.hpp index f447741..ab44667 100644 --- mlibc-clean/options/internal/include/mlibc/lock.hpp +++ mlibc-workdir/options/internal/include/mlibc/lock.hpp @@ -14,7 +14,7 @@ template struct alignas(4) FutexLockImpl { - FutexLockImpl() : _state{0}, _recursion{0} { } + constexpr FutexLockImpl() : _state{0}, _recursion{0} { } FutexLockImpl(const FutexLockImpl &) = delete; diff --git mlibc-clean/options/internal/include/mlibc/sysdep-signatures.hpp mlibc-workdir/options/internal/include/mlibc/sysdep-signatures.hpp index d639e43..694021a 100644 --- mlibc-clean/options/internal/include/mlibc/sysdep-signatures.hpp +++ mlibc-workdir/options/internal/include/mlibc/sysdep-signatures.hpp @@ -23,6 +23,10 @@ #include +#if __MLIBC_POSIX_OPTION +#include +#endif + namespace mlibc { template @@ -156,6 +160,7 @@ SYSDEP_FUNC(Linkat, int olddirfd, const char *old_path, int newdirfd, const char SYSDEP_FUNC(Symlink, const char *target_path, const char *link_path); SYSDEP_FUNC(Symlinkat, const char *target_path, int dirfd, const char *link_path); SYSDEP_FUNC(Renameat, int olddirfd, const char *old_path, int newdirfd, const char *new_path); +SYSDEP_FUNC(Renameat2, int olddirfd, const char *old_path, int newdirfd, const char *new_path, unsigned int flags); SYSDEP_FUNC(Fcntl, int fd, int request, va_list args, int *result); SYSDEP_FUNC(Ttyname, int fd, char *buf, size_t size); SYSDEP_FUNC(Fadvise, int fd, off_t offset, off_t length, int advice); @@ -235,6 +240,7 @@ SYSDEP_FUNC(SetRegid, gid_t rgid, gid_t egid); SYSDEP_FUNC(GetLoginR, char *name, size_t name_len); SYSDEP_FUNC(IfIndextoname, unsigned int index, char *name); SYSDEP_FUNC(IfNametoindex, const char *name, unsigned int *ret); +SYSDEP_FUNC(IfNameindex, struct if_nameindex **ret); SYSDEP_FUNC(Ptsname, int fd, char *buffer, size_t length); SYSDEP_FUNC(Unlockpt, int fd); SYSDEP_FUNC(ThreadSetname, void *tcb, const char *name); diff --git mlibc-clean/options/internal/include/mlibc/sysdep-tags.hpp mlibc-workdir/options/internal/include/mlibc/sysdep-tags.hpp index 17cf422..01941c1 100644 --- mlibc-clean/options/internal/include/mlibc/sysdep-tags.hpp +++ mlibc-workdir/options/internal/include/mlibc/sysdep-tags.hpp @@ -316,6 +316,8 @@ struct Symlink {}; struct Symlinkat {}; // int sys_renameat(int olddirfd, const char *old_path, int newdirfd, const char *new_path); struct Renameat {}; +// int sys_renameat2(int olddirfd, const char *old_path, int newdirfd, const char *new_path, unsigned int flags); +struct Renameat2 {}; // int sys_fcntl(int fd, int request, va_list args, int *result); struct Fcntl {}; // int sys_ttyname(int fd, char *buf, size_t size); @@ -476,6 +478,8 @@ struct GetLoginR {}; struct IfIndextoname {}; // int sys_if_nametoindex(const char *name, unsigned int *ret); struct IfNametoindex {}; +// int sys_if_nameindex(struct if_nameindex **ret); +struct IfNameindex {}; // int sys_ptsname(int fd, char *buffer, size_t length); struct Ptsname {}; // int sys_unlockpt(int fd); diff --git mlibc-clean/options/posix/generic/net-if.cpp mlibc-workdir/options/posix/generic/net-if.cpp index ed0c463..8df2580 100644 --- mlibc-clean/options/posix/generic/net-if.cpp +++ mlibc-workdir/options/posix/generic/net-if.cpp @@ -6,8 +6,13 @@ #include #include -void if_freenameindex(struct if_nameindex *) { - mlibc::infoLogger() << "mlibc: if_freenameindex is a no-op" << frg::endlog; +void if_freenameindex(struct if_nameindex *index) { + if(!index) + return; + + for(struct if_nameindex *it = index; it->if_index || it->if_name; ++it) + free(it->if_name); + free(index); } char *if_indextoname(unsigned int index, char *name) { @@ -20,9 +25,13 @@ char *if_indextoname(unsigned int index, char *name) { } struct if_nameindex *if_nameindex(void) { - mlibc::infoLogger() << "mlibc: if_nameindex() is a no-op" << frg::endlog; - errno = ENOSYS; - return nullptr; + struct if_nameindex *ret = nullptr; + if(int e = mlibc::sysdep_or_enosys(&ret); e) { + errno = e; + return nullptr; + } + + return ret; } unsigned int if_nametoindex(const char *name) { diff --git mlibc-clean/options/posix/generic/posix_stdio.cpp mlibc-workdir/options/posix/generic/posix_stdio.cpp index 8592ea5..94ceba1 100644 --- mlibc-clean/options/posix/generic/posix_stdio.cpp +++ mlibc-workdir/options/posix/generic/posix_stdio.cpp @@ -233,7 +233,10 @@ int renameat(int olddirfd, const char *old_path, int newdirfd, const char *new_p return 0; } -int renameat2(int, const char *, int, const char *, unsigned int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); +int renameat2(int olddirfd, const char *old_path, int newdirfd, const char *new_path, unsigned int flags) { + if(int e = mlibc::sysdep_or_enosys(olddirfd, old_path, newdirfd, new_path, flags); e) { + errno = e; + return -1; + } + return 0; } diff --git mlibc-clean/options/rtld/generic/main.cpp mlibc-workdir/options/rtld/generic/main.cpp index bf54bcb..106916a 100644 --- mlibc-clean/options/rtld/generic/main.cpp +++ mlibc-workdir/options/rtld/generic/main.cpp @@ -729,7 +729,12 @@ void *__dlapi_open(const char *file, int flags, void *returnAddress) { // TODO: Thread-safety! auto rts = rtsCounter++; - SharedObject *object = initialRepository->findLoadedObject(file); + auto objectName = frg::string_view{file}; + auto lastSlash = objectName.find_last('/'); + if (lastSlash != static_cast(-1)) + objectName = objectName.sub_string(lastSlash + 1, objectName.size() - (lastSlash + 1)); + + SharedObject *object = initialRepository->findLoadedObject(objectName); if (object && object->globalRts == 0 && (flags & RTLD_GLOBAL)) { // The object was opened with RTLD_LOCAL, but we are called with RTLD_GLOBAL. // According to the man page, we should promote to the global scope here. diff --git mlibc-clean/options/rtld/x86_64/runtime.S mlibc-workdir/options/rtld/x86_64/runtime.S index ba9a520..b958ef3 100644 --- mlibc-clean/options/rtld/x86_64/runtime.S +++ mlibc-workdir/options/rtld/x86_64/runtime.S @@ -60,4 +60,3 @@ pltRelocateStub: jmp *%r11 .section .note.GNU-stack,"",%progbits - diff --git mlibc-clean/sysdeps/astral/generic/generic.cpp mlibc-workdir/sysdeps/astral/generic/generic.cpp index 3b04372..e5741d1 100644 --- mlibc-clean/sysdeps/astral/generic/generic.cpp +++ mlibc-workdir/sysdeps/astral/generic/generic.cpp @@ -1,7 +1,9 @@ #include +#include #include #include #include +#include #include #include #include @@ -11,8 +13,31 @@ #include #include #include +#include +#include +#include +#include #include #include +#include + +typedef struct { + struct sockaddr addr; + struct sockaddr broadaddr; + struct sockaddr netmask; + struct sockaddr hwaddr; + short flags; + int mtu; +} astral_net_info_t; + +typedef struct { + struct ifaddrs ifa; + unsigned int if_index; + char if_name[IFNAMSIZ]; + struct sockaddr addr; + struct sockaddr broadaddr; + struct sockaddr netmask; +} astral_ifaddrs_t; namespace mlibc { int Sysdeps::operator()(size_t size, const gid_t *list) { @@ -31,14 +56,307 @@ namespace mlibc { return 0; } - int Sysdeps::operator()(int fd, int layer, int number, - void *__restrict buffer, socklen_t *__restrict size) { + int Sysdeps::operator()(double *samples) { + struct sysinfo si; + if(int e = sysdep(&si); e) + return e; + + for(int i = 0; i < 3; i++) + samples[i] = (double)si.loads[i] / (1 << SI_LOAD_SHIFT); + + return 0; + } + + int Sysdeps::operator()(struct tms *tms, clock_t *out) { + if(tms) { + tms->tms_utime = 0; + tms->tms_stime = 0; + tms->tms_cutime = 0; + tms->tms_cstime = 0; + } + + *out = 0; + return 0; + } + + int Sysdeps::operator()(int fd, off_t offset, off_t length, int advice) { + (void)fd; + (void)offset; + (void)length; + (void)advice; + return 0; + } + + int Sysdeps::operator()(const char *path, const char *name, + const void *val, size_t size, int flags) { + (void)path; + (void)name; + (void)val; (void)size; - (void)buffer; - // TODO unstub - mlibc::infoLogger() << "getsockopt: " << fd << " " << layer << " " << number << frg::endlog; + (void)flags; + return ENOTSUP; + } + + int Sysdeps::operator()(const char *path, const char *name, + const void *val, size_t size, int flags) { + (void)path; + (void)name; + (void)val; + (void)size; + (void)flags; + return ENOTSUP; + } + + int Sysdeps::operator()(int fd, const char *name, const void *val, + size_t size, int flags) { + (void)fd; + (void)name; + (void)val; + (void)size; + (void)flags; + return ENOTSUP; + } + + int Sysdeps::operator()(const char *path, const char *name, + void *val, size_t size, ssize_t *nread) { + (void)path; + (void)name; + (void)val; + (void)size; + (void)nread; + return ENOTSUP; + } + + int Sysdeps::operator()(const char *path, const char *name, + void *val, size_t size, ssize_t *nread) { + (void)path; + (void)name; + (void)val; + (void)size; + (void)nread; + return ENOTSUP; + } + + int Sysdeps::operator()(int fd, const char *name, void *val, + size_t size, ssize_t *nread) { + (void)fd; + (void)name; + (void)val; + (void)size; + (void)nread; + return ENOTSUP; + } + + int Sysdeps::operator()(const char *path, char *list, size_t size, + ssize_t *nread) { + (void)path; + (void)list; + (void)size; + (void)nread; + return ENOTSUP; + } + + int Sysdeps::operator()(const char *path, char *list, size_t size, + ssize_t *nread) { + (void)path; + (void)list; + (void)size; + (void)nread; + return ENOTSUP; + } + + int Sysdeps::operator()(int fd, char *list, size_t size, + ssize_t *nread) { + (void)fd; + (void)list; + (void)size; + (void)nread; + return ENOTSUP; + } + +#ifndef MLIBC_BUILDING_RTLD + int Sysdeps::operator()(struct ifaddrs **out) { + struct ifaddrs *list = nullptr; + + int dirfd; + int error = sysdep("/dev/", O_DIRECTORY | O_RDONLY, 0, &dirfd); + if(error) + return error; + + struct dirent dent; + size_t bytes_read; + for(;;) { + error = sysdep(dirfd, &dent, sizeof(dent), &bytes_read); + if(error) + goto leave; + + if(bytes_read == 0) + break; + + struct stat st; + if(sysdep(fsfd_target::fd_path, dirfd, dent.d_name, AT_SYMLINK_NOFOLLOW, &st)) + continue; + + if(!S_ISCHR(st.st_mode) || major(st.st_rdev) != 10) + continue; + + if(strlen(dent.d_name) >= IFNAMSIZ) + continue; + + int fd; + error = sysdep(dirfd, dent.d_name, 0, 0, &fd); + if(error) + continue; + + astral_net_info_t net_info = {}; + int r; + error = sysdep(fd, 0x1337631, &net_info, &r); + if(error) { + sysdep(fd); + continue; + } + + astral_ifaddrs_t *next = (astral_ifaddrs_t *)calloc(1, sizeof(*next)); + if(!next) { + sysdep(fd); + error = ENOMEM; + goto leave; + } + + next->ifa.ifa_next = list; + next->if_index = minor(st.st_rdev) + 1; + + strcpy(next->if_name, dent.d_name); + next->ifa.ifa_name = next->if_name; + + next->ifa.ifa_flags = net_info.flags; + + if(net_info.addr.sa_family) { + memcpy(&next->addr, &net_info.addr, sizeof(next->addr)); + next->ifa.ifa_addr = &next->addr; + } + + if(net_info.netmask.sa_family) { + memcpy(&next->netmask, &net_info.netmask, sizeof(next->netmask)); + next->ifa.ifa_netmask = &next->netmask; + } + + if(net_info.broadaddr.sa_family) { + memcpy(&next->broadaddr, &net_info.broadaddr, sizeof(next->broadaddr)); + next->ifa.ifa_broadaddr = &next->broadaddr; + } + + next->ifa.ifa_data = nullptr; + + list = &next->ifa; + sysdep(fd); + } + + *out = list; + +leave: + sysdep(dirfd); + if(error) + freeifaddrs(list); + return error; + } + + int Sysdeps::operator()(unsigned int index, char *name) { + if(!index || !name) + return EINVAL; + + struct ifaddrs *ifaddrs; + if(int e = sysdep(&ifaddrs); e) + return e; + + int error = ENXIO; + for(struct ifaddrs *it = ifaddrs; it; it = it->ifa_next) { + astral_ifaddrs_t *entry = (astral_ifaddrs_t *)it; + if(entry->if_index != index) + continue; + + strcpy(name, entry->if_name); + error = 0; + break; + } + + freeifaddrs(ifaddrs); + return error; + } + + int Sysdeps::operator()(const char *name, unsigned int *ret) { + if(!name) + return EINVAL; + + struct ifaddrs *ifaddrs; + if(int e = sysdep(&ifaddrs); e) + return e; + + int error = ENXIO; + for(struct ifaddrs *it = ifaddrs; it; it = it->ifa_next) { + astral_ifaddrs_t *entry = (astral_ifaddrs_t *)it; + if(strcmp(entry->if_name, name)) + continue; + + *ret = entry->if_index; + error = 0; + break; + } + + freeifaddrs(ifaddrs); + return error; + } + + int Sysdeps::operator()(struct if_nameindex **out) { + struct ifaddrs *ifaddrs; + if(int e = sysdep(&ifaddrs); e) + return e; + + struct ifaddrs *it = ifaddrs; + int count = 0; + while(it) { + ++count; + it = it->ifa_next; + } + + struct if_nameindex *arr = (struct if_nameindex *)malloc(sizeof(struct if_nameindex) * (count + 1)); + if(!arr) { + freeifaddrs(ifaddrs); + return ENOMEM; + } + + int i = 0; + for(struct ifaddrs *it = ifaddrs; it; it = it->ifa_next) { + astral_ifaddrs_t *entry = (astral_ifaddrs_t *)it; + + arr[i].if_index = entry->if_index; + arr[i].if_name = strdup(entry->if_name); + if(!arr[i].if_name) { + for(int j = 0; j < i; ++j) + free(arr[j].if_name); + free(arr); + freeifaddrs(ifaddrs); + return ENOMEM; + } + + ++i; + } + + arr[count].if_index = 0; + arr[count].if_name = nullptr; + + *out = arr; + freeifaddrs(ifaddrs); + return 0; } +#endif + + int Sysdeps::operator()(int fd, int layer, int number, + void *__restrict buffer, socklen_t *__restrict size) { + long ret; + return syscall(SYSCALL_GETSOCKOPT, &ret, fd, layer, number, (uint64_t)buffer, (uint64_t)size); + } int Sysdeps::operator()(bool *ipv4, bool *ipv6) { // there is no ipv6 support in the kernel currently and no way of checking for configured interfaces @@ -47,6 +365,71 @@ namespace mlibc { return 0; } + int Sysdeps::operator()(int fd) { + int r; + // unlockpt is a no-op kernel side, so use this to check for an invalid pty + return sysdep(fd, 0x13376167, nullptr, &r); + } + + int Sysdeps::operator()(const char *path, struct statfs *buf) { + struct statvfs stvfs; + int ret = sysdep(path, &stvfs); + if(ret) + return ret; + + buf->f_type = 0; /* statvfs has no f_type */ + buf->f_blocks = stvfs.f_blocks; + buf->f_bfree = stvfs.f_bfree; + buf->f_bavail = stvfs.f_bavail; + buf->f_files = stvfs.f_files; + buf->f_ffree = stvfs.f_ffree; + buf->f_fsid.__val[0] = (int)(stvfs.f_fsid & 0xFFFFFFFF); + buf->f_fsid.__val[1] = (int)(stvfs.f_fsid >> 32); + buf->f_namelen = stvfs.f_namemax; + buf->f_flags = stvfs.f_flag; + buf->f_bsize = stvfs.f_frsize; + buf->f_frsize = stvfs.f_bsize; + + return 0; + } + + int Sysdeps::operator()(int fd, struct statfs *buf) { + struct statvfs stvfs; + int ret = sysdep(fd, &stvfs); + if(ret) + return ret; + + buf->f_type = 0; /* statvfs has no f_type */ + buf->f_bsize = stvfs.f_bsize; + buf->f_bfree = stvfs.f_bfree; + buf->f_bavail = stvfs.f_bavail; + buf->f_files = stvfs.f_files; + buf->f_ffree = stvfs.f_ffree; + buf->f_fsid.__val[0] = (int)(stvfs.f_fsid & 0xFFFFFFFF); + buf->f_fsid.__val[1] = (int)(stvfs.f_fsid >> 32); + buf->f_namelen = stvfs.f_namemax; + buf->f_flags = stvfs.f_flag; + buf->f_bsize = stvfs.f_frsize; + buf->f_frsize = stvfs.f_bsize; + + return 0; + } + + int Sysdeps::operator()(const char *path, struct statvfs *out) { + long r; + return syscall(SYSCALL_FSTATVFSAT, &r, AT_FDCWD, (uint64_t)path, (uint64_t)out, 0); + } + + int Sysdeps::operator()(int fd, struct statvfs *out) { + long r; + return syscall(SYSCALL_FSTATVFS, &r, fd, (uint64_t)out); + } + + void Sysdeps::operator()() { + long r; + syscall(SYSCALL_YIELD, &r); + } + int Sysdeps::operator()(int fd, const struct iovec *iovs, int iovc, ssize_t *bytes_read) { long r; int error = syscall(SYSCALL_READV, &r, fd, (uint64_t)iovs, iovc); @@ -86,6 +469,11 @@ namespace mlibc { return e; } + int Sysdeps::operator()(int which, id_t who, int prio) { + long ret; + return syscall(SYSCALL_SETPRIORITY, &ret, which, who, prio); + } + int Sysdeps::operator()(int sockfd, int how) { long ret; return syscall(SYSCALL_SHUTDOWN, &ret, sockfd, how); @@ -487,8 +875,15 @@ namespace mlibc { return err; } + int Sysdeps::operator()(void *tcb, const char *name) { + (void)tcb; + (void)name; + return 0; + } + int Sysdeps::operator()(int fd, int layer, int number, const void *buffer, socklen_t size) { long ret; + mlibc::infoLogger() << "setsockopt: fd " << fd << " layer " << layer << " number " << number << frg::endlog; return syscall(SYSCALL_SETSOCKOPT, &ret, fd, layer, number, (uint64_t)buffer, size); } @@ -511,6 +906,11 @@ namespace mlibc { return err; } + int Sysdeps::operator()(int old_dirfd, const char *old_path, int new_dirfd, const char *new_path, unsigned int flags) { + long ret; + return syscall(SYSCALL_RENAMEAT, &ret, old_dirfd, (uint64_t)old_path, new_dirfd, (uint64_t)new_path, flags); + } + int Sysdeps::operator()(int olddirfd, const char *old_path, int newdirfd, const char *new_path) { long ret; return syscall(SYSCALL_RENAMEAT, &ret, olddirfd, (uint64_t)old_path, newdirfd, (uint64_t)new_path); @@ -562,6 +962,16 @@ namespace mlibc { return sysdep(fd, TCSETS, (void *)attr, &res); } + int Sysdeps::operator()(int fd, struct winsize *winsz) { + int res; + return sysdep(fd, TIOCGWINSZ, (void *)winsz, &res); + } + + int Sysdeps::operator()(int fd, const struct winsize *winsz) { + int res; + return sysdep(fd, TIOCSWINSZ, (void *)winsz, &res); + } + int Sysdeps::operator()(struct pollfd *fds, nfds_t count, int timeout, int *num_events) { long ret; long error = syscall(SYSCALL_POLL, &ret, (uint64_t)fds, count, timeout); @@ -932,4 +1342,13 @@ namespace mlibc { *nanos = ts.tv_nsec; return err; } + + int Sysdeps::operator()(int clock, time_t *secs, long *nanos) { + struct timespec ts; + long ret; + int err = syscall(SYSCALL_CLOCK_GETRES, &ret, clock, (uint64_t)&ts); + *secs = ts.tv_sec; + *nanos = ts.tv_nsec; + return err; + } } // namespace mlibc diff --git mlibc-clean/sysdeps/astral/include/astral/archctl.h mlibc-workdir/sysdeps/astral/include/astral/archctl.h index 7e4f2a1..ecc2677 100644 --- mlibc-clean/sysdeps/astral/include/astral/archctl.h +++ mlibc-workdir/sysdeps/astral/include/astral/archctl.h @@ -5,6 +5,17 @@ #define ARCH_CTL_SET_FSBASE 1 #define ARCH_CTL_GET_GSBASE 2 #define ARCH_CTL_GET_FSBASE 3 +#define ARCH_CTL_SET_SYSTRACE 4 +#define ARCH_CTL_SET_LDT_ENTRY 5 + +#define ARCH_CTL_SYSTRACE_OFF 0 +#define ARCH_CTL_SYSTRACE_SELF 1 +#define ARCH_CTL_SYSTRACE_ALL 2 + +typedef struct { + uint64_t entry; + uint16_t seg; +} archctl_ldt_request_t; #ifdef __cplusplus extern "C" { diff --git mlibc-clean/sysdeps/astral/include/astral/syscall.h mlibc-workdir/sysdeps/astral/include/astral/syscall.h index a6c4067..fd38197 100644 --- mlibc-clean/sysdeps/astral/include/astral/syscall.h +++ mlibc-workdir/sysdeps/astral/include/astral/syscall.h @@ -103,6 +103,12 @@ #define SYSCALL_SYSINFO 96 #define SYSCALL_WRITEV 97 #define SYSCALL_READV 98 +#define SYSCALL_YIELD 99 +#define SYSCALL_FSTATVFS 100 +#define SYSCALL_FSTATVFSAT 101 +#define SYSCALL_GETSOCKOPT 102 +#define SYSCALL_CLOCK_GETRES 103 +#define SYSCALL_SETPRIORITY 104 #ifndef __MLIBC_ABI_ONLY diff --git mlibc-clean/sysdeps/astral/include/mlibc/sysdeps.hpp mlibc-workdir/sysdeps/astral/include/mlibc/sysdeps.hpp index ce91084..0fffdf3 100644 --- mlibc-clean/sysdeps/astral/include/mlibc/sysdeps.hpp +++ mlibc-workdir/sysdeps/astral/include/mlibc/sysdeps.hpp @@ -7,8 +7,30 @@ namespace mlibc { struct AstralSysdepTags : SetGroups, GetGroups, + GetLoadavg, + Times, + Fadvise, + Setxattr, + Lsetxattr, + Fsetxattr, + Getxattr, + Lgetxattr, + Fgetxattr, + Listxattr, + Llistxattr, + Flistxattr, + Getifaddrs, + IfIndextoname, + IfNametoindex, + IfNameindex, GetSockopt, InetConfigured, + Unlockpt, + Statfs, + Fstatfs, + Statvfs, + Fstatvfs, + Yield, Readv, Writev, Sysinfo, @@ -66,6 +88,7 @@ struct AstralSysdepTags : SetSid, FutexTid, GetTid, + ThreadSetname, ThreadExit, Clone, Listen, @@ -77,6 +100,7 @@ struct AstralSysdepTags : Bind, Socket, Renameat, + Renameat2, Rename, Utimensat, Fchownat, @@ -85,6 +109,8 @@ struct AstralSysdepTags : Sleep, Tcgetattr, Tcsetattr, + Tcgetwinsize, + Tcsetwinsize, Poll, Ppoll, Pselect, @@ -135,7 +161,9 @@ struct AstralSysdepTags : VmUnmap, Isatty, ClockGet, - PrepareStack + ClockGetres, + PrepareStack, + SetPriority {}; template diff --git mlibc-clean/sysdeps/linux/generic/sysdeps.cpp mlibc-workdir/sysdeps/linux/generic/sysdeps.cpp index a07ed53..1474470 100644 --- mlibc-clean/sysdeps/linux/generic/sysdeps.cpp +++ mlibc-workdir/sysdeps/linux/generic/sysdeps.cpp @@ -1060,6 +1060,13 @@ int Sysdeps::operator()(int old_dirfd, const char *old_path, int new_d return 0; } +int Sysdeps::operator()(int old_dirfd, const char *old_path, int new_dirfd, const char *new_path, unsigned int flags) { + auto ret = do_syscall(SYS_renameat2, old_dirfd, old_path, new_dirfd, new_path, flags); + if (int e = sc_error(ret); e) + return e; + return 0; +} + int Sysdeps::operator()(int fd, int cmd, va_list args, int *result) { auto arg = va_arg(args, unsigned long); // TODO: the api for linux differs for each command so fcntl()s might fail with -EINVAL