Hi everyone, Please find attached the big patch for druntime. Feedback would be very welcome.
Notes: - I have not set up the clocks for processCPUTime and threadCPUTime because a failing clock_getres causes a unittest failure - linker stub warnings: The following linker stub warnings are emitted: sched_get_priority_min sched_get_priority_max pthread_setschedprio (pthread_setschedparam) should something be done about these (e.g. there is already a workaround for priority for netbsd in osthread.d) or should this just be left alone for now? - I am not entirely sure where to put the pthread enum types. These are shared between "core.sys.posix.sys.types" and "core.sys.posix.pthread" i put them in core.sys.hurd.sys.types for now. Also not sure what to do with the internal __pthread struct. I followed what is done in rustc, if there is a better solution let me know. - The runtime by default uses SIGRTMIN and SIGRTMIN +1 as the suspend/resume signals for its garbage collector. As these are not supported I changed them back to SIGUSR1 and SIGUSR2. - On x86_64 the dmd unittest runner gets killed with SIGUSR1 after a while. I am not entirely sure why as the runtime should handle that. - Some unittests segfault in pthread_join. I am not sure what is happening here and the problem is not reproducible when compiling and runnig the whole unittest module against the regular version of the runtime. (the dwarf warning might be a red herring as it also occurs on linux with libdruntime-ut.so)e.g:../generated/hurd/debug/32/unittest/test_runner core.sync.barrier Thread 4 received signal SIGSEGV, Segmentation fault. 0x016c1d9c in __GI___mach_msg_trap () at /tmp/guix-build-glibc-2.41.drv-0/build/mach/mach_msg_trap.S:2 ⚠️ warning: 2 /tmp/guix-build-glibc-2.41.drv-0/build/mach/mach_msg_trap.S: No such file or directory (gdb) bt #0 0x016c1d9c in __GI___mach_msg_trap () at /tmp/guix-build-glibc-2.41.drv-0/build/mach/mach_msg_trap.S:2 #1 0x016c24ca in __GI___mach_msg (msg=0x103c708, option=2, send_size=0, rcv_size=24, rcv_name=24, timeout=0, notify=0) at msg.c:111 #2 0x0175ddae in __GI___pthread_block (thread=0x200001a0) at ../sysdeps/mach/htl/pt-block.c:46 #3 0x0175e6a1 in __pthread_cond_timedwait_internal (cond=<optimized out>, mutex=<optimized out>, clockid=<optimized out>, abstime=<optimized out>) at ../sysdeps/htl/pt-cond-timedwait.c:164 #4 0x0175e788 in __GI___pthread_cond_clockwait ( cond=<error reading variable: DWARF Error: Cannot find DIE at 0x0 referenced from DIE at 0x47f20 [in module ../generated/hurd/debug/32/unittest/libdruntime-ut.so]>, mutex=0x200135b4, clockid=0, abstime=0x0) at ../sysdeps/htl/pt-cond-timedwait.c:50
>From c221e610604f6eba56d149a93ad53d75fbef8002 Mon Sep 17 00:00:00 2001 From: Yelninei <[email protected]> Date: Fri, 27 Mar 2026 14:56:20 +0000 Subject: [PATCH] WIP: Port druntime to GNU/Hurd --- druntime/Makefile | 2 +- druntime/mak/COPY | 10 + druntime/src/core/demangle.d | 1 + druntime/src/core/internal/backtrace/elf.d | 5 + druntime/src/core/internal/elf/dl.d | 14 ++ druntime/src/core/internal/elf/io.d | 9 + druntime/src/core/internal/execinfo.d | 2 + druntime/src/core/stdc/config.d | 4 + druntime/src/core/stdc/errno.d | 107 +++++++++ druntime/src/core/stdc/limits.d | 14 ++ druntime/src/core/sys/hurd/config.d | 28 +++ druntime/src/core/sys/hurd/dlfcn.d | 112 ++++++++++ druntime/src/core/sys/hurd/elf.d | 160 ++++++++++++++ druntime/src/core/sys/hurd/errno.d | 19 ++ druntime/src/core/sys/hurd/execinfo.d | 17 ++ druntime/src/core/sys/hurd/link.d | 132 ++++++++++++ druntime/src/core/sys/hurd/sys/types.d | 58 +++++ druntime/src/core/sys/hurd/time.d | 15 ++ druntime/src/core/sys/hurd/unistd.d | 25 +++ druntime/src/core/sys/linux/stdio.d | 2 +- druntime/src/core/sys/posix/dirent.d | 11 + druntime/src/core/sys/posix/fcntl.d | 88 ++++++++ druntime/src/core/sys/posix/poll.d | 16 ++ druntime/src/core/sys/posix/pthread.d | 150 ++++++++++++- druntime/src/core/sys/posix/sched.d | 11 + druntime/src/core/sys/posix/signal.d | 203 ++++++++++++++++++ druntime/src/core/sys/posix/spawn.d | 42 ++++ druntime/src/core/sys/posix/sys/ioctl.d | 4 + druntime/src/core/sys/posix/sys/ipc.d | 27 +++ druntime/src/core/sys/posix/sys/mman.d | 33 +++ druntime/src/core/sys/posix/sys/resource.d | 78 +++++++ druntime/src/core/sys/posix/sys/shm.d | 20 ++ druntime/src/core/sys/posix/sys/socket.d | 159 ++++++++++++++ druntime/src/core/sys/posix/sys/stat.d | 74 +++++++ druntime/src/core/sys/posix/sys/types.d | 169 +++++++++++++++ druntime/src/core/sys/posix/sys/un.d | 8 + druntime/src/core/sys/posix/sys/wait.d | 23 ++ druntime/src/core/sys/posix/termios.d | 98 +++++++++ druntime/src/core/sys/posix/time.d | 12 ++ .../core/thread/fiber/switch_context_asm.S | 2 +- druntime/src/core/thread/osthread.d | 8 + druntime/src/core/time.d | 25 +++ druntime/src/importc.h | 4 +- druntime/src/rt/sections_elf_shared.d | 8 + 44 files changed, 2001 insertions(+), 8 deletions(-) create mode 100644 druntime/src/core/sys/hurd/config.d create mode 100644 druntime/src/core/sys/hurd/dlfcn.d create mode 100644 druntime/src/core/sys/hurd/elf.d create mode 100644 druntime/src/core/sys/hurd/errno.d create mode 100644 druntime/src/core/sys/hurd/execinfo.d create mode 100644 druntime/src/core/sys/hurd/link.d create mode 100644 druntime/src/core/sys/hurd/sys/types.d create mode 100644 druntime/src/core/sys/hurd/time.d create mode 100644 druntime/src/core/sys/hurd/unistd.d diff --git a/druntime/Makefile b/druntime/Makefile index 89f5297fac..a3dfd5421e 100644 --- a/druntime/Makefile +++ b/druntime/Makefile @@ -76,7 +76,7 @@ endif # build with shared library support # (defaults to true on supported platforms, can be overridden w/ make SHARED=0) -SHARED=$(if $(findstring $(OS),linux freebsd dragonflybsd),1,) +SHARED=$(if $(findstring $(OS),linux freebsd dragonflybsd hurd),1,) LINKDL=$(if $(findstring $(OS),linux),-L-ldl,) diff --git a/druntime/mak/COPY b/druntime/mak/COPY index 644013386e..7d3babd60a 100644 --- a/druntime/mak/COPY +++ b/druntime/mak/COPY @@ -390,6 +390,16 @@ COPY=\ $(IMPDIR)\core\sys\solaris\sys\regset.d \ $(IMPDIR)\core\sys\solaris\sys\types.d \ \ + $(IMPDIR)\core\sys\hurd\config.d \ + $(IMPDIR)\core\sys\hurd\dlfcn.d \ + $(IMPDIR)\core\sys\hurd\elf.d \ + $(IMPDIR)\core\sys\hurd\execinfo.d \ + $(IMPDIR)\core\sys\hurd\errno.d \ + $(IMPDIR)\core\sys\hurd\link.d \ + $(IMPDIR)\core\sys\hurd\sys\types.d \ + $(IMPDIR)\core\sys\hurd\time.d \ + $(IMPDIR)\core\sys\hurd\unistd.d \ + \ $(IMPDIR)\core\sys\windows\accctrl.d \ $(IMPDIR)\core\sys\windows\aclapi.d \ $(IMPDIR)\core\sys\windows\aclui.d \ diff --git a/druntime/src/core/demangle.d b/druntime/src/core/demangle.d index e7efc8c3ec..285aacf667 100644 --- a/druntime/src/core/demangle.d +++ b/druntime/src/core/demangle.d @@ -2996,6 +2996,7 @@ CXX_DEMANGLER getCXXDemangler() nothrow @trusted version (OpenBSD) import core.sys.openbsd.dlfcn : RTLD_DEFAULT; version (Darwin) import core.sys.darwin.dlfcn : RTLD_DEFAULT; version (Solaris) import core.sys.solaris.dlfcn : RTLD_DEFAULT; + version (Hurd) import core.sys.hurd.dlfcn : RTLD_DEFAULT; if (auto found = cast(CXX_DEMANGLER) dlsym(RTLD_DEFAULT, "__cxa_demangle")) atomicStore(__cxa_demangle, found); diff --git a/druntime/src/core/internal/backtrace/elf.d b/druntime/src/core/internal/backtrace/elf.d index 1a235537bb..6da1ef1ecb 100644 --- a/druntime/src/core/internal/backtrace/elf.d +++ b/druntime/src/core/internal/backtrace/elf.d @@ -36,6 +36,11 @@ else version (Solaris) import core.sys.solaris.sys.elf : SHF_COMPRESSED, ET_DYN; version = LinuxOrBSD; } +else version (Hurd) +{ + import core.sys.hurd.elf : SHF_COMPRESSED, ET_DYN; + version = LinuxOrBSD; +} version (LinuxOrBSD): diff --git a/druntime/src/core/internal/elf/dl.d b/druntime/src/core/internal/elf/dl.d index 963b4249a3..62210299af 100644 --- a/druntime/src/core/internal/elf/dl.d +++ b/druntime/src/core/internal/elf/dl.d @@ -41,6 +41,11 @@ else version (Solaris) import core.sys.solaris.link : dl_iterate_phdr, dl_phdr_info, ElfW; version = LinuxOrBSD; } +else version (Hurd) +{ + import core.sys.hurd.link : dl_iterate_phdr, dl_phdr_info, ElfW; + version = LinuxOrBSD; +} version (LinuxOrBSD): @@ -93,6 +98,7 @@ struct SharedObject else version (NetBSD) enum IterateManually = true; else version (OpenBSD) enum IterateManually = true; else version (Solaris) enum IterateManually = true; + else version (Hurd) enum IterateManually = true; else enum IterateManually = false; static if (IterateManually) @@ -225,6 +231,14 @@ version (Linux_Use_GNU) return program_invocation_name; } } +else version (Hurd) +{ + const(char)* getprogname() + { + import core.sys.hurd.errno : program_invocation_name; + return program_invocation_name; + } +} else // Bionic, BSDs { extern(C) const(char)* getprogname(); diff --git a/druntime/src/core/internal/elf/io.d b/druntime/src/core/internal/elf/io.d index 80c9415e14..a1b50821da 100644 --- a/druntime/src/core/internal/elf/io.d +++ b/druntime/src/core/internal/elf/io.d @@ -50,6 +50,11 @@ else version (Solaris) import core.sys.solaris.link : ElfW; version = LinuxOrBSD; } +else version (Hurd) +{ + import core.sys.hurd.link : ElfW; + version = LinuxOrBSD; +} /** * File-based memory-mapped I/O (read-only). @@ -403,6 +408,10 @@ char* thisExePath() import core.sys.openbsd.stdlib : getprogname; return strdup(getprogname()); } + else version (Hurd) + { + return readLink("/proc/self/exe"); + } else { version (DragonFlyBSD) diff --git a/druntime/src/core/internal/execinfo.d b/druntime/src/core/internal/execinfo.d index 1ea467afbe..ce7d6de36e 100644 --- a/druntime/src/core/internal/execinfo.d +++ b/druntime/src/core/internal/execinfo.d @@ -68,6 +68,8 @@ else version (DragonFlyBSD) import _execinfo = core.sys.dragonflybsd.execinfo : backtrace, backtrace_symbols, backtrace_symbols_fd; else version (Solaris) import _execinfo = core.sys.solaris.execinfo : backtrace, backtrace_symbols, backtrace_symbols_fd; +else version (Hurd) + import _execinfo = core.sys.hurd.execinfo : backtrace, backtrace_symbols, backtrace_symbols_fd; /// Indicates the availability of backtrace functions enum bool hasExecinfo = is(_execinfo == module); diff --git a/druntime/src/core/stdc/config.d b/druntime/src/core/stdc/config.d index 952ceacb21..b36d9ca394 100644 --- a/druntime/src/core/stdc/config.d +++ b/druntime/src/core/stdc/config.d @@ -259,6 +259,8 @@ else version (DigitalMars) alias real c_long_double; else version (Darwin) alias real c_long_double; + else version (Hurd) + alias real c_long_double; } else version (AArch64) { @@ -276,6 +278,8 @@ else version (DigitalMars) alias real c_long_double; else version (Darwin) alias real c_long_double; + else version (Hurd) + alias real c_long_double; } } diff --git a/druntime/src/core/stdc/errno.d b/druntime/src/core/stdc/errno.d index db347e404b..6a4745f2b0 100644 --- a/druntime/src/core/stdc/errno.d +++ b/druntime/src/core/stdc/errno.d @@ -2457,6 +2457,113 @@ else version (WASI) enum ERFKILL = 132; enum EHWPOISON = 133; } +else version (Hurd) +{ + enum EPERM = 0x40000001; /* Operation not permitted */ + enum ENOENT = 0x40000002; /* No such file or directory */ + enum ESRCH = 0x40000003; /* No such process */ + enum EINTR = 0x40000004; /* Interrupted system call */ + enum EIO = 0x40000005; /* Input/output error */ + enum ENXIO = 0x40000006; /* No such device or address */ + enum E2BIG = 0x40000007; /* Argument list too long */ + enum ENOEXEC = 0x40000008; /*enum Exec format error */ + enum EBADF = 0x40000009; /* Bad file descriptor */ + enum ECHILD = 0x4000000a; /* No child processes */ + enum EDEADLK = 0x4000000b; /* Resource deadlock avoided */ + enum ENOMEM = 0x4000000c; /* Cannot allocate memory */ + enum EACCES = 0x4000000d; /* Permission denied */ + enum EFAULT = 0x4000000e; /* Bad address */ + enum ENOTBLK = 0x4000000f; /* Block device required */ + enum EBUSY = 0x40000010; /* Device or resource busy */ + enum EEXIST = 0x40000011; /* File exists */ + enum EXDEV = 0x40000012; /* Invalid cross-device link */ + enum ENODEV = 0x40000013; /* No such device */ + enum ENOTDIR = 0x40000014; /* Not a directory */ + enum EISDIR = 0x40000015; /* Is a directory */ + enum EINVAL = 0x40000016; /* Invalid argument */ + enum EMFILE = 0x40000018; /* Too many open files */ + enum ENFILE = 0x40000017; /* Too many open files in system */ + enum ENOTTY = 0x40000019; /* Inappropriate ioctl for device */ + enum ETXTBSY = 0x4000001a; /* Text file busy */ + enum EFBIG = 0x4000001b; /* File too large */ + enum ENOSPC = 0x4000001c; /* No space left on device */ + enum ESPIPE = 0x4000001d; /* Illegal seek */ + enum EROFS = 0x4000001e; /* Read-only file system */ + enum EMLINK = 0x4000001f; /* Too many links */ + enum EPIPE = 0x40000020; /* Broken pipe */ + enum EDOM = 0x40000021; /* Numerical argument out of domain */ + enum ERANGE = 0x40000022; /* Numerical result out of range */ + enum EAGAIN = 0x40000023; /* Resource temporarily unavailable */ + enum EINPROGRESS = 0x40000024; /* Operation now in progress */ + enum EALREADY = 0x40000025; /* Operation already in progress */ + enum ENOTSOCK = 0x40000026; /* Socket operation on non-socket */ + enum EMSGSIZE = 0x40000028; /* Message too long */ + enum EPROTOTYPE = 0x40000029; /* Protocol wrong type for socket */ + enum ENOPROTOOPT = 0x4000002a; /* Protocol not available */ + enum EPROTONOSUPPORT = 0x4000002b; /* Protocol not supported */ + enum ESOCKTNOSUPPORT = 0x4000002c; /* Socket type not supported */ + enum EOPNOTSUPP = 0x4000002d; /* Operation not supported */ + enum EPFNOSUPPORT = 0x4000002e; /* Protocol family not supported */ + enum EAFNOSUPPORT = 0x4000002f; /* Address family not supported by protocol */ + enum EADDRINUSE = 0x40000030; /* Address already in use */ + enum EADDRNOTAVAIL = 0x40000031; /* Cannot assign requested address */ + enum ENETDOWN = 0x40000032; /* Network is down */ + enum ENETUNREACH = 0x40000033; /* Network is unreachable */ + enum ENETRESET = 0x40000034; /* Network dropped connection on reset */ + enum ECONNABORTED = 0x40000035; /* Software caused connection abort */ + enum ECONNRESET = 0x40000036; /* Connection reset by peer */ + enum ENOBUFS = 0x40000037; /* No buffer space available */ + enum EISCONN = 0x40000038; /* Transport endpoint is already connected */ + enum ENOTCONN = 0x40000039; /* Transport endpoint is not connected */ + enum EDESTADDRREQ = 0x40000027; /* Destination address required */ + enum ESHUTDOWN = 0x4000003a; /* Cannot send after transport endpoint shutdown */ + enum ETOOMANYREFS = 0x4000003b; /* Too many references: cannot splice */ + enum ETIMEDOUT = 0x4000003c; /* Connection timed out */ + enum ECONNREFUSED = 0x4000003d; /* Connection refused */ + enum ELOOP = 0x4000003e; /* Too many levels of symbolic links */ + enum ENAMETOOLONG = 0x4000003f; /* File name too long */ + enum EHOSTDOWN = 0x40000040; /* Host is down */ + enum EHOSTUNREACH = 0x40000041; /* No route to host */ + enum ENOTEMPTY = 0x40000042; /* Directory not empty */ + enum EPROCLIM = 0x40000043; /* Too many processes */ + enum EUSERS = 0x40000044; /* Too many users */ + enum EDQUOT = 0x40000045; /* Disk quota exceeded */ + enum ESTALE = 0x40000046; /* Stale file handle */ + enum EREMOTE = 0x40000047; /* Object is remote */ + enum EBADRPC = 0x40000048; /* RPC struct is bad */ + enum ERPCMISMATCH = 0x40000049; /* RPC version wrong */ + enum EPROGUNAVAIL = 0x4000004a; /* RPC program not available */ + enum EPROGMISMATCH = 0x4000004b; /* RPC program version wrong */ + enum EPROCUNAVAIL = 0x4000004c; /* RPC bad procedure for program */ + enum ENOLCK = 0x4000004d; /* No locks available */ + enum EFTYPE = 0x4000004f; /* Inappropriate file type or format */ + enum EAUTH = 0x40000050; /* Authentication error */ + enum ENEEDAUTH = 0x40000051; /* Need authenticator */ + enum ENOSYS = 0x4000004e; /* Function not implemented */ + enum ELIBEXEC = 0x40000053; /* Cannot exec a shared library directly */ + enum ENOTSUP = 0x40000076; /* Not supported */ + enum EILSEQ = 0x4000006a; /* Invalid or incomplete multibyte or wide character */ + enum EBACKGROUND = 0x40000064; /* Inappropriate operation for background process */ + enum EDIED = 0x40000065; /* Translator died */ + enum ED = 0x40000066; /* ? */ + enum EGREGIOUS = 0x40000067; /* You really blew it this time */ + enum EIEIO = 0x40000068; /* Computer bought the farm */ + enum EGRATUITOUS = 0x40000069; /* Gratuitous error */ + enum EBADMSG = 0x4000006b; /* Bad message */ + enum EIDRM = 0x4000006c; /* Identifier removed */ + enum EMULTIHOP = 0x4000006d; /* Multihop attempted */ + enum ENODATA = 0x4000006e; /* No data available */ + enum ENOLINK = 0x4000006f; /* Link has been severed */ + enum ENOMSG = 0x40000070; /* No message of desired type */ + enum ENOSR = 0x40000071; /* Out of streams resources */ + enum ENOSTR = 0x40000072; /* Device not a stream */ + enum EOVERFLOW = 0x40000073; /* Value too large for defined data type */ + enum EPROTO = 0x40000074; /* Protocol error */ + enum ETIME = 0x40000075; /* Timer expired */ + enum ECANCELED = 0x40000077; /* Operation canceled */ + enum EOWNERDEAD = 0x40000078; /* Owner died */ + enum ENOTRECOVERABLE = 0x40000079; /* State not recoverable */ + } else { static assert(false, "Unsupported platform"); diff --git a/druntime/src/core/stdc/limits.d b/druntime/src/core/stdc/limits.d index 2684b22bfc..35ee96a052 100644 --- a/druntime/src/core/stdc/limits.d +++ b/druntime/src/core/stdc/limits.d @@ -181,5 +181,19 @@ else version (Windows) /// enum PIPE_BUF = 5120; } +else version (Hurd) +{ + // no arbitrary fixed limits + /// + // enum MAX_CANON + /// + // enum MAX_INPUT + /// + enum NAME_MAX = 255; + /// + // enum PATH_MAX + /// + // enum PIPE_BUF +} else static assert(0, "unsupported OS"); diff --git a/druntime/src/core/sys/hurd/config.d b/druntime/src/core/sys/hurd/config.d new file mode 100644 index 0000000000..eee7685ad1 --- /dev/null +++ b/druntime/src/core/sys/hurd/config.d @@ -0,0 +1,28 @@ +/** + * D header file for GNU Hurd + * + */ +module core.sys.hurd.config; + +version (Hurd): + +public import core.sys.posix.config; + +// man 7 feature_test_macros +// http://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html +enum _GNU_SOURCE = true; +// deduced <features.h> +// http://sourceware.org/git/?p=glibc.git;a=blob;f=include/features.h +enum _DEFAULT_SOURCE = true; +enum _ATFILE_SOURCE = true; + +// _BSD_SOURCE and _SVID_SOURCE are deprecated aliases for _DEFAULT_SOURCE. +deprecated("use _DEFAULT_SOURCE") +{ + enum _BSD_SOURCE = true; + enum _SVID_SOURCE = true; +} + +enum __USE_MISC = _DEFAULT_SOURCE; +enum __USE_ATFILE = _ATFILE_SOURCE; +enum __USE_GNU = _GNU_SOURCE; diff --git a/druntime/src/core/sys/hurd/dlfcn.d b/druntime/src/core/sys/hurd/dlfcn.d new file mode 100644 index 0000000000..61e979dfad --- /dev/null +++ b/druntime/src/core/sys/hurd/dlfcn.d @@ -0,0 +1,112 @@ +/** + * D header file for GNU/Linux + * + * $(LINK2 http://sourceware.org/git/?p=glibc.git;a=blob;f=dlfcn/dlfcn.h, glibc dlfcn/dlfcn.h) + */ +module core.sys.hurd.dlfcn; + +version (Hurd): +extern (C): +nothrow: +@nogc: +@system: + + +public import core.sys.posix.dlfcn; +import core.sys.hurd.config; + +// <bits/dlfcn.h> + +// http://sourceware.org/git/?p=glibc.git;a=blob;f=bits/dlfcn.h +// enum RTLD_LAZY = 0x00001; // POSIX +// enum RTLD_NOW = 0x00002; // POSIX +enum RTLD_BINDING_MASK = 0x3; +enum RTLD_NOLOAD = 0x00004; +enum RTLD_DEEPBIND = 0x00008; + +// enum RTLD_GLOBAL = 0x00100; // POSIX +// enum RTLD_LOCAL = 0; // POSIX +enum RTLD_NODELETE = 0x01000; + +static if (__USE_GNU) + { + RT DL_CALL_FCT(RT, Args...)(RT function(Args) fctp, auto ref Args args) + { + _dl_mcount_wrapper_check(cast(void*)fctp); + return fctp(args); + } + + void _dl_mcount_wrapper_check(void* __selfpc); + } +// <bits/dlfcn.h> + +static if (__USE_GNU) +{ + enum RTLD_NEXT = cast(void *)-1L; + enum RTLD_DEFAULT = cast(void *)0; + alias c_long Lmid_t; + enum LM_ID_BASE = 0; + enum LM_ID_NEWLM = -1; +} + +// void* dlopen(const scope char* __file, int __mode); // POSIX +// int dlclose(void* __handle); // POSIX +// void* dlsym(void* __handle, const scope char* __name); // POSIX + +static if (__USE_GNU) +{ + void* dlmopen(Lmid_t __nsid, const scope char* __file, int __mode); + void* dlvsym(void* __handle, const scope char* __name, const scope char* __version); +} + +// char* dlerror(); // POSIX + +static if (__USE_GNU) +{ + struct Dl_info + { + const(char)* dli_fname; + void* dli_fbase; + const(char)* dli_sname; + void* dli_saddr; + } + + int dladdr(const scope void* __address, Dl_info* __info); + int dladdr1(void* __address, Dl_info* __info, void** __extra_info, int __flags); + + enum + { + RTLD_DL_SYMENT = 1, + RTLD_DL_LINKMAP = 2, + } + + int dlinfo(void* __handle, int __request, void* __arg); + + enum + { + RTLD_DI_LMID = 1, + RTLD_DI_LINKMAP = 2, + RTLD_DI_CONFIGADDR = 3, + RTLD_DI_SERINFO = 4, + RTLD_DI_SERINFOSIZE = 5, + RTLD_DI_ORIGIN = 6, + RTLD_DI_PROFILENAME = 7, + RTLD_DI_PROFILEOUT = 8, + RTLD_DI_TLS_MODID = 9, + RTLD_DI_TLS_DATA = 10, + RTLD_DI_MAX = 10, + } + + struct Dl_serpath + { + char* dls_name; + uint dls_flags; + } + + struct Dl_serinfo + { + size_t dls_size; + uint dls_cnt; + Dl_serpath[1] dls_serpath; + } +} diff --git a/druntime/src/core/sys/hurd/elf.d b/druntime/src/core/sys/hurd/elf.d new file mode 100644 index 0000000000..e5a4e1f4e3 --- /dev/null +++ b/druntime/src/core/sys/hurd/elf.d @@ -0,0 +1,160 @@ +/** + * D header file for GNU Hurd + * + * $(LINK2 http://sourceware.org/git/?p=glibc.git;a=blob;f=elf/elf.h, glibc elf/elf.h) + */ +module core.sys.hurd.elf; + +version (Hurd): +extern (C): +pure: +nothrow: +@system: + +import core.stdc.stdint; +public import core.sys.elf; + +extern (D) +{ + auto ELF32_ST_VISIBILITY(O)(O o) { return o & 0x03; } + alias ELF32_ST_VISIBILITY ELF64_ST_VISIBILITY; +} + +struct Elf32_Nhdr +{ + Elf32_Word n_namesz; + Elf32_Word n_descsz; + Elf32_Word n_type; +} + +struct Elf64_Nhdr +{ + Elf64_Word n_namesz; + Elf64_Word n_descsz; + Elf64_Word n_type; +} + +enum NT_PRSTATUS = 1; +enum NT_FPREGSET = 2; +enum NT_PRPSINFO = 3; +enum NT_PRXREG = 4; +enum NT_TASKSTRUCT = 4; +enum NT_PLATFORM = 5; +enum NT_AUXV = 6; +enum NT_GWINDOWS = 7; +enum NT_ASRS = 8; +enum NT_PSTATUS = 10; +enum NT_PSINFO = 13; +enum NT_PRCRED = 14; +enum NT_UTSNAME = 15; +enum NT_LWPSTATUS = 16; +enum NT_LWPSINFO = 17; +enum NT_PRFPXREG = 20; +enum NT_SIGINFO = 0x53494749; +enum NT_FILE = 0x46494c45; +enum NT_PRXFPREG = 0x46e62b7f; +enum NT_PPC_VMX = 0x100; +enum NT_PPC_SPE = 0x101; +enum NT_PPC_VSX = 0x102; +enum NT_386_TLS = 0x200; +enum NT_386_IOPERM = 0x201; +enum NT_X86_XSTATE = 0x202; +enum NT_S390_HIGH_GPRS = 0x300; +enum NT_S390_TIMER = 0x301; +enum NT_S390_TODCMP = 0x302; +enum NT_S390_TODPREG = 0x303; +enum NT_S390_CTRS = 0x304; +enum NT_S390_PREFIX = 0x305; +enum NT_S390_LAST_BREAK = 0x306; +enum NT_S390_SYSTEM_CALL = 0x307; +enum NT_S390_TDB = 0x308; +enum NT_ARM_VFP = 0x400; +enum NT_ARM_TLS = 0x401; +enum NT_ARM_HW_BREAK = 0x402; +enum NT_ARM_HW_WATCH = 0x403; + +enum NT_VERSION = 1; + +struct Elf32_Dyn +{ + Elf32_Sword d_tag; + union _d_un + { + Elf32_Word d_val; + Elf32_Addr d_ptr; + } _d_un d_un; +} + +struct Elf64_Dyn +{ + Elf64_Sxword d_tag; + union _d_un + { + Elf64_Xword d_val; + Elf64_Addr d_ptr; + } _d_un d_un; +} + +enum NT_GNU_ABI_TAG = 1; +enum NT_GNU_HWCAP = 2; +enum NT_GNU_BUILD_ID = 3; +enum NT_GNU_GOLD_VERSION = 4; + +struct Elf32_auxv_t +{ + uint32_t a_type; + union _a_un + { + uint32_t a_val; + } _a_un a_un; +} + +struct Elf64_auxv_t +{ + uint64_t a_type; + union _a_un + { + uint64_t a_val; + } _a_un a_un; +} + +enum AT_NULL = 0; +enum AT_IGNORE = 1; +enum AT_EXECFD = 2; +enum AT_PHDR = 3; +enum AT_PHENT = 4; +enum AT_PHNUM = 5; +enum AT_PAGESZ = 6; +enum AT_BASE = 7; +enum AT_FLAGS = 8; +enum AT_ENTRY = 9; +enum AT_NOTELF = 10; +enum AT_UID = 11; +enum AT_EUID = 12; +enum AT_GID = 13; +enum AT_EGID = 14; +enum AT_CLKTCK = 17; +enum AT_PLATFORM = 15; +enum AT_HWCAP = 16; +enum AT_FPUCW = 18; +enum AT_DCACHEBSIZE = 19; +enum AT_ICACHEBSIZE = 20; +enum AT_UCACHEBSIZE = 21; +enum AT_IGNOREPPC = 22; + +enum AT_SECURE = 23; + +enum AT_BASE_PLATFORM = 24; + +enum AT_RANDOM = 25; + +enum AT_HWCAP2 = 26; + +enum AT_EXECFN = 31; +enum AT_SYSINFO = 32; +enum AT_SYSINFO_EHDR = 33; + +enum AT_L1I_CACHESHAPE = 34; +enum AT_L1D_CACHESHAPE = 35; +enum AT_L2_CACHESHAPE = 36; +enum AT_L3_CACHESHAPE = 37; diff --git a/druntime/src/core/sys/hurd/errno.d b/druntime/src/core/sys/hurd/errno.d new file mode 100644 index 0000000000..eb3362f90e --- /dev/null +++ b/druntime/src/core/sys/hurd/errno.d @@ -0,0 +1,19 @@ +/** + * D header file for GNU/Hurd + * + * $(LINK2 http://sourceware.org/git/?p=glibc.git;a=blob;f=stdlib/errno.h, glibc stdlib/errno.h) + */ +module core.sys.hurd.errno; + +version (Hurd): +extern (C): +nothrow: + +public import core.stdc.errno; +import core.sys.hurd.config; + +static if (_GNU_SOURCE) +{ + extern __gshared char* program_invocation_name, program_invocation_short_name; + alias error_t = int; +} diff --git a/druntime/src/core/sys/hurd/execinfo.d b/druntime/src/core/sys/hurd/execinfo.d new file mode 100644 index 0000000000..a99368d6bd --- /dev/null +++ b/druntime/src/core/sys/hurd/execinfo.d @@ -0,0 +1,17 @@ +/** + * D header file for GNU Hurd + * + * Copyright: Copyright Martin Nowak 2012. + * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Authors: Martin Nowak + */ +module core.sys.hurd.execinfo; + +version (Hurd): +extern (C): +nothrow: +@nogc: + +int backtrace(void** buffer, int size); +char** backtrace_symbols(const(void*)* buffer, int size); +void backtrace_symbols_fd(const(void*)* buffer, int size, int fd); diff --git a/druntime/src/core/sys/hurd/link.d b/druntime/src/core/sys/hurd/link.d new file mode 100644 index 0000000000..a6989cf582 --- /dev/null +++ b/druntime/src/core/sys/hurd/link.d @@ -0,0 +1,132 @@ +/** + * D header file for GNU Hurd + * + * $(LINK2 http://sourceware.org/git/?p=glibc.git;a=blob;f=elf/link.h, glibc elf/link.h) + */ +module core.sys.hurd.link; + +version (Hurd): +extern (C): +nothrow: +@system: + +version (X86) version = X86_Any; +version (X86_64) version = X86_Any; + +import core.stdc.stdint : uintptr_t, uint32_t, uint64_t; +import core.sys.hurd.config : __WORDSIZE; +import core.sys.hurd.dlfcn : Lmid_t; +import core.sys.hurd.elf; + +version (X86_Any) +{ + // http://sourceware.org/git/?p=glibc.git;a=blob;f=bits/elfclass.h + alias __WORDSIZE __ELF_NATIVE_CLASS; + alias uint32_t Elf_Symndx; +} +else + static assert(0, "unimplemented"); +// <bits/elfclass.h> + +template ElfW(string type) +{ + mixin("alias Elf"~__ELF_NATIVE_CLASS.stringof~"_"~type~" ElfW;"); +} + +enum +{ + RT_CONSISTENT, + RT_ADD, + RT_DELETE, +} + +struct r_debug +{ + int r_version; + link_map* r_map; + ElfW!"Addr" r_brk; + typeof(RT_CONSISTENT) r_state; + ElfW!"Addr" r_ldbase; +} + +extern r_debug _r_debug; +extern ElfW!"Dyn"* _DYNAMIC; + +struct link_map +{ + ElfW!"Addr" l_addr; + char* l_name; + ElfW!"Dyn"* l_ld; + link_map* l_next, l_prev; +} + +enum +{ + LA_ACT_CONSISTENT, + LA_ACT_ADD, + LA_ACT_DELETE, +} + +enum +{ + LA_SER_ORIG = 0x01, + LA_SER_LIBPATH = 0x02, + LA_SER_RUNPATH = 0x04, + LA_SER_CONFIG = 0x08, + LA_SER_DEFAULT = 0x40, + LA_SER_SECURE = 0x80, +} + + +enum +{ + LA_FLG_BINDTO = 0x01, + LA_FLG_BINDFROM = 0x02, +} + + +enum +{ + LA_SYMB_NOPLTENTER = 0x01, + LA_SYMB_NOPLTEXIT = 0x02, + LA_SYMB_STRUCTCALL = 0x04, + LA_SYMB_DLSYM = 0x08, + LA_SYMB_ALTVALUE = 0x10, +} + +struct dl_phdr_info +{ + ElfW!"Addr" dlpi_addr; + const(char)* dlpi_name; + const(ElfW!"Phdr")* dlpi_phdr; + ElfW!"Half" dlpi_phnum; + + // check the SIZE argument of the dl_iterate_phdr callback whether + // the following members are available + ulong dlpi_adds; + ulong dlpi_subs; + + size_t dlpi_tls_modid; + void *dlpi_tls_data; +} + +private alias extern(C) int function(dl_phdr_info*, size_t, void *) dl_iterate_phdr_cb; +private alias extern(C) int function(dl_phdr_info*, size_t, void *) @nogc dl_iterate_phdr_cb_ngc; +extern int dl_iterate_phdr(dl_iterate_phdr_cb __callback, void*__data); +extern int dl_iterate_phdr(dl_iterate_phdr_cb_ngc __callback, void*__data) @nogc; + +// ld.so auditing interfaces prototypes have to be defined by the auditing DSO. +extern uint la_version(uint __version); +extern void la_activity(uintptr_t *__cookie, uint __flag); +extern char* la_objsearch(const(char)* __name, uintptr_t* __cookie, + uint __flag); +extern uint la_objopen(link_map* __map, Lmid_t __lmid, + uintptr_t* __cookie); +extern void la_preinit(uintptr_t* __cookie); +extern uintptr_t la_symbind32(Elf32_Sym* __sym, uint __ndx, + uintptr_t* __refcook, uintptr_t* __defcook, + uint *__flags, const(char)* __symname); +extern uintptr_t la_symbind64(Elf64_Sym* __sym, uint __ndx, + uintptr_t* __refcook, uintptr_t* __defcook, + uint* __flags, const(char)* __symname); +extern uint la_objclose(uintptr_t *__cookie); diff --git a/druntime/src/core/sys/hurd/sys/types.d b/druntime/src/core/sys/hurd/sys/types.d new file mode 100644 index 0000000000..6f7255704e --- /dev/null +++ b/druntime/src/core/sys/hurd/sys/types.d @@ -0,0 +1,58 @@ +module core.sys.hurd.sys.types; + +version (Hurd): +extern(C): +@nogc: +nothrow: + + +enum __pthread_process_shared +{ + __PTHREAD_PROCESS_PRIVATE = 0, + __PTHREAD_PROCESS_SHARED, +} + +enum __pthread_inheritsched +{ + __PTHREAD_EXPLICIT_SCHED = 0, + __PTHREAD_INHERIT_SCHED, +} + +enum __pthread_contentionscope +{ + __PTHREAD_SCOPE_SYSTEM = 0, + __PTHREAD_SCOPE_PROCESS, +} + +enum __pthread_detachstate +{ + __PTHREAD_CREATE_JOINABLE = 0, + __PTHREAD_CREATE_DETACHED, +} + +enum __pthread_mutex_type +{ + __PTHREAD_MUTEX_TIMED, + __PTHREAD_MUTEX_ERRORCHECK, + __PTHREAD_MUTEX_RECURSIVE, +} + +enum __pthread_mutex_protocol +{ + __PTHREAD_PRIO_NONE = 0, + __PTHREAD_PRIO_INHERIT, + __PTHREAD_PRIO_PROTECT +} + +struct __sched_param +{ + int __sched_priority; +} + + + +// ???? +struct __pthread +{ + ubyte[1] _address; +} diff --git a/druntime/src/core/sys/hurd/time.d b/druntime/src/core/sys/hurd/time.d new file mode 100644 index 0000000000..1146a481e2 --- /dev/null +++ b/druntime/src/core/sys/hurd/time.d @@ -0,0 +1,15 @@ +//Written in the D programming language + +/++ + D header file for Hurd extensions to POSIX's time.h. + + +/ +module core.sys.hurd.time; + +public import core.sys.posix.time; + +version (Hurd): + +enum CLOCK_MONOTONIC_RAW = 4; +enum CLOCK_REALTIME_COARSE = 5; +enum CLOCK_MONOTONIC_COARSE = 6;; diff --git a/druntime/src/core/sys/hurd/unistd.d b/druntime/src/core/sys/hurd/unistd.d new file mode 100644 index 0000000000..12f84b2dea --- /dev/null +++ b/druntime/src/core/sys/hurd/unistd.d @@ -0,0 +1,25 @@ +module core.sys.hurd.unistd; + +public import core.sys.posix.unistd; + +version (Hurd): +extern(C): +nothrow: +@nogc: + + +// Additional seek constants for sparse file handling +// from Linux's unistd.h, stdio.h, and linux/fs.h +// (see http://man7.org/linux/man-pages/man2/lseek.2.html) +enum { + /// Offset is relative to the next location containing data + SEEK_DATA = 3, + /// Offset is relative to the next hole (or EOF if file is not sparse) + SEEK_HOLE = 4 +} + +/// Prompt for a password without echoing it. +char* getpass(const(char)* prompt); + +/// Close all open file descriptors greater or equal to `lowfd` +void closefrom(int lowfd); diff --git a/druntime/src/core/sys/linux/stdio.d b/druntime/src/core/sys/linux/stdio.d index 2d079fd71f..c06184ab8a 100644 --- a/druntime/src/core/sys/linux/stdio.d +++ b/druntime/src/core/sys/linux/stdio.d @@ -9,7 +9,7 @@ module core.sys.linux.stdio; version (CRuntime_Glibc): public import core.sys.posix.stdio; import core.sys.posix.sys.types : ssize_t, off64_t = off_t; -import core.sys.linux.config : __USE_FILE_OFFSET64; +import core.sys.posix.config : __USE_FILE_OFFSET64; import core.stdc.stdio : FILE; import core.stdc.stddef : wchar_t; diff --git a/druntime/src/core/sys/posix/dirent.d b/druntime/src/core/sys/posix/dirent.d index 0e822f556c..f576342bdc 100644 --- a/druntime/src/core/sys/posix/dirent.d +++ b/druntime/src/core/sys/posix/dirent.d @@ -158,6 +158,17 @@ else version (Solaris) char[1] d_name = 0; } } +else version (Hurd) +{ + struct dirent + { + ino_t d_ino; + ushort d_reclen; + ubyte d_type; + ubyte d_namlen; + char[1] d_name = 0; + } +} else { static assert(false, "Unsupported platform"); diff --git a/druntime/src/core/sys/posix/fcntl.d b/druntime/src/core/sys/posix/fcntl.d index 4f7a22592d..862dcb9838 100644 --- a/druntime/src/core/sys/posix/fcntl.d +++ b/druntime/src/core/sys/posix/fcntl.d @@ -870,6 +870,94 @@ else version (Solaris) enum AT_REMOVEDIR = 0x1; enum AT_EACCESS = 0x4; } +else version (Hurd) +{ + enum F_DUPFD = 0; + enum F_GETFD = 1; + enum F_SETFD = 2; + enum F_GETFL = 3; + enum F_SETFL = 4; + enum F_GETOWN = 5; + enum F_SETOWN = 6; + + static if ( __USE_FILE_OFFSET64 ) + { + enum F_GETLK = F_GETLK64; + enum F_SETLK = F_SETLK64; + enum F_SETLKW = F_SETLKW64; + } + else + { + enum F_GETLK = 7; + enum F_SETLK = 8; + enum F_SETLKW = 9; + } + enum F_GETLK64 = 10; + enum F_SETLK64 = 11; + enum F_SETLKW64 = 12; + + enum F_DUPFD_CLOEXEC = 1030; + + enum FD_CLOEXEC = 1; + + enum F_RDLCK = 1; + enum F_UNLCK = 2; + enum F_WRLCK = 3; + + enum O_CREAT = 0x0010; + enum O_EXCL = 0x0020; + enum O_NOCTTY = 0; + enum O_TRUNC = 0x00010000; + + enum O_APPEND = 0x0100; + enum O_DSYNC = O_SYNC; + enum O_NONBLOCK = 0x0004; + enum O_RSYNC = O_SYNC; + + + enum O_ACCMODE = O_RDWR; + enum O_RDONLY = 0x0001; + enum O_WRONLY = 0x0002; + enum O_RDWR = (O_RDONLY|O_WRONLY); + + enum O_SYNC = O_FSYNC; + enum O_FSYNC = 0x0400; + + enum O_READ = O_RDONLY; + enum O_WRITE = O_WRONLY; + enum O_EXEC = 0x0004; + enum O_NORW = 0; + enum O_LARGEFILE = 0; + enum O_NOLINK = 0x0040; + enum O_NOTRANS = 0x0080; + enum O_NOFOLLOW = 0x00100000; + enum O_DIRECTORY = 0x00200000; + enum O_ASYNC = 0x0200; + enum O_NOATIME = 0x0800; + enum O_SHLOCK = 0x00020000; + enum O_EXLOCK = 0x00040000; + enum O_NDELAY = O_NONBLOCK; + enum O_HURD = (0xffff | O_EXLOCK | O_SHLOCK); + enum O_CLOEXEC = 0x00400000; + enum O_TMPFILE = 0x00800000; + enum O_IGNORE_CTTY = 0x00080000; + + struct flock + { + short l_type; + short l_whence; + off_t l_start; + off_t l_len; + pid_t l_pid; + } + + enum AT_FDCWD = -100; + + enum AT_EACCESS = 0x200; + enum AT_SYMLINK_NOFOLLOW = 0x400; + enum AT_SYMLINK_FOLLOW = 0x400; + enum AT_REMOVEDIR = 0x200; +} else { static assert(false, "Unsupported platform"); diff --git a/druntime/src/core/sys/posix/poll.d b/druntime/src/core/sys/posix/poll.d index 5901f62b5c..eeaea0b364 100644 --- a/druntime/src/core/sys/posix/poll.d +++ b/druntime/src/core/sys/posix/poll.d @@ -338,6 +338,22 @@ else version (Solaris) POLLNVAL = 0x0020, } } +else version (Hurd) +{ + enum + { + POLLIN = 0x001, + POLLRDNORM = POLLIN, + POLLRDBAND = POLLPRI, + POLLPRI = 0x002, + POLLOUT = 0x004, + POLLWRNORM = POLLOUT, + POLLWRBAND = POLLOUT, + POLLERR = 0x008, /* ocatal 010 */ + POLLHUP = 0x010, /* ocatal 020 */ + POLLNVAL = 0x020, /* ocatal 040 */ + } +} else { static assert(false, "Unsupported platform"); diff --git a/druntime/src/core/sys/posix/pthread.d b/druntime/src/core/sys/posix/pthread.d index 86844f9c5c..11a20cb6e3 100644 --- a/druntime/src/core/sys/posix/pthread.d +++ b/druntime/src/core/sys/posix/pthread.d @@ -30,6 +30,9 @@ else version (TVOS) else version (WatchOS) version = Darwin; +version (Hurd) + import core.sys.hurd.sys.types; + version (Posix): extern (C) nothrow: @@ -104,6 +107,8 @@ void pthread_testcancel(); */ version (CRuntime_Glibc) { + version (linux) + { enum { PTHREAD_CANCEL_ENABLE, @@ -140,6 +145,47 @@ version (CRuntime_Glibc) PTHREAD_PROCESS_PRIVATE, PTHREAD_PROCESS_SHARED } + } + else version (Hurd) + { + enum + { + PTHREAD_CANCEL_DISABLE, + PTHREAD_CANCEL_ENABLE, + } + + enum + { + PTHREAD_CANCEL_DEFERRED, + PTHREAD_CANCEL_ASYNCHRONOUS + } + + enum PTHREAD_CANCELED = cast(void*) -1; + + // enum __pthread_cond PTHREAD_COND_INITIALIZER = { __PTHREAD_SPIN_LOCK_INITIALIZER, NULL, NULL, 0, NULL } + + + enum + { + PTHREAD_CREATE_JOINABLE = __pthread_detachstate.__PTHREAD_CREATE_JOINABLE, + PTHREAD_CREATE_DETACHED = __pthread_detachstate.__PTHREAD_CREATE_DETACHED, + } + + enum + { + PTHREAD_EXPLICIT_SCHED = __pthread_inheritsched.__PTHREAD_EXPLICIT_SCHED, + PTHREAD_INHERIT_SCHED = __pthread_inheritsched.__PTHREAD_INHERIT_SCHED, + } + + enum PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t.init; + enum PTHREAD_ONCE_INIT = pthread_once_t.init; + + enum + { + PTHREAD_PROCESS_PRIVATE = __pthread_process_shared.__PTHREAD_PROCESS_PRIVATE, + PTHREAD_PROCESS_SHARED = __pthread_process_shared.__PTHREAD_PROCESS_SHARED, + } + } } else version (Darwin) { @@ -477,6 +523,8 @@ alias void function(void*) _pthread_cleanup_routine; alias void function(void*) @nogc _pthread_cleanup_routine_nogc; version (CRuntime_Glibc) { + version (linux) + { struct _pthread_cleanup_buffer { _pthread_cleanup_routine __routine; @@ -503,6 +551,60 @@ version (CRuntime_Glibc) _pthread_cleanup_pop( &buffer, execute ); } } + } + else version (Hurd) + { + // glibc/sysdeps/htl/pthread.h + // glibc/sysdeps/htl/bits/cancellation.h + struct __pthread_cancelation_handler + { + _pthread_cleanup_routine __handler; + void* __arg; + __pthread_cancelation_handler* __next; + } + + __pthread_cancelation_handler** __pthread_get_cleanup_stack(); + + // glibc/sysdeps/htl/bits/cancellation.h + // Reimplement the macros in D. + // Not sure what to do with that. + // void pthread_cleanup_push(__pthread_cancelation_handler*, _pthread_cleanup_routine_nogc, void*) @nogc; + void pthread_cleanup_push(__pthread_cancelation_handler* , _pthread_cleanup_routine __handler, void* __arg){ + __pthread_cancelation_handler** handlers = __pthread_get_cleanup_stack(); + __pthread_cancelation_handler handler = { + __handler, __arg, * handlers + }; + *handlers = &handler; + } + + void pthread_cleanup_pop(int execute) + { + __pthread_cancelation_handler** handlers = __pthread_get_cleanup_stack(); + if (execute) + (*handlers).__handler((*handlers).__arg); + *handlers = (*handlers).__next; + } + + struct pthread_cleanup + { + __pthread_cancelation_handler cancelation_handler = void; + + extern (D) void push(F: _pthread_cleanup_routine)(F routine, void* arg ) + { + pthread_cleanup_push( &cancelation_handler, routine, arg ); + } + + extern (D) void pop()( int execute ) + { + pthread_cleanup_pop(execute); + } + } + } + else + { + static assert(false, "Unsupported platform"); + } + } else version (Darwin) { @@ -1064,9 +1166,24 @@ int pthread_setconcurrency(int); version (CRuntime_Glibc) { - enum PTHREAD_MUTEX_NORMAL = 0; - enum PTHREAD_MUTEX_RECURSIVE = 1; - enum PTHREAD_MUTEX_ERRORCHECK = 2; + + version(linux) + { + enum PTHREAD_MUTEX_NORMAL = 0; + enum PTHREAD_MUTEX_RECURSIVE = 1; + enum PTHREAD_MUTEX_ERRORCHECK = 2; + } + else version(Hurd) + { + enum PTHREAD_MUTEX_NORMAL = __pthread_mutex_type.__PTHREAD_MUTEX_TIMED; + enum PTHREAD_MUTEX_ERRORCHECK = __pthread_mutex_type.__PTHREAD_MUTEX_ERRORCHECK; + enum PTHREAD_MUTEX_RECURSIVE = __pthread_mutex_type.__PTHREAD_MUTEX_RECURSIVE; + + } + else + { + static assert(false, "Unsupported platform"); + } enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL; int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*); @@ -1400,6 +1517,22 @@ else version (Solaris) int pthread_mutexattr_setprioceiling(pthread_mutexattr_t*, int); int pthread_mutexattr_setprotocol(pthread_mutexattr_t*, int); } +else version (Hurd) +{ + enum + { + PTHREAD_PRIO_NONE =__pthread_mutex_protocol.__PTHREAD_PRIO_NONE, + PTHREAD_PRIO_INHERIT =__pthread_mutex_protocol.__PTHREAD_PRIO_INHERIT, + PTHREAD_PRIO_PROTECT =__pthread_mutex_protocol.__PTHREAD_PRIO_PROTECT, + } + + int pthread_mutex_getprioceiling(const scope pthread_mutex_t*, int*); + int pthread_mutex_setprioceiling(pthread_mutex_t*, int, int*); + int pthread_mutexattr_getprioceiling(const scope pthread_mutexattr_t*, int*); + int pthread_mutexattr_getprotocol(const scope pthread_mutexattr_t*, int*); + int pthread_mutexattr_setprioceiling(pthread_mutexattr_t*, int); + int pthread_mutexattr_setprotocol(pthread_mutexattr_t*, int); +} // // Scheduling (TPS) @@ -1421,11 +1554,22 @@ int pthread_setschedprio(pthread_t, int); version (CRuntime_Glibc) { + version (linux) + { enum { PTHREAD_SCOPE_SYSTEM, PTHREAD_SCOPE_PROCESS } + } + else version (Hurd) + { + enum + { + PTHREAD_SCOPE_SYSTEM = __pthread_contentionscope.__PTHREAD_SCOPE_SYSTEM, + PTHREAD_SCOPE_PROCESS = __pthread_contentionscope.__PTHREAD_SCOPE_PROCESS, + } + } int pthread_attr_getinheritsched(const scope pthread_attr_t*, int*); int pthread_attr_getschedpolicy(const scope pthread_attr_t*, int*); diff --git a/druntime/src/core/sys/posix/sched.d b/druntime/src/core/sys/posix/sched.d index d579835841..8b0ccea877 100644 --- a/druntime/src/core/sys/posix/sched.d +++ b/druntime/src/core/sys/posix/sched.d @@ -169,6 +169,17 @@ else version (Solaris) enum SCHED_FX = 6; enum _SCHED_NEXT = 7; } +else version (Hurd) +{ + struct sched_param + { + int sched_priority; + } + + enum SCHED_FIFO = 1; + enum SCHED_OTHER = 0; + enum SCHED_RR = 2; +} else { static assert(false, "Unsupported platform"); diff --git a/druntime/src/core/sys/posix/signal.d b/druntime/src/core/sys/posix/signal.d index bdc68687d0..d7971a944a 100644 --- a/druntime/src/core/sys/posix/signal.d +++ b/druntime/src/core/sys/posix/signal.d @@ -168,6 +168,31 @@ else version (NetBSD) enum SIGRTMIN = 33; enum SIGRTMAX = 63; } +else version (Hurd) +{ + // This exists but always return 32 + // private extern (C) nothrow @nogc + // { + // int __libc_current_sigrtmin(); + // int __libc_current_sigrtmax(); + // } + + // @property int SIGRTMIN()() nothrow @nogc { + // __gshared int sig = -1; + // if (sig == -1) { + // sig = __libc_current_sigrtmin(); + // } + // return sig; + // } + + // @property int SIGRTMAX()() nothrow @nogc { + // __gshared int sig = -1; + // if (sig == -1) { + // sig = __libc_current_sigrtmax(); + // } + // return sig; + // } +} else version (linux) { // Note: CRuntime_Bionic switched to calling these functions @@ -561,6 +586,24 @@ else version (Solaris) enum SIGUSR2 = 17; enum SIGURG = 21; } +else version (Hurd) +{ + enum SIGALRM = 14; + enum SIGBUS = 10; + enum SIGCHLD = 20; + enum SIGCONT = 19; + enum SIGHUP = 1; + enum SIGKILL = 9; + enum SIGPIPE = 13; + enum SIGQUIT = 3; + enum SIGSTOP = 17; + enum SIGTSTP = 18; + enum SIGTTIN = 21; + enum SIGTTOU = 22; + enum SIGUSR1 = 30; + enum SIGUSR2 = 31; + enum SIGURG = 16; +} else { static assert(false, "Unsupported platform"); @@ -848,6 +891,26 @@ else version (Darwin) int sa_flags; } } +else version (Hurd) +{ + struct sigaction_t + { + static if ( true /* __USE_POSIX199309 */ ) + { + union + { + sigfn_t sa_handler; + sigactfn_t sa_sigaction; + } + } + else + { + sigfn_t sa_handler; + } + sigset_t sa_mask; + int sa_flags; + } +} else { static assert(false, "Unsupported platform"); @@ -1417,6 +1480,41 @@ else version (Solaris) enum SI_ASYNCIO = -4; enum SI_MESGQ = -5; } +else version(Hurd) +{ + enum SIG_HOLD = cast(sigfn_t2) 2; + + alias sigset_t = uint; + + enum SA_NOCLDSTOP = 0x0008; // (CX|XSI) + + enum SIG_BLOCK = 1; + enum SIG_UNBLOCK = 2; + enum SIG_SETMASK = 3; + + struct siginfo_t + { + int si_signo; + int si_errno; + int si_code; + + pid_t si_pid; + uid_t si_uid; + void* si_addr; + int si_status; + c_long si_band; + sigval si_value; + } + + enum + { + SI_ASYNCIO = -4, + SI_MESGQ, + SI_TIMER, + SI_QUEUE, + SI_USER + } +} else { static assert(false, "Unsupported platform"); @@ -2375,6 +2473,89 @@ else version (Solaris) POLL_HUP, } } +else version(Hurd) +{ + enum SIGPOLL = 23; + enum SIGPROF = 27; + enum SIGSYS = 12; + enum SIGTRAP = 5; + enum SIGVTALRM = 26; + enum SIGXCPU = 24; + enum SIGXFSZ = 25; + + enum + { + SA_ONSTACK = 0x0001, + SA_RESETHAND = 0x0004, + SA_RESTART = 0x0002, + SA_SIGINFO = 0x0040, + // SA_NOCLDWAIT = , + SA_NODEFER = 0x00010, + } + + enum + { + ILL_ILLOPC = 1, + ILL_ILLOPN, + ILL_ILLADR, + ILL_ILLTRP, + ILL_PRVOPC, + ILL_PRVREG, + ILL_COPROC, + ILL_BADSTK + } + + enum + { + FPE_INTDIV = 1, + FPE_INTOVF, + FPE_FLTDIV, + FPE_FLTOVF, + FPE_FLTUND, + FPE_FLTRES, + FPE_FLTINV, + FPE_FLTSUB + } + + enum + { + SEGV_MAPERR = 1, + SEGV_ACCERR + } + + enum + { + BUS_ADRALN = 1, + BUS_ADRERR, + BUS_OBJERR + } + + enum + { + TRAP_BRKPT = 1, + TRAP_TRACE + } + + enum + { + CLD_EXITED = 1, + CLD_KILLED, + CLD_DUMPED, + CLD_TRAPPED, + CLD_STOPPED, + CLD_CONTINUED + } + + enum + { + POLL_IN = 1, + POLL_OUT, + POLL_MSG, + POLL_ERR, + POLL_PRI, + POLL_HUP + } +} else { static assert(false, "Unsupported platform"); @@ -2416,11 +2597,21 @@ int sigrelse(int); version (CRuntime_Glibc) { + version (linux) + { enum SS_ONSTACK = 1; enum SS_DISABLE = 2; enum MINSIGSTKSZ = 2048; enum SIGSTKSZ = 8192; + } + version (Hurd) + { + enum SS_ONSTACK = 0x0001; + enum SS_DISABLE = 0x0004; + enum MINSIGSTKSZ = 8192; + enum SIGSTKSZ = (MINSIGSTKSZ + 32768); + } //ucontext_t (defined in core.sys.posix.ucontext) //mcontext_t (defined in core.sys.posix.ucontext) @@ -2990,6 +3181,18 @@ else version (Solaris) int __sigev_pad2; } } +else version (Hurd) +{ + struct sigevent + { + sigval sigev_value; + int sigev_signo; + int sigev_notify; + + void function(sigval) sigev_notify_function; + void* sigev_notify_attributes; + } +} else { static assert(false, "Unsupported platform"); diff --git a/druntime/src/core/sys/posix/spawn.d b/druntime/src/core/sys/posix/spawn.d index 081270b42c..7b8473aa27 100644 --- a/druntime/src/core/sys/posix/spawn.d +++ b/druntime/src/core/sys/posix/spawn.d @@ -34,6 +34,8 @@ OpenBSD: https://github.com/openbsd/src/blob/master/include/spawn.h DragonFlyBSD: https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/include/spawn.h Solaris: https://github.com/illumos/illumos-gate/blob/master/usr/src/head/spawn.h + +Hurd: https://sourceware.org/git/?p=glibc.git;a=blob;f=posix/spawn.h;hb=HEAD */ version (OSX) // macOS and iOS only as this API is prohibited on WatchOS and TVOS @@ -370,5 +372,45 @@ else version (Solaris) int posix_spawnattr_setsigignore_np(posix_spawnattr_t* attr, const sigset_t* sigignore); } } +else version (Hurd) +{ + // Source: https://sourceware.org/git/?p=glibc.git;a=blob;f=posix/spawn.h;hb=HEAD + enum + { + POSIX_SPAWN_RESETIDS = 0x01, + POSIX_SPAWN_SETPGROUP = 0x02, + POSIX_SPAWN_SETSIGDEF = 0x04, + POSIX_SPAWN_SETSIGMASK = 0x08, + POSIX_SPAWN_SETSCHEDPARAM = 0x10, + POSIX_SPAWN_SETSCHEDULER = 0x20 + } + import core.sys.posix.config : _GNU_SOURCE; + static if (_GNU_SOURCE) + { + enum + { + POSIX_SPAWN_USEVFORK = 0x40, + POSIX_SPAWN_SETSID = 0x80 + } + } + struct posix_spawnattr_t + { + short __flags; + pid_t __pgrp; + sigset_t __sd; + sigset_t __ss; + sched_param __sp; + int __policy; + int[16] __pad; + } + struct __spawn_action; + struct posix_spawn_file_actions_t + { + int __allocated; + int __used; + __spawn_action* __actions; + int[16] __pad; + } +} else static assert(0, "Unsupported OS"); diff --git a/druntime/src/core/sys/posix/sys/ioctl.d b/druntime/src/core/sys/posix/sys/ioctl.d index 27584d357c..f1828b61c1 100644 --- a/druntime/src/core/sys/posix/sys/ioctl.d +++ b/druntime/src/core/sys/posix/sys/ioctl.d @@ -400,6 +400,10 @@ else version (DragonFlyBSD) else version (Solaris) { } +else version (Hurd) +{ + // What is needed here? +} else { static assert(false, "Unsupported platform"); diff --git a/druntime/src/core/sys/posix/sys/ipc.d b/druntime/src/core/sys/posix/sys/ipc.d index 32caba95a1..cf889e048a 100644 --- a/druntime/src/core/sys/posix/sys/ipc.d +++ b/druntime/src/core/sys/posix/sys/ipc.d @@ -246,6 +246,33 @@ else version (Solaris) enum IPC_SET = 11; enum IPC_STAT = 12; } +else version (Hurd) +{ + struct ipc_perm + { + key_t __key; + uid_t uid; + gid_t gid; + uid_t cuid; + gid_t cgid; + ushort mode; + ushort __pad1; + ushort __seq; + ushort __pad2; + c_ulong __unused1; + c_ulong __unused2; + } + + enum IPC_CREAT = 0x0200; // 01000 + enum IPC_EXCL = 0x0400; // 02000 + enum IPC_NOWAIT = 0x0800; // 04000 + + enum key_t IPC_PRIVATE = 0; + + enum IPC_RMID = 0; + enum IPC_SET = 1; + enum IPC_STAT = 2; +} else { static assert(false, "Unsupported platform"); diff --git a/druntime/src/core/sys/posix/sys/mman.d b/druntime/src/core/sys/posix/sys/mman.d index 42da553c40..538588dd3f 100644 --- a/druntime/src/core/sys/posix/sys/mman.d +++ b/druntime/src/core/sys/posix/sys/mman.d @@ -170,6 +170,14 @@ else version (DragonFlyBSD) else version (Solaris) { } +else version (Hurd) +{ + enum POSIX_MADV_NORMAL = 0; + enum POSIX_MADV_RANDOM = 1; + enum POSIX_MADV_SEQUENTIAL = 2; + enum POSIX_MADV_WILLNEED = 3; + enum POSIX_MADV_DONTNEED = 4; +} else { static assert(false, "Unsupported platform"); @@ -234,6 +242,13 @@ else version (Solaris) enum PROT_WRITE = 0x02; enum PROT_EXEC = 0x04; } +else version (Hurd) +{ + enum PROT_NONE = 0x00; + enum PROT_READ = 0x04; + enum PROT_WRITE = 0x02; + enum PROT_EXEC = 0x01; +} else { static assert(false, "Unsupported platform"); @@ -474,6 +489,19 @@ else version (Solaris) enum MS_SYNC = 0x0004; enum MS_ASYNC = 0x0001; enum MS_INVALIDATE = 0x0002; +} + else version (Hurd) +{ + enum MAP_SHARED = 0x0010; + enum MAP_PRIVATE = 0x0000; + enum MAP_FIXED = 0x0100; + enum MAP_ANON = 0x0002; + + enum MAP_FAILED = cast(void*)-1; + + enum MS_ASYNC = 1; + enum MS_INVALIDATE = 0; + enum MS_SYNC = 2; } else { @@ -591,6 +619,11 @@ else version (Solaris) enum MCL_CURRENT = 0x0001; enum MCL_FUTURE = 0x0002; } +else version (Hurd) +{ + enum MCL_CURRENT = 0x0001; + enum MCL_FUTURE = 0x0002; +} else { static assert(false, "Unsupported platform"); diff --git a/druntime/src/core/sys/posix/sys/resource.d b/druntime/src/core/sys/posix/sys/resource.d index b75c794e92..6a31af41d0 100644 --- a/druntime/src/core/sys/posix/sys/resource.d +++ b/druntime/src/core/sys/posix/sys/resource.d @@ -477,6 +477,84 @@ else version (Solaris) RLIMIT_AS = 6, } } +else version (Hurd) +{ + enum + { + PRIO_PROCESS = 0, + PRIO_PGRP = 1, + PRIO_USER = 2, + } + + static if (__USE_FILE_OFFSET64) + alias ulong rlim_t; + else + alias c_ulong rlim_t; + + static if (__USE_FILE_OFFSET64) + enum RLIM_INFINITY = 0xffffffffffffffffUL; + else + enum RLIM_INFINITY = cast(c_ulong)(~0UL); + + enum RLIM_SAVED_MAX = RLIM_INFINITY; + enum RLIM_SAVED_CUR = RLIM_INFINITY; + + enum + { + RUSAGE_SELF = 0, + RUSAGE_CHILDREN = -1, + RUSAGE_THREAD = 1 + } + + struct rusage + { + timeval ru_utime; + timeval ru_stime; + c_long ru_maxrss; + c_long ru_ixrss; + c_long ru_idrss; + c_long ru_isrss; + c_long ru_minflt; + c_long ru_majflt; + c_long ru_nswap; + c_long ru_inblock; + c_long ru_oublock; + c_long ru_msgsnd; + c_long ru_msgrcv; + c_long ru_nsignals; + c_long ru_nvcsw; + c_long ru_nivcsw; + version (CRuntime_Musl) + c_long[16] __reserved; + } + + version (MIPS_Any) + { + enum + { + RLIMIT_CORE = 4, + RLIMIT_CPU = 0, + RLIMIT_DATA = 2, + RLIMIT_FSIZE = 1, + RLIMIT_NOFILE = 5, + RLIMIT_STACK = 3, + RLIMIT_AS = 6, + } + } + else + { + enum + { + RLIMIT_CORE = 4, + RLIMIT_CPU = 0, + RLIMIT_DATA = 2, + RLIMIT_FSIZE = 1, + RLIMIT_NOFILE = 7, + RLIMIT_STACK = 3, + RLIMIT_AS = 9, + } + } +} else static assert (false, "Unsupported platform"); diff --git a/druntime/src/core/sys/posix/sys/shm.d b/druntime/src/core/sys/posix/sys/shm.d index 7481d8cc60..181dc65904 100644 --- a/druntime/src/core/sys/posix/sys/shm.d +++ b/druntime/src/core/sys/posix/sys/shm.d @@ -180,6 +180,26 @@ else version (Darwin) else version (Solaris) { +} +else version (Hurd) +{ + enum SHM_RDONLY = 0x01000; // 010000 + enum SHM_RND = 0x02000; // 020000 + enum SHM_REMAP = 0x4000; // 040000 + + alias short shmatt_t; + + struct shmid_ds + { + ipc_perm shm_perm; + size_t shm_segsz; + time_t shm_atime; + time_t shm_dtime; + time_t shm_ctime; + pid_t shm_cpid; + pid_t shm_lpid; + shmatt_t shm_nattch; + } } else { diff --git a/druntime/src/core/sys/posix/sys/socket.d b/druntime/src/core/sys/posix/sys/socket.d index 5bdc22294c..defe356369 100644 --- a/druntime/src/core/sys/posix/sys/socket.d +++ b/druntime/src/core/sys/posix/sys/socket.d @@ -1597,6 +1597,151 @@ else version (Solaris) SHUT_WR, SHUT_RDWR } +} + else version (Hurd) +{ + alias uint socklen_t; + alias ushort sa_family_t; + + struct sockaddr + { + sa_family_t sa_family; + byte[14] sa_data; + } + + private enum : size_t + { + _SS_SIZE = 128, + _SS_PADSIZE = _SS_SIZE - c_ulong.sizeof - sa_family_t.sizeof + } + + struct sockaddr_storage + { + sa_family_t ss_family; + byte[_SS_PADSIZE] __ss_padding; + c_ulong __ss_align; + } + struct msghdr + { + void* msg_name; + socklen_t msg_namelen; + iovec* msg_iov; + size_t msg_iovlen; + void* msg_control; + socklen_t msg_controllen; + int msg_flags; + } + + struct cmsghdr + { + socklen_t cmsg_len; + int cmsg_level; + int cmsg_type; + } + enum : uint + { + SCM_RIGHTS = 0x01 + } + + extern (D) inout(ubyte)* CMSG_DATA( return scope inout(cmsghdr)* cmsg ) pure nothrow @nogc { return cast(ubyte*)( cmsg + 1 ); } + private inout(cmsghdr)* __cmsg_nxthdr(inout(msghdr)*, inout(cmsghdr)*) pure nothrow @nogc; + extern (D) inout(cmsghdr)* CMSG_NXTHDR(inout(msghdr)* msg, inout(cmsghdr)* cmsg) pure nothrow @nogc + { + return __cmsg_nxthdr(msg, cmsg); + } + + extern (D) inout(cmsghdr)* CMSG_FIRSTHDR( inout(msghdr)* mhdr ) pure nothrow @nogc + { + return ( cast(size_t)mhdr.msg_controllen >= cmsghdr.sizeof + ? cast(inout(cmsghdr)*) mhdr.msg_control + : cast(inout(cmsghdr)*) null ); + } + + extern (D) + { + size_t CMSG_ALIGN( size_t len ) pure nothrow @nogc + { + return (len + size_t.sizeof - 1) & cast(size_t) (~(size_t.sizeof - 1)); + } + + size_t CMSG_LEN( size_t len ) pure nothrow @nogc + { + return CMSG_ALIGN(cmsghdr.sizeof) + len; + } + } + + extern (D) size_t CMSG_SPACE(size_t len) pure nothrow @nogc + { + return CMSG_ALIGN(len) + CMSG_ALIGN(cmsghdr.sizeof); + } + struct linger + { + int l_onoff; + int l_linger; + } + + enum + { + SOCK_DGRAM = 2, + SOCK_RDM = 4, + SOCK_SEQPACKET = 5, + SOCK_STREAM = 1, + } + enum + { + SOL_SOCKET = 0xffff + } + enum + { + SO_ACCEPTCONN = 0x0002, + SO_BROADCAST = 0x0020, + SO_DEBUG = 0x0001, + SO_DONTROUTE = 0x0010, + SO_ERROR = 0x1007, + SO_KEEPALIVE = 0x0008, + SO_LINGER = 0x0080, + SO_OOBINLINE = 0x0100, + SO_RCVBUF = 0x1002, + SO_RCVLOWAT = 0x1004, + SO_RCVTIMEO = 0x1006, + SO_REUSEADDR = 0x0004, + SO_REUSEPORT = 0x0200, + SO_SNDBUF = 0x1002, + SO_SNDLOWAT = 0x1003, + SO_SNDTIMEO = 0x1005, + SO_TYPE = 0x1008 + } + enum + { + SOMAXCONN = 128 + } + enum : uint + { + MSG_CTRUNC = 0x20, + MSG_DONTROUTE = 0x04, + MSG_EOR = 0x08, + MSG_OOB = 0x01, + MSG_PEEK = 0x02, + MSG_TRUNC = 0x10, + MSG_WAITALL = 0x40, + MSG_NOSIGNAL = 0x0400 + } + + enum + { + AF_INET = 2, + AF_LOCAL = 1, + AF_UNIX = AF_LOCAL, + AF_UNSPEC = 0, + AF_APPLETALK = 16, + AF_IPX = 23 + } + enum + { + SHUT_RD = 0, + SHUT_WR = 1, + SHUT_RDWR = 2 + } } else { @@ -1899,6 +2044,13 @@ else version (Solaris) AF_INET6 = 26, } } +else version (Hurd) +{ + enum + { + AF_INET6 = 26, + } +} else { static assert(false, "Unsupported platform"); @@ -1960,6 +2112,13 @@ else version (Solaris) SOCK_RAW = 4, } } +else version (Hurd) +{ + enum + { + SOCK_RAW = 3, + } +} else { static assert(false, "Unsupported platform"); diff --git a/druntime/src/core/sys/posix/sys/stat.d b/druntime/src/core/sys/posix/sys/stat.d index 762d6fcc76..97bb3ded12 100644 --- a/druntime/src/core/sys/posix/sys/stat.d +++ b/druntime/src/core/sys/posix/sys/stat.d @@ -1538,6 +1538,64 @@ else version (Solaris) enum S_ISGID = 0x400; enum S_ISVTX = 0x200; } +else version (Hurd) +{ + private alias fsid_t = ulong; + static assert (fsid_t.sizeof != int.sizeof); + static if (__USE_FILE_OFFSET64) + private enum SPARE_SIZE = 8; + else + private enum SPARE_SIZE = 11; + + struct stat_t { + int st_fstype; /* File system type. */ + fsid_t st_fsid; /* File system ID. */ + alias st_dev = st_fsid; + ino_t st_ino; /* File number. */ + uint st_gen; + dev_t st_rdev; + mode_t st_mode; + nlink_t st_nlink; + uid_t st_uid; + gid_t st_gid; + off_t st_size; + + static if (_DEFAULT_SOURCE || _XOPEN_SOURCE >= 700) + { + timespec st_atim; + timespec st_mtim; + timespec st_ctim; + extern(D) @safe @property inout pure nothrow + { + ref inout(time_t) st_atime() return { return st_atim.tv_sec; } + ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; } + ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } + } + } + else + { + time_t st_atime; + c_ulong st_atimensec; + time_t st_mtime; + c_ulong st_mtimensec; + time_t st_ctime; + c_ulong st_ctimensec; + } + + blksize_t st_blksize; + blkcnt_t st_blocks; + + uid_t st_author; + uint st_flags; + int[SPARE_SIZE] st_spare; + } + version (X86) static assert(stat_t.sizeof == 128); + version (X86_64) static assert(stat_t.sizeof == 176); + + enum S_ISUID = 0x800; // octal 0004000 + enum S_ISGID = 0x400; // octal 0002000 + enum S_ISVTX = 0x200; // octal 0001000 +} else { static assert(false, "Unsupported platform"); @@ -2207,6 +2265,11 @@ else version (Solaris) enum UTIME_NOW = -1; enum UTIME_OMIT = -2; } +else version (Hurd) +{ + enum UTIME_NOW = -1; + enum UTIME_OMIT = -2; +} else { static assert(false, "Unsupported platform"); @@ -2313,6 +2376,17 @@ else version (Solaris) enum S_IFDOOR = 0xD000; enum S_IFPORT = 0xE000; } +else version (Hurd) +{ + enum S_IFMT = 0xF000; // octal 0170000 + enum S_IFBLK = 0x6000; // octal 0060000 + enum S_IFCHR = 0x2000; // octal 0020000 + enum S_IFIFO = 0x1000; // octal 0010000 + enum S_IFREG = 0x8000; // octal 0100000 + enum S_IFDIR = 0x4000; // octal 0040000 + enum S_IFLNK = 0xA000; // octal 0120000 + enum S_IFSOCK = 0xC000; // octal 0140000 +} else { static assert(false, "Unsupported platform"); diff --git a/druntime/src/core/sys/posix/sys/types.d b/druntime/src/core/sys/posix/sys/types.d index 859c4ea0d2..d333d7c137 100644 --- a/druntime/src/core/sys/posix/sys/types.d +++ b/druntime/src/core/sys/posix/sys/types.d @@ -293,6 +293,32 @@ else version (Solaris) alias c_long time_t; alias uint uid_t; } +else version (Hurd) +{ + static if ( __USE_FILE_OFFSET64 ) + { + alias long blkcnt_t; + alias ulong ino_t; + alias long off_t; + } + else + { + alias slong_t blkcnt_t; + alias ulong_t ino_t; + alias slong_t off_t; + } + alias slong_t blksize_t; + alias ulong_t dev_t; + alias uint gid_t; + alias uint mode_t; + alias ulong_t nlink_t; + alias int pid_t; + //size_t (defined in core.stdc.stddef) + alias c_long ssize_t; + alias uint uid_t; + + alias slong_t time_t; +} else { static assert(false, "Unsupported platform"); @@ -404,6 +430,24 @@ else version (Solaris) alias id_t zoneid_t; alias id_t ctid_t; } +else version (Hurd) +{ + static if ( __USE_FILE_OFFSET64 ) + { + alias ulong fsblkcnt_t; + alias ulong fsfilcnt_t; + } + else + { + alias ulong_t fsblkcnt_t; + alias ulong_t fsfilcnt_t; + } + alias slong_t clock_t; + alias uint id_t; + alias int key_t; + alias slong_t suseconds_t; + alias uint useconds_t; +} else { static assert(false, "Unsupported platform"); @@ -427,6 +471,90 @@ pthread_t version (CRuntime_Glibc) { + version (Hurd) + { + import core.sys.hurd.sys.types; + import core.sys.posix.time: clockid_t; + + struct pthread_attr_t + { + __sched_param schedparam; + void* stackaddr; + size_t __stacksize; + size_t __guardsize; + __pthread_detachstate __detachstate; + __pthread_inheritsched __inheritsched; + __pthread_contentionscope __contentionscope; + int __schedpolicy; + } + + struct pthread_cond_t + { + pthread_spinlock_t __lock; + __pthread *__queue; + pthread_condattr_t *__attr; + uint __wrefs; + void *__data; + } + + struct pthread_condattr_t + { + __pthread_process_shared __pshared; + clockid_t __clock; + } + + alias int pthread_key_t; + + struct pthread_mutex_t + { + uint __lock; + uint __owner_id; + uint __cnt; + int __shpid; + int __type; + int __flags; + union + { + uint[2] __reserved; + void *__pointer_aligned; + } + } + + struct pthread_mutexattr_t + { + int __prioceiling; + __pthread_mutex_protocol __protocol; + __pthread_process_shared __pshared; + __pthread_mutex_type __mutex_type; + } + + struct pthread_once_t + { + int __run; + pthread_spinlock_t __lock; + } + + struct pthread_rwlock_t + { + pthread_spinlock_t __held; + pthread_spinlock_t __lock; + int __readers; + __pthread *__readerqueue; + __pthread *__writerqueue; + pthread_rwlockattr_t *__attr; + void *__data; + } + + struct pthread_rwlockattr_t + { + __pthread_process_shared __pshared; + } + + alias c_long pthread_t; + + } + else version (linux) + { version (X86) { enum __SIZEOF_PTHREAD_ATTR_T = 36; @@ -708,6 +836,7 @@ version (CRuntime_Glibc) } alias c_ulong pthread_t; + } } else version (CRuntime_Musl) { @@ -1315,6 +1444,8 @@ pthread_barrierattr_t version (CRuntime_Glibc) { + version (linux) + { struct pthread_barrier_t { byte[__SIZEOF_PTHREAD_BARRIER_T] __size; @@ -1326,6 +1457,24 @@ version (CRuntime_Glibc) byte[__SIZEOF_PTHREAD_BARRIERATTR_T] __size; int __align; } + } + else version (Hurd) + { + struct pthread_barrier_t + { + pthread_spinlock_t __lock; + __pthread *__queue; + uint __pending; + uint __count; + pthread_barrierattr_t *__attr; + void *__data; + } + + struct pthread_barrierattr_t + { + __pthread_process_shared __pshared; + } + } } else version (FreeBSD) { @@ -1352,6 +1501,8 @@ else version (Darwin) } else version (Solaris) { + version (linux) + { struct pthread_barrier_t { uint __pthread_barrier_count; @@ -1366,6 +1517,24 @@ else version (Solaris) { void* __pthread_barrierattrp; } + } + else version (Hurd) + { + struct pthread_barrier_t + { + pthread_spinlock_t __lock; + __pthread *__queue; + uint __pending; + uint __count; + pthread_barrierattr_t *__attr; + void *__data; + } + + struct pthread_barrierattr_t + { + __pthread_process_shared __pshared; + } + } } else version (CRuntime_Bionic) { diff --git a/druntime/src/core/sys/posix/sys/un.d b/druntime/src/core/sys/posix/sys/un.d index 11e98a72ab..6103ad578e 100644 --- a/druntime/src/core/sys/posix/sys/un.d +++ b/druntime/src/core/sys/posix/sys/un.d @@ -104,3 +104,11 @@ else version (Solaris) byte[108] sun_path; } } +else version (Hurd) +{ + struct sockaddr_un + { + sa_family_t sun_family; + byte[108] sun_path; + } +} diff --git a/druntime/src/core/sys/posix/sys/wait.d b/druntime/src/core/sys/posix/sys/wait.d index 131a9400dc..91fe9020a1 100644 --- a/druntime/src/core/sys/posix/sys/wait.d +++ b/druntime/src/core/sys/posix/sys/wait.d @@ -106,6 +106,15 @@ else version (Solaris) enum WNOHANG = 64; enum WUNTRACED = 4; } +else version (Hurd) +{ + enum WNOHANG = 1; + enum WUNTRACED = 2; + private + { + enum __W_CONTINUED = 0xFFFF; + } +} else { static assert(false, "Unsupported platform"); @@ -430,6 +439,20 @@ else version (Solaris) P_CPUID, /* CPU identifier. */ P_PSETID, /* Processor set identifier */ } +} + else version (Hurd) +{ + enum WEXITED = 16; + enum WSTOPPED = WUNTRACED; + enum WCONTINUED = 4; + enum WNOWAIT = 8; + + enum idtype_t + { + P_ALL, + P_PID, + P_PGID + } } else { diff --git a/druntime/src/core/sys/posix/termios.d b/druntime/src/core/sys/posix/termios.d index e4a99e6865..b0141cea79 100644 --- a/druntime/src/core/sys/posix/termios.d +++ b/druntime/src/core/sys/posix/termios.d @@ -831,6 +831,104 @@ else version (Solaris) enum B460800 = 22; enum B921600 = 23; } + else version (Hurd) +{ + alias ubyte cc_t; + alias uint speed_t; + alias uint tcflag_t; + + enum NCCS = 32; + + struct termios + { + tcflag_t c_iflag; + tcflag_t c_oflag; + tcflag_t c_cflag; + tcflag_t c_lflag; + cc_t c_line; + cc_t[NCCS] c_cc; + speed_t c_ispeed; + speed_t c_ospeed; + } + + enum VEOF = 4; + enum VEOL = 11; + enum VERASE = 2; + enum VINTR = 0; + enum VKILL = 3; + enum VMIN = 6; + enum VQUIT = 1; + enum VSTART = 8; + enum VSTOP = 9; + enum VSUSP = 10; + enum VTIME = 5; + + enum BRKINT = 0x0000002; // 0000002 + enum ICRNL = 0x0000100; // 0000400 + enum IGNBRK = 0x0000001; // 0000001 + enum IGNCR = 0x0000080; // 0000200 + enum IGNPAR = 0x0000004; // 0000004 + enum INLCR = 0x0000040; // 0000100 + enum INPCK = 0x0000010; // 0000020 + enum ISTRIP = 0x0000020; // 0000040 + enum IXOFF = 0x0001000; // 0010000 + enum IXON = 0x0000400; // 0002000 + enum PARMRK = 0x0000008; // 0000010 + + enum OPOST = 0x0000001; // 0000001 + + enum B0 = 0x0000000; // 0000000 + enum B50 = 0x0000001; // 0000001 + enum B75 = 0x0000002; // 0000002 + enum B110 = 0x0000003; // 0000003 + enum B134 = 0x0000004; // 0000004 + enum B150 = 0x0000005; // 0000005 + enum B200 = 0x0000006; // 0000006 + enum B300 = 0x0000007; // 0000007 + enum B600 = 0x0000008; // 0000010 + enum B1200 = 0x0000009; // 0000011 + enum B1800 = 0x000000A; // 0000012 + enum B2400 = 0x000000B; // 0000013 + enum B4800 = 0x000000C; // 0000014 + enum B9600 = 0x000000D; // 0000015 + enum B19200 = 0x000000E; // 0000016 + enum B38400 = 0x000000F; // 0000017 + + enum CSIZE = 0x0000030; // 0000060 + enum CS5 = 0x0000000; // 0000000 + enum CS6 = 0x0000010; // 0000020 + enum CS7 = 0x0000020; // 0000040 + enum CS8 = 0x0000030; // 0000060 + enum CSTOPB = 0x0000040; // 0000100 + enum CREAD = 0x0000080; // 0000200 + enum PARENB = 0x0000100; // 0000400 + enum PARODD = 0x0000200; // 0001000 + enum HUPCL = 0x0000400; // 0002000 + enum CLOCAL = 0x0000800; // 0004000 + + enum ECHO = 0x0000008; // 0000010 + enum ECHOE = 0x0000010; // 0000020 + enum ECHOK = 0x0000020; // 0000040 + enum ECHONL = 0x0000040; // 0000100 + enum ICANON = 0x0000002; // 0000002 + enum IEXTEN = 0x0008000; // 0100000 + enum ISIG = 0x0000001; // 0000001 + enum NOFLSH = 0x0000080; // 0000200 + enum TOSTOP = 0x0000100; // 0000400 + + enum TCSANOW = 0; + enum TCSADRAIN = 1; + enum TCSAFLUSH = 2; + + enum TCIFLUSH = 0; + enum TCOFLUSH = 1; + enum TCIOFLUSH = 2; + + enum TCIOFF = 2; + enum TCION = 3; + enum TCOOFF = 0; + enum TCOON = 1; +} /* speed_t cfgetispeed(const scope termios*); diff --git a/druntime/src/core/sys/posix/time.d b/druntime/src/core/sys/posix/time.d index fdd6b0a888..37234579ba 100644 --- a/druntime/src/core/sys/posix/time.d +++ b/druntime/src/core/sys/posix/time.d @@ -156,6 +156,10 @@ else version (Solaris) { enum CLOCK_MONOTONIC = 4; } +else version (Hurd) +{ + enum CLOCK_MONOTONIC = 1; +} else { static assert(0); @@ -259,6 +263,14 @@ else version (Solaris) alias timespec timestruc_t; } +else version (Hurd) +{ + struct timespec + { + time_t tv_sec; + c_long tv_nsec; + } +} else { static assert(false, "Unsupported platform"); diff --git a/druntime/src/core/thread/fiber/switch_context_asm.S b/druntime/src/core/thread/fiber/switch_context_asm.S index cef64f65f0..ca44874262 100644 --- a/druntime/src/core/thread/fiber/switch_context_asm.S +++ b/druntime/src/core/thread/fiber/switch_context_asm.S @@ -13,7 +13,7 @@ * http://www.boost.org/LICENSE_1_0.txt) */ -#if (__linux__ || __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __DragonFly__) && __ELF__ +#if (__linux__ || __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __DragonFly__ | __GNU__) && __ELF__ /* * Mark the resulting object file as not requiring execution permissions on * stack memory. The absence of this section would mark the whole resulting diff --git a/druntime/src/core/thread/osthread.d b/druntime/src/core/thread/osthread.d index ff82283a83..09942332ee 100644 --- a/druntime/src/core/thread/osthread.d +++ b/druntime/src/core/thread/osthread.d @@ -2252,6 +2252,14 @@ extern (C) void thread_init() @nogc nothrow enum SIGRTMIN = SIGUSR1; enum SIGRTMAX = 32; } + else version (Hurd) + { + // Hurd does not support SIGRTMIN or SIGRTMAX + // Use SIGUSR1 for SIGRTMIN, SIGUSR2 for SIGRTMIN + 1 + // And use 32 for SIGRTMAX (32 is the max signal number on Hurd) + enum SIGRTMIN = SIGUSR1; + enum SIGRTMAX = 32; + } else { import core.sys.posix.signal : SIGRTMAX, SIGRTMIN; diff --git a/druntime/src/core/time.d b/druntime/src/core/time.d index 8189e67f8a..e8c6188682 100644 --- a/druntime/src/core/time.d +++ b/druntime/src/core/time.d @@ -337,6 +337,17 @@ else version (Solaris) enum ClockType second = 6, threadCPUTime = 7, } +else version (Hurd) enum ClockType +{ + normal = 0, + coarse = 2, + precise = 3, + // processCPUTime = 4, + raw = 5, + second = 6, + // threadCPUTime = 7, + +} else { // It needs to be decided (and implemented in an appropriate version branch @@ -436,6 +447,20 @@ version (Posix) case second: assert(0); } } + else version (Hurd) + { + import core.sys.hurd.time; + with(ClockType) final switch (clockType) + { + case coarse: return CLOCK_MONOTONIC_COARSE; + case normal: return CLOCK_MONOTONIC; + case precise: return CLOCK_MONOTONIC; + // case processCPUTime: return CLOCK_PROCESS_CPUTIME_ID; + case raw: return CLOCK_MONOTONIC_RAW; + // case threadCPUTime: return CLOCK_THREAD_CPUTIME_ID; + case second: assert(0); + } + } else // It needs to be decided (and implemented in an appropriate // version branch here) which clock types new platforms are going diff --git a/druntime/src/importc.h b/druntime/src/importc.h index b97d33807b..e93d1b1a7e 100644 --- a/druntime/src/importc.h +++ b/druntime/src/importc.h @@ -172,7 +172,7 @@ typedef unsigned long long __uint64_t; #endif #define _Float16 float -#ifdef __linux__ // Microsoft won't allow the following macro +#if defined(__linux__) || defined(__GNU__) // Microsoft won't allow the following macro // Ubuntu's assert.h uses this #define __PRETTY_FUNCTION__ __func__ @@ -195,7 +195,7 @@ typedef struct {} __SVFloat32_t; typedef struct {} __SVFloat64_t; #endif -#endif // __linux__ +#endif // __linux__ || __GNU__ #if __APPLE__ #undef __SIZEOF_INT128__ diff --git a/druntime/src/rt/sections_elf_shared.d b/druntime/src/rt/sections_elf_shared.d index 2061d3caeb..414a86014f 100644 --- a/druntime/src/rt/sections_elf_shared.d +++ b/druntime/src/rt/sections_elf_shared.d @@ -64,6 +64,12 @@ else version (DragonFlyBSD) import core.sys.dragonflybsd.sys.elf : DT_AUXILIARY, DT_FILTER, DT_NEEDED, DT_STRTAB, PF_W, PF_X, PT_DYNAMIC, PT_LOAD, PT_TLS; import core.sys.dragonflybsd.sys.link_elf : ElfW, link_map; } +else version (Hurd) +{ + import core.sys.hurd.dlfcn : Dl_info, dladdr, dlclose, dlinfo, dlopen, RTLD_DI_LINKMAP, RTLD_LAZY, RTLD_NOLOAD; + import core.sys.hurd.elf : DT_AUXILIARY, DT_FILTER, DT_NEEDED, DT_STRTAB, PF_W, PF_X, PT_DYNAMIC, PT_LOAD, PT_TLS; + import core.sys.hurd.link : ElfW, link_map; +} else { static assert(0, "unimplemented"); @@ -744,6 +750,8 @@ version (Shared) enum relocate = true; else version (DragonFlyBSD) enum relocate = true; + else version (Hurd) + enum relocate = false; else static assert(0, "unimplemented"); -- 2.52.0
