From 40b2c02864edaeee8619d30371dd210ed8d4d042 Mon Sep 17 00:00:00 2001 From: Lubos Dolezel Date: Wed, 12 Dec 2012 19:39:51 +0100 Subject: [PATCH] Adding: - a couple of xlocale functions - malloc_zone fake functions on top of malloc/free - some missing stdio functions - improved (configurable) uname - full posix_spawn implementation --- config.h.in | 2 + etc/version.conf | 5 + src/dyld/keymgr.cpp | 4 + src/dyld/keymgr.h | 1 + src/dyld/ld.cpp | 2 +- src/libSystem/CMakeLists.txt | 4 + src/libSystem/common/auto.h | 8 ++ src/libSystem/libc/exec.cpp | 14 +-- src/libSystem/libc/exec.h | 6 + src/libSystem/libc/mac.c | 182 --------------------------- src/libSystem/libc/malloc_zone.cpp | 65 ++++++++++ src/libSystem/libc/malloc_zone.h | 36 ++++++ src/libSystem/libc/signals.cpp | 18 +-- src/libSystem/libc/signals.h | 3 + src/libSystem/libc/spawn.cpp | 196 +++++++++++++++++++++++++++++ src/libSystem/libc/spawn.h | 52 ++++++++ src/libSystem/libc/stdio.cpp | 10 ++ src/libSystem/libc/stdio.h | 2 + src/libSystem/libc/uname.cpp | 68 ++++++++++ src/libSystem/libc/uname.h | 19 +++ src/libSystem/libc/xlocale.cpp | 59 +++++++++ src/libSystem/libc/xlocale.h | 82 ++++++++++++ 22 files changed, 639 insertions(+), 199 deletions(-) create mode 100644 etc/version.conf create mode 100644 src/libSystem/libc/malloc_zone.cpp create mode 100644 src/libSystem/libc/malloc_zone.h create mode 100644 src/libSystem/libc/spawn.cpp create mode 100644 src/libSystem/libc/spawn.h create mode 100644 src/libSystem/libc/uname.cpp create mode 100644 src/libSystem/libc/uname.h create mode 100644 src/libSystem/libc/xlocale.cpp create mode 100644 src/libSystem/libc/xlocale.h diff --git a/config.h.in b/config.h.in index 937d9a04f..e7916ad62 100644 --- a/config.h.in +++ b/config.h.in @@ -6,6 +6,8 @@ #define LIB_DIR_NAME "lib@SUFFIX@" #define INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" +#define ETC_DARLING_PATH "/etc/darling" + #cmakedefine MULTILIB /* diff --git a/etc/version.conf b/etc/version.conf new file mode 100644 index 000000000..7be81bcc2 --- /dev/null +++ b/etc/version.conf @@ -0,0 +1,5 @@ +[uname] +sysname=Darwin +release=12.0.0 +version=Darwin Kernel Version 12.0.0 + diff --git a/src/dyld/keymgr.cpp b/src/dyld/keymgr.cpp index ab18149e0..f6ee7e016 100644 --- a/src/dyld/keymgr.cpp +++ b/src/dyld/keymgr.cpp @@ -46,3 +46,7 @@ void _keymgr_unlock_processwide_ptr(unsigned key) pthread_mutex_unlock(&m_keymgr[key].mutex); } +void __keymgr_dwarf2_register_sections() +{ +} + diff --git a/src/dyld/keymgr.h b/src/dyld/keymgr.h index 8275aa865..465a1ff23 100644 --- a/src/dyld/keymgr.h +++ b/src/dyld/keymgr.h @@ -7,6 +7,7 @@ extern "C" { void* _keymgr_get_and_lock_processwide_ptr(unsigned key); void _keymgr_set_and_unlock_processwide_ptr(unsigned key, void* ptr); void _keymgr_unlock_processwide_ptr(unsigned key); +void __keymgr_dwarf2_register_sections(); } diff --git a/src/dyld/ld.cpp b/src/dyld/ld.cpp index de4ea9299..00223cb8a 100644 --- a/src/dyld/ld.cpp +++ b/src/dyld/ld.cpp @@ -87,7 +87,7 @@ static void initLD() try { - g_iniConfig = new IniConfig("/etc/darling/dylib.conf"); + g_iniConfig = new IniConfig(ETC_DARLING_PATH "/dylib.conf"); } catch (const std::exception& e) { diff --git a/src/libSystem/CMakeLists.txt b/src/libSystem/CMakeLists.txt index 88d1d96ae..accc054fb 100644 --- a/src/libSystem/CMakeLists.txt +++ b/src/libSystem/CMakeLists.txt @@ -67,6 +67,9 @@ set(libc_SRCS libc/signals.cpp libc/termios.cpp libc/attrlist.cpp + libc/spawn.cpp + libc/xlocale.cpp + libc/malloc_zone.cpp common/auto.cpp common/path.cpp ) @@ -91,6 +94,7 @@ set(machkern_SRCS kernel-mach/error.cpp kernel-mach/Futex.cpp kernel-mach/FutexSemaphore.cpp + kernel-mach/compat.cpp ) add_library(System.B.dylib SHARED ${libc_SRCS} ${bsdkern_SRCS} ${machkern_SRCS}) diff --git a/src/libSystem/common/auto.h b/src/libSystem/common/auto.h index 6a4280674..a0f898f2c 100644 --- a/src/libSystem/common/auto.h +++ b/src/libSystem/common/auto.h @@ -36,6 +36,14 @@ template RetVal AutoErrno(Fu return rv; } +template int AutoErrnoPosix(Func f, Params... params) +{ + int rv = f(params...); + if (rv != 0) + rv = errnoLinuxToDarwin(rv); + return rv; +} + namespace Darling { struct MappedFlag diff --git a/src/libSystem/libc/exec.cpp b/src/libSystem/libc/exec.cpp index 4cd2e9ba1..74a2c6240 100644 --- a/src/libSystem/libc/exec.cpp +++ b/src/libSystem/libc/exec.cpp @@ -18,7 +18,7 @@ extern char g_loader_path[PATH_MAX]; -static const char* findInPath(const char* file) +const char* Darling::findInPath(const char* file) { static __thread char buffer[DARWIN_MAXPATHLEN]; @@ -67,7 +67,7 @@ static const char* findInPath(const char* file) return 0; } -static char* const* prependLoaderPath(char *const argv[], const char* fullMachoPath) +char* const* Darling::prependLoaderPath(char *const argv[], const char* fullMachoPath) { int count = 0; const char** rv; @@ -156,8 +156,8 @@ int __darwin_execv(const char *path, char *const argv[]) } else { - argv = prependLoaderPath(argv, path); - int rv = execvp(g_loader_path, argv); + argv = Darling::prependLoaderPath(argv, path); + int rv = execvp(g_loader_path, argv); // TODO: change to execv? std::cout << "Executing with loader at " << g_loader_path << std::endl; @@ -172,7 +172,7 @@ int __darwin_execvp(const char *file, char *const argv[]) { TRACE1(file); - const char* path = findInPath(file); + const char* path = Darling::findInPath(file); if (!path) { std::cout << "Path failed to be located: " << file << std::endl; @@ -187,7 +187,7 @@ int __darwin_execvpe(const char *file, char *const argv[], char *const envp[]) { TRACE1(file); - const char* path = findInPath(file); + const char* path = Darling::findInPath(file); if (!path) { errno = DARWIN_ENOENT; @@ -202,7 +202,7 @@ int __darwin_execvpe(const char *file, char *const argv[], char *const envp[]) } else { - argv = prependLoaderPath(argv, path); + argv = Darling::prependLoaderPath(argv, path); int rv = execvpe(g_loader_path, argv, envp); errnoOut(); diff --git a/src/libSystem/libc/exec.h b/src/libSystem/libc/exec.h index 94af3bf39..8fc967949 100644 --- a/src/libSystem/libc/exec.h +++ b/src/libSystem/libc/exec.h @@ -15,6 +15,12 @@ int __darwin_execvpe(const char *file, char *const argv[], char *const envp[]); #ifdef __cplusplus } + +namespace Darling +{ + const char* findInPath(const char* file); + char* const* prependLoaderPath(char *const argv[], const char* fullMachoPath); +} #endif #endif diff --git a/src/libSystem/libc/mac.c b/src/libSystem/libc/mac.c index 8da17b6be..c0cd63765 100644 --- a/src/libSystem/libc/mac.c +++ b/src/libSystem/libc/mac.c @@ -70,14 +70,6 @@ int __maskrune_l(__darwin_ct_rune_t _c, unsigned long _f, void* l) { return __maskrune(_c, _f); } -size_t mbstowcs_l(wchar_t* pwcs, const char* s, size_t n, void* l) { - return mbstowcs(pwcs, s, n); -} - -size_t wcswidth_l(wchar_t* pwcs, size_t n, void* l) { - return wcswidth(pwcs, n); -} - void libiconv_set_relocation_prefix(const char* orig, const char* curr) { // TODO: What should we do? abort(); @@ -101,134 +93,6 @@ void *__darwin_mmap(void *addr, size_t length, int prot, int flags, return mmap(addr, length, prot, flags, fd, offset); } -extern char* __loader_path; - -static char** add_loader_to_argv(char* argv[]) { - int i, argc; - for (argc = 0; argv[argc]; argc++); - LOGF("\n"); - char** new_argv = malloc(sizeof(char*) * (argc + 2)); - new_argv[0] = __loader_path; - for (i = 0; i < argc + 1; i++) { - new_argv[i + 1] = argv[i]; - } - return new_argv; -} - -// It seems the size of posix_spawn_file_actions_t of Mac is smaller -// than Linux so modifying posix_spawn_file_actions_t allocated in -// Mac's stack would cause stack overflow. Let's wrap it. - -int __darwin_posix_spawn(pid_t* pid, - const char* path, - const posix_spawn_file_actions_t** file_actions, - const posix_spawnattr_t* attrp, - char* argv[], - char* const envp[]) { - char** new_argv = add_loader_to_argv(argv); - const posix_spawn_file_actions_t* fa = NULL; - if (file_actions) - fa = *file_actions; - int r = posix_spawn(pid, - __loader_path, - fa, - attrp, - new_argv, - envp); - free(new_argv); - return r; -} - -int __darwin_posix_spawnp(pid_t *pid, - const char* file, - const posix_spawn_file_actions_t* file_actions, - const posix_spawnattr_t* attrp, - char* const argv[], - char* const envp[]) { - err(1, "posix_spawnp is not implemented yet\n"); - return 0; -} - -int __darwin_posix_spawn_file_actions_init(posix_spawn_file_actions_t** p) { - *p = (posix_spawn_file_actions_t*)malloc(sizeof(posix_spawn_file_actions_t)); - return posix_spawn_file_actions_init(*p); -} - -int __darwin_posix_spawn_file_actions_destroy(posix_spawn_file_actions_t** p) { - int r = posix_spawn_file_actions_destroy(*p); - free(*p); - return r; -} - -int __darwin_posix_spawn_file_actions_addopen( - posix_spawn_file_actions_t** file_actions, - int fd, - const char* path, - int oflag, - int mode) { - return posix_spawn_file_actions_addopen( - *file_actions, fd, path, oflag, mode); -} - -int __darwin_posix_spawn_file_actions_addclose( - posix_spawn_file_actions_t** file_actions, - int fd) { - return posix_spawn_file_actions_addclose(*file_actions, fd); -} - -int __darwin_posix_spawn_file_actions_adddup2( - posix_spawn_file_actions_t** file_actions, - int fd, - int newfd) { - return posix_spawn_file_actions_adddup2(*file_actions, fd, newfd); -} - -typedef struct { - void* ss_sp; - size_t ss_size; - int ss_flags; -} __darwin_stack_t; - -int __darwin_sigaltstack(const __darwin_stack_t* ss, __darwin_stack_t* oss) { - return 0; - -#if 0 - stack_t linux_ss; - stack_t linux_oss; - linux_ss.ss_sp = ss->ss_sp; - linux_ss.ss_size = ss->ss_size; - linux_ss.ss_flags = ss->ss_flags; - if (oss) { - linux_oss.ss_sp = oss->ss_sp; - linux_oss.ss_size = oss->ss_size; - linux_oss.ss_flags = oss->ss_flags; - } - int r = sigaltstack(&linux_ss, &linux_oss); - if (oss) { - oss->ss_sp = linux_oss.ss_sp; - oss->ss_size = linux_oss.ss_size; - oss->ss_flags = linux_oss.ss_flags; - } - return r; -#endif -} - -typedef struct malloc_statistics_t { - unsigned blocks_in_use; - size_t size_in_use; - size_t max_size_in_use; - size_t size_allocated; -} __darwin_malloc_statistics_t; - -void* malloc_default_zone() { - return NULL; -} - -// TODO: implement via mallinfo -void malloc_zone_statistics(void* zone, __darwin_malloc_statistics_t* stats) { - fprintf(stderr, "malloc_zone_statistics\n"); - memset(stats, 0, sizeof(*stats)); -} int task_get_exception_ports() { fprintf(stderr, "task_get_exception_ports\n"); @@ -240,52 +104,6 @@ int task_set_exception_ports() { return 0; } - - -static void do_nothing(void) { -} -static void* do_nothing2(void) { - return 0; -} -static void do_nothing3(int status) { -} - -void (*mach_init_routine)(void) = do_nothing; -void* (*_cthread_init_routine)(void) = do_nothing2; -void (*_cthread_exit_routine) (int) = do_nothing3; - -void __keymgr_dwarf2_register_sections() { -} - -#define __DARWIN_SYS_NAMELEN 256 -typedef struct { - char sysname[__DARWIN_SYS_NAMELEN]; - char nodename[__DARWIN_SYS_NAMELEN]; - char release[__DARWIN_SYS_NAMELEN]; - char version[__DARWIN_SYS_NAMELEN]; - char machine[__DARWIN_SYS_NAMELEN]; -} __darwin_utsname; - -int __darwin_uname(__darwin_utsname* buf) { - struct utsname linux_buf; - int r = uname(&linux_buf); - if (r) - return r; - - // Linux's buf size is currently much smaller, only 65, so strcpy() is safe - //strcpy(buf->sysname, linux_buf.sysname); - //strcpy(buf->nodename, linux_buf.nodename); - //strcpy(buf->release, linux_buf.release); - //strcpy(buf->version, linux_buf.version); - //strcpy(buf->machine, linux_buf.machine); - strcpy(buf->sysname, "Darwin"); - strcpy(buf->nodename, linux_buf.nodename); - strcpy(buf->release, "12.0.0"); - strcpy(buf->version, "Darwin Kernel Version 12.0.0"); - strcpy(buf->machine, linux_buf.machine); - return 0; -} - #define __DARWIN_LC_ALL_MASK ( __DARWIN_LC_COLLATE_MASK \ | __DARWIN_LC_CTYPE_MASK \ | __DARWIN_LC_MESSAGES_MASK \ diff --git a/src/libSystem/libc/malloc_zone.cpp b/src/libSystem/libc/malloc_zone.cpp new file mode 100644 index 000000000..92421537a --- /dev/null +++ b/src/libSystem/libc/malloc_zone.cpp @@ -0,0 +1,65 @@ +#include "malloc_zone.h" +#include + +static uint32_t dummy = 0xbaadf00d; + +malloc_zone_t* malloc_create_zone(vm_size_t start_size, unsigned flags) +{ + return malloc_default_zone(); +} + +void malloc_destroy_zone(malloc_zone_t *zone) +{ +} + +malloc_zone_t* malloc_default_zone() +{ + return &dummy; +} + +malloc_zone_t* malloc_zone_from_ptr(const void *ptr) +{ + return malloc_default_zone(); +} + +void* malloc_zone_malloc(malloc_zone_t *zone, size_t size) +{ + return malloc(size); +} + +void* malloc_zone_calloc(malloc_zone_t *zone, size_t num_items, size_t size) +{ + return calloc(num_items, size); +} + +void* malloc_zone_valloc(malloc_zone_t *zone, size_t size) +{ + return valloc(size); +} + +void* malloc_zone_realloc(malloc_zone_t *zone, void *ptr, size_t size) +{ + return realloc(ptr, size); +} + +void* malloc_zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size) +{ + return memalign(alignment, size); +} + +void malloc_zone_free(malloc_zone_t *zone, void *ptr) +{ + return free(ptr); +} + +void malloc_zone_statistics(malloc_zone_t* zone, __darwin_malloc_statistics_t* stats) +{ + struct mallinfo info = mallinfo(); + + // No idea if this is even nearly correct + stats->size_allocated = info.uordblks; + stats->size_in_use = info.hblkhd; + stats->max_size_in_use = info.usmblks; + stats->blocks_in_use = stats->size_in_use; +} + diff --git a/src/libSystem/libc/malloc_zone.h b/src/libSystem/libc/malloc_zone.h new file mode 100644 index 000000000..64b698687 --- /dev/null +++ b/src/libSystem/libc/malloc_zone.h @@ -0,0 +1,36 @@ +#ifndef LIBC_MALLOC_ZONE_H +#define LIBC_MALLOC_ZONE_H +#include +#include + +typedef uint32_t malloc_zone_t; +typedef uintptr_t vm_size_t; + +struct __darwin_malloc_statistics_t +{ + unsigned blocks_in_use; + size_t size_in_use; + size_t max_size_in_use; + size_t size_allocated; +}; + + +extern "C" { + +malloc_zone_t* malloc_create_zone(vm_size_t start_size, unsigned flags); +void malloc_destroy_zone(malloc_zone_t *zone); +malloc_zone_t* malloc_default_zone(); +malloc_zone_t* malloc_zone_from_ptr(const void *ptr); +void* malloc_zone_malloc(malloc_zone_t *zone, size_t size); +void* malloc_zone_calloc(malloc_zone_t *zone, size_t num_items, size_t size); +void* malloc_zone_valloc(malloc_zone_t *zone, size_t size); +void* malloc_zone_realloc(malloc_zone_t *zone, void *ptr, size_t size); +void* malloc_zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size); +void malloc_zone_free(malloc_zone_t *zone, void *ptr); + +void malloc_zone_statistics(malloc_zone_t* zone, __darwin_malloc_statistics_t* stats); + +} + +#endif + diff --git a/src/libSystem/libc/signals.cpp b/src/libSystem/libc/signals.cpp index aeccd64d6..29df4fffe 100644 --- a/src/libSystem/libc/signals.cpp +++ b/src/libSystem/libc/signals.cpp @@ -89,7 +89,7 @@ sighandler_t __darwin_signal(int signum, sighandler_t handler) return signal(signum, handler); } -static sigset_t sigsetDarwinToLinux(const __darwin_sigset_t* set) +sigset_t Darling::sigsetDarwinToLinux(const __darwin_sigset_t* set) { sigset_t rv; @@ -104,7 +104,7 @@ static sigset_t sigsetDarwinToLinux(const __darwin_sigset_t* set) return rv; } -static __darwin_sigset_t sigsetLinuxToDarwin(const sigset_t* set) +__darwin_sigset_t Darling::sigsetLinuxToDarwin(const sigset_t* set) { __darwin_sigset_t rv = 0; @@ -136,7 +136,7 @@ int __darwin_sigaction(int signum, const struct __darwin_sigaction* act, struct nact->sa_flags = Darling::flagsDarwinToNative(g_sigactionFlags, sizeof(g_sigactionFlags)/sizeof(g_sigactionFlags[0]), act->sa_flags); nact->sa_handler = act->xsa_handler; nact->sa_sigaction = act->xsa_sigaction; - nact->sa_mask = sigsetDarwinToLinux(&act->sa_mask); + nact->sa_mask = Darling::sigsetDarwinToLinux(&act->sa_mask); oldhdl = g_darwinHandlers[signum]; // defer a user-supplied function to a wrapper that will translate the signal number @@ -159,7 +159,7 @@ int __darwin_sigaction(int signum, const struct __darwin_sigaction* act, struct else oldact->xsa_handler = noldact->sa_handler; oldact->xsa_sigaction = oldhdl; - oldact->sa_mask = sigsetLinuxToDarwin(&noldact->sa_mask); + oldact->sa_mask = Darling::sigsetLinuxToDarwin(&noldact->sa_mask); } if (rv == -1) errnoOut(); @@ -228,7 +228,7 @@ int __darwin_sigprocmask(int how, const __darwin_sigset_t *set, __darwin_sigset_ if (set) { nset.reset(new sigset_t); - *nset = sigsetDarwinToLinux(set); + *nset = Darling::sigsetDarwinToLinux(set); } if (oldset) noldset.reset(new sigset_t); @@ -239,14 +239,14 @@ int __darwin_sigprocmask(int how, const __darwin_sigset_t *set, __darwin_sigset_ if (rv == -1) errnoOut(); else if (oldset) - *oldset = sigsetLinuxToDarwin(noldset.get()); + *oldset = Darling::sigsetLinuxToDarwin(noldset.get()); return rv; } int __darwin_sigsuspend(const __darwin_sigset_t *mask) { - sigset_t set = sigsetDarwinToLinux(mask); + sigset_t set = Darling::sigsetDarwinToLinux(mask); int rv = sigsuspend(&set); if (rv == -1) errnoOut(); @@ -255,7 +255,7 @@ int __darwin_sigsuspend(const __darwin_sigset_t *mask) int __darwin_sigwait(const __darwin_sigset_t *set, int *sig) { - sigset_t nset = sigsetDarwinToLinux(set); + sigset_t nset = Darling::sigsetDarwinToLinux(set); int rv = sigwait(&nset, sig); if (rv == -1) errnoOut(); @@ -271,7 +271,7 @@ int __darwin_sigpending(__darwin_sigset_t *set) if (rv == -1) errnoOut(); else - *set = sigsetLinuxToDarwin(&nset); + *set = Darling::sigsetLinuxToDarwin(&nset); return rv; } diff --git a/src/libSystem/libc/signals.h b/src/libSystem/libc/signals.h index de70f28e4..54d2bb29f 100644 --- a/src/libSystem/libc/signals.h +++ b/src/libSystem/libc/signals.h @@ -77,6 +77,9 @@ namespace Darling { int signalLinuxToDarwin(int sig); int signalDarwinToLinux(int sig); + + sigset_t sigsetDarwinToLinux(const __darwin_sigset_t* set); + __darwin_sigset_t sigsetLinuxToDarwin(const sigset_t* set); } #endif diff --git a/src/libSystem/libc/spawn.cpp b/src/libSystem/libc/spawn.cpp new file mode 100644 index 000000000..edeabeaab --- /dev/null +++ b/src/libSystem/libc/spawn.cpp @@ -0,0 +1,196 @@ +#include "spawn.h" +#include "errno.h" +#include "../common/auto.h" +#include "../kernel-bsd/io.h" +#include "darwin_errno_codes.h" +#include "exec.h" +#include +#include "MachO.h" +#include "trace.h" + +template int GenericInit(T* t, NativeInit nativeInit) +{ + int err; + + if (!t) + return DARWIN_EINVAL; + + t->native = new typename std::remove_referencenative)>::type; + err = AutoErrnoPosix(nativeInit, t->native); + + if (err) + delete t->native; + return err; +} + +template int GenericDestroy(T* t, NativeDestroy nativeDestroy) +{ + if (t != nullptr) + { + int err = AutoErrnoPosix(nativeDestroy, t->native); + delete t->native; + return err; + } + else + return DARWIN_EINVAL; +} + +int __darwin_posix_spawn_file_actions_destroy(__darwin_posix_spawn_file_actions_t* file_actions) +{ + return GenericDestroy(file_actions, posix_spawn_file_actions_destroy); +} + +int __darwin_posix_spawn_file_actions_init(__darwin_posix_spawn_file_actions_t* file_actions) +{ + return GenericInit(file_actions, posix_spawn_file_actions_init); +} + +int __darwin_posix_spawn_file_actions_addclose(__darwin_posix_spawn_file_actions_t* file_actions, int filedes) +{ + return AutoErrnoPosix(posix_spawn_file_actions_addclose, file_actions->native, filedes); +} + +int __darwin_posix_spawn_file_actions_addopen(__darwin_posix_spawn_file_actions_t* file_actions, int filedes, const char* path, int oflag, mode_t mode) +{ + return AutoErrnoPosix(posix_spawn_file_actions_addopen, file_actions->native, filedes, translatePathCI(path), Darling::openflagsDarwinToNative(oflag), mode); +} + +int __darwin_posix_spawn_file_actions_adddup2(__darwin_posix_spawn_file_actions_t* file_actions, int filedes, int newfiledes) +{ + return AutoErrnoPosix(posix_spawn_file_actions_adddup2, file_actions->native, filedes, newfiledes); +} + +int __darwin_posix_spawn_file_actions_addinherit_np(__darwin_posix_spawn_file_actions_t* file_actions, int filedes) +{ + return DARWIN_ENOTSUP; +} + +int __darwin_posix_spawnattr_destroy(__darwin_posix_spawnattr_t* attr) +{ + return GenericDestroy(attr, posix_spawnattr_destroy); +} + +int __darwin_posix_spawnattr_init(__darwin_posix_spawnattr_t* attr) +{ + return GenericInit(attr, posix_spawnattr_init); +} + +int __darwin_posix_spawnattr_getsigdefault(const __darwin_posix_spawnattr_t* attr, __darwin_sigset_t* sigdefault) +{ + sigset_t ns; + int err = AutoErrnoPosix(posix_spawnattr_getsigdefault, attr->native, &ns); + + if (!err) + *sigdefault = Darling::sigsetLinuxToDarwin(&ns); + + return err; +} + +int __darwin_posix_spawnattr_setsigdefault(__darwin_posix_spawnattr_t* attr, const __darwin_sigset_t* sigdefault) +{ + sigset_t ns; + ns = Darling::sigsetDarwinToLinux(sigdefault); + + return AutoErrnoPosix(posix_spawnattr_setsigdefault, attr->native, &ns); +} + +int __darwin_posix_spawnattr_getsigmask(const __darwin_posix_spawnattr_t* attr, __darwin_sigset_t* sigmask) +{ + sigset_t ns; + int err = AutoErrnoPosix(posix_spawnattr_getsigmask, attr->native, &ns); + + if (!err) + *sigmask = Darling::sigsetLinuxToDarwin(&ns); + + return err; +} + +int __darwin_posix_spawnattr_setsigmask(__darwin_posix_spawnattr_t* attr, const __darwin_sigset_t* sigmask) +{ + sigset_t ns; + ns = Darling::sigsetDarwinToLinux(sigmask); + + return AutoErrnoPosix(posix_spawnattr_setsigmask, attr->native, &ns); +} + + +// flag values are compatible +int __darwin_posix_spawnattr_getflags(const __darwin_posix_spawnattr_t* attr, short* flags) +{ + return AutoErrnoPosix(posix_spawnattr_getflags, attr->native, flags); +} + +int __darwin_posix_spawnattr_setflags(__darwin_posix_spawnattr_t* attr, short flags) +{ + return AutoErrnoPosix(posix_spawnattr_setflags, attr->native, flags); +} + +int __darwin_posix_spawnattr_getpgroup(const __darwin_posix_spawnattr_t* attr, pid_t* pgroup) +{ + return AutoErrnoPosix(posix_spawnattr_getpgroup, attr->native, pgroup); +} + +int __darwin_posix_spawnattr_setpgroup(__darwin_posix_spawnattr_t *attr, pid_t pgroup) +{ + return AutoErrnoPosix(posix_spawnattr_setpgroup, attr->native, pgroup); +} + +int __darwin_posix_spawnattr_getschedparam(const __darwin_posix_spawnattr_t* attr, struct sched_param* schedparam) +{ + return AutoErrnoPosix(posix_spawnattr_getschedparam, attr->native, schedparam); +} + +int __darwin_posix_spawnattr_setschedparam(__darwin_posix_spawnattr_t* attr, const struct sched_param* schedparam) +{ + return AutoErrnoPosix(posix_spawnattr_setschedparam, attr->native, schedparam); +} + +int __darwin_posix_spawnattr_getschedpolicy(const __darwin_posix_spawnattr_t* attr, int* schedpolicy) +{ + return AutoErrnoPosix(posix_spawnattr_getschedpolicy, attr->native, schedpolicy); +} + +int __darwin_posix_spawnattr_setschedpolicy(__darwin_posix_spawnattr_t *attr, int schedpolicy) +{ + return AutoErrnoPosix(posix_spawnattr_setschedpolicy, attr->native, schedpolicy); +} + +int __darwin_posix_spawn(pid_t* pid, const char* path, const __darwin_posix_spawn_file_actions_t* file_actions, const __darwin_posix_spawnattr_t* attrp, + char* const argv[], char* const envp[]) +{ + TRACE6(pid, path, file_actions, attrp, argv, envp); + char* const* argv_copy = nullptr; + int err; + + path = translatePathCI(path); + + if (MachO::isMachO(path)) + argv = argv_copy = Darling::prependLoaderPath(argv, path); + + err = AutoErrnoPosix(posix_spawn, pid, path, file_actions->native, attrp->native, argv, envp); + + delete [] argv_copy; + return err; +} + +int __darwin_posix_spawnp(pid_t* pid, const char* file, const __darwin_posix_spawn_file_actions_t* file_actions,const __darwin_posix_spawnattr_t* attrp, + char* const argv[], char* const envp[]) +{ + TRACE6(pid, file, file_actions, attrp, argv, envp); + char* const* argv_copy = nullptr; + int err; + + const char* path = Darling::findInPath(file); + if (!path) + return DARWIN_ENOENT; + + if (MachO::isMachO(path)) + argv = argv_copy = Darling::prependLoaderPath(argv, path); + + err = AutoErrnoPosix(posix_spawn, pid, path, file_actions->native, attrp->native, argv, envp); + + delete [] argv_copy; + return err; +} + + diff --git a/src/libSystem/libc/spawn.h b/src/libSystem/libc/spawn.h new file mode 100644 index 000000000..5bf061a23 --- /dev/null +++ b/src/libSystem/libc/spawn.h @@ -0,0 +1,52 @@ +#ifndef LIBC_SPAWN_H +#define LIBC_SPAWN_H +#include +#include "signals.h" + +extern "C" { + +// sizeof on Darwin: ptr size +// sizeof on Linux (x86-64): 80 bytes +struct __darwin_posix_spawn_file_actions_t +{ + posix_spawn_file_actions_t* native; +}; + +struct __darwin_posix_spawnattr_t +{ + posix_spawnattr_t* native; +}; + +int __darwin_posix_spawn_file_actions_destroy(__darwin_posix_spawn_file_actions_t* file_actions); +int __darwin_posix_spawn_file_actions_init(__darwin_posix_spawn_file_actions_t* file_actions); + +int __darwin_posix_spawn_file_actions_addclose(__darwin_posix_spawn_file_actions_t* file_actions, int filedes); +int __darwin_posix_spawn_file_actions_addopen(__darwin_posix_spawn_file_actions_t* file_actions, int filedes, const char* path, int oflag, mode_t mode); +int __darwin_posix_spawn_file_actions_adddup2(__darwin_posix_spawn_file_actions_t* file_actions, int filedes, int newfiledes); +int __darwin_posix_spawn_file_actions_addinherit_np(__darwin_posix_spawn_file_actions_t* file_actions, int filedes); + +int __darwin_posix_spawnattr_destroy(__darwin_posix_spawnattr_t* attr); +int __darwin_posix_spawnattr_init(__darwin_posix_spawnattr_t* attr); + +int __darwin_posix_spawnattr_getsigdefault(const __darwin_posix_spawnattr_t* attr, __darwin_sigset_t* sigdefault); +int __darwin_posix_spawnattr_setsigdefault(__darwin_posix_spawnattr_t* attr, const __darwin_sigset_t* sigdefault); +int __darwin_posix_spawnattr_getsigmask(const __darwin_posix_spawnattr_t* attr, __darwin_sigset_t* sigmask); +int __darwin_posix_spawnattr_setsigmask(__darwin_posix_spawnattr_t* attr, const __darwin_sigset_t* sigmask); +int __darwin_posix_spawnattr_getflags(const __darwin_posix_spawnattr_t* attr, short* flags); +int __darwin_posix_spawnattr_setflags(__darwin_posix_spawnattr_t* attr, short flags); +int __darwin_posix_spawnattr_getpgroup(const __darwin_posix_spawnattr_t* attr, pid_t* pgroup); +int __darwin_posix_spawnattr_setpgroup(__darwin_posix_spawnattr_t *attr, pid_t pgroup); +int __darwin_posix_spawnattr_getschedparam(const __darwin_posix_spawnattr_t* attr, struct sched_param* schedparam); +int __darwin_posix_spawnattr_setschedparam(__darwin_posix_spawnattr_t* attr, const struct sched_param* schedparam); +int __darwin_posix_spawnattr_getschedpolicy(const __darwin_posix_spawnattr_t* attr, int* schedpolicy); +int __darwin_posix_spawnattr_setschedpolicy(__darwin_posix_spawnattr_t *attr, int schedpolicy); + +int __darwin_posix_spawn(pid_t* pid, const char* path, const __darwin_posix_spawn_file_actions_t* file_actions, const __darwin_posix_spawnattr_t* attrp, + char* const argv[], char* const envp[]); +int __darwin_posix_spawnp(pid_t* pid, const char* file, const __darwin_posix_spawn_file_actions_t* file_actions,const __darwin_posix_spawnattr_t* attrp, + char* const argv[], char* const envp[]); + +} + +#endif + diff --git a/src/libSystem/libc/stdio.cpp b/src/libSystem/libc/stdio.cpp index 6b391f846..2b71c4b00 100644 --- a/src/libSystem/libc/stdio.cpp +++ b/src/libSystem/libc/stdio.cpp @@ -149,11 +149,21 @@ int __darwin_fseek(__darwin_FILE* fp, long offset, int whence) return fseek(fp->linux_fp, offset, whence); } +int __darwin_fseeko(__darwin_FILE* fp, off_t offset, int whence) +{ + return fseeko(fp->linux_fp, offset, whence); +} + long __darwin_ftell(__darwin_FILE* fp) { return ftell(fp->linux_fp); } +off_t __darwin_ftello(__darwin_FILE* fp) +{ + return ftello(fp->linux_fp); +} + void __darwin_rewind(__darwin_FILE* fp) { return rewind(fp->linux_fp); diff --git a/src/libSystem/libc/stdio.h b/src/libSystem/libc/stdio.h index c61b10f79..25827b882 100644 --- a/src/libSystem/libc/stdio.h +++ b/src/libSystem/libc/stdio.h @@ -65,7 +65,9 @@ int __darwin_fclose(__darwin_FILE* fp); size_t __darwin_fread(void* ptr, size_t size, size_t nmemb, __darwin_FILE* fp); size_t __darwin_fwrite(void* ptr, size_t size, size_t nmemb, __darwin_FILE* fp); int __darwin_fseek(__darwin_FILE* fp, long offset, int whence); +int __darwin_fseeko(__darwin_FILE* fp, off_t offset, int whence); long __darwin_ftell(__darwin_FILE* fp); +off_t __darwin_ftello(__darwin_FILE* fp); void __darwin_rewind(__darwin_FILE* fp); int __darwin_getc(__darwin_FILE* fp); int __darwin_fgetc(__darwin_FILE* fp); diff --git a/src/libSystem/libc/uname.cpp b/src/libSystem/libc/uname.cpp new file mode 100644 index 000000000..721378359 --- /dev/null +++ b/src/libSystem/libc/uname.cpp @@ -0,0 +1,68 @@ +#include "config,h" +#include "uname.h" +#include "errno.h" +#include +#include +#include "darwin_errno_codes.h" +#include +#ifndef NO_DARWIN_UNAME +# include "IniConfig.h" +#endif +#include + +int __darwin_uname(__darwin_utsname* buf) +{ + if (!buf) + { + errno = DARWIN_EINVAL; + return -1; + } + + struct utsname nbuf; + int rv = uname(&nbuf); + + if (rv == -1) + { + errnoOut(); + return rv; + } + + strcpy(buf->nodename, nbuf.nodename); + strcpy(buf->machine, nbuf.machine); + +#ifdef NO_DARWIN_UNAME + strcpy(buf->sysname, nbuf.sysname); + strcpy(buf->release, nbuf.release); + strcpy(buf->version, nbuf.version); +#else + static IniConfig iniConfig(ETC_DARWIN_PATH "/version.conf"); + const char *sysname = nullptr, *release = nullptr, *version = nullptr; + + if (iniConfig.hasSection("uname")) + { + const IniConfig::ValueMap* map = iniConfig.getSection("uname"); + sysname = map->find("sysname")->second.c_str(); + release = map->find("release")->second.c_str(); + version = map->find("version")->second.c_str(); + } + + if (!sysname || !*sysname) + strcpy(buf->sysname, "Darwin"); + else + strlcpy(buf->sysname, sysname, __DARWIN_SYS_NAMELEN); + + if (!release || !*release) + strcpy(buf->release, "12.0.0"); + else + strlcpy(buf->release, release, __DARWIN_SYS_NAMELEN); + + if (!version || !*version) + strcpy(buf->version, "Darwin Kernel Version 12.0.0"); + else + strlcpy(buf->version, version, __DARWIN_SYS_NAMELEN); +#endif + + return 0; +} + + diff --git a/src/libSystem/libc/uname.h b/src/libSystem/libc/uname.h new file mode 100644 index 000000000..6041e30b9 --- /dev/null +++ b/src/libSystem/libc/uname.h @@ -0,0 +1,19 @@ +#ifndef LIBC_UNAME_H +#define LIBC_UNAME_H + +#define __DARWIN_SYS_NAMELEN 256 + +struct __darwin_utsname +{ + char sysname[__DARWIN_SYS_NAMELEN]; + char nodename[__DARWIN_SYS_NAMELEN]; + char release[__DARWIN_SYS_NAMELEN]; + char version[__DARWIN_SYS_NAMELEN]; + char machine[__DARWIN_SYS_NAMELEN]; +}; + + +extern "C" int __darwin_uname(__darwin_utsname* buf); + +#endif + diff --git a/src/libSystem/libc/xlocale.cpp b/src/libSystem/libc/xlocale.cpp new file mode 100644 index 000000000..52b9f9327 --- /dev/null +++ b/src/libSystem/libc/xlocale.cpp @@ -0,0 +1,59 @@ +#include "xlocale.h" + +#define WRAP_TRIVIAL(name, type) int name ## _l (wint_t wc, locale_t l) throw() { return UseLocale(name, l, wc); } + +template T UseLocale(Func func, locale_t l, Params... params) +{ + locale_t oldLoc = uselocale(l); + + T rv = func(params...); + + uselocale(oldLoc); + return rv; +} + +size_t mbstowcs_l(wchar_t* pwcs, const char* s, size_t n, locale_t l) +{ + return UseLocale(mbstowcs, l, pwcs, s, n); +} + +size_t wcswidth_l(wchar_t* pwcs, size_t n, locale_t l) +{ + return UseLocale(wcswidth, l, pwcs, n); +} + +int iswnumber(wint_t wc) throw() +{ + return iswdigit(wc); +} + +WRAP_TRIVIAL(iswalnum, WCTYPE_ALNUM); +WRAP_TRIVIAL(iswalpha, WCTYPE_ALPHA); +// WRAP_TRIVIAL(iswascii); +WRAP_TRIVIAL(iswblank, WCTYPE_BLANK); +WRAP_TRIVIAL(iswcntrl, WCTYPE_CNTRL); +WRAP_TRIVIAL(iswdigit, WCTYPE_DIGIT); +WRAP_TRIVIAL(iswgraph, WCTYPE_GRAPH); +// WRAP_TRIVIAL(iswhexnumber); +// WRAP_TRIVIAL(iswideogram); +WRAP_TRIVIAL(iswlower, WCTYPE_LOWER); +WRAP_TRIVIAL(iswnumber, WCTYPE_DIGIT); +// WRAP_TRIVIAL(iswphonogram); +WRAP_TRIVIAL(iswprint, WCTYPE_PRINT); +WRAP_TRIVIAL(iswpunct, WCTYPE_PUNCT); +// WRAP_TRIVIAL(iswrune); +WRAP_TRIVIAL(iswspace, WCTYPE_SPACE); +// WRAP_TRIVIAL(iswspecial); +WRAP_TRIVIAL(iswupper, WCTYPE_UPPER); +WRAP_TRIVIAL(iswxdigit, WCTYPE_XDIGIT); + +int iswctype_l(wint_t wc, wctype_t charclass, locale_t loc) throw() +{ + return UseLocale(iswctype, loc, wc, charclass); +} + +wctype_t wctype_l(const char *property, locale_t loc) throw() +{ + return UseLocale(wctype, loc, property); +} + diff --git a/src/libSystem/libc/xlocale.h b/src/libSystem/libc/xlocale.h new file mode 100644 index 000000000..2f09fe82d --- /dev/null +++ b/src/libSystem/libc/xlocale.h @@ -0,0 +1,82 @@ +#ifndef LIBC_MULTIBYTE_H +#define LIBC_MULTIBYTE_H +#include +#include +#include +#include + +extern "C" { + +size_t mbstowcs_l(wchar_t* pwcs, const char* s, size_t n, locale_t l); +size_t wcswidth_l(wchar_t* pwcs, size_t n, locale_t l); +int mbtowc_l(wchar_t * pwc, const char * s, size_t n, locale_t loc); +size_t mbrtowc_l(wchar_t * pwc, const char * s, size_t n, mbstate_t * ps, locale_t loc); +int mblen_l(const char *s, size_t n, locale_t loc); +size_t wcrtomb_l(char * s, wchar_t wc, mbstate_t * ps, locale_t loc); + +int iswalnum_l(wint_t wc, locale_t loc) throw(); +int iswalpha_l(wint_t wc, locale_t loc) throw(); +int iswascii_l(wint_t wc, locale_t loc) throw(); +int iswblank_l(wint_t wc, locale_t loc) throw(); +int iswcntrl_l(wint_t wc, locale_t loc) throw(); +int iswdigit_l(wint_t wc, locale_t loc) throw(); +int iswgraph_l(wint_t wc, locale_t loc) throw(); +int iswhexnumber_l(wint_t wc, locale_t loc) throw(); +int iswideogram_l(wint_t wc, locale_t loc) throw(); +int iswlower_l(wint_t wc, locale_t loc) throw(); +int iswnumber_l(wint_t wc, locale_t loc) throw(); +int iswphonogram_l(wint_t wc, locale_t loc) throw(); +int iswprint_l(wint_t wc, locale_t loc) throw(); +int iswpunct_l(wint_t wc, locale_t loc) throw(); +int iswrune_l(wint_t wc, locale_t loc) throw(); +int iswspace_l(wint_t wc, locale_t loc) throw(); +int iswspecial_l(wint_t wc, locale_t loc) throw(); +int iswupper_l(wint_t wc, locale_t loc) throw(); +int iswxdigit_l(wint_t wc, locale_t loc) throw(); +int iswnumber(wint_t wc) throw(); + +int iswctype_l(wint_t wc, wctype_t charclass, locale_t loc) throw(); +wctype_t wctype_l(const char *property, locale_t loc) throw(); + + +/* +TODO: + + digittoint_l(3), isalnum_l(3), isalpha_l(3), isblank_l(3), iscntrl_l(3), isdigit_l(3), isgraph_l(3), ishexnumber_l(3), isideogram_l(3), islower_l(3), isnumber_l(3), + isphonogram_l(3), isprint_l(3), ispunct_l(3), isrune_l(3), isspace_l(3), isspecial_l(3), isupper_l(3), isxdigit_l(3), tolower_l(3), toupper_l(3) + + + strtoimax_l(3), strtoumax_l(3), wcstoimax_l(3), wcstoumax_l(3) + + + nl_langinfo_l(3) + + + strfmon_l(3) + + asprintf_l(3), fprintf_l(3), fscanf_l(3), printf_l(3), scanf_l(3), snprintf_l(3), sprintf_l(3), sscanf_l(3), vasprintf_l(3), vfprintf_l(3), vfscanf_l(3), vprintf_l(3), + vscanf_l(3), vsnprintf_l(3), vsprintf_l(3), vsscanf_l(3) + + atof_l(3), atoi_l(3), atol_l(3), atoll_l(3), mblen_l(3), mbstowcs_l(3), mbtowc_l(3), strtod_l(3), strtof_l(3), strtol_l(3), strtold_l(3), strtoll_l(3), strtoq_l(3), + strtoul_l(3), strtoull_l(3), strtouq_l(3), wcstombs_l(3), wctomb_l(3) + + strcoll_l(3), strxfrm_l(3), strcasecmp_l(3), strcasestr_l(3), strncasecmp_l(3) + + strftime_l(3), strptime_l(3) + + btowc_l(3), fgetwc_l(3), *fgetws_l(3), fputwc_l(3), fputws_l(3), fwprintf_l(3), fwscanf_l(3), getwc_l(3), getwchar_l(3), mbrlen_l(3), mbrtowc_l(3), mbsinit_l(3), + mbsnrtowcs_l(3), mbsrtowcs_l(3), putwc_l(3), putwchar_l(3), swprintf_l(3), swscanf_l(3), ungetwc_l(3), vfwprintf_l(3), vfwscanf_l(3), vswprintf_l(3), vswscanf_l(3), + vwprintf_l(3), vwscanf_l(3), wcrtomb_l(3), wcscoll_l(3), wcsftime_l(3), wcsnrtombs_l(3), wcsrtombs_l(3), wcstod_l(3), wcstof_l(3), wcstol_l(3), wcstold_l(3), + wcstoll_l(3), wcstoul_l(3), wcstoull_l(3), wcswidth_l(3), wcsxfrm_l(3), wctob_l(3), wcwidth_l(3), wprintf_l(3), wscanf_l(3) + + iswblank_l(3), iswhexnumber_l(3), iswideogram_l(3), iswnumber_l(3), iswphonogram_l(3), iswrune_l(3), iswspecial_l(3), nextwctype_l(3), towctrans_l(3), wctrans_l(3) + + + localeconv_l(3) + +*/ + +} + +#endif + -- 2.51.2