projects/guix·blob python-team · refs

5155 lines · 173.8 KiB

1Upstream-status: https://github.com/dlang/dmd/pull/22829
2
3Backported to 2.113. Should be obsolete with 2.114.
4
5From 4e9294e6d7ce493634e018b6bfb83729cb8bba80 Mon Sep 17 00:00:00 2001
6From: Yelninei <[email protected]>
7Date: Sat, 21 Mar 2026 15:42:32 +0000
8Subject: [PATCH 1/3] dmd: Port to GNU/Hurd.
9
10---
11 compiler/ini/hurd/bin32/dmd.conf | 5 ++
12 compiler/ini/hurd/bin64/dmd.conf | 5 ++
13 compiler/src/build.d | 4 +-
14 compiler/src/dmd/backend/arm/cod1.d | 2 +-
15 compiler/src/dmd/backend/backconfig.d | 46 +++++++++++++++++--
16 compiler/src/dmd/backend/cdef.d | 12 ++++-
17 compiler/src/dmd/backend/elfobj.d | 9 +++-
18 compiler/src/dmd/backend/melf.d | 3 +-
19 compiler/src/dmd/backend/x86/cod1.d | 21 +++++----
20 compiler/src/dmd/backend/x86/cod3.d | 6 +--
21 compiler/src/dmd/cli.d | 12 +++--
22 compiler/src/dmd/dmdparams.d | 2 +
23 compiler/src/dmd/dmsc.d | 1 +
24 compiler/src/dmd/json.d | 2 +
25 compiler/src/dmd/main.d | 2 +-
26 compiler/src/dmd/mars.d | 7 +--
27 compiler/src/dmd/target.d | 41 +++++++++++------
28 compiler/src/dmd/target.h | 5 +-
29 compiler/src/osmodel.mak | 7 ++-
30 compiler/test/compilable/cdcmp.d | 2 +-
31 compiler/test/compilable/test21672.d | 2 +-
32 compiler/test/compilable/test22346.c | 2 +-
33 compiler/test/compilable/test23875.c | 2 +-
34 compiler/test/compilable/test24130.c | 2 +-
35 compiler/test/compilable/vcg-ast.d | 2 +-
36 compiler/test/fail_compilation/fail17105.d | 2 +-
37 compiler/test/fail_compilation/fail18372.d | 2 +-
38 .../test/fail_compilation/fail21227_win.d | 2 +-
39 compiler/test/fail_compilation/fail3753.d | 2 +-
40 compiler/test/fail_compilation/fail6451.d | 2 +-
41 compiler/test/fail_compilation/ice20042.d | 2 +-
42 compiler/test/fail_compilation/ice20264.d | 2 +-
43 compiler/test/fail_compilation/impconv.d | 2 +-
44 compiler/test/fail_compilation/invalid_lib.d | 2 +-
45 compiler/test/fail_compilation/vector_types.d | 2 +-
46 compiler/test/fail_compilation/xmmslice.d | 2 +-
47 compiler/test/run.d | 2 +-
48 compiler/test/runnable/bitfieldsms.c | 2 +-
49 compiler/test/runnable/bitfieldsposix32.c | 2 +-
50 compiler/test/runnable/bitfieldsposix64.c | 2 +-
51 compiler/test/runnable/dbitfieldsdm.d | 2 +-
52 compiler/test/runnable/dbitfieldsms.d | 2 +-
53 compiler/test/runnable/dbitfieldsposix32.d | 2 +-
54 compiler/test/runnable/dbitfieldsposix64.d | 2 +-
55 compiler/test/runnable/dhry.d | 15 ++++++
56 compiler/test/runnable/ice21727.d | 2 +-
57 compiler/test/runnable/test22.d | 30 ++++++++++++
58 compiler/test/runnable/test23343.c | 2 +-
59 compiler/test/runnable/test_cdstrpar.d | 2 +-
60 compiler/test/runnable/testargtypes.d | 2 +-
61 compiler/test/runnable_cxx/cpp_abi_tests.d | 2 +-
62 compiler/test/runnable_cxx/cppa.d | 2 +-
63 compiler/test/runnable_cxx/nonpod_byval.d | 2 +-
64 compiler/test/tools/paths.d | 2 +
65 54 files changed, 220 insertions(+), 83 deletions(-)
66 create mode 100644 compiler/ini/hurd/bin32/dmd.conf
67 create mode 100644 compiler/ini/hurd/bin64/dmd.conf
68
69diff --git a/compiler/ini/hurd/bin32/dmd.conf b/compiler/ini/hurd/bin32/dmd.conf
70new file mode 100644
71index 0000000000..15f03e72fe
72--- /dev/null
73+++ b/compiler/ini/hurd/bin32/dmd.conf
74@@ -0,0 +1,5 @@
75+[Environment32]
76+DFLAGS=-I%@P%/../../src/phobos -I%@P%/../../src/druntime/import -L-L%@P%/../lib32 -L--export-dynamic -fPIC
77+
78+[Environment64]
79+DFLAGS=-I%@P%/../../src/phobos -I%@P%/../../src/druntime/import -L-L%@P%/../lib64 -L--export-dynamic -fPIC
80diff --git a/compiler/ini/hurd/bin64/dmd.conf b/compiler/ini/hurd/bin64/dmd.conf
81new file mode 100644
82index 0000000000..15f03e72fe
83--- /dev/null
84+++ b/compiler/ini/hurd/bin64/dmd.conf
85@@ -0,0 +1,5 @@
86+[Environment32]
87+DFLAGS=-I%@P%/../../src/phobos -I%@P%/../../src/druntime/import -L-L%@P%/../lib32 -L--export-dynamic -fPIC
88+
89+[Environment64]
90+DFLAGS=-I%@P%/../../src/phobos -I%@P%/../../src/druntime/import -L-L%@P%/../lib64 -L--export-dynamic -fPIC
91diff --git a/compiler/src/build.d b/compiler/src/build.d
92index 0dd0aa4b36..bebf0aa004 100755
93--- a/compiler/src/build.d
94+++ b/compiler/src/build.d
95@@ -1689,7 +1689,7 @@ bool download(string to, string from, uint tries = 3)
96 /**
97 Detects the host OS.
98
99-Returns: a string from `{windows, osx,linux,freebsd,openbsd,netbsd,dragonflybsd,solaris}`
100+Returns: a string from `{windows, osx,linux,freebsd,openbsd,netbsd,dragonflybsd,solaris,hurd}`
101 */
102 string detectOS()
103 {
104@@ -1709,6 +1709,8 @@ string detectOS()
105 return "dragonflybsd";
106 else version(Solaris)
107 return "solaris";
108+ else version(Hurd)
109+ return "hurd";
110 else
111 static assert(0, "Unrecognized or unsupported OS.");
112 }
113diff --git a/compiler/src/dmd/backend/arm/cod1.d b/compiler/src/dmd/backend/arm/cod1.d
114index 54711ad6f9..9f96eeabe3 100644
115--- a/compiler/src/dmd/backend/arm/cod1.d
116+++ b/compiler/src/dmd/backend/arm/cod1.d
117@@ -1748,7 +1748,7 @@ void cdfunc(ref CGstate cg, ref CodeBuilder cdb, elem* e, ref regm_t pretregs)
118
119 /* Assume called function accesses TLS statics
120 */
121- if (config.exe & (EX_LINUX | EX_LINUX64 | EX_OSX | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD | EX_OPENBSD64) &&
122+ if (config.exe & (EX_LINUX | EX_LINUX64 | EX_OSX | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD | EX_OPENBSD64 | EX_HURD | EX_HURD64) &&
123 config.flags3 & CFG3pic)
124 cg.accessedTLS = true;
125
126diff --git a/compiler/src/dmd/backend/backconfig.d b/compiler/src/dmd/backend/backconfig.d
127index a848ac4c16..9328a97fcc 100644
128--- a/compiler/src/dmd/backend/backconfig.d
129+++ b/compiler/src/dmd/backend/backconfig.d
130@@ -288,6 +288,42 @@ void out_config_init(
131 cfg.objfmt = OBJ_ELF;
132 cfg.ehmethod = useExceptions ? EHmethod.EH_DWARF : EHmethod.EH_NONE;
133 }
134+ else if (cfg.exe & (EX_HURD | EX_HURD64))
135+ {
136+ cfg.fpxmmregs = true;
137+ cfg.avx = avx;
138+ if (model == 64)
139+ {
140+ cfg.ehmethod = useExceptions ? EHmethod.EH_DWARF : EHmethod.EH_NONE;
141+ }
142+ else
143+ {
144+ cfg.ehmethod = useExceptions ? EHmethod.EH_DWARF : EHmethod.EH_NONE;
145+ if (!exe)
146+ cfg.flags |= CFGromable; // put switch tables in code segment
147+ }
148+ cfg.flags |= CFGnoebp;
149+ switch (pic)
150+ {
151+ case 0: // PIC.fixed
152+ break;
153+
154+ case 1: // PIC.pic
155+ cfg.flags3 |= CFG3pic;
156+ break;
157+
158+ case 2: // PIC.pie
159+ cfg.flags3 |= CFG3pic | CFG3pie;
160+ break;
161+
162+ default:
163+ assert(0);
164+ }
165+ if (symdebug)
166+ cfg.flags |= CFGalwaysframe;
167+
168+ cfg.objfmt = OBJ_ELF;
169+ }
170
171 cfg.flags2 |= CFG2nodeflib; // no default library
172 cfg.flags3 |= CFG3eseqds;
173@@ -320,7 +356,7 @@ static if (0)
174 if (symdebug)
175 {
176 if (cfg.exe & (EX_LINUX | EX_LINUX64 | EX_OPENBSD | EX_OPENBSD64 | EX_FREEBSD | EX_FREEBSD64 | EX_DRAGONFLYBSD64 |
177- EX_SOLARIS | EX_SOLARIS64 | EX_OSX | EX_OSX64))
178+ EX_SOLARIS | EX_SOLARIS64 | EX_OSX | EX_OSX64 | EX_HURD | EX_HURD64))
179 {
180 configv.addlinenumbers = 1;
181 cfg.fulltypes = (symdebug == 1) ? CVDWARF_D : CVDWARF_C;
182@@ -446,7 +482,7 @@ void util_set32(exefmt_t exe)
183 _tysize[TYnullptr] = LONGSIZE;
184 _tysize[TYnptr] = LONGSIZE;
185 _tysize[TYnref] = LONGSIZE;
186-if (exe & (EX_LINUX | EX_LINUX64 | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD | EX_OPENBSD64 | EX_DRAGONFLYBSD64 | EX_SOLARIS | EX_SOLARIS64))
187+if (exe & (EX_LINUX | EX_LINUX64 | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD | EX_OPENBSD64 | EX_DRAGONFLYBSD64 | EX_SOLARIS | EX_SOLARIS64 | EX_HURD | EX_HURD64))
188 {
189 _tysize[TYreal] = 12;
190 _tysize[TYireal] = 12;
191@@ -477,7 +513,7 @@ if (exe & EX_windos)
192 _tyalignsize[TYnullptr] = LONGSIZE;
193 _tyalignsize[TYnref] = LONGSIZE;
194 _tyalignsize[TYnptr] = LONGSIZE;
195-if (exe & (EX_LINUX | EX_LINUX64 | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD | EX_OPENBSD64 | EX_DRAGONFLYBSD64 | EX_SOLARIS | EX_SOLARIS64))
196+if (exe & (EX_LINUX | EX_LINUX64 | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD | EX_OPENBSD64 | EX_DRAGONFLYBSD64 | EX_SOLARIS | EX_SOLARIS64 | EX_HURD | EX_HURD64))
197 {
198 _tyalignsize[TYreal] = 4;
199 _tyalignsize[TYireal] = 4;
200@@ -533,7 +569,7 @@ void util_set64(exefmt_t exe)
201 _tysize[TYnptr] = 8;
202 _tysize[TYnref] = 8;
203 if (exe & (EX_LINUX | EX_LINUX64 | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD |
204- EX_OPENBSD64 | EX_DRAGONFLYBSD64 | EX_SOLARIS | EX_SOLARIS64 | EX_OSX | EX_OSX64))
205+ EX_OPENBSD64 | EX_DRAGONFLYBSD64 | EX_SOLARIS | EX_SOLARIS64 | EX_OSX | EX_OSX64 | EX_HURD | EX_HURD64))
206 {
207 _tysize[TYreal] = 16;
208 _tysize[TYireal] = 16;
209@@ -557,7 +593,7 @@ void util_set64(exefmt_t exe)
210 _tyalignsize[TYnullptr] = 8;
211 _tyalignsize[TYnptr] = 8;
212 _tyalignsize[TYnref] = 8;
213- if (exe & (EX_LINUX | EX_LINUX64 | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD | EX_OPENBSD64 | EX_DRAGONFLYBSD64 | EX_SOLARIS | EX_SOLARIS64))
214+ if (exe & (EX_LINUX | EX_LINUX64 | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD | EX_OPENBSD64 | EX_DRAGONFLYBSD64 | EX_SOLARIS | EX_SOLARIS64 | EX_HURD | EX_HURD64))
215 {
216 _tyalignsize[TYreal] = 16;
217 _tyalignsize[TYireal] = 16;
218diff --git a/compiler/src/dmd/backend/cdef.d b/compiler/src/dmd/backend/cdef.d
219index 836aad2891..903d813458 100644
220--- a/compiler/src/dmd/backend/cdef.d
221+++ b/compiler/src/dmd/backend/cdef.d
222@@ -44,6 +44,7 @@ enum TARGET_OPENBSD = xversion!`OpenBSD`;
223 enum TARGET_SOLARIS = xversion!`Solaris`;
224 enum TARGET_WINDOS = xversion!`Windows`;
225 enum TARGET_DRAGONFLYBSD = xversion!`DragonFlyBSD`;
226+enum TARGET_HURD = xversion!`Hurd`;
227
228 //
229 // Attributes
230@@ -304,6 +305,8 @@ enum
231 EX_OPENBSD = 0x400000,
232 EX_OPENBSD64 = 0x800000,
233 EX_DRAGONFLYBSD64 = 0x1000000,
234+ EX_HURD = 0x2000000,
235+ EX_HURD64 = 0x4000000,
236 }
237
238 // All of them
239@@ -328,7 +331,9 @@ enum exefmt_t EX_all =
240 EX_SOLARIS64 |
241 EX_OPENBSD |
242 EX_OPENBSD64 |
243- EX_DRAGONFLYBSD64;
244+ EX_DRAGONFLYBSD64 |
245+ EX_HURD |
246+ EX_HURD64;
247
248 // All segmented memory models
249 enum exefmt_t EX_segmented = EX_DOSX | EX_ZPM | EX_RATIONAL | EX_PHARLAP |
250@@ -350,6 +355,7 @@ enum exefmt_t EX_posix = EX_LINUX | EX_LINUX64 |
251 EX_FREEBSD | EX_FREEBSD64 |
252 EX_SOLARIS | EX_SOLARIS64 |
253 EX_OPENBSD | EX_OPENBSD64 |
254+ EX_HURD | EX_HURD64 |
255 EX_DRAGONFLYBSD64;
256
257 // All 16 bit targets
258@@ -362,7 +368,8 @@ enum exefmt_t EX_32 = EX_DOSX | EX_OS2 | EX_PHARLAP |
259 EX_OSX |
260 EX_FREEBSD |
261 EX_SOLARIS |
262- EX_OPENBSD;
263+ EX_OPENBSD |
264+ EX_HURD;
265
266 // All 64 bit targets
267 enum exefmt_t EX_64 =
268@@ -372,6 +379,7 @@ enum exefmt_t EX_64 =
269 EX_FREEBSD64 |
270 EX_SOLARIS64 |
271 EX_OPENBSD64 |
272+ EX_HURD64 |
273 EX_DRAGONFLYBSD64;
274
275 // Constraints
276diff --git a/compiler/src/dmd/backend/elfobj.d b/compiler/src/dmd/backend/elfobj.d
277index 68f2f006e3..b004413468 100644
278--- a/compiler/src/dmd/backend/elfobj.d
279+++ b/compiler/src/dmd/backend/elfobj.d
280@@ -68,7 +68,7 @@ else
281 enum DMDV2 = false;
282 bool REQUIRE_DSO_REGISTRY()
283 {
284- return DMDV2 && (config.exe & (EX_LINUX | EX_LINUX64 | EX_FREEBSD | EX_FREEBSD64 | EX_DRAGONFLYBSD64));
285+ return DMDV2 && (config.exe & (EX_LINUX | EX_LINUX64 | EX_FREEBSD | EX_FREEBSD64 | EX_DRAGONFLYBSD64 | EX_HURD | EX_HURD64));
286 }
287
288 /**
289@@ -81,7 +81,7 @@ bool USE_INIT_ARRAY() { return true; }
290 * FreeBSD defaults to lld as of FreeBSD 13 (2021); OpenBSD as of 6.5 (2019).
291 */
292
293-bool ELF_COMDAT() { return (config.exe & (EX_LINUX | EX_LINUX64 | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD | EX_OPENBSD64)) != 0; }
294+bool ELF_COMDAT() { return (config.exe & (EX_LINUX | EX_LINUX64 | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD | EX_OPENBSD64 | EX_HURD | EX_HURD64)) != 0; }
295
296 /***************************************************
297 * Correspondence of relocation types
298@@ -1239,6 +1239,11 @@ void ElfObj_term(const(char)[] objfilename)
299 ELFOSABI = ELFOSABI_OPENBSD;
300 break;
301
302+ case EX_HURD:
303+ case EX_HURD64:
304+ ELFOSABI = ELFOSABI_GNU;
305+ break;
306+
307 case EX_SOLARIS:
308 case EX_SOLARIS64:
309 case EX_DRAGONFLYBSD64:
310diff --git a/compiler/src/dmd/backend/melf.d b/compiler/src/dmd/backend/melf.d
311index 3efa3ec2ee..947f7f2286 100644
312--- a/compiler/src/dmd/backend/melf.d
313+++ b/compiler/src/dmd/backend/melf.d
314@@ -54,7 +54,8 @@ nothrow:
315 enum ELFOSABI_SYSV = 0; /* UNIX System V ABI */
316 enum ELFOSABI_HPUX = 1; /* HP-UX */
317 enum ELFOSABI_NETBSD = 2;
318- enum ELFOSABI_LINUX = 3;
319+ enum ELFOSABI_GNU = 3;
320+ enum ELFOSABI_LINUX = ELFOSABI_GNU;
321 enum ELFOSABI_FREEBSD = 9;
322 enum ELFOSABI_OPENBSD = 12;
323 enum ELFOSABI_ARM = 97; /* ARM */
324diff --git a/compiler/src/dmd/backend/x86/cod1.d b/compiler/src/dmd/backend/x86/cod1.d
325index 7a43b8f754..c9496232e7 100644
326--- a/compiler/src/dmd/backend/x86/cod1.d
327+++ b/compiler/src/dmd/backend/x86/cod1.d
328@@ -2152,7 +2152,8 @@ void getClibFunction(uint clib, ref Symbol* s, ref ClibInfo* cinfo, objfmt_t obj
329 EX_FREEBSD | EX_FREEBSD64 |
330 EX_OPENBSD | EX_OPENBSD64 |
331 EX_DRAGONFLYBSD64 |
332- EX_SOLARIS | EX_SOLARIS64);
333+ EX_SOLARIS | EX_SOLARIS64 |
334+ EX_HURD | EX_HURD64);
335
336 switch (clib)
337 {
338@@ -2174,7 +2175,7 @@ void getClibFunction(uint clib, ref Symbol* s, ref ClibInfo* cinfo, objfmt_t obj
339
340 case CLIB.ldiv:
341 cinfo.retregs16 = mDX|mAX;
342- if (exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD))
343+ if (exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD | EX_HURD))
344 {
345 s = symboly("__divdi3", mAX|mBX|mCX|mDX);
346 cinfo.flags = INFpushebx;
347@@ -2202,7 +2203,7 @@ void getClibFunction(uint clib, ref Symbol* s, ref ClibInfo* cinfo, objfmt_t obj
348
349 case CLIB.lmod:
350 cinfo.retregs16 = mCX|mBX;
351- if (exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD))
352+ if (exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD | EX_HURD))
353 {
354 s = symboly("__moddi3", mAX|mBX|mCX|mDX);
355 cinfo.flags = INFpushebx;
356@@ -2230,7 +2231,7 @@ void getClibFunction(uint clib, ref Symbol* s, ref ClibInfo* cinfo, objfmt_t obj
357
358 case CLIB.uldiv:
359 cinfo.retregs16 = mDX|mAX;
360- if (exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD))
361+ if (exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD | EX_HURD))
362 {
363 s = symboly("__udivdi3", mAX|mBX|mCX|mDX);
364 cinfo.flags = INFpushebx;
365@@ -2258,7 +2259,7 @@ void getClibFunction(uint clib, ref Symbol* s, ref ClibInfo* cinfo, objfmt_t obj
366
367 case CLIB.ulmod:
368 cinfo.retregs16 = mCX|mBX;
369- if (exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD))
370+ if (exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD | EX_HURD))
371 {
372 s = symboly("__umoddi3", mAX|mBX|mCX|mDX);
373 cinfo.flags = INFpushebx;
374@@ -2899,7 +2900,7 @@ void callclib(ref CodeBuilder cdb, elem* e, uint clib, ref regm_t pretregs, regm
375 }
376 if (pushebx)
377 {
378- if (config.exe & (EX_LINUX | EX_LINUX64 | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD | EX_OPENBSD64 | EX_DRAGONFLYBSD64))
379+ if (config.exe & (EX_LINUX | EX_LINUX64 | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD | EX_OPENBSD64 | EX_DRAGONFLYBSD64 | EX_HURD | EX_HURD64))
380 {
381 cdb.gen1(0x50 + CX); // PUSH ECX
382 cdb.gen1(0x50 + BX); // PUSH EBX
383@@ -2920,7 +2921,7 @@ void callclib(ref CodeBuilder cdb, elem* e, uint clib, ref regm_t pretregs, regm
384 cdb.gen1(0x50 + DX); // PUSH EDX
385 cdb.gen1(0x50 + AX); // PUSH EAX
386 }
387- if (config.exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD | EX_SOLARIS))
388+ if (config.exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD | EX_SOLARIS | EX_HURD))
389 {
390 // Note: not for OSX
391 /* Pass EBX on the stack instead, this is because EBX is used
392@@ -3408,7 +3409,7 @@ void cdfunc(ref CGstate cg, ref CodeBuilder cdb, elem* e, ref regm_t pretregs)
393
394 /* Assume called function access statics
395 */
396- if (config.exe & (EX_LINUX | EX_LINUX64 | EX_OSX | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD | EX_OPENBSD64) &&
397+ if (config.exe & (EX_LINUX | EX_LINUX64 | EX_OSX | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD | EX_OPENBSD64 | EX_HURD | EX_HURD64) &&
398 config.flags3 & CFG3pic)
399 cgstate.accessedTLS = true;
400
401@@ -3455,7 +3456,7 @@ void cdfunc(ref CGstate cg, ref CodeBuilder cdb, elem* e, ref regm_t pretregs)
402 parameters[i].numalign = 0;
403 if (alignsize > stackalign &&
404 (I64 || (alignsize >= 16 &&
405- (config.exe & (EX_OSX | EX_LINUX) && (tyaggregate(ep.Ety) || tyvector(ep.Ety))))))
406+ (config.exe & (EX_OSX | EX_LINUX | EX_HURD) && (tyaggregate(ep.Ety) || tyvector(ep.Ety))))))
407 {
408 if (alignsize > STACKALIGN)
409 {
410@@ -4023,7 +4024,7 @@ private void funccall(ref CodeBuilder cdb, elem* e, uint numpara, uint numalign,
411 tym_t e11ty = tybasic(e11.Ety);
412 assert(!I16 || (e11ty == (farfunc ? TYfptr : TYnptr)));
413 load_localgot(cdb);
414- if (config.exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD | EX_SOLARIS)) // 32 bit only
415+ if (config.exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD | EX_SOLARIS | EX_HURD)) // 32 bit only
416 {
417 if (config.flags3 & CFG3pic)
418 keepmsk |= mBX;
419diff --git a/compiler/src/dmd/backend/x86/cod3.d b/compiler/src/dmd/backend/x86/cod3.d
420index ed079b1c7a..56acc13a5b 100644
421--- a/compiler/src/dmd/backend/x86/cod3.d
422+++ b/compiler/src/dmd/backend/x86/cod3.d
423@@ -2460,7 +2460,7 @@ void outjmptab(block* b)
424 break;
425 }
426 }
427- if (config.exe & (EX_LINUX64 | EX_FREEBSD64 | EX_OPENBSD64 | EX_DRAGONFLYBSD64 | EX_SOLARIS64))
428+ if (config.exe & (EX_LINUX64 | EX_FREEBSD64 | EX_OPENBSD64 | EX_DRAGONFLYBSD64 | EX_SOLARIS64 | EX_HURD64))
429 {
430 if (config.flags3 & CFG3pic)
431 {
432@@ -2473,7 +2473,7 @@ void outjmptab(block* b)
433 *poffset += 8;
434 }
435 }
436- else if (config.exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD | EX_SOLARIS))
437+ else if (config.exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD | EX_SOLARIS | EX_HURD))
438 {
439 if (config.flags3 & CFG3pic)
440 {
441@@ -3126,7 +3126,7 @@ void cdgot(ref CGstate cg, ref CodeBuilder cdb, elem* e, ref regm_t pretregs)
442 @trusted
443 void load_localgot(ref CodeBuilder cdb)
444 {
445- if (config.exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD | EX_SOLARIS)) // note: I32 only
446+ if (config.exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD | EX_SOLARIS | EX_HURD)) // note: I32 only
447 {
448 if (config.flags3 & CFG3pic)
449 {
450diff --git a/compiler/src/dmd/cli.d b/compiler/src/dmd/cli.d
451index a958696807..a9bdad011d 100644
452--- a/compiler/src/dmd/cli.d
453+++ b/compiler/src/dmd/cli.d
454@@ -33,10 +33,11 @@ enum TargetOS : ubyte
455 FreeBSD = 0x10,
456 Solaris = 0x20,
457 DragonFlyBSD = 0x40,
458+ Hurd = 0x80,
459
460 // Combination masks
461- all = linux | Windows | OSX | OpenBSD | FreeBSD | Solaris | DragonFlyBSD,
462- Posix = linux | OSX | OpenBSD | FreeBSD | Solaris | DragonFlyBSD,
463+ all = linux | Windows | OSX | OpenBSD | FreeBSD | Solaris | DragonFlyBSD | Hurd,
464+ Posix = linux | OSX | OpenBSD | FreeBSD | Solaris | DragonFlyBSD | Hurd,
465 }
466
467 // Detect the current TargetOS
468@@ -68,6 +69,10 @@ else version(Solaris)
469 {
470 private enum targetOS = TargetOS.Solaris;
471 }
472+else version(Hurd)
473+{
474+ private enum targetOS = TargetOS.Hurd;
475+}
476 else
477 {
478 private enum targetOS = TargetOS.all;
479@@ -791,6 +796,7 @@ dmd -cov -unittest myprog.d
480 $(LI $(I openbsd): OpenBSD)
481 $(LI $(I osx): OSX)
482 $(LI $(I solaris): Solaris)
483+ $(LI $(I hurd): Hurd)
484 $(LI $(I windows): Windows)
485 )`
486 ),
487@@ -877,7 +883,7 @@ dmd -cov -unittest myprog.d
488 $(I os) is the operating system, this may have a trailing version number:
489 `freestanding` for no operating system,
490 `darwin` or `osx` for MacOS, `dragonfly` or `dragonflybsd` for DragonflyBSD,
491- `freebsd`, `openbsd`, `linux`, `solaris` or `windows` for their respective operating systems.
492+ `freebsd`, `openbsd`, `linux`, `solaris`, `hurd` or `windows` for their respective operating systems.
493 $(I cenv) is the C runtime environment and is optional: `musl` for musl-libc,
494 `msvc` for the MSVC runtime, `bionic` for the Andriod libc, `gnu` or `glibc`
495 for the GCC C runtime, `newlib` or `uclibc` for their respective C runtimes.
496diff --git a/compiler/src/dmd/dmdparams.d b/compiler/src/dmd/dmdparams.d
497index 12a0a31cc1..9b112a70d0 100644
498--- a/compiler/src/dmd/dmdparams.d
499+++ b/compiler/src/dmd/dmdparams.d
500@@ -227,6 +227,8 @@ struct Triple
501 os = Target.OS.OpenBSD;
502 else if (matches("linux"))
503 os = Target.OS.linux;
504+ else if (matches("hurd"))
505+ os = Target.OS.Hurd;
506 else if (matches("windows"))
507 os = Target.OS.Windows;
508 else
509diff --git a/compiler/src/dmd/dmsc.d b/compiler/src/dmd/dmsc.d
510index 5ffa486519..b0b1c33bea 100644
511--- a/compiler/src/dmd/dmsc.d
512+++ b/compiler/src/dmd/dmsc.d
513@@ -55,6 +55,7 @@ void backend_init(const ref Param params, const ref DMDparams driverParams, cons
514 case Target.OS.OpenBSD: exfmt = is64 ? EX_OPENBSD64 : EX_OPENBSD; break;
515 case Target.OS.Solaris: exfmt = is64 ? EX_SOLARIS64 : EX_SOLARIS; break;
516 case Target.OS.DragonFlyBSD: assert(is64); exfmt = EX_DRAGONFLYBSD64; break;
517+ case Target.OS.Hurd: exfmt = is64 ? EX_HURD64 : EX_HURD; break;
518 default: assert(0);
519 }
520
521diff --git a/compiler/src/dmd/json.d b/compiler/src/dmd/json.d
522index 512b4dc757..969a67d4b3 100644
523--- a/compiler/src/dmd/json.d
524+++ b/compiler/src/dmd/json.d
525@@ -869,6 +869,8 @@ public:
526 item("solaris");
527 item("bsd");
528 }
529+ else if (target.os == Target.OS.Hurd)
530+ item("hurd");
531 }
532 arrayEnd();
533
534diff --git a/compiler/src/dmd/main.d b/compiler/src/dmd/main.d
535index dbbde2889b..016494cad1 100644
536--- a/compiler/src/dmd/main.d
537+++ b/compiler/src/dmd/main.d
538@@ -1048,7 +1048,7 @@ void reconcileCommands(ref Param params, ref Target target)
539 error(Loc.initial, "`-m32` is not supported on DragonFlyBSD, it is 64-bit only");
540 }
541
542- if (target.os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.Solaris | Target.OS.DragonFlyBSD))
543+ if (target.os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.Solaris | Target.OS.DragonFlyBSD | Target.OS.Hurd))
544 {
545 if (driverParams.lib && driverParams.dll)
546 error(Loc.initial, "cannot mix `-lib` and `-shared`");
547diff --git a/compiler/src/dmd/mars.d b/compiler/src/dmd/mars.d
548index 7a62dc4c64..3fa6ed14d5 100644
549--- a/compiler/src/dmd/mars.d
550+++ b/compiler/src/dmd/mars.d
551@@ -377,7 +377,7 @@ void setDefaultLibraries(const ref Target target, ref const(char)[] defaultlibna
552 {
553 defaultlibname = target.isX86_64 ? "phobos64" : "phobos32mscoff";
554 }
555- else if (target.os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.Solaris | Target.OS.DragonFlyBSD))
556+ else if (target.os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.Solaris | Target.OS.DragonFlyBSD | Target.OS.Hurd))
557 {
558 defaultlibname = "libphobos2.a";
559 }
560@@ -1155,7 +1155,7 @@ bool parseCommandLine(const ref Strings arguments, const size_t argc, out Param
561 enum len = "-os=".length;
562 // Parse:
563 // -os=identifier
564- immutable string msg = "Only `host`, `linux`, `windows`, `osx`,`openbsd`, `freebsd`, `solaris`, `dragonflybsd` allowed for `-os`";
565+ immutable string msg = "Only `host`, `linux`, `windows`, `osx`,`openbsd`, `freebsd`, `solaris`, `dragonflybsd`, `hurd` allowed for `-os`";
566 if (Identifier.isValidIdentifier(p + len))
567 {
568 const ident = p + len;
569@@ -1169,6 +1169,7 @@ bool parseCommandLine(const ref Strings arguments, const size_t argc, out Param
570 case "freebsd": target.os = Target.OS.FreeBSD; break;
571 case "solaris": target.os = Target.OS.Solaris; break;
572 case "dragonflybsd": target.os = Target.OS.DragonFlyBSD; break;
573+ case "hurd": target.os = Target.OS.Hurd; break;
574 default:
575 errorInvalidSwitch(p, msg);
576 return false;
577@@ -1907,7 +1908,7 @@ bool createModule(const(char)* file, ref Strings libmodules, ref Param params, c
578 libmodules.push(file);
579 return false;
580 }
581- if (target.os & (Target.OS.linux | Target.OS.OSX| Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.Solaris | Target.OS.DragonFlyBSD))
582+ if (target.os & (Target.OS.linux | Target.OS.OSX| Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.Solaris | Target.OS.DragonFlyBSD | Target.OS.Hurd))
583 {
584 if (FileName.equals(ext, target.dll_ext))
585 {
586diff --git a/compiler/src/dmd/target.d b/compiler/src/dmd/target.d
587index 7f86cf8d23..cee48785cf 100644
588--- a/compiler/src/dmd/target.d
589+++ b/compiler/src/dmd/target.d
590@@ -65,6 +65,8 @@ Target.OS defaultTargetOS() @safe
591 return Target.OS.Solaris;
592 else version (DragonFlyBSD)
593 return Target.OS.DragonFlyBSD;
594+ else version (Hurd)
595+ return Target.OS.Hurd;
596 else
597 static assert(0, "unknown TARGET");
598 }
599@@ -184,7 +186,7 @@ void addPredefinedGlobalIdentifiers(const ref Target tgt)
600 {
601 if (tgt.os & OS.Posix)
602 predef("Posix");
603- if (tgt.os & (OS.linux | OS.FreeBSD | OS.OpenBSD | OS.DragonFlyBSD | OS.Solaris))
604+ if (tgt.os & (OS.linux | OS.FreeBSD | OS.OpenBSD | OS.DragonFlyBSD | OS.Solaris | OS.Hurd))
605 predef("ELFv1");
606 switch (tgt.os)
607 {
608@@ -193,6 +195,7 @@ void addPredefinedGlobalIdentifiers(const ref Target tgt)
609 case OS.OpenBSD: { predef("OpenBSD"); break; }
610 case OS.DragonFlyBSD: { predef("DragonFlyBSD"); break; }
611 case OS.Solaris: { predef("Solaris"); break; }
612+ case OS.Hurd: { predef("Hurd"); break; }
613 case OS.Windows:
614 {
615 predef("Windows");
616@@ -335,10 +338,11 @@ extern (C++) struct Target
617 FreeBSD = 0x10,
618 Solaris = 0x20,
619 DragonFlyBSD = 0x40,
620+ Hurd = 0x80,
621
622 // Combination masks
623- all = linux | Windows | OSX | OpenBSD | FreeBSD | Solaris | DragonFlyBSD,
624- Posix = linux | OSX | OpenBSD | FreeBSD | Solaris | DragonFlyBSD,
625+ all = linux | Windows | OSX | OpenBSD | FreeBSD | Solaris | DragonFlyBSD | Hurd,
626+ Posix = linux | OSX | OpenBSD | FreeBSD | Solaris | DragonFlyBSD | Hurd,
627 }
628
629 extern(D) enum ObjectFormat : ubyte
630@@ -462,7 +466,7 @@ extern (C++) struct Target
631 classinfosize = 0x98+16; // 168
632 }
633
634- if (os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris))
635+ if (os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris | Target.OS.Hurd))
636 {
637 realsize = 12;
638 realpad = 2;
639@@ -485,7 +489,7 @@ extern (C++) struct Target
640
641 if (isX86_64 || isAArch64)
642 {
643- if (os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris))
644+ if (os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris | Target.OS.Hurd))
645 {
646 realsize = 16;
647 realpad = 6;
648@@ -520,7 +524,7 @@ extern (C++) struct Target
649 dll_ext = "dll";
650 run_noext = false;
651 }
652- else if (os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris | Target.OS.OSX))
653+ else if (os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris | Target.OS.OSX | Target.OS.Hurd))
654 {
655 obj_ext = "o";
656 lib_ext = "a";
657@@ -1120,7 +1124,8 @@ extern (C++) struct Target
658 if (tns.ty != TY.Tstruct)
659 {
660 L2:
661- if (os == Target.OS.linux && tf.linkage != LINK.d && isX86)
662+ if ((os & (Target.OS.linux | Target.OS.Hurd)) &&
663+ tf.linkage != LINK.d && isX86)
664 {
665 // 32 bit C/C++ structs always on stack
666 }
667@@ -1147,7 +1152,8 @@ extern (C++) struct Target
668 if (auto ts = tns.isTypeStruct())
669 {
670 auto sd = ts.sym;
671- if (os == Target.OS.linux && tf.linkage != LINK.d && isX86)
672+ if ((os & (Target.OS.linux | Target.OS.Hurd)) &&
673+ tf.linkage != LINK.d && isX86)
674 {
675 //printf(" 2 true\n");
676 return true; // 32 bit C/C++ structs always on stack
677@@ -1464,7 +1470,7 @@ struct TargetC
678 shortsize = 2;
679 intsize = 4;
680 long_longsize = 8;
681- if (os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris))
682+ if (os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris | Target.OS.Hurd))
683 longsize = 4;
684 else if (os == Target.OS.OSX)
685 longsize = 4;
686@@ -1474,7 +1480,7 @@ struct TargetC
687 assert(0);
688 if (target.isX86_64 || target.isAArch64)
689 {
690- if (os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris))
691+ if (os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris | Target.OS.Hurd))
692 longsize = 8;
693 else if (os == Target.OS.OSX)
694 longsize = 8;
695@@ -1499,11 +1505,16 @@ struct TargetC
696 else
697 runtime = Runtime.Glibc;
698 }
699+ else if (os == Target.OS.Hurd)
700+ {
701+ runtime = Runtime.Glibc;
702+ }
703
704 if (os == Target.OS.Windows)
705 bitFieldStyle = BitFieldStyle.MS;
706 else if (os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OSX |
707- Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris))
708+ Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris |
709+ Target.OS.Hurd))
710 bitFieldStyle = BitFieldStyle.Gcc_Clang;
711 else
712 assert(0);
713@@ -1564,7 +1575,7 @@ struct TargetCPP
714 extern (D) void initialize(ref const Param params, ref const Target target) @safe
715 {
716 const os = target.os;
717- if (os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris))
718+ if (os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris | Target.OS.Hurd))
719 twoDtorInVtable = true;
720 else if (os == Target.OS.OSX)
721 twoDtorInVtable = true;
722@@ -1578,7 +1589,7 @@ struct TargetCPP
723 exceptions = (os & Target.OS.Posix) != 0;
724 if (os == Target.OS.Windows)
725 runtime = Runtime.Microsoft;
726- else if (os & (Target.OS.linux | Target.OS.DragonFlyBSD))
727+ else if (os & (Target.OS.linux | Target.OS.DragonFlyBSD | Target.OS.Hurd))
728 runtime = Runtime.GNU;
729 else if (os & (Target.OS.OSX | Target.OS.FreeBSD | Target.OS.OpenBSD))
730 runtime = Runtime.LLVM;
731@@ -1602,7 +1613,7 @@ struct TargetCPP
732 import dmd.mangle.cpp : toCppMangleItanium;
733 import dmd.mangle.cppwin : toCppMangleMSVC;
734
735- if (target.os & (Target.OS.linux | Target.OS.OSX | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.Solaris | Target.OS.DragonFlyBSD))
736+ if (target.os & (Target.OS.linux | Target.OS.OSX | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.Solaris | Target.OS.DragonFlyBSD | Target.OS.Hurd))
737 return toCppMangleItanium(s);
738 if (target.os == Target.OS.Windows)
739 return toCppMangleMSVC(s);
740@@ -1622,7 +1633,7 @@ struct TargetCPP
741 import dmd.mangle.cpp : cppTypeInfoMangleItanium;
742 import dmd.mangle.cppwin : cppTypeInfoMangleMSVC;
743
744- if (target.os & (Target.OS.linux | Target.OS.OSX | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.Solaris | Target.OS.DragonFlyBSD))
745+ if (target.os & (Target.OS.linux | Target.OS.OSX | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.Solaris | Target.OS.DragonFlyBSD | Target.OS.Hurd))
746 return cppTypeInfoMangleItanium(cd);
747 if (target.os == Target.OS.Windows)
748 return cppTypeInfoMangleMSVC(cd);
749diff --git a/compiler/src/dmd/target.h b/compiler/src/dmd/target.h
750index f7a267ab08..b6fbb4efc0 100644
751--- a/compiler/src/dmd/target.h
752+++ b/compiler/src/dmd/target.h
753@@ -129,10 +129,11 @@ struct Target
754 OS_FreeBSD = 0x10,
755 OS_Solaris = 0x20,
756 OS_DragonFlyBSD = 0x40,
757+ OS_Hurd = 0x80,
758
759 // Combination masks
760- all = OS_linux | OS_Windows | OS_OSX | OS_OpenBSD | OS_FreeBSD | OS_Solaris | OS_DragonFlyBSD,
761- Posix = OS_linux | OS_OSX | OS_OpenBSD | OS_FreeBSD | OS_Solaris | OS_DragonFlyBSD,
762+ all = OS_linux | OS_Windows | OS_OSX | OS_OpenBSD | OS_FreeBSD | OS_Solaris | OS_DragonFlyBSD | OS_Hurd,
763+ Posix = OS_linux | OS_OSX | OS_OpenBSD | OS_FreeBSD | OS_Solaris | OS_DragonFlyBSD | OS_Hurd,
764 };
765
766 OS os;
767diff --git a/compiler/src/osmodel.mak b/compiler/src/osmodel.mak
768index 69676c18b0..443509c61e 100644
769--- a/compiler/src/osmodel.mak
770+++ b/compiler/src/osmodel.mak
771@@ -2,7 +2,7 @@
772 #
773 # Detects and sets the macros:
774 #
775-# OS = one of {windows,osx,linux,freebsd,openbsd,netbsd,dragonflybsd,solaris}
776+# OS = one of {windows,osx,linux,freebsd,openbsd,netbsd,dragonflybsd,solaris,hurd}
777 # MODEL = one of { 32, 64 }
778 # MODEL_FLAG = one of { -m32, -m64 }
779 # ARCH = one of { x86, x86_64, aarch64 }
780@@ -40,6 +40,9 @@ ifeq (,$(OS))
781 ifeq (SunOS,$(uname_S))
782 OS:=solaris
783 endif
784+ ifeq (GNU,$(uname_S))
785+ OS:=hurd
786+ endif
787 ifeq (,$(OS))
788 $(error Unrecognized or unsupported OS for uname: $(uname_S))
789 endif
790@@ -87,7 +90,7 @@ ifeq (,$(MODEL))
791 MODEL:=64
792 ARCH:=aarch64
793 endif
794- ifneq (,$(findstring $(uname_M),i386 i586 i686))
795+ ifneq (,$(findstring $(uname_M),i386 i586 i686 i686-AT386))
796 MODEL:=32
797 ARCH:=x86
798 endif
799diff --git a/compiler/test/compilable/cdcmp.d b/compiler/test/compilable/cdcmp.d
800index 16abde0bd5..f8f9106e5f 100644
801--- a/compiler/test/compilable/cdcmp.d
802+++ b/compiler/test/compilable/cdcmp.d
803@@ -2,7 +2,7 @@
804 // REQUIRED_ARGS: -O
805 // POST_SCRIPT: compilable/extra-files/objdump-postscript.sh
806 // only testing on SYSV-ABI, but backend code is identical across platforms
807-// DISABLED: win32 win64 osx linux32 freebsd32 freebsd64 openbsd32 openbsd64
808+// DISABLED: win32 win64 osx linux32 freebsd32 freebsd64 openbsd32 openbsd64 hurd32
809
810 bool test_ltz(ubyte x) { return x < 0; }
811 bool test_lez(ubyte x) { return x <= 0; }
812diff --git a/compiler/test/compilable/test21672.d b/compiler/test/compilable/test21672.d
813index abad340fcc..81ab7622b7 100644
814--- a/compiler/test/compilable/test21672.d
815+++ b/compiler/test/compilable/test21672.d
816@@ -1,5 +1,5 @@
817 // REQUIRED_ARGS: -mcpu=avx2 -O
818-// DISABLED: win32 linux32 freebsd32 openbsd32
819+// DISABLED: win32 linux32 freebsd32 openbsd32 hurd32
820
821 // https://issues.dlang.org/show_bug.cgi?id=21672
822
823diff --git a/compiler/test/compilable/test22346.c b/compiler/test/compilable/test22346.c
824index 9d1444ad74..8c4d85b6cf 100644
825--- a/compiler/test/compilable/test22346.c
826+++ b/compiler/test/compilable/test22346.c
827@@ -1,4 +1,4 @@
828-/* DISABLED: win32 win64 linux32 osx32 osx64 freebsd32 openbsd32
829+/* DISABLED: win32 win64 linux32 osx32 osx64 freebsd32 openbsd32 hurd32
830 */
831
832 // https://issues.dlang.org/show_bug.cgi?id=23346
833diff --git a/compiler/test/compilable/test23875.c b/compiler/test/compilable/test23875.c
834index c5ee060cc6..b074f12680 100644
835--- a/compiler/test/compilable/test23875.c
836+++ b/compiler/test/compilable/test23875.c
837@@ -1,4 +1,4 @@
838-/* DISABLED: win32 linux32
839+/* DISABLED: win32 linux32 hurd32
840 */
841
842 // https://issues.dlang.org/show_bug.cgi?id=23875
843diff --git a/compiler/test/compilable/test24130.c b/compiler/test/compilable/test24130.c
844index 5f7f69f6cc..5160968b55 100644
845--- a/compiler/test/compilable/test24130.c
846+++ b/compiler/test/compilable/test24130.c
847@@ -1,5 +1,5 @@
848 /*
849- * DISABLED: freebsd32 freebsd64 linux32 linux64 osx32 osx64 win64 dragonflybsd openbsd
850+ * DISABLED: freebsd32 freebsd64 linux32 linux64 osx32 osx64 win64 dragonflybsd openbsd hurd
851 */
852
853 // https://issues.dlang.org/show_bug.cgi?id=24130
854diff --git a/compiler/test/compilable/vcg-ast.d b/compiler/test/compilable/vcg-ast.d
855index 6a90555740..3e0647f50b 100644
856--- a/compiler/test/compilable/vcg-ast.d
857+++ b/compiler/test/compilable/vcg-ast.d
858@@ -5,7 +5,7 @@ OUTPUT_FILES: compilable/vcg-ast.d.cg
859 EXTRA_FILES: imports/vcg_ast_import.d
860 TEST_OUTPUT_FILE: extra-files/vcg-ast.d.cg
861 // size_t currently must be ulong in this test, not uint
862-DISABLED: freebsd32 openbsd32 linux32 osx32 win32
863+DISABLED: freebsd32 openbsd32 linux32 osx32 win32 hurd32
864 */
865
866 module vcg;
867diff --git a/compiler/test/fail_compilation/fail17105.d b/compiler/test/fail_compilation/fail17105.d
868index 407c40222c..14be167f9c 100644
869--- a/compiler/test/fail_compilation/fail17105.d
870+++ b/compiler/test/fail_compilation/fail17105.d
871@@ -1,5 +1,5 @@
872 /* REQUIRED_ARGS: -m64
873-DISABLED: win32 linux32 osx32 freebsd32 openbsd32
874+DISABLED: win32 linux32 osx32 freebsd32 openbsd32 hurd32
875 TEST_OUTPUT:
876 ---
877 fail_compilation/fail17105.d(20): Error: missing 4th parameter to `__simd()`
878diff --git a/compiler/test/fail_compilation/fail18372.d b/compiler/test/fail_compilation/fail18372.d
879index 6100894bb0..8eb92786c0 100644
880--- a/compiler/test/fail_compilation/fail18372.d
881+++ b/compiler/test/fail_compilation/fail18372.d
882@@ -1,5 +1,5 @@
883 /*
884-DISABLED: win32 win64 linux32 osx32 freebsd32 openbsd32
885+DISABLED: win32 win64 linux32 osx32 freebsd32 openbsd32 hurd32
886 TEST_OUTPUT:
887 ---
888 fail_compilation/fail18372.d(103): Error: `__va_list_tag` is not defined, perhaps `import core.stdc.stdarg;` ?
889diff --git a/compiler/test/fail_compilation/fail21227_win.d b/compiler/test/fail_compilation/fail21227_win.d
890index a0a029f08f..00305ae7c9 100644
891--- a/compiler/test/fail_compilation/fail21227_win.d
892+++ b/compiler/test/fail_compilation/fail21227_win.d
893@@ -1,6 +1,6 @@
894 /*
895 REQUIRED_ARGS: -Jfail_compilation
896-DISABLED: linux osx freebsd dragonflybsd netbsd openbsd
897+DISABLED: linux osx freebsd dragonflybsd netbsd openbsd hurd
898 TEST_OUTPUT:
899 ---
900 fail_compilation\fail21227_win.d(2): Error: absolute path is not allowed in import expression: `"\\\\UNC\\path\\to\\file.txt"`
901diff --git a/compiler/test/fail_compilation/fail3753.d b/compiler/test/fail_compilation/fail3753.d
902index 97deb00eb8..98ac1a3231 100644
903--- a/compiler/test/fail_compilation/fail3753.d
904+++ b/compiler/test/fail_compilation/fail3753.d
905@@ -1,5 +1,5 @@
906 /*
907-DISABLED: dragonflybsd freebsd linux osx win32 openbsd
908+DISABLED: dragonflybsd freebsd linux osx win32 openbsd hurd
909 TEST_OUTPUT:
910 ---
911 Error: cannot mix `core.std.stdlib.alloca()` and exception handling in `_Dmain()`
912diff --git a/compiler/test/fail_compilation/fail6451.d b/compiler/test/fail_compilation/fail6451.d
913index fcc1d76a70..7e1977bba9 100644
914--- a/compiler/test/fail_compilation/fail6451.d
915+++ b/compiler/test/fail_compilation/fail6451.d
916@@ -1,5 +1,5 @@
917 /*
918-DISABLED: win32 win64 linux32 osx32 freebsd32 openbsd32
919+DISABLED: win32 win64 linux32 osx32 freebsd32 openbsd32 hurd32
920 TEST_OUTPUT:
921 ---
922 fail_compilation/fail6451.d(9): Error: `__va_list_tag` is not defined, perhaps `import core.stdc.stdarg;` ?
923diff --git a/compiler/test/fail_compilation/ice20042.d b/compiler/test/fail_compilation/ice20042.d
924index 7a674b3c54..3836932195 100644
925--- a/compiler/test/fail_compilation/ice20042.d
926+++ b/compiler/test/fail_compilation/ice20042.d
927@@ -1,5 +1,5 @@
928 /*
929-DISABLED: freebsd32 openbsd32 linux32 osx32 win32
930+DISABLED: freebsd32 openbsd32 linux32 osx32 win32 hurd32
931 TEST_OUTPUT:
932 ---
933 fail_compilation/ice20042.d(18): Error: slice operation `cast(__vector(float[4]))[nanF, nanF, nanF, nanF] = [1.0F, 2.0F, 3.0F, 4.0F][0..4]` cannot be evaluated at compile time
934diff --git a/compiler/test/fail_compilation/ice20264.d b/compiler/test/fail_compilation/ice20264.d
935index a8a1e7119b..03ffa77931 100644
936--- a/compiler/test/fail_compilation/ice20264.d
937+++ b/compiler/test/fail_compilation/ice20264.d
938@@ -1,5 +1,5 @@
939 /*
940-DISABLED: freebsd32 openbsd32 linux32 osx32 win32
941+DISABLED: freebsd32 openbsd32 linux32 osx32 win32 hurd32
942 TEST_OUTPUT:
943 ---
944 fail_compilation/ice20264.d(12): Error: cannot modify expression `cast(__vector(float[4]))a` because it is not an lvalue
945diff --git a/compiler/test/fail_compilation/impconv.d b/compiler/test/fail_compilation/impconv.d
946index 0cc2deb13d..e4026957f2 100644
947--- a/compiler/test/fail_compilation/impconv.d
948+++ b/compiler/test/fail_compilation/impconv.d
949@@ -3,7 +3,7 @@ FIXME: DMD host compilers < 2.073 with faulty optimization
950 lead to unfortunate test failures, see
951 https://github.com/dlang/dmd/pull/6831#issuecomment-304495842.
952
953-DISABLED: win32 win64 linux osx freebsd openbsd
954+DISABLED: win32 win64 linux osx freebsd openbsd hurd
955 */
956
957 /*
958diff --git a/compiler/test/fail_compilation/invalid_lib.d b/compiler/test/fail_compilation/invalid_lib.d
959index 70121123a7..19eb4eaddf 100644
960--- a/compiler/test/fail_compilation/invalid_lib.d
961+++ b/compiler/test/fail_compilation/invalid_lib.d
962@@ -1,6 +1,6 @@
963 /*
964 REQUIRED_ARGS: -lib
965-REQUIRED_ARGS(linux freebsd osx openbsd): fail_compilation/extra-files/fake.a
966+REQUIRED_ARGS(linux freebsd osx openbsd hurd): fail_compilation/extra-files/fake.a
967 REQUIRED_ARGS(windows): -m32 fail_compilation/extra-files/fake.lib
968
969 Use a regex because the path is really strange on Azure (OMF_32, 64):
970diff --git a/compiler/test/fail_compilation/vector_types.d b/compiler/test/fail_compilation/vector_types.d
971index 322bbc66cb..f17dbc25e2 100644
972--- a/compiler/test/fail_compilation/vector_types.d
973+++ b/compiler/test/fail_compilation/vector_types.d
974@@ -1,7 +1,7 @@
975 /*
976 REQUIRED_ARGS: -o-
977 TEST_OUTPUT:
978-DISABLED: freebsd32 openbsd32 linux32 osx32 win32
979+DISABLED: freebsd32 openbsd32 linux32 osx32 win32 hurd32
980 ---
981 fail_compilation/vector_types.d(15): Error: 32 byte vector type `__vector(double[4])` is not supported on this platform
982 fail_compilation/vector_types.d(16): Error: 32 byte vector type `__vector(float[8])` is not supported on this platform
983diff --git a/compiler/test/fail_compilation/xmmslice.d b/compiler/test/fail_compilation/xmmslice.d
984index f91ac1f525..48f79c65d2 100644
985--- a/compiler/test/fail_compilation/xmmslice.d
986+++ b/compiler/test/fail_compilation/xmmslice.d
987@@ -1,6 +1,6 @@
988
989 /* REQUIRED_ARGS: -mcpu=avx
990-DISABLED: win32 freebsd32 openbsd32 linux32 osx32
991+DISABLED: win32 freebsd32 openbsd32 linux32 osx32 hurd32
992 TEST_OUTPUT:
993 ---
994 fail_compilation/xmmslice.d(110): Error: `__vector(int[4])` cannot be sliced with `[]`
995diff --git a/compiler/test/run.d b/compiler/test/run.d
996index d652292bd4..aca8f85282 100755
997--- a/compiler/test/run.d
998+++ b/compiler/test/run.d
999@@ -579,7 +579,7 @@ string[string] getEnvironment()
1000 env["PIC_FLAG"] = pic ? "-fPIC" : "";
1001 env["DFLAGS"] = "-I%s/import -I%s".format(druntimePath, phobosPath)
1002 ~ " -L-L%s/%s".format(phobosPath, generatedSuffix);
1003- bool isShared = environment.get("SHARED") != "0" && os.among("linux", "freebsd") > 0;
1004+ bool isShared = environment.get("SHARED") != "0" && os.among("linux", "freebsd", "hurd") > 0;
1005 if (isShared)
1006 env["DFLAGS"] = env["DFLAGS"] ~ " -defaultlib=libphobos2.so -L-rpath=%s/%s".format(phobosPath, generatedSuffix);
1007
1008diff --git a/compiler/test/runnable/bitfieldsms.c b/compiler/test/runnable/bitfieldsms.c
1009index 5aee443d55..85af0eb5f8 100644
1010--- a/compiler/test/runnable/bitfieldsms.c
1011+++ b/compiler/test/runnable/bitfieldsms.c
1012@@ -1,5 +1,5 @@
1013 /* test bitfields for Microsoft C
1014- * DISABLED: win32 linux freebsd openbsd osx
1015+ * DISABLED: win32 linux freebsd openbsd osx hurd
1016 * RUN_OUTPUT:
1017 ---
1018 DM | MS | P32 | P64
1019diff --git a/compiler/test/runnable/bitfieldsposix32.c b/compiler/test/runnable/bitfieldsposix32.c
1020index 790b594912..19804a06db 100644
1021--- a/compiler/test/runnable/bitfieldsposix32.c
1022+++ b/compiler/test/runnable/bitfieldsposix32.c
1023@@ -1,5 +1,5 @@
1024 /* test bitfields
1025- * DISABLED: win32 win64 linux64 freebsd64 openbsd64 osx64
1026+ * DISABLED: win32 win64 linux64 freebsd64 openbsd64 osx64 hurd64
1027 * RUN_OUTPUT:
1028 ---
1029 T0 = 1 1 | 1 1
1030diff --git a/compiler/test/runnable/bitfieldsposix64.c b/compiler/test/runnable/bitfieldsposix64.c
1031index 8a2b089334..d4196376a9 100644
1032--- a/compiler/test/runnable/bitfieldsposix64.c
1033+++ b/compiler/test/runnable/bitfieldsposix64.c
1034@@ -1,5 +1,5 @@
1035 /* test bitfields
1036- * DISABLED: win32 win64 linux32 freebsd32 openbsd32 osx32
1037+ * DISABLED: win32 win64 linux32 freebsd32 openbsd32 osx32 hurd32
1038 * RUN_OUTPUT:
1039 ---
1040 T0 = 1 1 | 1 1
1041diff --git a/compiler/test/runnable/dbitfieldsdm.d b/compiler/test/runnable/dbitfieldsdm.d
1042index e18ad9abeb..9e0da41056 100644
1043--- a/compiler/test/runnable/dbitfieldsdm.d
1044+++ b/compiler/test/runnable/dbitfieldsdm.d
1045@@ -2,7 +2,7 @@
1046 * Note that this test is for win32 only
1047 *
1048 *
1049- * DISABLED: win32mscoff win64 linux freebsd osx
1050+ * DISABLED: win32mscoff win64 linux freebsd osx hurd
1051 * RUN_OUTPUT:
1052 ---
1053 DM | MS | P32 | P64
1054diff --git a/compiler/test/runnable/dbitfieldsms.d b/compiler/test/runnable/dbitfieldsms.d
1055index 70a72c19b7..2021da2218 100644
1056--- a/compiler/test/runnable/dbitfieldsms.d
1057+++ b/compiler/test/runnable/dbitfieldsms.d
1058@@ -1,5 +1,5 @@
1059 /* test bitfields for Microsoft C
1060- * DISABLED: win32 linux freebsd openbsd osx
1061+ * DISABLED: win32 linux freebsd openbsd osx hurd
1062 * RUN_OUTPUT:
1063 ---
1064 DM | MS | P32 | P64
1065diff --git a/compiler/test/runnable/dbitfieldsposix32.d b/compiler/test/runnable/dbitfieldsposix32.d
1066index 26e44d29fc..6e1944cf2d 100644
1067--- a/compiler/test/runnable/dbitfieldsposix32.d
1068+++ b/compiler/test/runnable/dbitfieldsposix32.d
1069@@ -1,5 +1,5 @@
1070 /* test bitfields
1071- * DISABLED: win32 win64 linux64 freebsd64 openbsd64 osx64
1072+ * DISABLED: win32 win64 linux64 freebsd64 openbsd64 osx64 hurd64
1073 * RUN_OUTPUT:
1074 ---
1075 T0 = 1 1 | 1 1
1076diff --git a/compiler/test/runnable/dbitfieldsposix64.d b/compiler/test/runnable/dbitfieldsposix64.d
1077index 86c3a5d861..972375d084 100644
1078--- a/compiler/test/runnable/dbitfieldsposix64.d
1079+++ b/compiler/test/runnable/dbitfieldsposix64.d
1080@@ -1,5 +1,5 @@
1081 /* test bitfields
1082- * DISABLED: win32 win64 linux32 freebsd32 openbsd32 osx32
1083+ * DISABLED: win32 win64 linux32 freebsd32 openbsd32 osx32 hurd32
1084 * RUN_OUTPUT:
1085 ---
1086 T0 = 1 1 | 1 1
1087diff --git a/compiler/test/runnable/dhry.d b/compiler/test/runnable/dhry.d
1088index 4d2e1b3c64..598feda290 100644
1089--- a/compiler/test/runnable/dhry.d
1090+++ b/compiler/test/runnable/dhry.d
1091@@ -945,3 +945,18 @@ version (OpenBSD)
1092 return q;
1093 }
1094 }
1095+version (Hurd)
1096+{
1097+ import core.sys.posix.sys.time;
1098+
1099+ double dtime()
1100+ {
1101+ double q;
1102+ timeval tv;
1103+
1104+ gettimeofday(&tv,null);
1105+ q = cast(double)tv.tv_sec + cast(double)tv.tv_usec * 1.0e-6;
1106+
1107+ return q;
1108+ }
1109+}
1110diff --git a/compiler/test/runnable/ice21727.d b/compiler/test/runnable/ice21727.d
1111index c373c53c25..e4f615297b 100644
1112--- a/compiler/test/runnable/ice21727.d
1113+++ b/compiler/test/runnable/ice21727.d
1114@@ -1,5 +1,5 @@
1115 // REQUIRED_ARGS: -m64 -O -inline
1116-// DISABLED: win32 linux32 freebsd32 osx32 openbsd32 netbsd32 dragonflybsd32
1117+// DISABLED: win32 linux32 freebsd32 osx32 openbsd32 netbsd32 dragonflybsd32 hurd32
1118 // https://issues.dlang.org/show_bug.cgi?id=21727
1119
1120 import core.simd;
1121diff --git a/compiler/test/runnable/test22.d b/compiler/test/runnable/test22.d
1122index 38a9cc367e..2087c17ff8 100644
1123--- a/compiler/test/runnable/test22.d
1124+++ b/compiler/test/runnable/test22.d
1125@@ -756,6 +756,36 @@ do
1126 fxch ST(1) ; // ST1 = r, ST0 = x
1127 fstp ST(0) ; // dump x
1128 align 4 ;
1129+ return_ST: ;
1130+ ;
1131+ }
1132+ }
1133+ else version (Hurd)
1134+ {
1135+ asm // assembler by W. Bright
1136+ {
1137+ // EDX = (A.length - 1) * real.sizeof
1138+ mov ECX,A[EBP] ; // ECX = A.length
1139+ dec ECX ;
1140+ lea EDX,[ECX][ECX*8] ;
1141+ add EDX,ECX ;
1142+ add EDX,ECX ;
1143+ add EDX,ECX ;
1144+ add EDX,A+4[EBP] ;
1145+ fld real ptr [EDX] ; // ST0 = coeff[ECX]
1146+ jecxz return_ST ;
1147+ fld x[EBP] ; // ST0 = x
1148+ fxch ST(1) ; // ST1 = x, ST0 = r
1149+ align 4 ;
1150+ L2: fmul ST,ST(1) ; // r *= x
1151+ fld real ptr -12[EDX] ;
1152+ sub EDX,12 ; // deg--
1153+ faddp ST(1),ST ;
1154+ dec ECX ;
1155+ jne L2 ;
1156+ fxch ST(1) ; // ST1 = r, ST0 = x
1157+ fstp ST(0) ; // dump x
1158+ align 4 ;
1159 return_ST: ;
1160 ;
1161 }
1162diff --git a/compiler/test/runnable/test23343.c b/compiler/test/runnable/test23343.c
1163index 27ff5a7cb8..eeb3f1054e 100644
1164--- a/compiler/test/runnable/test23343.c
1165+++ b/compiler/test/runnable/test23343.c
1166@@ -1,4 +1,4 @@
1167-/* DISABLED: win linux freebsd openbsd osx32 dragonflybsd netbsd
1168+/* DISABLED: win linux freebsd openbsd osx32 dragonflybsd netbsd hurd
1169 */
1170
1171 /* https://issues.dlang.org/show_bug.cgi?id=23343
1172diff --git a/compiler/test/runnable/test_cdstrpar.d b/compiler/test/runnable/test_cdstrpar.d
1173index 90aa499ab9..1a2907de96 100644
1174--- a/compiler/test/runnable/test_cdstrpar.d
1175+++ b/compiler/test/runnable/test_cdstrpar.d
1176@@ -1,7 +1,7 @@
1177 // REQUIRED_ARGS: -O -fPIC
1178 // PERMUTE_ARGS:
1179 // only testing on SYSV-ABI, but backend code is identical across platforms
1180-// DISABLED: win32 win64 osx linux32 freebsd32 openbsd32
1181+// DISABLED: win32 win64 osx linux32 freebsd32 openbsd32 hurd32
1182 debug = PRINTF;
1183 debug (PRINTF) import core.stdc.stdio;
1184
1185diff --git a/compiler/test/runnable/testargtypes.d b/compiler/test/runnable/testargtypes.d
1186index 4492420aa8..8f08348a61 100644
1187--- a/compiler/test/runnable/testargtypes.d
1188+++ b/compiler/test/runnable/testargtypes.d
1189@@ -1,5 +1,5 @@
1190 /*
1191-DISABLED: win32 win64 osx32 linux32 freebsd32 openbsd32
1192+DISABLED: win32 win64 osx32 linux32 freebsd32 openbsd32 hurd32
1193 */
1194
1195 void chkArgTypes(S, V...)()
1196diff --git a/compiler/test/runnable_cxx/cpp_abi_tests.d b/compiler/test/runnable_cxx/cpp_abi_tests.d
1197index 4e241749fb..5240009816 100644
1198--- a/compiler/test/runnable_cxx/cpp_abi_tests.d
1199+++ b/compiler/test/runnable_cxx/cpp_abi_tests.d
1200@@ -1,5 +1,5 @@
1201 // EXTRA_CPP_SOURCES: cpp_abi_tests.cpp
1202-// CXXFLAGS(linux freebsd osx openbsd netbsd dragonflybsd): -std=c++11
1203+// CXXFLAGS(linux freebsd osx openbsd netbsd dragonflybsd hurd): -std=c++11
1204
1205 // N.B MSVC doesn't have a C++11 switch, but it defaults to the latest fully-supported standard
1206 // N.B MSVC 2013 doesn't support char16_t/char32_t
1207diff --git a/compiler/test/runnable_cxx/cppa.d b/compiler/test/runnable_cxx/cppa.d
1208index c62bc6face..f7bc035895 100644
1209--- a/compiler/test/runnable_cxx/cppa.d
1210+++ b/compiler/test/runnable_cxx/cppa.d
1211@@ -2,7 +2,7 @@
1212 // PERMUTE_ARGS: -g
1213 // EXTRA_CPP_SOURCES: cppb.cpp
1214 // EXTRA_FILES: extra-files/cppb.h
1215-// CXXFLAGS(linux freebsd osx openbsd netbsd dragonflybsd): -std=c++11
1216+// CXXFLAGS(linux freebsd osx openbsd netbsd dragonflybsd hurd): -std=c++11
1217 // druntime isn't linked, this prevents missing symbols '_d_arraybounds_slicep':
1218 // REQUIRED_ARGS: -checkaction=C
1219 // TRANSFORM_OUTPUT: remove_lines("warning: vsprintf\(\) is often misused")
1220diff --git a/compiler/test/runnable_cxx/nonpod_byval.d b/compiler/test/runnable_cxx/nonpod_byval.d
1221index c7fac46a04..4314d6b3a8 100644
1222--- a/compiler/test/runnable_cxx/nonpod_byval.d
1223+++ b/compiler/test/runnable_cxx/nonpod_byval.d
1224@@ -1,5 +1,5 @@
1225 // EXTRA_CPP_SOURCES: cpp_nonpod_byval.cpp
1226-// CXXFLAGS(linux osx freebsd dragonflybsd): -std=c++11
1227+// CXXFLAGS(linux osx freebsd dragonflybsd hurd): -std=c++11
1228
1229 extern (C) int printf(const(char)*, ...);
1230
1231diff --git a/compiler/test/tools/paths.d b/compiler/test/tools/paths.d
1232index acb525bda7..1b1ca9d07c 100644
1233--- a/compiler/test/tools/paths.d
1234+++ b/compiler/test/tools/paths.d
1235@@ -27,6 +27,8 @@ else version (Solaris)
1236 enum os = "solaris";
1237 else version (SunOS)
1238 enum os = "solaris";
1239+else version (Hurd)
1240+ enum os = "hurd";
1241 else
1242 static assert(0, "Unrecognized or unsupported OS.");
1243
1244--
12452.54.0
1246
1247From 5432ed63f8064ebbc19f6fb1d7953f57509c6c12 Mon Sep 17 00:00:00 2001
1248From: Yelninei <[email protected]>
1249Date: Fri, 27 Mar 2026 14:56:20 +0000
1250Subject: [PATCH 2/3] druntime: Port to GNU/Hurd.
1251
1252---
1253 druntime/Makefile | 2 +-
1254 druntime/mak/COPY | 10 +
1255 druntime/src/core/demangle.d | 1 +
1256 druntime/src/core/internal/backtrace/elf.d | 5 +
1257 druntime/src/core/internal/elf/dl.d | 14 +
1258 druntime/src/core/internal/elf/io.d | 9 +
1259 druntime/src/core/internal/execinfo.d | 2 +
1260 druntime/src/core/internal/gc/os.d | 2 +
1261 druntime/src/core/stdc/config.d | 4 +
1262 druntime/src/core/stdc/errno.d | 107 +++
1263 druntime/src/core/stdc/limits.d | 14 +
1264 druntime/src/core/sys/hurd/config.d | 30 +
1265 druntime/src/core/sys/hurd/dlfcn.d | 114 +++
1266 druntime/src/core/sys/hurd/elf.d | 162 ++++
1267 druntime/src/core/sys/hurd/errno.d | 21 +
1268 druntime/src/core/sys/hurd/execinfo.d | 16 +
1269 druntime/src/core/sys/hurd/link.d | 134 ++++
1270 druntime/src/core/sys/hurd/sys/types.d | 22 +
1271 druntime/src/core/sys/hurd/time.d | 15 +
1272 druntime/src/core/sys/hurd/unistd.d | 30 +
1273 druntime/src/core/sys/posix/dirent.d | 11 +
1274 druntime/src/core/sys/posix/fcntl.d | 107 +++
1275 druntime/src/core/sys/posix/netinet/in_.d | 58 +-
1276 druntime/src/core/sys/posix/poll.d | 16 +
1277 druntime/src/core/sys/posix/pthread.d | 218 ++++--
1278 druntime/src/core/sys/posix/sched.d | 11 +
1279 druntime/src/core/sys/posix/semaphore.d | 32 +-
1280 druntime/src/core/sys/posix/signal.d | 189 ++++-
1281 druntime/src/core/sys/posix/spawn.d | 42 ++
1282 druntime/src/core/sys/posix/sys/ioctl.d | 37 +
1283 druntime/src/core/sys/posix/sys/ipc.d | 43 ++
1284 druntime/src/core/sys/posix/sys/mman.d | 33 +
1285 druntime/src/core/sys/posix/sys/msg.d | 44 ++
1286 druntime/src/core/sys/posix/sys/resource.d | 58 ++
1287 druntime/src/core/sys/posix/sys/shm.d | 26 +
1288 druntime/src/core/sys/posix/sys/socket.d | 161 ++++
1289 druntime/src/core/sys/posix/sys/stat.d | 74 ++
1290 druntime/src/core/sys/posix/sys/statvfs.d | 152 ++--
1291 druntime/src/core/sys/posix/sys/types.d | 703 +++++++++++-------
1292 druntime/src/core/sys/posix/sys/un.d | 13 +
1293 druntime/src/core/sys/posix/sys/utsname.d | 39 +-
1294 druntime/src/core/sys/posix/sys/wait.d | 23 +
1295 druntime/src/core/sys/posix/termios.d | 102 +++
1296 druntime/src/core/sys/posix/time.d | 12 +
1297 .../core/thread/fiber/switch_context_asm.S | 2 +-
1298 druntime/src/core/thread/osthread.d | 8 +
1299 druntime/src/core/time.d | 25 +
1300 druntime/src/importc.h | 4 +-
1301 druntime/src/rt/sections_elf_shared.d | 8 +
1302 .../importc_compare/src/importc_compare.d | 4 +
1303 .../test/profile/myprofilegc.log.hurd.32.exp | 18 +
1304 .../test/profile/myprofilegc.log.hurd.64.exp | 18 +
1305 druntime/test/shared/src/load.d | 1 +
1306 53 files changed, 2587 insertions(+), 419 deletions(-)
1307 create mode 100644 druntime/src/core/sys/hurd/config.d
1308 create mode 100644 druntime/src/core/sys/hurd/dlfcn.d
1309 create mode 100644 druntime/src/core/sys/hurd/elf.d
1310 create mode 100644 druntime/src/core/sys/hurd/errno.d
1311 create mode 100644 druntime/src/core/sys/hurd/execinfo.d
1312 create mode 100644 druntime/src/core/sys/hurd/link.d
1313 create mode 100644 druntime/src/core/sys/hurd/sys/types.d
1314 create mode 100644 druntime/src/core/sys/hurd/time.d
1315 create mode 100644 druntime/src/core/sys/hurd/unistd.d
1316 create mode 100644 druntime/test/profile/myprofilegc.log.hurd.32.exp
1317 create mode 100644 druntime/test/profile/myprofilegc.log.hurd.64.exp
1318
1319diff --git a/druntime/Makefile b/druntime/Makefile
1320index 1b5f4165ce..17452874b7 100644
1321--- a/druntime/Makefile
1322+++ b/druntime/Makefile
1323@@ -76,7 +76,7 @@ endif
1324
1325 # build with shared library support
1326 # (defaults to true on supported platforms, can be overridden w/ make SHARED=0)
1327-SHARED=$(if $(findstring $(OS),linux freebsd dragonflybsd),1,)
1328+SHARED=$(if $(findstring $(OS),linux freebsd dragonflybsd hurd),1,)
1329
1330 LINKDL=$(if $(findstring $(OS),linux),-L-ldl,)
1331
1332diff --git a/druntime/mak/COPY b/druntime/mak/COPY
1333index 2a4f03a9a8..1b6dbcbab4 100644
1334--- a/druntime/mak/COPY
1335+++ b/druntime/mak/COPY
1336@@ -391,6 +391,16 @@ COPY=\
1337 $(IMPDIR)\core\sys\solaris\sys\regset.d \
1338 $(IMPDIR)\core\sys\solaris\sys\types.d \
1339 \
1340+ $(IMPDIR)\core\sys\hurd\config.d \
1341+ $(IMPDIR)\core\sys\hurd\dlfcn.d \
1342+ $(IMPDIR)\core\sys\hurd\elf.d \
1343+ $(IMPDIR)\core\sys\hurd\execinfo.d \
1344+ $(IMPDIR)\core\sys\hurd\errno.d \
1345+ $(IMPDIR)\core\sys\hurd\link.d \
1346+ $(IMPDIR)\core\sys\hurd\sys\types.d \
1347+ $(IMPDIR)\core\sys\hurd\time.d \
1348+ $(IMPDIR)\core\sys\hurd\unistd.d \
1349+ \
1350 $(IMPDIR)\core\sys\windows\accctrl.d \
1351 $(IMPDIR)\core\sys\windows\aclapi.d \
1352 $(IMPDIR)\core\sys\windows\aclui.d \
1353diff --git a/druntime/src/core/demangle.d b/druntime/src/core/demangle.d
1354index e7efc8c3ec..e95984c26c 100644
1355--- a/druntime/src/core/demangle.d
1356+++ b/druntime/src/core/demangle.d
1357@@ -2996,6 +2996,7 @@ CXX_DEMANGLER getCXXDemangler() nothrow @trusted
1358 version (OpenBSD) import core.sys.openbsd.dlfcn : RTLD_DEFAULT;
1359 version (Darwin) import core.sys.darwin.dlfcn : RTLD_DEFAULT;
1360 version (Solaris) import core.sys.solaris.dlfcn : RTLD_DEFAULT;
1361+ version (Hurd) import core.sys.hurd.dlfcn : RTLD_DEFAULT;
1362
1363 if (auto found = cast(CXX_DEMANGLER) dlsym(RTLD_DEFAULT, "__cxa_demangle"))
1364 atomicStore(__cxa_demangle, found);
1365diff --git a/druntime/src/core/internal/backtrace/elf.d b/druntime/src/core/internal/backtrace/elf.d
1366index 1a235537bb..6da1ef1ecb 100644
1367--- a/druntime/src/core/internal/backtrace/elf.d
1368+++ b/druntime/src/core/internal/backtrace/elf.d
1369@@ -36,6 +36,11 @@ else version (Solaris)
1370 import core.sys.solaris.sys.elf : SHF_COMPRESSED, ET_DYN;
1371 version = LinuxOrBSD;
1372 }
1373+else version (Hurd)
1374+{
1375+ import core.sys.hurd.elf : SHF_COMPRESSED, ET_DYN;
1376+ version = LinuxOrBSD;
1377+}
1378
1379 version (LinuxOrBSD):
1380
1381diff --git a/druntime/src/core/internal/elf/dl.d b/druntime/src/core/internal/elf/dl.d
1382index 963b4249a3..c7b24e854a 100644
1383--- a/druntime/src/core/internal/elf/dl.d
1384+++ b/druntime/src/core/internal/elf/dl.d
1385@@ -41,6 +41,11 @@ else version (Solaris)
1386 import core.sys.solaris.link : dl_iterate_phdr, dl_phdr_info, ElfW;
1387 version = LinuxOrBSD;
1388 }
1389+else version (Hurd)
1390+{
1391+ import core.sys.hurd.link : dl_iterate_phdr, dl_phdr_info, ElfW;
1392+ version = LinuxOrBSD;
1393+}
1394
1395 version (LinuxOrBSD):
1396
1397@@ -93,6 +98,7 @@ struct SharedObject
1398 else version (NetBSD) enum IterateManually = true;
1399 else version (OpenBSD) enum IterateManually = true;
1400 else version (Solaris) enum IterateManually = true;
1401+ else version (Hurd) enum IterateManually = true;
1402 else enum IterateManually = false;
1403
1404 static if (IterateManually)
1405@@ -225,6 +231,14 @@ version (Linux_Use_GNU)
1406 return program_invocation_name;
1407 }
1408 }
1409+else version (Hurd)
1410+{
1411+ const(char)* getprogname()
1412+ {
1413+ import core.sys.hurd.errno : program_invocation_name;
1414+ return program_invocation_name;
1415+ }
1416+}
1417 else // Bionic, BSDs
1418 {
1419 extern(C) const(char)* getprogname();
1420diff --git a/druntime/src/core/internal/elf/io.d b/druntime/src/core/internal/elf/io.d
1421index 80c9415e14..437589ec97 100644
1422--- a/druntime/src/core/internal/elf/io.d
1423+++ b/druntime/src/core/internal/elf/io.d
1424@@ -50,6 +50,11 @@ else version (Solaris)
1425 import core.sys.solaris.link : ElfW;
1426 version = LinuxOrBSD;
1427 }
1428+else version (Hurd)
1429+{
1430+ import core.sys.hurd.link : ElfW;
1431+ version = LinuxOrBSD;
1432+}
1433
1434 /**
1435 * File-based memory-mapped I/O (read-only).
1436@@ -403,6 +408,10 @@ char* thisExePath()
1437 import core.sys.openbsd.stdlib : getprogname;
1438 return strdup(getprogname());
1439 }
1440+ else version (Hurd)
1441+ {
1442+ return readLink("/proc/self/exe");
1443+ }
1444 else
1445 {
1446 version (DragonFlyBSD)
1447diff --git a/druntime/src/core/internal/execinfo.d b/druntime/src/core/internal/execinfo.d
1448index 1ea467afbe..ce7d6de36e 100644
1449--- a/druntime/src/core/internal/execinfo.d
1450+++ b/druntime/src/core/internal/execinfo.d
1451@@ -68,6 +68,8 @@ else version (DragonFlyBSD)
1452 import _execinfo = core.sys.dragonflybsd.execinfo : backtrace, backtrace_symbols, backtrace_symbols_fd;
1453 else version (Solaris)
1454 import _execinfo = core.sys.solaris.execinfo : backtrace, backtrace_symbols, backtrace_symbols_fd;
1455+else version (Hurd)
1456+ import _execinfo = core.sys.hurd.execinfo : backtrace, backtrace_symbols, backtrace_symbols_fd;
1457
1458 /// Indicates the availability of backtrace functions
1459 enum bool hasExecinfo = is(_execinfo == module);
1460diff --git a/druntime/src/core/internal/gc/os.d b/druntime/src/core/internal/gc/os.d
1461index 914b7b903c..cdefbb87a4 100644
1462--- a/druntime/src/core/internal/gc/os.d
1463+++ b/druntime/src/core/internal/gc/os.d
1464@@ -95,6 +95,8 @@ else version (Posix)
1465 version = GCSignalsUnblock;
1466 version (Solaris)
1467 version = GCSignalsUnblock;
1468+ version (Hurd)
1469+ version = GCSignalsUnblock;
1470
1471 //version = GC_Use_Alloc_MMap;
1472 }
1473diff --git a/druntime/src/core/stdc/config.d b/druntime/src/core/stdc/config.d
1474index 7c5b53df1f..17bce4e740 100644
1475--- a/druntime/src/core/stdc/config.d
1476+++ b/druntime/src/core/stdc/config.d
1477@@ -259,6 +259,8 @@ else version (DigitalMars)
1478 alias c_long_double = real;
1479 else version (Darwin)
1480 alias c_long_double = real;
1481+ else version (Hurd)
1482+ alias c_long_double = real;
1483 }
1484 else version (AArch64)
1485 {
1486@@ -276,6 +278,8 @@ else version (DigitalMars)
1487 alias c_long_double = real;
1488 else version (Darwin)
1489 alias c_long_double = real;
1490+ else version (Hurd)
1491+ alias c_long_double = real;
1492 }
1493 }
1494
1495diff --git a/druntime/src/core/stdc/errno.d b/druntime/src/core/stdc/errno.d
1496index db347e404b..ee48ac2e17 100644
1497--- a/druntime/src/core/stdc/errno.d
1498+++ b/druntime/src/core/stdc/errno.d
1499@@ -2457,6 +2457,113 @@ else version (WASI)
1500 enum ERFKILL = 132;
1501 enum EHWPOISON = 133;
1502 }
1503+else version (Hurd)
1504+{
1505+ enum EPERM = 0x40000001; /* Operation not permitted */
1506+ enum ENOENT = 0x40000002; /* No such file or directory */
1507+ enum ESRCH = 0x40000003; /* No such process */
1508+ enum EINTR = 0x40000004; /* Interrupted system call */
1509+ enum EIO = 0x40000005; /* Input/output error */
1510+ enum ENXIO = 0x40000006; /* No such device or address */
1511+ enum E2BIG = 0x40000007; /* Argument list too long */
1512+ enum ENOEXEC = 0x40000008; /*enum Exec format error */
1513+ enum EBADF = 0x40000009; /* Bad file descriptor */
1514+ enum ECHILD = 0x4000000a; /* No child processes */
1515+ enum EDEADLK = 0x4000000b; /* Resource deadlock avoided */
1516+ enum ENOMEM = 0x4000000c; /* Cannot allocate memory */
1517+ enum EACCES = 0x4000000d; /* Permission denied */
1518+ enum EFAULT = 0x4000000e; /* Bad address */
1519+ enum ENOTBLK = 0x4000000f; /* Block device required */
1520+ enum EBUSY = 0x40000010; /* Device or resource busy */
1521+ enum EEXIST = 0x40000011; /* File exists */
1522+ enum EXDEV = 0x40000012; /* Invalid cross-device link */
1523+ enum ENODEV = 0x40000013; /* No such device */
1524+ enum ENOTDIR = 0x40000014; /* Not a directory */
1525+ enum EISDIR = 0x40000015; /* Is a directory */
1526+ enum EINVAL = 0x40000016; /* Invalid argument */
1527+ enum EMFILE = 0x40000018; /* Too many open files */
1528+ enum ENFILE = 0x40000017; /* Too many open files in system */
1529+ enum ENOTTY = 0x40000019; /* Inappropriate ioctl for device */
1530+ enum ETXTBSY = 0x4000001a; /* Text file busy */
1531+ enum EFBIG = 0x4000001b; /* File too large */
1532+ enum ENOSPC = 0x4000001c; /* No space left on device */
1533+ enum ESPIPE = 0x4000001d; /* Illegal seek */
1534+ enum EROFS = 0x4000001e; /* Read-only file system */
1535+ enum EMLINK = 0x4000001f; /* Too many links */
1536+ enum EPIPE = 0x40000020; /* Broken pipe */
1537+ enum EDOM = 0x40000021; /* Numerical argument out of domain */
1538+ enum ERANGE = 0x40000022; /* Numerical result out of range */
1539+ enum EAGAIN = 0x40000023; /* Resource temporarily unavailable */
1540+ enum EINPROGRESS = 0x40000024; /* Operation now in progress */
1541+ enum EALREADY = 0x40000025; /* Operation already in progress */
1542+ enum ENOTSOCK = 0x40000026; /* Socket operation on non-socket */
1543+ enum EMSGSIZE = 0x40000028; /* Message too long */
1544+ enum EPROTOTYPE = 0x40000029; /* Protocol wrong type for socket */
1545+ enum ENOPROTOOPT = 0x4000002a; /* Protocol not available */
1546+ enum EPROTONOSUPPORT = 0x4000002b; /* Protocol not supported */
1547+ enum ESOCKTNOSUPPORT = 0x4000002c; /* Socket type not supported */
1548+ enum EOPNOTSUPP = 0x4000002d; /* Operation not supported */
1549+ enum EPFNOSUPPORT = 0x4000002e; /* Protocol family not supported */
1550+ enum EAFNOSUPPORT = 0x4000002f; /* Address family not supported by protocol */
1551+ enum EADDRINUSE = 0x40000030; /* Address already in use */
1552+ enum EADDRNOTAVAIL = 0x40000031; /* Cannot assign requested address */
1553+ enum ENETDOWN = 0x40000032; /* Network is down */
1554+ enum ENETUNREACH = 0x40000033; /* Network is unreachable */
1555+ enum ENETRESET = 0x40000034; /* Network dropped connection on reset */
1556+ enum ECONNABORTED = 0x40000035; /* Software caused connection abort */
1557+ enum ECONNRESET = 0x40000036; /* Connection reset by peer */
1558+ enum ENOBUFS = 0x40000037; /* No buffer space available */
1559+ enum EISCONN = 0x40000038; /* Transport endpoint is already connected */
1560+ enum ENOTCONN = 0x40000039; /* Transport endpoint is not connected */
1561+ enum EDESTADDRREQ = 0x40000027; /* Destination address required */
1562+ enum ESHUTDOWN = 0x4000003a; /* Cannot send after transport endpoint shutdown */
1563+ enum ETOOMANYREFS = 0x4000003b; /* Too many references: cannot splice */
1564+ enum ETIMEDOUT = 0x4000003c; /* Connection timed out */
1565+ enum ECONNREFUSED = 0x4000003d; /* Connection refused */
1566+ enum ELOOP = 0x4000003e; /* Too many levels of symbolic links */
1567+ enum ENAMETOOLONG = 0x4000003f; /* File name too long */
1568+ enum EHOSTDOWN = 0x40000040; /* Host is down */
1569+ enum EHOSTUNREACH = 0x40000041; /* No route to host */
1570+ enum ENOTEMPTY = 0x40000042; /* Directory not empty */
1571+ enum EPROCLIM = 0x40000043; /* Too many processes */
1572+ enum EUSERS = 0x40000044; /* Too many users */
1573+ enum EDQUOT = 0x40000045; /* Disk quota exceeded */
1574+ enum ESTALE = 0x40000046; /* Stale file handle */
1575+ enum EREMOTE = 0x40000047; /* Object is remote */
1576+ enum EBADRPC = 0x40000048; /* RPC struct is bad */
1577+ enum ERPCMISMATCH = 0x40000049; /* RPC version wrong */
1578+ enum EPROGUNAVAIL = 0x4000004a; /* RPC program not available */
1579+ enum EPROGMISMATCH = 0x4000004b; /* RPC program version wrong */
1580+ enum EPROCUNAVAIL = 0x4000004c; /* RPC bad procedure for program */
1581+ enum ENOLCK = 0x4000004d; /* No locks available */
1582+ enum EFTYPE = 0x4000004f; /* Inappropriate file type or format */
1583+ enum EAUTH = 0x40000050; /* Authentication error */
1584+ enum ENEEDAUTH = 0x40000051; /* Need authenticator */
1585+ enum ENOSYS = 0x4000004e; /* Function not implemented */
1586+ enum ELIBEXEC = 0x40000053; /* Cannot exec a shared library directly */
1587+ enum ENOTSUP = 0x40000076; /* Not supported */
1588+ enum EILSEQ = 0x4000006a; /* Invalid or incomplete multibyte or wide character */
1589+ enum EBACKGROUND = 0x40000064; /* Inappropriate operation for background process */
1590+ enum EDIED = 0x40000065; /* Translator died */
1591+ enum ED = 0x40000066; /* ? */
1592+ enum EGREGIOUS = 0x40000067; /* You really blew it this time */
1593+ enum EIEIO = 0x40000068; /* Computer bought the farm */
1594+ enum EGRATUITOUS = 0x40000069; /* Gratuitous error */
1595+ enum EBADMSG = 0x4000006b; /* Bad message */
1596+ enum EIDRM = 0x4000006c; /* Identifier removed */
1597+ enum EMULTIHOP = 0x4000006d; /* Multihop attempted */
1598+ enum ENODATA = 0x4000006e; /* No data available */
1599+ enum ENOLINK = 0x4000006f; /* Link has been severed */
1600+ enum ENOMSG = 0x40000070; /* No message of desired type */
1601+ enum ENOSR = 0x40000071; /* Out of streams resources */
1602+ enum ENOSTR = 0x40000072; /* Device not a stream */
1603+ enum EOVERFLOW = 0x40000073; /* Value too large for defined data type */
1604+ enum EPROTO = 0x40000074; /* Protocol error */
1605+ enum ETIME = 0x40000075; /* Timer expired */
1606+ enum ECANCELED = 0x40000077; /* Operation canceled */
1607+ enum EOWNERDEAD = 0x40000078; /* Owner died */
1608+ enum ENOTRECOVERABLE = 0x40000079; /* State not recoverable */
1609+ }
1610 else
1611 {
1612 static assert(false, "Unsupported platform");
1613diff --git a/druntime/src/core/stdc/limits.d b/druntime/src/core/stdc/limits.d
1614index 2684b22bfc..35ee96a052 100644
1615--- a/druntime/src/core/stdc/limits.d
1616+++ b/druntime/src/core/stdc/limits.d
1617@@ -181,5 +181,19 @@ else version (Windows)
1618 ///
1619 enum PIPE_BUF = 5120;
1620 }
1621+else version (Hurd)
1622+{
1623+ // no arbitrary fixed limits
1624+ ///
1625+ // enum MAX_CANON
1626+ ///
1627+ // enum MAX_INPUT
1628+ ///
1629+ enum NAME_MAX = 255;
1630+ ///
1631+ // enum PATH_MAX
1632+ ///
1633+ // enum PIPE_BUF
1634+}
1635 else
1636 static assert(0, "unsupported OS");
1637diff --git a/druntime/src/core/sys/hurd/config.d b/druntime/src/core/sys/hurd/config.d
1638new file mode 100644
1639index 0000000000..109990d544
1640--- /dev/null
1641+++ b/druntime/src/core/sys/hurd/config.d
1642@@ -0,0 +1,30 @@
1643+/**
1644+ * D header file for GNU/Hurd.
1645+ *
1646+ * Copyright: Copyright (c) 2026 D Language Foundation
1647+ * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
1648+ */
1649+module core.sys.hurd.config;
1650+
1651+version (Hurd):
1652+
1653+public import core.sys.posix.config;
1654+
1655+// man 7 feature_test_macros
1656+// http://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html
1657+enum _GNU_SOURCE = true;
1658+// deduced <features.h>
1659+// http://sourceware.org/git/?p=glibc.git;a=blob;f=include/features.h
1660+enum _DEFAULT_SOURCE = true;
1661+enum _ATFILE_SOURCE = true;
1662+
1663+// _BSD_SOURCE and _SVID_SOURCE are deprecated aliases for _DEFAULT_SOURCE.
1664+deprecated("use _DEFAULT_SOURCE")
1665+{
1666+ enum _BSD_SOURCE = true;
1667+ enum _SVID_SOURCE = true;
1668+}
1669+
1670+enum __USE_MISC = _DEFAULT_SOURCE;
1671+enum __USE_ATFILE = _ATFILE_SOURCE;
1672+enum __USE_GNU = _GNU_SOURCE;
1673diff --git a/druntime/src/core/sys/hurd/dlfcn.d b/druntime/src/core/sys/hurd/dlfcn.d
1674new file mode 100644
1675index 0000000000..d496507511
1676--- /dev/null
1677+++ b/druntime/src/core/sys/hurd/dlfcn.d
1678@@ -0,0 +1,114 @@
1679+/**
1680+ * D header file for GNU/Hurd.
1681+ *
1682+ * Copyright: Copyright (c) 2026 D Language Foundation
1683+ * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
1684+ * $(LINK2 http://sourceware.org/git/?p=glibc.git;a=blob;f=dlfcn/dlfcn.h, glibc dlfcn/dlfcn.h)
1685+ */
1686+module core.sys.hurd.dlfcn;
1687+
1688+version (Hurd):
1689+extern (C):
1690+nothrow:
1691+@nogc:
1692+@system:
1693+
1694+
1695+public import core.sys.posix.dlfcn;
1696+import core.sys.hurd.config;
1697+
1698+// <bits/dlfcn.h>
1699+
1700+// http://sourceware.org/git/?p=glibc.git;a=blob;f=bits/dlfcn.h
1701+// enum RTLD_LAZY = 0x00001; // POSIX
1702+// enum RTLD_NOW = 0x00002; // POSIX
1703+enum RTLD_BINDING_MASK = 0x3;
1704+enum RTLD_NOLOAD = 0x00004;
1705+enum RTLD_DEEPBIND = 0x00008;
1706+
1707+// enum RTLD_GLOBAL = 0x00100; // POSIX
1708+// enum RTLD_LOCAL = 0; // POSIX
1709+enum RTLD_NODELETE = 0x01000;
1710+
1711+static if (__USE_GNU)
1712+{
1713+ RT DL_CALL_FCT(RT, Args...)(RT function(Args) fctp, auto ref Args args)
1714+ {
1715+ _dl_mcount_wrapper_check(cast(void*)fctp);
1716+ return fctp(args);
1717+ }
1718+
1719+ void _dl_mcount_wrapper_check(void* __selfpc);
1720+}
1721+// <bits/dlfcn.h>
1722+
1723+static if (__USE_GNU)
1724+{
1725+ enum RTLD_NEXT = cast(void *)-1L;
1726+ enum RTLD_DEFAULT = cast(void *)0;
1727+ alias Lmid_t = c_long;
1728+ enum LM_ID_BASE = 0;
1729+ enum LM_ID_NEWLM = -1;
1730+}
1731+
1732+// void* dlopen(const scope char* __file, int __mode); // POSIX
1733+// int dlclose(void* __handle); // POSIX
1734+// void* dlsym(void* __handle, const scope char* __name); // POSIX
1735+
1736+static if (__USE_GNU)
1737+{
1738+ void* dlmopen(Lmid_t __nsid, const scope char* __file, int __mode);
1739+ void* dlvsym(void* __handle, const scope char* __name, const scope char* __version);
1740+}
1741+
1742+// char* dlerror(); // POSIX
1743+
1744+static if (__USE_GNU)
1745+{
1746+ struct Dl_info
1747+ {
1748+ const(char)* dli_fname;
1749+ void* dli_fbase;
1750+ const(char)* dli_sname;
1751+ void* dli_saddr;
1752+ }
1753+
1754+ int dladdr(const scope void* __address, Dl_info* __info);
1755+ int dladdr1(void* __address, Dl_info* __info, void** __extra_info, int __flags);
1756+
1757+ enum
1758+ {
1759+ RTLD_DL_SYMENT = 1,
1760+ RTLD_DL_LINKMAP = 2,
1761+ }
1762+
1763+ int dlinfo(void* __handle, int __request, void* __arg);
1764+
1765+ enum
1766+ {
1767+ RTLD_DI_LMID = 1,
1768+ RTLD_DI_LINKMAP = 2,
1769+ RTLD_DI_CONFIGADDR = 3,
1770+ RTLD_DI_SERINFO = 4,
1771+ RTLD_DI_SERINFOSIZE = 5,
1772+ RTLD_DI_ORIGIN = 6,
1773+ RTLD_DI_PROFILENAME = 7,
1774+ RTLD_DI_PROFILEOUT = 8,
1775+ RTLD_DI_TLS_MODID = 9,
1776+ RTLD_DI_TLS_DATA = 10,
1777+ RTLD_DI_MAX = 10,
1778+ }
1779+
1780+ struct Dl_serpath
1781+ {
1782+ char* dls_name;
1783+ uint dls_flags;
1784+ }
1785+
1786+ struct Dl_serinfo
1787+ {
1788+ size_t dls_size;
1789+ uint dls_cnt;
1790+ Dl_serpath[1] dls_serpath;
1791+ }
1792+}
1793diff --git a/druntime/src/core/sys/hurd/elf.d b/druntime/src/core/sys/hurd/elf.d
1794new file mode 100644
1795index 0000000000..47080ecbcb
1796--- /dev/null
1797+++ b/druntime/src/core/sys/hurd/elf.d
1798@@ -0,0 +1,162 @@
1799+/**
1800+ * D header file for GNU/Hurd.
1801+ *
1802+ * Copyright: Copyright (c) 2026 D Language Foundation
1803+ * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
1804+ * $(LINK2 http://sourceware.org/git/?p=glibc.git;a=blob;f=elf/elf.h, glibc elf/elf.h)
1805+ */
1806+module core.sys.hurd.elf;
1807+
1808+version (Hurd):
1809+extern (C):
1810+pure:
1811+nothrow:
1812+@system:
1813+
1814+import core.stdc.stdint;
1815+public import core.sys.elf;
1816+
1817+extern (D)
1818+{
1819+ auto ELF32_ST_VISIBILITY(O)(O o) { return o & 0x03; }
1820+ alias ELF64_ST_VISIBILITY = ELF32_ST_VISIBILITY;
1821+}
1822+
1823+struct Elf32_Nhdr
1824+{
1825+ Elf32_Word n_namesz;
1826+ Elf32_Word n_descsz;
1827+ Elf32_Word n_type;
1828+}
1829+
1830+struct Elf64_Nhdr
1831+{
1832+ Elf64_Word n_namesz;
1833+ Elf64_Word n_descsz;
1834+ Elf64_Word n_type;
1835+}
1836+
1837+enum NT_PRSTATUS = 1;
1838+enum NT_FPREGSET = 2;
1839+enum NT_PRPSINFO = 3;
1840+enum NT_PRXREG = 4;
1841+enum NT_TASKSTRUCT = 4;
1842+enum NT_PLATFORM = 5;
1843+enum NT_AUXV = 6;
1844+enum NT_GWINDOWS = 7;
1845+enum NT_ASRS = 8;
1846+enum NT_PSTATUS = 10;
1847+enum NT_PSINFO = 13;
1848+enum NT_PRCRED = 14;
1849+enum NT_UTSNAME = 15;
1850+enum NT_LWPSTATUS = 16;
1851+enum NT_LWPSINFO = 17;
1852+enum NT_PRFPXREG = 20;
1853+enum NT_SIGINFO = 0x53494749;
1854+enum NT_FILE = 0x46494c45;
1855+enum NT_PRXFPREG = 0x46e62b7f;
1856+enum NT_PPC_VMX = 0x100;
1857+enum NT_PPC_SPE = 0x101;
1858+enum NT_PPC_VSX = 0x102;
1859+enum NT_386_TLS = 0x200;
1860+enum NT_386_IOPERM = 0x201;
1861+enum NT_X86_XSTATE = 0x202;
1862+enum NT_S390_HIGH_GPRS = 0x300;
1863+enum NT_S390_TIMER = 0x301;
1864+enum NT_S390_TODCMP = 0x302;
1865+enum NT_S390_TODPREG = 0x303;
1866+enum NT_S390_CTRS = 0x304;
1867+enum NT_S390_PREFIX = 0x305;
1868+enum NT_S390_LAST_BREAK = 0x306;
1869+enum NT_S390_SYSTEM_CALL = 0x307;
1870+enum NT_S390_TDB = 0x308;
1871+enum NT_ARM_VFP = 0x400;
1872+enum NT_ARM_TLS = 0x401;
1873+enum NT_ARM_HW_BREAK = 0x402;
1874+enum NT_ARM_HW_WATCH = 0x403;
1875+
1876+enum NT_VERSION = 1;
1877+
1878+struct Elf32_Dyn
1879+{
1880+ Elf32_Sword d_tag;
1881+ union _d_un
1882+ {
1883+ Elf32_Word d_val;
1884+ Elf32_Addr d_ptr;
1885+ } _d_un d_un;
1886+}
1887+
1888+struct Elf64_Dyn
1889+{
1890+ Elf64_Sxword d_tag;
1891+ union _d_un
1892+ {
1893+ Elf64_Xword d_val;
1894+ Elf64_Addr d_ptr;
1895+ } _d_un d_un;
1896+}
1897+
1898+enum NT_GNU_ABI_TAG = 1;
1899+enum NT_GNU_HWCAP = 2;
1900+enum NT_GNU_BUILD_ID = 3;
1901+enum NT_GNU_GOLD_VERSION = 4;
1902+
1903+struct Elf32_auxv_t
1904+{
1905+ uint32_t a_type;
1906+ union _a_un
1907+ {
1908+ uint32_t a_val;
1909+ } _a_un a_un;
1910+}
1911+
1912+struct Elf64_auxv_t
1913+{
1914+ uint64_t a_type;
1915+ union _a_un
1916+ {
1917+ uint64_t a_val;
1918+ } _a_un a_un;
1919+}
1920+
1921+enum AT_NULL = 0;
1922+enum AT_IGNORE = 1;
1923+enum AT_EXECFD = 2;
1924+enum AT_PHDR = 3;
1925+enum AT_PHENT = 4;
1926+enum AT_PHNUM = 5;
1927+enum AT_PAGESZ = 6;
1928+enum AT_BASE = 7;
1929+enum AT_FLAGS = 8;
1930+enum AT_ENTRY = 9;
1931+enum AT_NOTELF = 10;
1932+enum AT_UID = 11;
1933+enum AT_EUID = 12;
1934+enum AT_GID = 13;
1935+enum AT_EGID = 14;
1936+enum AT_CLKTCK = 17;
1937+enum AT_PLATFORM = 15;
1938+enum AT_HWCAP = 16;
1939+enum AT_FPUCW = 18;
1940+enum AT_DCACHEBSIZE = 19;
1941+enum AT_ICACHEBSIZE = 20;
1942+enum AT_UCACHEBSIZE = 21;
1943+enum AT_IGNOREPPC = 22;
1944+
1945+enum AT_SECURE = 23;
1946+
1947+enum AT_BASE_PLATFORM = 24;
1948+
1949+enum AT_RANDOM = 25;
1950+
1951+enum AT_HWCAP2 = 26;
1952+
1953+enum AT_EXECFN = 31;
1954+enum AT_SYSINFO = 32;
1955+enum AT_SYSINFO_EHDR = 33;
1956+
1957+enum AT_L1I_CACHESHAPE = 34;
1958+enum AT_L1D_CACHESHAPE = 35;
1959+enum AT_L2_CACHESHAPE = 36;
1960+enum AT_L3_CACHESHAPE = 37;
1961diff --git a/druntime/src/core/sys/hurd/errno.d b/druntime/src/core/sys/hurd/errno.d
1962new file mode 100644
1963index 0000000000..db9c83c901
1964--- /dev/null
1965+++ b/druntime/src/core/sys/hurd/errno.d
1966@@ -0,0 +1,21 @@
1967+/**
1968+ * D header file for GNU/Hurd
1969+ *
1970+ * Copyright: Copyright (c) 2026 D Language Foundation
1971+ * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
1972+ * $(LINK2 http://sourceware.org/git/?p=glibc.git;a=blob;f=stdlib/errno.h, glibc stdlib/errno.h)
1973+ */
1974+module core.sys.hurd.errno;
1975+
1976+version (Hurd):
1977+extern (C):
1978+nothrow:
1979+
1980+public import core.stdc.errno;
1981+import core.sys.hurd.config;
1982+
1983+static if (_GNU_SOURCE)
1984+{
1985+ extern __gshared char* program_invocation_name, program_invocation_short_name;
1986+ alias error_t = int;
1987+}
1988diff --git a/druntime/src/core/sys/hurd/execinfo.d b/druntime/src/core/sys/hurd/execinfo.d
1989new file mode 100644
1990index 0000000000..4afeffa8ff
1991--- /dev/null
1992+++ b/druntime/src/core/sys/hurd/execinfo.d
1993@@ -0,0 +1,16 @@
1994+/**
1995+ * D header file for GNU/Hurd.
1996+ *
1997+ * Copyright: Copyright (c) 2026 D Language Foundation
1998+ * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
1999+ */
2000+module core.sys.hurd.execinfo;
2001+
2002+version (Hurd):
2003+extern (C):
2004+nothrow:
2005+@nogc:
2006+
2007+int backtrace(void** buffer, int size);
2008+char** backtrace_symbols(const(void*)* buffer, int size);
2009+void backtrace_symbols_fd(const(void*)* buffer, int size, int fd);
2010diff --git a/druntime/src/core/sys/hurd/link.d b/druntime/src/core/sys/hurd/link.d
2011new file mode 100644
2012index 0000000000..7089cb9075
2013--- /dev/null
2014+++ b/druntime/src/core/sys/hurd/link.d
2015@@ -0,0 +1,134 @@
2016+/**
2017+ * D header file for GNU/Hurd.
2018+ * Copyright: Copyright (c) 2026 D Language Foundation
2019+ * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
2020+ *
2021+ * $(LINK2 http://sourceware.org/git/?p=glibc.git;a=blob;f=elf/link.h, glibc elf/link.h)
2022+ */
2023+module core.sys.hurd.link;
2024+
2025+version (Hurd):
2026+extern (C):
2027+nothrow:
2028+@system:
2029+
2030+version (X86) version = X86_Any;
2031+version (X86_64) version = X86_Any;
2032+
2033+import core.stdc.stdint : uintptr_t, uint32_t, uint64_t;
2034+import core.sys.hurd.config : __WORDSIZE;
2035+import core.sys.hurd.dlfcn : Lmid_t;
2036+import core.sys.hurd.elf;
2037+
2038+version (X86_Any)
2039+{
2040+ // http://sourceware.org/git/?p=glibc.git;a=blob;f=bits/elfclass.h
2041+ alias __ELF_NATIVE_CLASS = __WORDSIZE;
2042+ alias Elf_Symndx = uint32_t;
2043+}
2044+else
2045+ static assert(0, "unimplemented");
2046+// <bits/elfclass.h>
2047+
2048+template ElfW(string type)
2049+{
2050+ mixin("alias ElfW = Elf"~__ELF_NATIVE_CLASS.stringof~"_"~type~";");
2051+}
2052+
2053+enum
2054+{
2055+ RT_CONSISTENT,
2056+ RT_ADD,
2057+ RT_DELETE,
2058+}
2059+
2060+struct r_debug
2061+{
2062+ int r_version;
2063+ link_map* r_map;
2064+ ElfW!"Addr" r_brk;
2065+ typeof(RT_CONSISTENT) r_state;
2066+ ElfW!"Addr" r_ldbase;
2067+}
2068+
2069+extern r_debug _r_debug;
2070+extern ElfW!"Dyn"* _DYNAMIC;
2071+
2072+struct link_map
2073+{
2074+ ElfW!"Addr" l_addr;
2075+ char* l_name;
2076+ ElfW!"Dyn"* l_ld;
2077+ link_map* l_next, l_prev;
2078+}
2079+
2080+enum
2081+{
2082+ LA_ACT_CONSISTENT,
2083+ LA_ACT_ADD,
2084+ LA_ACT_DELETE,
2085+}
2086+
2087+enum
2088+{
2089+ LA_SER_ORIG = 0x01,
2090+ LA_SER_LIBPATH = 0x02,
2091+ LA_SER_RUNPATH = 0x04,
2092+ LA_SER_CONFIG = 0x08,
2093+ LA_SER_DEFAULT = 0x40,
2094+ LA_SER_SECURE = 0x80,
2095+}
2096+
2097+
2098+enum
2099+{
2100+ LA_FLG_BINDTO = 0x01,
2101+ LA_FLG_BINDFROM = 0x02,
2102+}
2103+
2104+
2105+enum
2106+{
2107+ LA_SYMB_NOPLTENTER = 0x01,
2108+ LA_SYMB_NOPLTEXIT = 0x02,
2109+ LA_SYMB_STRUCTCALL = 0x04,
2110+ LA_SYMB_DLSYM = 0x08,
2111+ LA_SYMB_ALTVALUE = 0x10,
2112+}
2113+
2114+struct dl_phdr_info
2115+{
2116+ ElfW!"Addr" dlpi_addr;
2117+ const(char)* dlpi_name;
2118+ const(ElfW!"Phdr")* dlpi_phdr;
2119+ ElfW!"Half" dlpi_phnum;
2120+
2121+ // check the SIZE argument of the dl_iterate_phdr callback whether
2122+ // the following members are available
2123+ ulong dlpi_adds;
2124+ ulong dlpi_subs;
2125+
2126+ size_t dlpi_tls_modid;
2127+ void *dlpi_tls_data;
2128+}
2129+
2130+private alias dl_iterate_phdr_cb = extern(C) int function(dl_phdr_info*, size_t, void *);
2131+private alias dl_iterate_phdr_cb_ngc = extern(C) int function(dl_phdr_info*, size_t, void *) @nogc;
2132+extern int dl_iterate_phdr(dl_iterate_phdr_cb __callback, void*__data);
2133+extern int dl_iterate_phdr(dl_iterate_phdr_cb_ngc __callback, void*__data) @nogc;
2134+
2135+// ld.so auditing interfaces prototypes have to be defined by the auditing DSO.
2136+extern uint la_version(uint __version);
2137+extern void la_activity(uintptr_t *__cookie, uint __flag);
2138+extern char* la_objsearch(const(char)* __name, uintptr_t* __cookie,
2139+ uint __flag);
2140+extern uint la_objopen(link_map* __map, Lmid_t __lmid,
2141+ uintptr_t* __cookie);
2142+extern void la_preinit(uintptr_t* __cookie);
2143+extern uintptr_t la_symbind32(Elf32_Sym* __sym, uint __ndx,
2144+ uintptr_t* __refcook, uintptr_t* __defcook,
2145+ uint *__flags, const(char)* __symname);
2146+extern uintptr_t la_symbind64(Elf64_Sym* __sym, uint __ndx,
2147+ uintptr_t* __refcook, uintptr_t* __defcook,
2148+ uint* __flags, const(char)* __symname);
2149+extern uint la_objclose(uintptr_t *__cookie);
2150diff --git a/druntime/src/core/sys/hurd/sys/types.d b/druntime/src/core/sys/hurd/sys/types.d
2151new file mode 100644
2152index 0000000000..96e46040ff
2153--- /dev/null
2154+++ b/druntime/src/core/sys/hurd/sys/types.d
2155@@ -0,0 +1,22 @@
2156+/**
2157+ * D header file for Hurd extensions to POSIX's sys/types.h.
2158+ *
2159+ * Copyright: Copyright (c) 2026 D Language Foundation
2160+ * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
2161+ */
2162+
2163+module core.sys.hurd.sys.types;
2164+
2165+import core.sys.posix.config;
2166+
2167+version (Hurd):
2168+extern(C):
2169+@nogc:
2170+nothrow:
2171+
2172+static if (__WORDSIZE == 32)
2173+ alias ipc_pid_t = ushort;
2174+else
2175+ alias ipc_pid_t = int;
2176+
2177+alias fsid_t = ulong;
2178diff --git a/druntime/src/core/sys/hurd/time.d b/druntime/src/core/sys/hurd/time.d
2179new file mode 100644
2180index 0000000000..12031e599c
2181--- /dev/null
2182+++ b/druntime/src/core/sys/hurd/time.d
2183@@ -0,0 +1,15 @@
2184+/**
2185+ * D header file for Hurd extensions to POSIX's time.h.
2186+ *
2187+ * Copyright: Copyright (c) 2026 D Language Foundation
2188+ * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
2189+ */
2190+module core.sys.hurd.time;
2191+
2192+public import core.sys.posix.time;
2193+
2194+version (Hurd):
2195+
2196+enum CLOCK_MONOTONIC_RAW = 4;
2197+enum CLOCK_REALTIME_COARSE = 5;
2198+enum CLOCK_MONOTONIC_COARSE = 6;
2199diff --git a/druntime/src/core/sys/hurd/unistd.d b/druntime/src/core/sys/hurd/unistd.d
2200new file mode 100644
2201index 0000000000..a351134cd4
2202--- /dev/null
2203+++ b/druntime/src/core/sys/hurd/unistd.d
2204@@ -0,0 +1,30 @@
2205+/**
2206+ * D header file for GNU/Hurd.
2207+ *
2208+ * Copyright: Copyright (c) 2026 D Language Foundation
2209+ * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
2210+ */
2211+module core.sys.hurd.unistd;
2212+
2213+public import core.sys.posix.unistd;
2214+
2215+version (Hurd):
2216+extern(C):
2217+nothrow:
2218+@nogc:
2219+
2220+
2221+// Additional seek constants for sparse file handling
2222+// from Hurds's unistd.h, stdio.h
2223+enum {
2224+ /// Offset is relative to the next location containing data
2225+ SEEK_DATA = 3,
2226+ /// Offset is relative to the next hole (or EOF if file is not sparse)
2227+ SEEK_HOLE = 4
2228+}
2229+
2230+/// Prompt for a password without echoing it.
2231+char* getpass(const(char)* prompt);
2232+
2233+/// Close all open file descriptors greater or equal to `lowfd`
2234+void closefrom(int lowfd);
2235diff --git a/druntime/src/core/sys/posix/dirent.d b/druntime/src/core/sys/posix/dirent.d
2236index c77d6da22b..24274ba98d 100644
2237--- a/druntime/src/core/sys/posix/dirent.d
2238+++ b/druntime/src/core/sys/posix/dirent.d
2239@@ -158,6 +158,17 @@ else version (Solaris)
2240 char[1] d_name = 0;
2241 }
2242 }
2243+else version (Hurd)
2244+{
2245+ struct dirent
2246+ {
2247+ ino_t d_ino;
2248+ ushort d_reclen;
2249+ ubyte d_type;
2250+ ubyte d_namlen;
2251+ char[1] d_name = 0;
2252+ }
2253+}
2254 else
2255 {
2256 static assert(false, "Unsupported platform");
2257diff --git a/druntime/src/core/sys/posix/fcntl.d b/druntime/src/core/sys/posix/fcntl.d
2258index f64e234ced..79c6043400 100644
2259--- a/druntime/src/core/sys/posix/fcntl.d
2260+++ b/druntime/src/core/sys/posix/fcntl.d
2261@@ -870,6 +870,113 @@ else version (Solaris)
2262 enum AT_REMOVEDIR = 0x1;
2263 enum AT_EACCESS = 0x4;
2264 }
2265+else version (Hurd)
2266+{
2267+ enum F_DUPFD = 0;
2268+ enum F_GETFD = 1;
2269+ enum F_SETFD = 2;
2270+ enum F_GETFL = 3;
2271+ enum F_SETFL = 4;
2272+ enum F_GETOWN = 5;
2273+ enum F_SETOWN = 6;
2274+
2275+ static if ( __USE_FILE_OFFSET64 )
2276+ {
2277+ enum F_GETLK = F_GETLK64;
2278+ enum F_SETLK = F_SETLK64;
2279+ enum F_SETLKW = F_SETLKW64;
2280+ }
2281+ else
2282+ {
2283+ enum F_GETLK = 7;
2284+ enum F_SETLK = 8;
2285+ enum F_SETLKW = 9;
2286+ }
2287+ enum F_GETLK64 = 10;
2288+ enum F_SETLK64 = 11;
2289+ enum F_SETLKW64 = 12;
2290+
2291+ enum F_DUPFD_CLOEXEC = 1030;
2292+
2293+ enum FD_CLOEXEC = 1;
2294+
2295+ enum F_RDLCK = 1;
2296+ enum F_WRLCK = 2;
2297+ enum F_UNLCK = 3;
2298+
2299+ enum O_CREAT = 0x0010;
2300+ enum O_EXCL = 0x0020;
2301+ enum O_NOCTTY = 0;
2302+ enum O_TRUNC = 0x00010000;
2303+
2304+ enum O_APPEND = 0x0100;
2305+ enum O_DSYNC = O_SYNC;
2306+ enum O_NONBLOCK = 0x0004;
2307+ enum O_RSYNC = O_SYNC;
2308+
2309+
2310+ enum O_ACCMODE = O_RDWR;
2311+ enum O_RDONLY = 0x0001;
2312+ enum O_WRONLY = 0x0002;
2313+ enum O_RDWR = (O_RDONLY|O_WRONLY);
2314+
2315+ enum O_SYNC = O_FSYNC;
2316+ enum O_FSYNC = 0x0400;
2317+
2318+ enum O_READ = O_RDONLY;
2319+ enum O_WRITE = O_WRONLY;
2320+ enum O_EXEC = 0x0004;
2321+ enum O_NORW = 0;
2322+ enum O_LARGEFILE = 0;
2323+ enum O_NOLINK = 0x0040;
2324+ enum O_NOTRANS = 0x0080;
2325+ enum O_NOFOLLOW = 0x00100000;
2326+ enum O_DIRECTORY = 0x00200000;
2327+ enum O_ASYNC = 0x0200;
2328+ enum O_NOATIME = 0x0800;
2329+ enum O_SHLOCK = 0x00020000;
2330+ enum O_EXLOCK = 0x00040000;
2331+ enum O_NDELAY = O_NONBLOCK;
2332+ enum O_HURD = (0xffff | O_EXLOCK | O_SHLOCK);
2333+ enum O_CLOEXEC = 0x00400000;
2334+ enum O_TMPFILE = 0x00800000;
2335+ enum O_IGNORE_CTTY = 0x00080000;
2336+
2337+
2338+ version (X86)
2339+ {
2340+ struct flock
2341+ {
2342+ int l_type;
2343+ int l_whence;
2344+ off_t l_start;
2345+ off_t l_len;
2346+ pid_t l_pid;
2347+ }
2348+ }
2349+ else version (X86_64)
2350+ {
2351+ struct flock
2352+ {
2353+ short l_type;
2354+ short l_whence;
2355+ off_t l_start;
2356+ off_t l_len;
2357+ pid_t l_pid;
2358+ }
2359+ }
2360+ else
2361+ {
2362+ static assert(false, "Unsupported platform");
2363+ }
2364+
2365+ enum AT_FDCWD = -100;
2366+
2367+ enum AT_EACCESS = 0x200;
2368+ enum AT_SYMLINK_NOFOLLOW = 0x100;
2369+ enum AT_SYMLINK_FOLLOW = 0x400;
2370+ enum AT_REMOVEDIR = 0x200;
2371+}
2372 else
2373 {
2374 static assert(false, "Unsupported platform");
2375diff --git a/druntime/src/core/sys/posix/netinet/in_.d b/druntime/src/core/sys/posix/netinet/in_.d
2376index 75359ea213..fc25ed5b4a 100644
2377--- a/druntime/src/core/sys/posix/netinet/in_.d
2378+++ b/druntime/src/core/sys/posix/netinet/in_.d
2379@@ -85,18 +85,31 @@ version (CRuntime_Glibc)
2380 //{
2381 // in_addr_t s_addr;
2382 //}
2383+ version (linux)
2384+ {
2385+ private enum __SOCK_SIZE__ = 16;
2386
2387- private enum __SOCK_SIZE__ = 16;
2388+ struct sockaddr_in
2389+ {
2390+ sa_family_t sin_family;
2391+ in_port_t sin_port;
2392+ in_addr sin_addr;
2393
2394- struct sockaddr_in
2395+ /* Pad to size of `struct sockaddr'. */
2396+ ubyte[__SOCK_SIZE__ - sa_family_t.sizeof -
2397+ in_port_t.sizeof - in_addr.sizeof] __pad;
2398+ }
2399+ }
2400+ else version (Hurd)
2401 {
2402- sa_family_t sin_family;
2403- in_port_t sin_port;
2404- in_addr sin_addr;
2405-
2406- /* Pad to size of `struct sockaddr'. */
2407- ubyte[__SOCK_SIZE__ - sa_family_t.sizeof -
2408- in_port_t.sizeof - in_addr.sizeof] __pad;
2409+ struct sockaddr_in
2410+ {
2411+ ubyte sin_len;
2412+ sa_family_t sin_family;
2413+ in_port_t sin_port;
2414+ in_addr sin_addr;
2415+ ubyte[8] sin_zero;
2416+ }
2417 }
2418
2419 enum
2420@@ -513,13 +526,28 @@ version (CRuntime_Glibc)
2421 }
2422 }
2423
2424- struct sockaddr_in6
2425+ version (linux)
2426 {
2427- sa_family_t sin6_family;
2428- in_port_t sin6_port;
2429- uint32_t sin6_flowinfo;
2430- in6_addr sin6_addr;
2431- uint32_t sin6_scope_id;
2432+ struct sockaddr_in6
2433+ {
2434+ ushort sin6_family;
2435+ uint16_t sin6_port;
2436+ uint32_t sin6_flowinfo;
2437+ in6_addr sin6_addr;
2438+ uint32_t sin6_scope_id;
2439+ }
2440+ }
2441+ else version (Hurd)
2442+ {
2443+ struct sockaddr_in6
2444+ {
2445+ uint8_t sin6_len;
2446+ sa_family_t sin6_family;
2447+ uint16_t sin6_port;
2448+ uint32_t sin6_flowinfo;
2449+ in6_addr sin6_addr;
2450+ uint32_t sin6_scope_id;
2451+ }
2452 }
2453
2454 extern __gshared immutable in6_addr in6addr_any;
2455diff --git a/druntime/src/core/sys/posix/poll.d b/druntime/src/core/sys/posix/poll.d
2456index 4a320d158d..e8084a2a70 100644
2457--- a/druntime/src/core/sys/posix/poll.d
2458+++ b/druntime/src/core/sys/posix/poll.d
2459@@ -338,6 +338,22 @@ else version (Solaris)
2460 POLLNVAL = 0x0020,
2461 }
2462 }
2463+else version (Hurd)
2464+{
2465+ enum
2466+ {
2467+ POLLIN = 0x001,
2468+ POLLRDNORM = POLLIN,
2469+ POLLRDBAND = POLLPRI,
2470+ POLLPRI = 0x002,
2471+ POLLOUT = 0x004,
2472+ POLLWRNORM = POLLOUT,
2473+ POLLWRBAND = POLLOUT,
2474+ POLLERR = 0x008, /* ocatal 010 */
2475+ POLLHUP = 0x010, /* ocatal 020 */
2476+ POLLNVAL = 0x020, /* ocatal 040 */
2477+ }
2478+}
2479 else
2480 {
2481 static assert(false, "Unsupported platform");
2482diff --git a/druntime/src/core/sys/posix/pthread.d b/druntime/src/core/sys/posix/pthread.d
2483index 33c442df08..9064e1e615 100644
2484--- a/druntime/src/core/sys/posix/pthread.d
2485+++ b/druntime/src/core/sys/posix/pthread.d
2486@@ -104,41 +104,83 @@ void pthread_testcancel();
2487 */
2488 version (CRuntime_Glibc)
2489 {
2490- enum
2491+ version (linux)
2492 {
2493- PTHREAD_CANCEL_ENABLE,
2494- PTHREAD_CANCEL_DISABLE
2495- }
2496+ enum
2497+ {
2498+ PTHREAD_CANCEL_ENABLE,
2499+ PTHREAD_CANCEL_DISABLE
2500+ }
2501
2502- enum
2503- {
2504- PTHREAD_CANCEL_DEFERRED,
2505- PTHREAD_CANCEL_ASYNCHRONOUS
2506- }
2507+ enum
2508+ {
2509+ PTHREAD_CANCEL_DEFERRED,
2510+ PTHREAD_CANCEL_ASYNCHRONOUS
2511+ }
2512
2513- enum PTHREAD_CANCELED = cast(void*) -1;
2514+ enum PTHREAD_CANCELED = cast(void*) -1;
2515
2516- //enum pthread_mutex_t PTHREAD_COND_INITIALIZER = { __LOCK_ALT_INITIALIZER, 0, "", 0 };
2517+ //enum pthread_mutex_t PTHREAD_COND_INITIALIZER = { __LOCK_ALT_INITIALIZER, 0, "", 0 };
2518
2519- enum
2520- {
2521- PTHREAD_CREATE_JOINABLE,
2522- PTHREAD_CREATE_DETACHED
2523- }
2524+ enum
2525+ {
2526+ PTHREAD_CREATE_JOINABLE,
2527+ PTHREAD_CREATE_DETACHED
2528+ }
2529
2530- enum
2531- {
2532- PTHREAD_INHERIT_SCHED,
2533- PTHREAD_EXPLICIT_SCHED
2534- }
2535+ enum
2536+ {
2537+ PTHREAD_INHERIT_SCHED,
2538+ PTHREAD_EXPLICIT_SCHED
2539+ }
2540
2541- enum PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t.init;
2542- enum PTHREAD_ONCE_INIT = pthread_once_t.init;
2543+ enum PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t.init;
2544+ enum PTHREAD_ONCE_INIT = pthread_once_t.init;
2545
2546- enum
2547+ enum
2548+ {
2549+ PTHREAD_PROCESS_PRIVATE,
2550+ PTHREAD_PROCESS_SHARED
2551+ }
2552+ }
2553+ else version (Hurd)
2554 {
2555- PTHREAD_PROCESS_PRIVATE,
2556- PTHREAD_PROCESS_SHARED
2557+ enum
2558+ {
2559+ PTHREAD_CANCEL_DISABLE,
2560+ PTHREAD_CANCEL_ENABLE,
2561+ }
2562+
2563+ enum
2564+ {
2565+ PTHREAD_CANCEL_DEFERRED,
2566+ PTHREAD_CANCEL_ASYNCHRONOUS
2567+ }
2568+
2569+ enum PTHREAD_CANCELED = cast(void*) -1;
2570+
2571+ // enum __pthread_cond PTHREAD_COND_INITIALIZER = { __PTHREAD_SPIN_LOCK_INITIALIZER, NULL, NULL, 0, NULL }
2572+
2573+ enum
2574+ {
2575+ PTHREAD_CREATE_JOINABLE = 0,
2576+ PTHREAD_CREATE_DETACHED,
2577+ }
2578+
2579+ enum
2580+ {
2581+ PTHREAD_EXPLICIT_SCHED = 0,
2582+ PTHREAD_INHERIT_SCHED ,
2583+ }
2584+
2585+ enum PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t.init;
2586+ enum PTHREAD_ONCE_INIT = pthread_once_t.init;
2587+
2588+ enum
2589+ {
2590+ PTHREAD_PROCESS_PRIVATE = 0,
2591+ PTHREAD_PROCESS_SHARED,
2592+ }
2593 }
2594 }
2595 else version (Darwin)
2596@@ -477,32 +519,70 @@ alias _pthread_cleanup_routine = void function(void*);
2597 alias _pthread_cleanup_routine_nogc = void function(void*) @nogc;
2598 version (CRuntime_Glibc)
2599 {
2600- struct _pthread_cleanup_buffer
2601+ version (linux)
2602 {
2603- _pthread_cleanup_routine __routine;
2604- void* __arg;
2605- int __canceltype;
2606- _pthread_cleanup_buffer* __prev;
2607- }
2608+ struct _pthread_cleanup_buffer
2609+ {
2610+ _pthread_cleanup_routine __routine;
2611+ void* __arg;
2612+ int __canceltype;
2613+ _pthread_cleanup_buffer* __prev;
2614+ }
2615
2616- void _pthread_cleanup_push(_pthread_cleanup_buffer*, _pthread_cleanup_routine, void*);
2617- void _pthread_cleanup_push(_pthread_cleanup_buffer*, _pthread_cleanup_routine_nogc, void*) @nogc;
2618- void _pthread_cleanup_pop(_pthread_cleanup_buffer*, int);
2619+ void _pthread_cleanup_push(_pthread_cleanup_buffer*, _pthread_cleanup_routine, void*);
2620+ void _pthread_cleanup_push(_pthread_cleanup_buffer*, _pthread_cleanup_routine_nogc, void*) @nogc;
2621+ void _pthread_cleanup_pop(_pthread_cleanup_buffer*, int);
2622
2623- struct pthread_cleanup
2624- {
2625- _pthread_cleanup_buffer buffer = void;
2626+ struct pthread_cleanup
2627+ {
2628+ _pthread_cleanup_buffer buffer = void;
2629
2630- extern (D) void push(F: _pthread_cleanup_routine)(F routine, void* arg )
2631+ extern (D) void push(F: _pthread_cleanup_routine)(F routine, void* arg )
2632+ {
2633+ _pthread_cleanup_push( &buffer, routine, arg );
2634+ }
2635+
2636+ extern (D) void pop()( int execute )
2637+ {
2638+ _pthread_cleanup_pop( &buffer, execute );
2639+ }
2640+ }
2641+ }
2642+ else version (Hurd)
2643+ {
2644+ struct __pthread_cancelation_handler
2645 {
2646- _pthread_cleanup_push( &buffer, routine, arg );
2647+ _pthread_cleanup_routine __handler;
2648+ void* __arg;
2649+ __pthread_cancelation_handler* __next;
2650 }
2651
2652- extern (D) void pop()( int execute )
2653+ private __pthread_cancelation_handler** __pthread_get_cleanup_stack();
2654+
2655+ struct pthread_cleanup
2656 {
2657- _pthread_cleanup_pop( &buffer, execute );
2658+ __pthread_cancelation_handler** handlers = void;
2659+ __pthread_cancelation_handler handler = void;
2660+
2661+ extern (D) void push(F: _pthread_cleanup_routine)(F routine, void* arg)
2662+ {
2663+ handlers = __pthread_get_cleanup_stack();
2664+ handler = __pthread_cancelation_handler(routine, arg, *handlers);
2665+ *handlers = &handler;
2666+ }
2667+ extern (D) void pop()(int execute)
2668+ {
2669+ if (execute)
2670+ handler.__handler(handler.__arg);
2671+ *handlers = handler.__next;
2672+ }
2673 }
2674 }
2675+ else
2676+ {
2677+ static assert(false, "Unsupported platform");
2678+ }
2679+
2680 }
2681 else version (Darwin)
2682 {
2683@@ -1064,9 +1144,24 @@ int pthread_setconcurrency(int);
2684
2685 version (CRuntime_Glibc)
2686 {
2687- enum PTHREAD_MUTEX_NORMAL = 0;
2688- enum PTHREAD_MUTEX_RECURSIVE = 1;
2689- enum PTHREAD_MUTEX_ERRORCHECK = 2;
2690+
2691+ version(linux)
2692+ {
2693+ enum PTHREAD_MUTEX_NORMAL = 0;
2694+ enum PTHREAD_MUTEX_RECURSIVE = 1;
2695+ enum PTHREAD_MUTEX_ERRORCHECK = 2;
2696+ }
2697+ else version(Hurd)
2698+ {
2699+ enum PTHREAD_MUTEX_NORMAL = 0;
2700+ enum PTHREAD_MUTEX_ERRORCHECK = 1;
2701+ enum PTHREAD_MUTEX_RECURSIVE = 2;
2702+
2703+ }
2704+ else
2705+ {
2706+ static assert(false, "Unsupported platform");
2707+ }
2708 enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL;
2709
2710 int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*);
2711@@ -1400,6 +1495,22 @@ else version (Solaris)
2712 int pthread_mutexattr_setprioceiling(pthread_mutexattr_t*, int);
2713 int pthread_mutexattr_setprotocol(pthread_mutexattr_t*, int);
2714 }
2715+else version (Hurd)
2716+{
2717+ enum
2718+ {
2719+ PTHREAD_PRIO_NONE = 0,
2720+ PTHREAD_PRIO_INHERIT,
2721+ PTHREAD_PRIO_PROTECT,
2722+ }
2723+
2724+ int pthread_mutex_getprioceiling(const scope pthread_mutex_t*, int*);
2725+ int pthread_mutex_setprioceiling(pthread_mutex_t*, int, int*);
2726+ int pthread_mutexattr_getprioceiling(const scope pthread_mutexattr_t*, int*);
2727+ int pthread_mutexattr_getprotocol(const scope pthread_mutexattr_t*, int*);
2728+ int pthread_mutexattr_setprioceiling(pthread_mutexattr_t*, int);
2729+ int pthread_mutexattr_setprotocol(pthread_mutexattr_t*, int);
2730+}
2731
2732 //
2733 // Scheduling (TPS)
2734@@ -1421,10 +1532,21 @@ int pthread_setschedprio(pthread_t, int);
2735
2736 version (CRuntime_Glibc)
2737 {
2738- enum
2739+ version (linux)
2740 {
2741- PTHREAD_SCOPE_SYSTEM,
2742- PTHREAD_SCOPE_PROCESS
2743+ enum
2744+ {
2745+ PTHREAD_SCOPE_SYSTEM,
2746+ PTHREAD_SCOPE_PROCESS
2747+ }
2748+ }
2749+ else version (Hurd)
2750+ {
2751+ enum
2752+ {
2753+ PTHREAD_SCOPE_SYSTEM = 0,
2754+ PTHREAD_SCOPE_PROCESS,
2755+ }
2756 }
2757
2758 int pthread_attr_getinheritsched(const scope pthread_attr_t*, int*);
2759diff --git a/druntime/src/core/sys/posix/sched.d b/druntime/src/core/sys/posix/sched.d
2760index 273be5e819..d8a1bfe0e4 100644
2761--- a/druntime/src/core/sys/posix/sched.d
2762+++ b/druntime/src/core/sys/posix/sched.d
2763@@ -169,6 +169,17 @@ else version (Solaris)
2764 enum SCHED_FX = 6;
2765 enum _SCHED_NEXT = 7;
2766 }
2767+else version (Hurd)
2768+{
2769+ struct sched_param
2770+ {
2771+ int sched_priority;
2772+ }
2773+
2774+ enum SCHED_FIFO = 1;
2775+ enum SCHED_OTHER = 0;
2776+ enum SCHED_RR = 2;
2777+}
2778 else
2779 {
2780 static assert(false, "Unsupported platform");
2781diff --git a/druntime/src/core/sys/posix/semaphore.d b/druntime/src/core/sys/posix/semaphore.d
2782index dc9c14fd96..8a8b2321b9 100644
2783--- a/druntime/src/core/sys/posix/semaphore.d
2784+++ b/druntime/src/core/sys/posix/semaphore.d
2785@@ -51,19 +51,31 @@ int sem_wait(sem_t*);
2786
2787 version (CRuntime_Glibc)
2788 {
2789- private alias __atomic_lock_t = int;
2790-
2791- private struct _pthread_fastlock
2792+ version(linux)
2793 {
2794- c_long __status;
2795- __atomic_lock_t __spinlock;
2796- }
2797+ private alias __atomic_lock_t = int;
2798
2799- struct sem_t
2800+ private struct _pthread_fastlock
2801+ {
2802+ c_long __status;
2803+ __atomic_lock_t __spinlock;
2804+ }
2805+
2806+ struct sem_t
2807+ {
2808+ _pthread_fastlock __sem_lock;
2809+ int __sem_value;
2810+ void* __sem_waiting;
2811+ }
2812+ }
2813+ else version (Hurd)
2814 {
2815- _pthread_fastlock __sem_lock;
2816- int __sem_value;
2817- void* __sem_waiting;
2818+ private enum __SIZEOF_SEM_T = 20;
2819+ union sem_t
2820+ {
2821+ byte[__SIZEOF_SEM_T] __size;
2822+ c_long __align;
2823+ }
2824 }
2825
2826 enum SEM_FAILED = cast(sem_t*) null;
2827diff --git a/druntime/src/core/sys/posix/signal.d b/druntime/src/core/sys/posix/signal.d
2828index ffa88f48f1..3413df0e86 100644
2829--- a/druntime/src/core/sys/posix/signal.d
2830+++ b/druntime/src/core/sys/posix/signal.d
2831@@ -168,6 +168,9 @@ else version (NetBSD)
2832 enum SIGRTMIN = 33;
2833 enum SIGRTMAX = 63;
2834 }
2835+else version (Hurd)
2836+{
2837+}
2838 else version (linux)
2839 {
2840 // Note: CRuntime_Bionic switched to calling these functions
2841@@ -585,6 +588,24 @@ else version (Solaris)
2842 enum SIGUSR2 = 17;
2843 enum SIGURG = 21;
2844 }
2845+else version (Hurd)
2846+{
2847+ enum SIGALRM = 14;
2848+ enum SIGBUS = 10;
2849+ enum SIGCHLD = 20;
2850+ enum SIGCONT = 19;
2851+ enum SIGHUP = 1;
2852+ enum SIGKILL = 9;
2853+ enum SIGPIPE = 13;
2854+ enum SIGQUIT = 3;
2855+ enum SIGSTOP = 17;
2856+ enum SIGTSTP = 18;
2857+ enum SIGTTIN = 21;
2858+ enum SIGTTOU = 22;
2859+ enum SIGUSR1 = 30;
2860+ enum SIGUSR2 = 31;
2861+ enum SIGURG = 16;
2862+}
2863 else
2864 {
2865 static assert(false, "Unsupported platform");
2866@@ -872,6 +893,26 @@ else version (Darwin)
2867 int sa_flags;
2868 }
2869 }
2870+else version (Hurd)
2871+{
2872+ struct sigaction_t
2873+ {
2874+ static if ( true /* __USE_POSIX199309 */ )
2875+ {
2876+ union
2877+ {
2878+ sigfn_t sa_handler;
2879+ sigactfn_t sa_sigaction;
2880+ }
2881+ }
2882+ else
2883+ {
2884+ sigfn_t sa_handler;
2885+ }
2886+ sigset_t sa_mask;
2887+ int sa_flags;
2888+ }
2889+}
2890 else
2891 {
2892 static assert(false, "Unsupported platform");
2893@@ -1441,6 +1482,41 @@ else version (Solaris)
2894 enum SI_ASYNCIO = -4;
2895 enum SI_MESGQ = -5;
2896 }
2897+else version(Hurd)
2898+{
2899+ enum SIG_HOLD = cast(sigfn_t2) 2;
2900+
2901+ alias sigset_t = c_ulong;
2902+
2903+ enum SA_NOCLDSTOP = 0x0008; // (CX|XSI)
2904+
2905+ enum SIG_BLOCK = 1;
2906+ enum SIG_UNBLOCK = 2;
2907+ enum SIG_SETMASK = 3;
2908+
2909+ struct siginfo_t
2910+ {
2911+ int si_signo;
2912+ int si_errno;
2913+ int si_code;
2914+
2915+ pid_t si_pid;
2916+ uid_t si_uid;
2917+ void* si_addr;
2918+ int si_status;
2919+ c_long si_band;
2920+ sigval si_value;
2921+ }
2922+
2923+ enum
2924+ {
2925+ SI_ASYNCIO = -4,
2926+ SI_MESGQ,
2927+ SI_TIMER,
2928+ SI_QUEUE,
2929+ SI_USER
2930+ }
2931+}
2932 else
2933 {
2934 static assert(false, "Unsupported platform");
2935@@ -2409,6 +2485,89 @@ else version (Solaris)
2936 POLL_HUP,
2937 }
2938 }
2939+else version(Hurd)
2940+{
2941+ enum SIGPOLL = 23;
2942+ enum SIGPROF = 27;
2943+ enum SIGSYS = 12;
2944+ enum SIGTRAP = 5;
2945+ enum SIGVTALRM = 26;
2946+ enum SIGXCPU = 24;
2947+ enum SIGXFSZ = 25;
2948+
2949+ enum
2950+ {
2951+ SA_ONSTACK = 0x0001,
2952+ SA_RESETHAND = 0x0004,
2953+ SA_RESTART = 0x0002,
2954+ SA_SIGINFO = 0x0040,
2955+ // SA_NOCLDWAIT = ,
2956+ SA_NODEFER = 0x00010,
2957+ }
2958+
2959+ enum
2960+ {
2961+ ILL_ILLOPC = 1,
2962+ ILL_ILLOPN,
2963+ ILL_ILLADR,
2964+ ILL_ILLTRP,
2965+ ILL_PRVOPC,
2966+ ILL_PRVREG,
2967+ ILL_COPROC,
2968+ ILL_BADSTK
2969+ }
2970+
2971+ enum
2972+ {
2973+ FPE_INTDIV = 1,
2974+ FPE_INTOVF,
2975+ FPE_FLTDIV,
2976+ FPE_FLTOVF,
2977+ FPE_FLTUND,
2978+ FPE_FLTRES,
2979+ FPE_FLTINV,
2980+ FPE_FLTSUB
2981+ }
2982+
2983+ enum
2984+ {
2985+ SEGV_MAPERR = 1,
2986+ SEGV_ACCERR
2987+ }
2988+
2989+ enum
2990+ {
2991+ BUS_ADRALN = 1,
2992+ BUS_ADRERR,
2993+ BUS_OBJERR
2994+ }
2995+
2996+ enum
2997+ {
2998+ TRAP_BRKPT = 1,
2999+ TRAP_TRACE
3000+ }
3001+
3002+ enum
3003+ {
3004+ CLD_EXITED = 1,
3005+ CLD_KILLED,
3006+ CLD_DUMPED,
3007+ CLD_TRAPPED,
3008+ CLD_STOPPED,
3009+ CLD_CONTINUED
3010+ }
3011+
3012+ enum
3013+ {
3014+ POLL_IN = 1,
3015+ POLL_OUT,
3016+ POLL_MSG,
3017+ POLL_ERR,
3018+ POLL_PRI,
3019+ POLL_HUP
3020+ }
3021+}
3022 else
3023 {
3024 static assert(false, "Unsupported platform");
3025@@ -2450,11 +2609,21 @@ int sigrelse(int);
3026
3027 version (CRuntime_Glibc)
3028 {
3029- enum SS_ONSTACK = 1;
3030- enum SS_DISABLE = 2;
3031- enum MINSIGSTKSZ = 2048;
3032- enum SIGSTKSZ = 8192;
3033+ version (linux)
3034+ {
3035+ enum SS_ONSTACK = 1;
3036+ enum SS_DISABLE = 2;
3037+ enum MINSIGSTKSZ = 2048;
3038+ enum SIGSTKSZ = 8192;
3039+ }
3040
3041+ version (Hurd)
3042+ {
3043+ enum SS_ONSTACK = 0x0001;
3044+ enum SS_DISABLE = 0x0004;
3045+ enum MINSIGSTKSZ = 8192;
3046+ enum SIGSTKSZ = (MINSIGSTKSZ + 32768);
3047+ }
3048 //ucontext_t (defined in core.sys.posix.ucontext)
3049 //mcontext_t (defined in core.sys.posix.ucontext)
3050
3051@@ -3029,6 +3198,18 @@ else version (Solaris)
3052 int __sigev_pad2;
3053 }
3054 }
3055+else version (Hurd)
3056+{
3057+ struct sigevent
3058+ {
3059+ sigval sigev_value;
3060+ int sigev_signo;
3061+ int sigev_notify;
3062+
3063+ void function(sigval) sigev_notify_function;
3064+ void* sigev_notify_attributes;
3065+ }
3066+}
3067 else
3068 {
3069 static assert(false, "Unsupported platform");
3070diff --git a/druntime/src/core/sys/posix/spawn.d b/druntime/src/core/sys/posix/spawn.d
3071index 081270b42c..ece7ff7e25 100644
3072--- a/druntime/src/core/sys/posix/spawn.d
3073+++ b/druntime/src/core/sys/posix/spawn.d
3074@@ -34,6 +34,8 @@ OpenBSD: https://github.com/openbsd/src/blob/master/include/spawn.h
3075 DragonFlyBSD: https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/include/spawn.h
3076
3077 Solaris: https://github.com/illumos/illumos-gate/blob/master/usr/src/head/spawn.h
3078+
3079+Hurd: https://sourceware.org/git/?p=glibc.git;a=blob;f=posix/spawn.h;hb=HEAD
3080 */
3081
3082 version (OSX) // macOS and iOS only as this API is prohibited on WatchOS and TVOS
3083@@ -370,5 +372,45 @@ else version (Solaris)
3084 int posix_spawnattr_setsigignore_np(posix_spawnattr_t* attr, const sigset_t* sigignore);
3085 }
3086 }
3087+else version (Hurd)
3088+{
3089+ // Source: https://sourceware.org/git/?p=glibc.git;a=blob;f=posix/spawn.h;hb=HEAD
3090+ enum
3091+ {
3092+ POSIX_SPAWN_RESETIDS = 0x01,
3093+ POSIX_SPAWN_SETPGROUP = 0x02,
3094+ POSIX_SPAWN_SETSIGDEF = 0x04,
3095+ POSIX_SPAWN_SETSIGMASK = 0x08,
3096+ POSIX_SPAWN_SETSCHEDPARAM = 0x10,
3097+ POSIX_SPAWN_SETSCHEDULER = 0x20,
3098+ }
3099+ import core.sys.posix.config : _GNU_SOURCE;
3100+ static if (_GNU_SOURCE)
3101+ {
3102+ enum
3103+ {
3104+ POSIX_SPAWN_USEVFORK = 0x40,
3105+ POSIX_SPAWN_SETSID = 0x80
3106+ }
3107+ }
3108+ struct posix_spawnattr_t
3109+ {
3110+ short __flags;
3111+ pid_t __pgrp;
3112+ sigset_t __sd;
3113+ sigset_t __ss;
3114+ sched_param __sp;
3115+ int __policy;
3116+ int[16] __pad;
3117+ }
3118+ private struct __spawn_action;
3119+ struct posix_spawn_file_actions_t
3120+ {
3121+ int __allocated;
3122+ int __used;
3123+ __spawn_action* __actions;
3124+ int[16] __pad;
3125+ }
3126+}
3127 else
3128 static assert(0, "Unsupported OS");
3129diff --git a/druntime/src/core/sys/posix/sys/ioctl.d b/druntime/src/core/sys/posix/sys/ioctl.d
3130index 27584d357c..56bc87e252 100644
3131--- a/druntime/src/core/sys/posix/sys/ioctl.d
3132+++ b/druntime/src/core/sys/posix/sys/ioctl.d
3133@@ -400,6 +400,43 @@ else version (DragonFlyBSD)
3134 else version (Solaris)
3135 {
3136 }
3137+else version (Hurd)
3138+{
3139+ struct tchars
3140+ {
3141+ char t_intrc;
3142+ char t_quitc;
3143+ char t_startc;
3144+ char t_stopc;
3145+ char t_eofc;
3146+ char t_brkc;
3147+ }
3148+ struct ltchars
3149+ {
3150+ char t_suspc;
3151+ char t_dsuspc;
3152+ char t_rprntc;
3153+ char t_flushc;
3154+ char t_werasc;
3155+ char t_lnextc;
3156+ }
3157+ struct sgttyb
3158+ {
3159+ char sg_ispeed;
3160+ char sg_ospeed;
3161+ char sg_erase;
3162+ char sg_kill;
3163+ short sg_flags;
3164+ }
3165+
3166+ struct winsize
3167+ {
3168+ ushort ws_row;
3169+ ushort ws_col;
3170+ ushort ws_xpixel;
3171+ ushort ws_ypixel;
3172+ }
3173+}
3174 else
3175 {
3176 static assert(false, "Unsupported platform");
3177diff --git a/druntime/src/core/sys/posix/sys/ipc.d b/druntime/src/core/sys/posix/sys/ipc.d
3178index 32caba95a1..1d12841fff 100644
3179--- a/druntime/src/core/sys/posix/sys/ipc.d
3180+++ b/druntime/src/core/sys/posix/sys/ipc.d
3181@@ -246,6 +246,49 @@ else version (Solaris)
3182 enum IPC_SET = 11;
3183 enum IPC_STAT = 12;
3184 }
3185+else version (Hurd)
3186+{
3187+ version (X86)
3188+ {
3189+ struct ipc_perm
3190+ {
3191+ key_t __key;
3192+ ushort uid;
3193+ ushort gid;
3194+ ushort cuid;
3195+ ushort cgid;
3196+ ushort mode;
3197+ ushort __seq;
3198+ }
3199+ }
3200+ else version (X86_64)
3201+ {
3202+ struct ipc_perm
3203+ {
3204+ key_t __key;
3205+ uid_t uid;
3206+ gid_t gid;
3207+ uid_t cuid;
3208+ gid_t cgid;
3209+ mode_t mode;
3210+ ushort __seq;
3211+ }
3212+ }
3213+ else
3214+ {
3215+ static assert(false, "Unsupported platform");
3216+ }
3217+
3218+ enum IPC_CREAT = 0x0200; // 01000
3219+ enum IPC_EXCL = 0x0400; // 02000
3220+ enum IPC_NOWAIT = 0x0800; // 04000
3221+
3222+ enum key_t IPC_PRIVATE = 0;
3223+
3224+ enum IPC_RMID = 0;
3225+ enum IPC_SET = 1;
3226+ enum IPC_STAT = 2;
3227+}
3228 else
3229 {
3230 static assert(false, "Unsupported platform");
3231diff --git a/druntime/src/core/sys/posix/sys/mman.d b/druntime/src/core/sys/posix/sys/mman.d
3232index 42da553c40..538588dd3f 100644
3233--- a/druntime/src/core/sys/posix/sys/mman.d
3234+++ b/druntime/src/core/sys/posix/sys/mman.d
3235@@ -170,6 +170,14 @@ else version (DragonFlyBSD)
3236 else version (Solaris)
3237 {
3238 }
3239+else version (Hurd)
3240+{
3241+ enum POSIX_MADV_NORMAL = 0;
3242+ enum POSIX_MADV_RANDOM = 1;
3243+ enum POSIX_MADV_SEQUENTIAL = 2;
3244+ enum POSIX_MADV_WILLNEED = 3;
3245+ enum POSIX_MADV_DONTNEED = 4;
3246+}
3247 else
3248 {
3249 static assert(false, "Unsupported platform");
3250@@ -234,6 +242,13 @@ else version (Solaris)
3251 enum PROT_WRITE = 0x02;
3252 enum PROT_EXEC = 0x04;
3253 }
3254+else version (Hurd)
3255+{
3256+ enum PROT_NONE = 0x00;
3257+ enum PROT_READ = 0x04;
3258+ enum PROT_WRITE = 0x02;
3259+ enum PROT_EXEC = 0x01;
3260+}
3261 else
3262 {
3263 static assert(false, "Unsupported platform");
3264@@ -474,6 +489,19 @@ else version (Solaris)
3265 enum MS_SYNC = 0x0004;
3266 enum MS_ASYNC = 0x0001;
3267 enum MS_INVALIDATE = 0x0002;
3268+}
3269+ else version (Hurd)
3270+{
3271+ enum MAP_SHARED = 0x0010;
3272+ enum MAP_PRIVATE = 0x0000;
3273+ enum MAP_FIXED = 0x0100;
3274+ enum MAP_ANON = 0x0002;
3275+
3276+ enum MAP_FAILED = cast(void*)-1;
3277+
3278+ enum MS_ASYNC = 1;
3279+ enum MS_INVALIDATE = 0;
3280+ enum MS_SYNC = 2;
3281 }
3282 else
3283 {
3284@@ -591,6 +619,11 @@ else version (Solaris)
3285 enum MCL_CURRENT = 0x0001;
3286 enum MCL_FUTURE = 0x0002;
3287 }
3288+else version (Hurd)
3289+{
3290+ enum MCL_CURRENT = 0x0001;
3291+ enum MCL_FUTURE = 0x0002;
3292+}
3293 else
3294 {
3295 static assert(false, "Unsupported platform");
3296diff --git a/druntime/src/core/sys/posix/sys/msg.d b/druntime/src/core/sys/posix/sys/msg.d
3297index 519811820f..fe56c5a532 100644
3298--- a/druntime/src/core/sys/posix/sys/msg.d
3299+++ b/druntime/src/core/sys/posix/sys/msg.d
3300@@ -173,6 +173,50 @@ version (linux)
3301 }
3302 }
3303 }
3304+else version (Hurd)
3305+{
3306+ import core.sys.hurd.sys.types;
3307+ enum MSG_STAT = 11;
3308+ enum MSG_INFO = 12;
3309+
3310+ enum MSG_NOERROR = 1 << 12; // octal!10000
3311+ enum MSG_EXCEPT = 2 << 12; // octal!20000
3312+
3313+ struct msginfo
3314+ {
3315+ int msgpool;
3316+ int msgmap;
3317+ int msgmax;
3318+ int msgmnb;
3319+ int msgmni;
3320+ int msgssz;
3321+ int msgtql;
3322+ ushort msgseg;
3323+ }
3324+
3325+ alias msgqnum_t = ushort;
3326+ alias msglen_t = ushort;
3327+
3328+ private struct msg;
3329+ private struct __wait_queue;
3330+
3331+ struct msqid_ds
3332+ {
3333+ ipc_perm msg_perm;
3334+ msg *__msg_first;
3335+ msg *__msg_last;
3336+ time_t msg_stime;
3337+ time_t msg_rtime;
3338+ time_t msg_ctime;
3339+ __wait_queue *__wwait;
3340+ __wait_queue *__rwait;
3341+ ushort __msg_cbytes;
3342+ msgqnum_t msg_qnum;
3343+ msglen_t msg_qbytes;
3344+ ipc_pid_t msg_lspid;
3345+ ipc_pid_t msg_lrpid;
3346+ }
3347+}
3348 else
3349 {
3350 // https://sourceware.org/git/?p=glibc.git;a=blob;f=bits/msq.h
3351diff --git a/druntime/src/core/sys/posix/sys/resource.d b/druntime/src/core/sys/posix/sys/resource.d
3352index eb62e4950f..6221814f88 100644
3353--- a/druntime/src/core/sys/posix/sys/resource.d
3354+++ b/druntime/src/core/sys/posix/sys/resource.d
3355@@ -477,6 +477,64 @@ else version (Solaris)
3356 RLIMIT_AS = 6,
3357 }
3358 }
3359+else version (Hurd)
3360+{
3361+ enum
3362+ {
3363+ PRIO_PROCESS = 0,
3364+ PRIO_PGRP = 1,
3365+ PRIO_USER = 2,
3366+ }
3367+
3368+ static if (__USE_FILE_OFFSET64)
3369+ alias rlim_t = ulong;
3370+ else
3371+ alias rlim_t = c_ulong;
3372+
3373+ static if (__USE_FILE_OFFSET64)
3374+ enum RLIM_INFINITY = 0xffffffffffffffffUL;
3375+ else
3376+ enum RLIM_INFINITY = cast(c_ulong)(~0UL);
3377+
3378+ enum RLIM_SAVED_MAX = RLIM_INFINITY;
3379+ enum RLIM_SAVED_CUR = RLIM_INFINITY;
3380+
3381+ enum
3382+ {
3383+ RUSAGE_SELF = 0,
3384+ RUSAGE_CHILDREN = -1,
3385+ }
3386+
3387+ struct rusage
3388+ {
3389+ timeval ru_utime;
3390+ timeval ru_stime;
3391+ c_long ru_maxrss;
3392+ c_long ru_ixrss;
3393+ c_long ru_idrss;
3394+ c_long ru_isrss;
3395+ c_long ru_minflt;
3396+ c_long ru_majflt;
3397+ c_long ru_nswap;
3398+ c_long ru_inblock;
3399+ c_long ru_oublock;
3400+ c_long ru_msgsnd;
3401+ c_long ru_msgrcv;
3402+ c_long ru_nsignals;
3403+ c_long ru_nvcsw;
3404+ c_long ru_nivcsw;
3405+ }
3406+ enum
3407+ {
3408+ RLIMIT_CORE = 4,
3409+ RLIMIT_CPU = 0,
3410+ RLIMIT_DATA = 2,
3411+ RLIMIT_FSIZE = 1,
3412+ RLIMIT_NOFILE = 8,
3413+ RLIMIT_STACK = 3,
3414+ RLIMIT_AS = 10,
3415+ }
3416+}
3417 else
3418 static assert (false, "Unsupported platform");
3419
3420diff --git a/druntime/src/core/sys/posix/sys/shm.d b/druntime/src/core/sys/posix/sys/shm.d
3421index 358fcf9e32..4ef4755ce5 100644
3422--- a/druntime/src/core/sys/posix/sys/shm.d
3423+++ b/druntime/src/core/sys/posix/sys/shm.d
3424@@ -180,6 +180,32 @@ else version (Darwin)
3425 else version (Solaris)
3426 {
3427
3428+}
3429+else version (Hurd)
3430+{
3431+ import core.sys.hurd.sys.types;
3432+ enum SHM_RDONLY = 0x01000; // 010000
3433+ enum SHM_RND = 0x02000; // 020000
3434+ enum SHM_REMAP = 0x4000; // 040000
3435+
3436+ alias shmatt_t = short;
3437+
3438+ private struct __vm_area_struct;
3439+
3440+ struct shmid_ds
3441+ {
3442+ ipc_perm shm_perm;
3443+ size_t shm_segsz;
3444+ time_t shm_atime;
3445+ time_t shm_dtime;
3446+ time_t shm_ctime;
3447+ ipc_pid_t shm_cpid;
3448+ ipc_pid_t shm_lpid;
3449+ shmatt_t shm_nattch;
3450+ private ushort __shm_npages;
3451+ private c_ulong* __shm_pages;
3452+ private __vm_area_struct* __attaches;
3453+ }
3454 }
3455 else
3456 {
3457diff --git a/druntime/src/core/sys/posix/sys/socket.d b/druntime/src/core/sys/posix/sys/socket.d
3458index 0ae101db09..c121a2bba0 100644
3459--- a/druntime/src/core/sys/posix/sys/socket.d
3460+++ b/druntime/src/core/sys/posix/sys/socket.d
3461@@ -1598,6 +1598,153 @@ else version (Solaris)
3462 SHUT_RDWR
3463 }
3464 }
3465+else version (Hurd)
3466+{
3467+ alias socklen_t = uint;
3468+ alias sa_family_t = ubyte;
3469+
3470+ struct sockaddr
3471+ {
3472+ ubyte ss_len;
3473+ sa_family_t sa_family;
3474+ byte[14] sa_data;
3475+ }
3476+
3477+ private enum : size_t
3478+ {
3479+ _SS_SIZE = 128,
3480+ _SS_PADSIZE = _SS_SIZE - c_ulong.sizeof - sa_family_t.sizeof - ubyte.sizeof,
3481+ }
3482+
3483+ struct sockaddr_storage
3484+ {
3485+ ubyte ss_len;
3486+ sa_family_t ss_family;
3487+ byte[_SS_PADSIZE] __ss_padding;
3488+ c_ulong __ss_align;
3489+ }
3490+ struct msghdr
3491+ {
3492+ void* msg_name;
3493+ socklen_t msg_namelen;
3494+ iovec* msg_iov;
3495+ int msg_iovlen;
3496+ void* msg_control;
3497+ socklen_t msg_controllen;
3498+ int msg_flags;
3499+ }
3500+
3501+ struct cmsghdr
3502+ {
3503+ socklen_t cmsg_len;
3504+ int cmsg_level;
3505+ int cmsg_type;
3506+ }
3507+ enum : uint
3508+ {
3509+ SCM_RIGHTS = 0x01
3510+ }
3511+
3512+ extern (D) inout(ubyte)* CMSG_DATA( return scope inout(cmsghdr)* cmsg ) pure nothrow @nogc { return cast(ubyte*)( cmsg + 1 ); }
3513+ private inout(cmsghdr)* __cmsg_nxthdr(inout(msghdr)*, inout(cmsghdr)*) pure nothrow @nogc;
3514+ extern (D) inout(cmsghdr)* CMSG_NXTHDR(inout(msghdr)* msg, inout(cmsghdr)* cmsg) pure nothrow @nogc
3515+ {
3516+ return __cmsg_nxthdr(msg, cmsg);
3517+ }
3518+
3519+ extern (D) inout(cmsghdr)* CMSG_FIRSTHDR( inout(msghdr)* mhdr ) pure nothrow @nogc
3520+ {
3521+ return ( cast(size_t)mhdr.msg_controllen >= cmsghdr.sizeof
3522+ ? cast(inout(cmsghdr)*) mhdr.msg_control
3523+ : cast(inout(cmsghdr)*) null );
3524+ }
3525+
3526+ extern (D)
3527+ {
3528+ size_t CMSG_ALIGN( size_t len ) pure nothrow @nogc
3529+ {
3530+ return (len + size_t.sizeof - 1) & cast(size_t) (~(size_t.sizeof - 1));
3531+ }
3532+
3533+ size_t CMSG_LEN( size_t len ) pure nothrow @nogc
3534+ {
3535+ return CMSG_ALIGN(cmsghdr.sizeof) + len;
3536+ }
3537+ }
3538+
3539+ extern (D) size_t CMSG_SPACE(size_t len) pure nothrow @nogc
3540+ {
3541+ return CMSG_ALIGN(len) + CMSG_ALIGN(cmsghdr.sizeof);
3542+ }
3543+ struct linger
3544+ {
3545+ int l_onoff;
3546+ int l_linger;
3547+ }
3548+
3549+ enum
3550+ {
3551+ SOCK_DGRAM = 2,
3552+ SOCK_RDM = 4,
3553+ SOCK_SEQPACKET = 5,
3554+ SOCK_STREAM = 1,
3555+ }
3556+ enum
3557+ {
3558+ SOL_SOCKET = 0xffff
3559+ }
3560+ enum
3561+ {
3562+ SO_ACCEPTCONN = 0x0002,
3563+ SO_BROADCAST = 0x0020,
3564+ SO_DEBUG = 0x0001,
3565+ SO_DONTROUTE = 0x0010,
3566+ SO_ERROR = 0x1007,
3567+ SO_KEEPALIVE = 0x0008,
3568+ SO_LINGER = 0x0080,
3569+ SO_OOBINLINE = 0x0100,
3570+ SO_RCVBUF = 0x1002,
3571+ SO_RCVLOWAT = 0x1004,
3572+ SO_RCVTIMEO = 0x1006,
3573+ SO_REUSEADDR = 0x0004,
3574+ SO_REUSEPORT = 0x0200,
3575+ SO_SNDBUF = 0x1002,
3576+ SO_SNDLOWAT = 0x1003,
3577+ SO_SNDTIMEO = 0x1005,
3578+ SO_TYPE = 0x1008
3579+ }
3580+ enum
3581+ {
3582+ SOMAXCONN = 128
3583+ }
3584+ enum : uint
3585+ {
3586+ MSG_CTRUNC = 0x20,
3587+ MSG_DONTROUTE = 0x04,
3588+ MSG_EOR = 0x08,
3589+ MSG_OOB = 0x01,
3590+ MSG_PEEK = 0x02,
3591+ MSG_TRUNC = 0x10,
3592+ MSG_WAITALL = 0x40,
3593+ MSG_NOSIGNAL = 0x0400
3594+ }
3595+
3596+ enum
3597+ {
3598+ AF_INET = 2,
3599+ AF_LOCAL = 1,
3600+ AF_UNIX = AF_LOCAL,
3601+ AF_UNSPEC = 0,
3602+ AF_APPLETALK = 16,
3603+ AF_IPX = 23
3604+ }
3605+ enum
3606+ {
3607+ SHUT_RD = 0,
3608+ SHUT_WR = 1,
3609+ SHUT_RDWR = 2
3610+ }
3611+}
3612 else
3613 {
3614 static assert(false, "Unsupported platform");
3615@@ -1899,6 +2046,13 @@ else version (Solaris)
3616 AF_INET6 = 26,
3617 }
3618 }
3619+else version (Hurd)
3620+{
3621+ enum
3622+ {
3623+ AF_INET6 = 26,
3624+ }
3625+}
3626 else
3627 {
3628 static assert(false, "Unsupported platform");
3629@@ -1960,6 +2114,13 @@ else version (Solaris)
3630 SOCK_RAW = 4,
3631 }
3632 }
3633+else version (Hurd)
3634+{
3635+ enum
3636+ {
3637+ SOCK_RAW = 3,
3638+ }
3639+}
3640 else
3641 {
3642 static assert(false, "Unsupported platform");
3643diff --git a/druntime/src/core/sys/posix/sys/stat.d b/druntime/src/core/sys/posix/sys/stat.d
3644index 83590b5b99..00eb13b15f 100644
3645--- a/druntime/src/core/sys/posix/sys/stat.d
3646+++ b/druntime/src/core/sys/posix/sys/stat.d
3647@@ -1540,6 +1540,64 @@ else version (Solaris)
3648 enum S_ISGID = 0x400;
3649 enum S_ISVTX = 0x200;
3650 }
3651+else version (Hurd)
3652+{
3653+ import core.sys.hurd.sys.types;
3654+ static if (__USE_FILE_OFFSET64)
3655+ private enum SPARE_SIZE = 8;
3656+ else
3657+ private enum SPARE_SIZE = 11;
3658+
3659+ struct stat_t
3660+ {
3661+ int st_fstype; /* File system type. */
3662+ fsid_t st_fsid; /* File system ID. */
3663+ alias st_dev = st_fsid;
3664+ ino_t st_ino; /* File number. */
3665+ uint st_gen;
3666+ dev_t st_rdev;
3667+ mode_t st_mode;
3668+ nlink_t st_nlink;
3669+ uid_t st_uid;
3670+ gid_t st_gid;
3671+ off_t st_size;
3672+
3673+ static if (_DEFAULT_SOURCE || _XOPEN_SOURCE >= 700)
3674+ {
3675+ timespec st_atim;
3676+ timespec st_mtim;
3677+ timespec st_ctim;
3678+ extern(D) @safe @property inout pure nothrow
3679+ {
3680+ ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
3681+ ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
3682+ ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
3683+ }
3684+ }
3685+ else
3686+ {
3687+ time_t st_atime;
3688+ c_ulong st_atimensec;
3689+ time_t st_mtime;
3690+ c_ulong st_mtimensec;
3691+ time_t st_ctime;
3692+ c_ulong st_ctimensec;
3693+ }
3694+
3695+ blksize_t st_blksize;
3696+ blkcnt_t st_blocks;
3697+
3698+ uid_t st_author;
3699+ uint st_flags;
3700+ int[SPARE_SIZE] st_spare;
3701+ }
3702+ version (X86) static assert(stat_t.sizeof == 128);
3703+ version (X86_64) static assert(stat_t.sizeof == 176);
3704+
3705+ enum S_ISUID = 0x800; // octal 0004000
3706+ enum S_ISGID = 0x400; // octal 0002000
3707+ enum S_ISVTX = 0x200; // octal 0001000
3708+}
3709 else
3710 {
3711 static assert(false, "Unsupported platform");
3712@@ -2213,6 +2271,11 @@ else version (Solaris)
3713 enum UTIME_NOW = -1;
3714 enum UTIME_OMIT = -2;
3715 }
3716+else version (Hurd)
3717+{
3718+ enum UTIME_NOW = -1;
3719+ enum UTIME_OMIT = -2;
3720+}
3721 else
3722 {
3723 static assert(false, "Unsupported platform");
3724@@ -2319,6 +2382,17 @@ else version (Solaris)
3725 enum S_IFDOOR = 0xD000;
3726 enum S_IFPORT = 0xE000;
3727 }
3728+else version (Hurd)
3729+{
3730+ enum S_IFMT = 0xF000; // octal 0170000
3731+ enum S_IFBLK = 0x6000; // octal 0060000
3732+ enum S_IFCHR = 0x2000; // octal 0020000
3733+ enum S_IFIFO = 0x1000; // octal 0010000
3734+ enum S_IFREG = 0x8000; // octal 0100000
3735+ enum S_IFDIR = 0x4000; // octal 0040000
3736+ enum S_IFLNK = 0xA000; // octal 0120000
3737+ enum S_IFSOCK = 0xC000; // octal 0140000
3738+}
3739 else
3740 {
3741 static assert(false, "Unsupported platform");
3742diff --git a/druntime/src/core/sys/posix/sys/statvfs.d b/druntime/src/core/sys/posix/sys/statvfs.d
3743index a8f3dd5065..327f235a9b 100644
3744--- a/druntime/src/core/sys/posix/sys/statvfs.d
3745+++ b/druntime/src/core/sys/posix/sys/statvfs.d
3746@@ -18,71 +18,117 @@ nothrow:
3747 @nogc:
3748
3749 version (CRuntime_Glibc) {
3750- static if (__WORDSIZE == 32)
3751+ version (linux)
3752 {
3753- version=_STATVFSBUF_F_UNUSED;
3754- }
3755- struct statvfs_t
3756- {
3757- c_ulong f_bsize;
3758- c_ulong f_frsize;
3759- fsblkcnt_t f_blocks;
3760- fsblkcnt_t f_bfree;
3761- fsblkcnt_t f_bavail;
3762- fsfilcnt_t f_files;
3763- fsfilcnt_t f_ffree;
3764- fsfilcnt_t f_favail;
3765- c_ulong f_fsid;
3766- version (_STATVFSBUF_F_UNUSED)
3767+ static if (__WORDSIZE == 32)
3768 {
3769- int __f_unused;
3770+ version=_STATVFSBUF_F_UNUSED;
3771+ }
3772+ struct statvfs_t
3773+ {
3774+ c_ulong f_bsize;
3775+ c_ulong f_frsize;
3776+ fsblkcnt_t f_blocks;
3777+ fsblkcnt_t f_bfree;
3778+ fsblkcnt_t f_bavail;
3779+ fsfilcnt_t f_files;
3780+ fsfilcnt_t f_ffree;
3781+ fsfilcnt_t f_favail;
3782+ c_ulong f_fsid;
3783+ version (_STATVFSBUF_F_UNUSED)
3784+ {
3785+ int __f_unused;
3786+ }
3787+ c_ulong f_flag;
3788+ c_ulong f_namemax;
3789+ int[6] __f_spare;
3790+ }
3791+ /* Definitions for the flag in `f_flag'. These definitions should be
3792+ kept in sync with the definitions in <sys/mount.h>. */
3793+ static if (_GNU_SOURCE)
3794+ {
3795+ enum FFlag
3796+ {
3797+ ST_RDONLY = 1, /* Mount read-only. */
3798+ ST_NOSUID = 2,
3799+ ST_NODEV = 4, /* Disallow access to device special files. */
3800+ ST_NOEXEC = 8, /* Disallow program execution. */
3801+ ST_SYNCHRONOUS = 16, /* Writes are synced at once. */
3802+ ST_MANDLOCK = 64, /* Allow mandatory locks on an FS. */
3803+ ST_WRITE = 128, /* Write on file/directory/symlink. */
3804+ ST_APPEND = 256, /* Append-only file. */
3805+ ST_IMMUTABLE = 512, /* Immutable file. */
3806+ ST_NOATIME = 1024, /* Do not update access times. */
3807+ ST_NODIRATIME = 2048, /* Do not update directory access times. */
3808+ ST_RELATIME = 4096 /* Update atime relative to mtime/ctime. */
3809+
3810+ }
3811+ } /* Use GNU. */
3812+ else
3813+ { // Posix defined:
3814+ enum FFlag
3815+ {
3816+ ST_RDONLY = 1, /* Mount read-only. */
3817+ ST_NOSUID = 2
3818+ }
3819+ }
3820+ static if ( __USE_FILE_OFFSET64 )
3821+ {
3822+ int statvfs64 (const char * file, statvfs_t* buf);
3823+ alias statvfs = statvfs64;
3824+
3825+ int fstatvfs64 (int fildes, statvfs_t *buf) @trusted;
3826+ alias fstatvfs = fstatvfs64;
3827+ }
3828+ else
3829+ {
3830+ int statvfs (const char * file, statvfs_t* buf);
3831+ int fstatvfs (int fildes, statvfs_t *buf);
3832 }
3833- c_ulong f_flag;
3834- c_ulong f_namemax;
3835- int[6] __f_spare;
3836 }
3837- /* Definitions for the flag in `f_flag'. These definitions should be
3838- kept in sync with the definitions in <sys/mount.h>. */
3839- static if (_GNU_SOURCE)
3840+ else version (Hurd)
3841 {
3842- enum FFlag
3843+ import core.sys.hurd.sys.types;
3844+ struct statvfs_t
3845 {
3846- ST_RDONLY = 1, /* Mount read-only. */
3847- ST_NOSUID = 2,
3848- ST_NODEV = 4, /* Disallow access to device special files. */
3849- ST_NOEXEC = 8, /* Disallow program execution. */
3850- ST_SYNCHRONOUS = 16, /* Writes are synced at once. */
3851- ST_MANDLOCK = 64, /* Allow mandatory locks on an FS. */
3852- ST_WRITE = 128, /* Write on file/directory/symlink. */
3853- ST_APPEND = 256, /* Append-only file. */
3854- ST_IMMUTABLE = 512, /* Immutable file. */
3855- ST_NOATIME = 1024, /* Do not update access times. */
3856- ST_NODIRATIME = 2048, /* Do not update directory access times. */
3857- ST_RELATIME = 4096 /* Update atime relative to mtime/ctime. */
3858-
3859+ uint f_type;
3860+ c_ulong f_bsize;
3861+ fsblkcnt_t f_blocks;
3862+ fsblkcnt_t f_bfree;
3863+ fsblkcnt_t f_bavail;
3864+ fsfilcnt_t f_files;
3865+ fsfilcnt_t f_ffree;
3866+ fsid_t f_fsid;
3867+ c_ulong f_namelen;
3868+ fsfilcnt_t f_favail;
3869+ c_ulong f_frsize;
3870+ c_ulong f_flag;
3871+ uint[3] f_spare;
3872 }
3873- } /* Use GNU. */
3874- else
3875- { // Posix defined:
3876+
3877 enum FFlag
3878 {
3879- ST_RDONLY = 1, /* Mount read-only. */
3880- ST_NOSUID = 2
3881+ ST_RDONLY = 1,
3882+ ST_NOSUID = 2,
3883+ ST_NOEXEC = 8,
3884+ ST_SYNCHRONOUS = 16,
3885+ ST_NOATIME = 32,
3886+ ST_RELATIME = 64,
3887 }
3888- }
3889
3890- static if ( __USE_FILE_OFFSET64 )
3891- {
3892- int statvfs64 (const char * file, statvfs_t* buf);
3893- alias statvfs = statvfs64;
3894+ static if ( __USE_FILE_OFFSET64 )
3895+ {
3896+ int statvfs64 (const char * file, statvfs_t* buf);
3897+ alias statvfs = statvfs64;
3898
3899- int fstatvfs64 (int fildes, statvfs_t *buf) @trusted;
3900- alias fstatvfs = fstatvfs64;
3901- }
3902- else
3903- {
3904- int statvfs (const char * file, statvfs_t* buf);
3905- int fstatvfs (int fildes, statvfs_t *buf);
3906+ int fstatvfs64 (int fildes, statvfs_t *buf) @trusted;
3907+ alias fstatvfs = fstatvfs64;
3908+ }
3909+ else
3910+ {
3911+ int statvfs (const char * file, statvfs_t* buf);
3912+ int fstatvfs (int fildes, statvfs_t *buf);
3913+ }
3914 }
3915 }
3916 else version (CRuntime_Musl)
3917diff --git a/druntime/src/core/sys/posix/sys/types.d b/druntime/src/core/sys/posix/sys/types.d
3918index cad60b4da4..45e655c3b6 100644
3919--- a/druntime/src/core/sys/posix/sys/types.d
3920+++ b/druntime/src/core/sys/posix/sys/types.d
3921@@ -328,6 +328,32 @@ else version (Solaris)
3922 alias time_t = c_long;
3923 alias uid_t = uint;
3924 }
3925+else version (Hurd)
3926+{
3927+ static if ( __USE_FILE_OFFSET64 )
3928+ {
3929+ alias blkcnt_t = long;
3930+ alias ino_t = ulong;
3931+ alias off_t = long;
3932+ }
3933+ else
3934+ {
3935+ alias blkcnt_t = slong_t;
3936+ alias ino_t = ulong_t;
3937+ alias off_t = slong_t;
3938+ }
3939+ alias blksize_t = slong_t;
3940+ alias dev_t = ulong_t;
3941+ alias gid_t = uint;
3942+ alias mode_t = uint;
3943+ alias nlink_t = ulong_t;
3944+ alias pid_t = int;
3945+ //size_t (defined in core.stdc.stddef)
3946+ alias ssize_t = c_long;
3947+ alias uid_t = uint;
3948+
3949+ alias time_t = slong_t;
3950+}
3951 else
3952 {
3953 static assert(false, "Unsupported platform");
3954@@ -439,6 +465,24 @@ else version (Solaris)
3955 alias zoneid_t = id_t;
3956 alias ctid_t = id_t;
3957 }
3958+else version (Hurd)
3959+{
3960+ static if ( __USE_FILE_OFFSET64 )
3961+ {
3962+ alias fsblkcnt_t = ulong;
3963+ alias fsfilcnt_t = ulong;
3964+ }
3965+ else
3966+ {
3967+ alias fsblkcnt_t = ulong_t;
3968+ alias fsfilcnt_t = ulong_t;
3969+ }
3970+ alias clock_t = slong_t;
3971+ alias id_t = uint;
3972+ alias key_t = int;
3973+ alias suseconds_t = slong_t;
3974+ alias useconds_t = uint;
3975+}
3976 else
3977 {
3978 static assert(false, "Unsupported platform");
3979@@ -462,287 +506,378 @@ pthread_t
3980
3981 version (CRuntime_Glibc)
3982 {
3983- version (X86)
3984+ version (linux)
3985 {
3986- enum __SIZEOF_PTHREAD_ATTR_T = 36;
3987- enum __SIZEOF_PTHREAD_MUTEX_T = 24;
3988- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
3989- enum __SIZEOF_PTHREAD_COND_T = 48;
3990- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
3991- enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
3992- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
3993- enum __SIZEOF_PTHREAD_BARRIER_T = 20;
3994- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
3995+ version (X86)
3996+ {
3997+ enum __SIZEOF_PTHREAD_ATTR_T = 36;
3998+ enum __SIZEOF_PTHREAD_MUTEX_T = 24;
3999+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4000+ enum __SIZEOF_PTHREAD_COND_T = 48;
4001+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4002+ enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
4003+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4004+ enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4005+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4006+ }
4007+ else version (X86_64)
4008+ {
4009+ static if (__WORDSIZE == 64)
4010+ {
4011+ enum __SIZEOF_PTHREAD_ATTR_T = 56;
4012+ enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4013+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4014+ enum __SIZEOF_PTHREAD_COND_T = 48;
4015+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4016+ enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4017+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4018+ enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4019+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4020+ }
4021+ else
4022+ {
4023+ enum __SIZEOF_PTHREAD_ATTR_T = 32;
4024+ enum __SIZEOF_PTHREAD_MUTEX_T = 32;
4025+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4026+ enum __SIZEOF_PTHREAD_COND_T = 48;
4027+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4028+ enum __SIZEOF_PTHREAD_RWLOCK_T = 44;
4029+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4030+ enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4031+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4032+ }
4033+ }
4034+ else version (AArch64)
4035+ {
4036+ enum __SIZEOF_PTHREAD_ATTR_T = 64;
4037+ enum __SIZEOF_PTHREAD_MUTEX_T = 48;
4038+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 8;
4039+ enum __SIZEOF_PTHREAD_COND_T = 48;
4040+ enum __SIZEOF_PTHREAD_CONDATTR_T = 8;
4041+ enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4042+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4043+ enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4044+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 8;
4045+ }
4046+ else version (ARM)
4047+ {
4048+ enum __SIZEOF_PTHREAD_ATTR_T = 36;
4049+ enum __SIZEOF_PTHREAD_MUTEX_T = 24;
4050+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4051+ enum __SIZEOF_PTHREAD_COND_T = 48;
4052+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4053+ enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
4054+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4055+ enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4056+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4057+ }
4058+ else version (HPPA)
4059+ {
4060+ enum __SIZEOF_PTHREAD_ATTR_T = 36;
4061+ enum __SIZEOF_PTHREAD_MUTEX_T = 48;
4062+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4063+ enum __SIZEOF_PTHREAD_COND_T = 48;
4064+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4065+ enum __SIZEOF_PTHREAD_RWLOCK_T = 64;
4066+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4067+ enum __SIZEOF_PTHREAD_BARRIER_T = 48;
4068+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4069+ }
4070+ else version (IA64)
4071+ {
4072+ enum __SIZEOF_PTHREAD_ATTR_T = 56;
4073+ enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4074+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4075+ enum __SIZEOF_PTHREAD_COND_T = 48;
4076+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4077+ enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4078+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4079+ enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4080+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4081+ }
4082+ else version (MIPS32)
4083+ {
4084+ enum __SIZEOF_PTHREAD_ATTR_T = 36;
4085+ enum __SIZEOF_PTHREAD_MUTEX_T = 24;
4086+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4087+ enum __SIZEOF_PTHREAD_COND_T = 48;
4088+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4089+ enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
4090+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4091+ enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4092+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4093+ }
4094+ else version (MIPS64)
4095+ {
4096+ enum __SIZEOF_PTHREAD_ATTR_T = 56;
4097+ enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4098+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4099+ enum __SIZEOF_PTHREAD_COND_T = 48;
4100+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4101+ enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4102+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4103+ enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4104+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4105+ }
4106+ else version (PPC)
4107+ {
4108+ enum __SIZEOF_PTHREAD_ATTR_T = 36;
4109+ enum __SIZEOF_PTHREAD_MUTEX_T = 24;
4110+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4111+ enum __SIZEOF_PTHREAD_COND_T = 48;
4112+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4113+ enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
4114+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4115+ enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4116+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4117+ }
4118+ else version (PPC64)
4119+ {
4120+ enum __SIZEOF_PTHREAD_ATTR_T = 56;
4121+ enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4122+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4123+ enum __SIZEOF_PTHREAD_COND_T = 48;
4124+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4125+ enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4126+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4127+ enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4128+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4129+ }
4130+ else version (RISCV32)
4131+ {
4132+ enum __SIZEOF_PTHREAD_ATTR_T = 36;
4133+ enum __SIZEOF_PTHREAD_MUTEX_T = 24;
4134+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4135+ enum __SIZEOF_PTHREAD_COND_T = 48;
4136+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4137+ enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
4138+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4139+ enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4140+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4141+ }
4142+ else version (RISCV64)
4143+ {
4144+ enum __SIZEOF_PTHREAD_ATTR_T = 56;
4145+ enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4146+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4147+ enum __SIZEOF_PTHREAD_COND_T = 48;
4148+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4149+ enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4150+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4151+ enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4152+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4153+ }
4154+ else version (SPARC)
4155+ {
4156+ enum __SIZEOF_PTHREAD_ATTR_T = 36;
4157+ enum __SIZEOF_PTHREAD_MUTEX_T = 24;
4158+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4159+ enum __SIZEOF_PTHREAD_COND_T = 48;
4160+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4161+ enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
4162+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4163+ enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4164+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4165+ }
4166+ else version (SPARC64)
4167+ {
4168+ enum __SIZEOF_PTHREAD_ATTR_T = 56;
4169+ enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4170+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4171+ enum __SIZEOF_PTHREAD_COND_T = 48;
4172+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4173+ enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4174+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4175+ enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4176+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4177+ }
4178+ else version (S390)
4179+ {
4180+ enum __SIZEOF_PTHREAD_ATTR_T = 36;
4181+ enum __SIZEOF_PTHREAD_MUTEX_T = 24;
4182+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4183+ enum __SIZEOF_PTHREAD_COND_T = 48;
4184+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4185+ enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
4186+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4187+ enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4188+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4189+ }
4190+ else version (SystemZ)
4191+ {
4192+ enum __SIZEOF_PTHREAD_ATTR_T = 56;
4193+ enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4194+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4195+ enum __SIZEOF_PTHREAD_COND_T = 48;
4196+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4197+ enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4198+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4199+ enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4200+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4201+ }
4202+ else version (LoongArch64)
4203+ {
4204+ enum __SIZEOF_PTHREAD_ATTR_T = 56;
4205+ enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4206+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4207+ enum __SIZEOF_PTHREAD_COND_T = 48;
4208+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4209+ enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4210+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4211+ enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4212+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4213+ }
4214+ else
4215+ {
4216+ static assert (false, "Unsupported platform");
4217+ }
4218+
4219+ union pthread_attr_t
4220+ {
4221+ byte[__SIZEOF_PTHREAD_ATTR_T] __size;
4222+ c_long __align;
4223+ }
4224+
4225+ private alias __atomic_lock_t = int;
4226+
4227+ private struct _pthread_fastlock
4228+ {
4229+ c_long __status;
4230+ __atomic_lock_t __spinlock;
4231+ }
4232+
4233+ private alias _pthread_descr = void*;
4234+
4235+ union pthread_cond_t
4236+ {
4237+ byte[__SIZEOF_PTHREAD_COND_T] __size;
4238+ long __align;
4239+ }
4240+
4241+ union pthread_condattr_t
4242+ {
4243+ byte[__SIZEOF_PTHREAD_CONDATTR_T] __size;
4244+ int __align;
4245+ }
4246+
4247+ alias pthread_key_t = uint;
4248+
4249+ union pthread_mutex_t
4250+ {
4251+ byte[__SIZEOF_PTHREAD_MUTEX_T] __size;
4252+ c_long __align;
4253+ }
4254+
4255+ union pthread_mutexattr_t
4256+ {
4257+ byte[__SIZEOF_PTHREAD_MUTEXATTR_T] __size;
4258+ int __align;
4259+ }
4260+
4261+ alias pthread_once_t = int;
4262+
4263+ struct pthread_rwlock_t
4264+ {
4265+ byte[__SIZEOF_PTHREAD_RWLOCK_T] __size;
4266+ c_long __align;
4267+ }
4268+
4269+ struct pthread_rwlockattr_t
4270+ {
4271+ byte[__SIZEOF_PTHREAD_RWLOCKATTR_T] __size;
4272+ c_long __align;
4273+ }
4274+
4275+ alias pthread_t = c_ulong;
4276 }
4277- else version (X86_64)
4278+ else version (Hurd)
4279 {
4280- static if (__WORDSIZE == 64)
4281- {
4282- enum __SIZEOF_PTHREAD_ATTR_T = 56;
4283- enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4284- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4285- enum __SIZEOF_PTHREAD_COND_T = 48;
4286- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4287- enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4288- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4289- enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4290- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4291- }
4292- else
4293+ import core.sys.hurd.sys.types;
4294+ import core.sys.posix.time: clockid_t;
4295+
4296+ private struct __sched_param
4297 {
4298- enum __SIZEOF_PTHREAD_ATTR_T = 32;
4299- enum __SIZEOF_PTHREAD_MUTEX_T = 32;
4300- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4301- enum __SIZEOF_PTHREAD_COND_T = 48;
4302- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4303- enum __SIZEOF_PTHREAD_RWLOCK_T = 44;
4304- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4305- enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4306- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4307+ int __sched_priority;
4308 }
4309- }
4310- else version (AArch64)
4311- {
4312- enum __SIZEOF_PTHREAD_ATTR_T = 64;
4313- enum __SIZEOF_PTHREAD_MUTEX_T = 48;
4314- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 8;
4315- enum __SIZEOF_PTHREAD_COND_T = 48;
4316- enum __SIZEOF_PTHREAD_CONDATTR_T = 8;
4317- enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4318- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4319- enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4320- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 8;
4321- }
4322- else version (ARM)
4323- {
4324- enum __SIZEOF_PTHREAD_ATTR_T = 36;
4325- enum __SIZEOF_PTHREAD_MUTEX_T = 24;
4326- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4327- enum __SIZEOF_PTHREAD_COND_T = 48;
4328- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4329- enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
4330- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4331- enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4332- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4333- }
4334- else version (HPPA)
4335- {
4336- enum __SIZEOF_PTHREAD_ATTR_T = 36;
4337- enum __SIZEOF_PTHREAD_MUTEX_T = 48;
4338- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4339- enum __SIZEOF_PTHREAD_COND_T = 48;
4340- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4341- enum __SIZEOF_PTHREAD_RWLOCK_T = 64;
4342- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4343- enum __SIZEOF_PTHREAD_BARRIER_T = 48;
4344- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4345- }
4346- else version (IA64)
4347- {
4348- enum __SIZEOF_PTHREAD_ATTR_T = 56;
4349- enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4350- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4351- enum __SIZEOF_PTHREAD_COND_T = 48;
4352- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4353- enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4354- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4355- enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4356- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4357- }
4358- else version (MIPS32)
4359- {
4360- enum __SIZEOF_PTHREAD_ATTR_T = 36;
4361- enum __SIZEOF_PTHREAD_MUTEX_T = 24;
4362- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4363- enum __SIZEOF_PTHREAD_COND_T = 48;
4364- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4365- enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
4366- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4367- enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4368- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4369- }
4370- else version (MIPS64)
4371- {
4372- enum __SIZEOF_PTHREAD_ATTR_T = 56;
4373- enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4374- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4375- enum __SIZEOF_PTHREAD_COND_T = 48;
4376- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4377- enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4378- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4379- enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4380- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4381- }
4382- else version (PPC)
4383- {
4384- enum __SIZEOF_PTHREAD_ATTR_T = 36;
4385- enum __SIZEOF_PTHREAD_MUTEX_T = 24;
4386- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4387- enum __SIZEOF_PTHREAD_COND_T = 48;
4388- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4389- enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
4390- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4391- enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4392- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4393- }
4394- else version (PPC64)
4395- {
4396- enum __SIZEOF_PTHREAD_ATTR_T = 56;
4397- enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4398- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4399- enum __SIZEOF_PTHREAD_COND_T = 48;
4400- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4401- enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4402- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4403- enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4404- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4405- }
4406- else version (RISCV32)
4407- {
4408- enum __SIZEOF_PTHREAD_ATTR_T = 36;
4409- enum __SIZEOF_PTHREAD_MUTEX_T = 24;
4410- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4411- enum __SIZEOF_PTHREAD_COND_T = 48;
4412- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4413- enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
4414- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4415- enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4416- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4417- }
4418- else version (RISCV64)
4419- {
4420- enum __SIZEOF_PTHREAD_ATTR_T = 56;
4421- enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4422- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4423- enum __SIZEOF_PTHREAD_COND_T = 48;
4424- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4425- enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4426- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4427- enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4428- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4429- }
4430- else version (SPARC)
4431- {
4432- enum __SIZEOF_PTHREAD_ATTR_T = 36;
4433- enum __SIZEOF_PTHREAD_MUTEX_T = 24;
4434- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4435- enum __SIZEOF_PTHREAD_COND_T = 48;
4436- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4437- enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
4438- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4439- enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4440- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4441- }
4442- else version (SPARC64)
4443- {
4444- enum __SIZEOF_PTHREAD_ATTR_T = 56;
4445- enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4446- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4447- enum __SIZEOF_PTHREAD_COND_T = 48;
4448- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4449- enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4450- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4451- enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4452- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4453- }
4454- else version (S390)
4455- {
4456- enum __SIZEOF_PTHREAD_ATTR_T = 36;
4457- enum __SIZEOF_PTHREAD_MUTEX_T = 24;
4458- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4459- enum __SIZEOF_PTHREAD_COND_T = 48;
4460- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4461- enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
4462- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4463- enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4464- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4465- }
4466- else version (SystemZ)
4467- {
4468- enum __SIZEOF_PTHREAD_ATTR_T = 56;
4469- enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4470- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4471- enum __SIZEOF_PTHREAD_COND_T = 48;
4472- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4473- enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4474- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4475- enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4476- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4477- }
4478- else version (LoongArch64)
4479- {
4480- enum __SIZEOF_PTHREAD_ATTR_T = 56;
4481- enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4482- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4483- enum __SIZEOF_PTHREAD_COND_T = 48;
4484- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4485- enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4486- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4487- enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4488- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4489- }
4490- else
4491- {
4492- static assert (false, "Unsupported platform");
4493- }
4494
4495- union pthread_attr_t
4496- {
4497- byte[__SIZEOF_PTHREAD_ATTR_T] __size;
4498- c_long __align;
4499- }
4500+ private struct __pthread;
4501
4502- private alias __atomic_lock_t = int;
4503-
4504- private struct _pthread_fastlock
4505- {
4506- c_long __status;
4507- __atomic_lock_t __spinlock;
4508- }
4509+ struct pthread_attr_t
4510+ {
4511+ __sched_param schedparam;
4512+ void* stackaddr;
4513+ size_t __stacksize;
4514+ size_t __guardsize;
4515+ int __detachstate;
4516+ int __inheritsched;
4517+ int __contentionscope;
4518+ int __schedpolicy;
4519+ }
4520
4521- private alias _pthread_descr = void*;
4522+ struct pthread_cond_t
4523+ {
4524+ pthread_spinlock_t __lock;
4525+ __pthread *__queue;
4526+ pthread_condattr_t *__attr;
4527+ uint __wrefs;
4528+ void *__data;
4529+ }
4530
4531- union pthread_cond_t
4532- {
4533- byte[__SIZEOF_PTHREAD_COND_T] __size;
4534- long __align;
4535- }
4536+ struct pthread_condattr_t
4537+ {
4538+ int __pshared;
4539+ clockid_t __clock;
4540+ }
4541
4542- union pthread_condattr_t
4543- {
4544- byte[__SIZEOF_PTHREAD_CONDATTR_T] __size;
4545- int __align;
4546- }
4547+ alias pthread_key_t = int;
4548
4549- alias pthread_key_t = uint;
4550+ struct pthread_mutex_t
4551+ {
4552+ uint __lock;
4553+ uint __owner_id;
4554+ uint __cnt;
4555+ int __shpid;
4556+ int __type;
4557+ int __flags;
4558+ union
4559+ {
4560+ uint[2] __reserved;
4561+ void *__pointer_aligned;
4562+ }
4563+ }
4564
4565- union pthread_mutex_t
4566- {
4567- byte[__SIZEOF_PTHREAD_MUTEX_T] __size;
4568- c_long __align;
4569- }
4570+ struct pthread_mutexattr_t
4571+ {
4572+ int __prioceiling;
4573+ int __protocol;
4574+ int __pshared;
4575+ int __mutex_type;
4576+ }
4577
4578- union pthread_mutexattr_t
4579- {
4580- byte[__SIZEOF_PTHREAD_MUTEXATTR_T] __size;
4581- int __align;
4582- }
4583+ struct pthread_once_t
4584+ {
4585+ int __run;
4586+ pthread_spinlock_t __lock;
4587+ }
4588
4589- alias pthread_once_t = int;
4590+ struct pthread_rwlock_t
4591+ {
4592+ pthread_spinlock_t __held;
4593+ pthread_spinlock_t __lock;
4594+ int __readers;
4595+ __pthread *__readerqueue;
4596+ __pthread *__writerqueue;
4597+ pthread_rwlockattr_t *__attr;
4598+ void *__data;
4599+ }
4600
4601- struct pthread_rwlock_t
4602- {
4603- byte[__SIZEOF_PTHREAD_RWLOCK_T] __size;
4604- c_long __align;
4605- }
4606+ struct pthread_rwlockattr_t
4607+ {
4608+ int __pshared;
4609+ }
4610
4611- struct pthread_rwlockattr_t
4612- {
4613- byte[__SIZEOF_PTHREAD_RWLOCKATTR_T] __size;
4614- c_long __align;
4615+ alias pthread_t = c_ulong;
4616 }
4617-
4618- alias pthread_t = c_ulong;
4619 }
4620 else version (CRuntime_Musl)
4621 {
4622@@ -1350,17 +1485,37 @@ pthread_barrierattr_t
4623
4624 version (CRuntime_Glibc)
4625 {
4626- struct pthread_barrier_t
4627- {
4628- byte[__SIZEOF_PTHREAD_BARRIER_T] __size;
4629- c_long __align;
4630- }
4631+ version (linux)
4632+ {
4633+ struct pthread_barrier_t
4634+ {
4635+ byte[__SIZEOF_PTHREAD_BARRIER_T] __size;
4636+ c_long __align;
4637+ }
4638
4639- struct pthread_barrierattr_t
4640- {
4641- byte[__SIZEOF_PTHREAD_BARRIERATTR_T] __size;
4642- int __align;
4643- }
4644+ struct pthread_barrierattr_t
4645+ {
4646+ byte[__SIZEOF_PTHREAD_BARRIERATTR_T] __size;
4647+ int __align;
4648+ }
4649+ }
4650+ else version (Hurd)
4651+ {
4652+ struct pthread_barrier_t
4653+ {
4654+ pthread_spinlock_t __lock;
4655+ __pthread *__queue;
4656+ uint __pending;
4657+ uint __count;
4658+ pthread_barrierattr_t *__attr;
4659+ void *__data;
4660+ }
4661+
4662+ struct pthread_barrierattr_t
4663+ {
4664+ int __pshared;
4665+ }
4666+ }
4667 }
4668 else version (FreeBSD)
4669 {
4670diff --git a/druntime/src/core/sys/posix/sys/un.d b/druntime/src/core/sys/posix/sys/un.d
4671index 11e98a72ab..a65ead9bfa 100644
4672--- a/druntime/src/core/sys/posix/sys/un.d
4673+++ b/druntime/src/core/sys/posix/sys/un.d
4674@@ -104,3 +104,16 @@ else version (Solaris)
4675 byte[108] sun_path;
4676 }
4677 }
4678+else version (Hurd)
4679+{
4680+ struct sockaddr_un
4681+ {
4682+ ubyte sun_len;
4683+ sa_family_t sun_family;
4684+ byte[108] sun_path;
4685+ }
4686+}
4687+else
4688+{
4689+ static assert(false, "Unsupported platform");
4690+}
4691diff --git a/druntime/src/core/sys/posix/sys/utsname.d b/druntime/src/core/sys/posix/sys/utsname.d
4692index 5de50aca46..507113b6fb 100644
4693--- a/druntime/src/core/sys/posix/sys/utsname.d
4694+++ b/druntime/src/core/sys/posix/sys/utsname.d
4695@@ -19,19 +19,36 @@ nothrow:
4696
4697 version (CRuntime_Glibc)
4698 {
4699- private enum utsNameLength = 65;
4700-
4701- struct utsname
4702+ version(linux)
4703 {
4704- char[utsNameLength] sysname = 0;
4705- char[utsNameLength] nodename = 0;
4706- char[utsNameLength] release = 0;
4707- char[utsNameLength] version_ = 0;
4708- // TODO Deprecate after version_ has been in an official release.
4709- alias update = version_;
4710- char[utsNameLength] machine = 0;
4711+ private enum utsNameLength = 65;
4712+ struct utsname
4713+ {
4714+ char[utsNameLength] sysname = 0;
4715+ char[utsNameLength] nodename = 0;
4716+ char[utsNameLength] release = 0;
4717+ char[utsNameLength] version_ = 0;
4718+ // TODO Deprecate after version_ has been in an official release.
4719+ alias update = version_;
4720+ char[utsNameLength] machine = 0;
4721+
4722+ char[utsNameLength] __domainname = 0;
4723+ }
4724+ }
4725
4726- char[utsNameLength] __domainname = 0;
4727+ else version(Hurd)
4728+ {
4729+ private enum utsNameLength = 1024;
4730+ struct utsname
4731+ {
4732+ char[utsNameLength] sysname = 0;
4733+ char[utsNameLength] nodename = 0;
4734+ char[utsNameLength] release = 0;
4735+ char[utsNameLength] version_ = 0;
4736+ // TODO Deprecate after version_ has been in an official release.
4737+ alias update = version_;
4738+ char[utsNameLength] machine = 0;
4739+ }
4740 }
4741
4742 int uname(utsname* __name);
4743diff --git a/druntime/src/core/sys/posix/sys/wait.d b/druntime/src/core/sys/posix/sys/wait.d
4744index 0c4e72e999..ab4106c748 100644
4745--- a/druntime/src/core/sys/posix/sys/wait.d
4746+++ b/druntime/src/core/sys/posix/sys/wait.d
4747@@ -106,6 +106,15 @@ else version (Solaris)
4748 enum WNOHANG = 64;
4749 enum WUNTRACED = 4;
4750 }
4751+else version (Hurd)
4752+{
4753+ enum WNOHANG = 1;
4754+ enum WUNTRACED = 2;
4755+ private
4756+ {
4757+ enum __W_CONTINUED = 0xFFFF;
4758+ }
4759+}
4760 else
4761 {
4762 static assert(false, "Unsupported platform");
4763@@ -430,6 +439,20 @@ else version (Solaris)
4764 P_CPUID, /* CPU identifier. */
4765 P_PSETID, /* Processor set identifier */
4766 }
4767+}
4768+ else version (Hurd)
4769+{
4770+ enum WEXITED = 16;
4771+ enum WSTOPPED = WUNTRACED;
4772+ enum WCONTINUED = 4;
4773+ enum WNOWAIT = 8;
4774+
4775+ enum idtype_t
4776+ {
4777+ P_ALL,
4778+ P_PID,
4779+ P_PGID
4780+ }
4781 }
4782 else
4783 {
4784diff --git a/druntime/src/core/sys/posix/termios.d b/druntime/src/core/sys/posix/termios.d
4785index 38181a9d84..e7371aa9b1 100644
4786--- a/druntime/src/core/sys/posix/termios.d
4787+++ b/druntime/src/core/sys/posix/termios.d
4788@@ -831,6 +831,108 @@ else version (Solaris)
4789 enum B460800 = 22;
4790 enum B921600 = 23;
4791 }
4792+else version (Hurd)
4793+{
4794+ alias cc_t = ubyte;
4795+ alias speed_t = uint;
4796+ alias tcflag_t = uint;
4797+
4798+ enum NCCS = 20;
4799+
4800+ struct termios
4801+ {
4802+ tcflag_t c_iflag;
4803+ tcflag_t c_oflag;
4804+ tcflag_t c_cflag;
4805+ tcflag_t c_lflag;
4806+ cc_t[NCCS] c_cc;
4807+ speed_t c_ispeed;
4808+ speed_t c_ospeed;
4809+ }
4810+
4811+ enum VEOF = 0;
4812+ enum VEOL = 1;
4813+ enum VERASE = 3;
4814+ enum VINTR = 8;
4815+ enum VKILL = 5;
4816+ enum VMIN = 16;
4817+ enum VQUIT = 9;
4818+ enum VSTART = 12;
4819+ enum VSTOP = 13;
4820+ enum VSUSP = 10;
4821+ enum VTIME = 17;
4822+
4823+ enum BRKINT = 0x0000002;
4824+ enum ICRNL = 0x0000100;
4825+ enum IGNBRK = 0x0000001;
4826+ enum IGNCR = 0x0000080;
4827+ enum IGNPAR = 0x0000004;
4828+ enum INLCR = 0x0000040;
4829+ enum INPCK = 0x0000010;
4830+ enum ISTRIP = 0x0000020;
4831+ enum IXOFF = 0x0000400;
4832+ enum IXON = 0x0000200;
4833+ enum PARMRK = 0x0000008;
4834+
4835+ enum OPOST = 0x0000001;
4836+
4837+ enum B0 = 0;
4838+ enum B50 = 50;
4839+ enum B75 = 75;
4840+ enum B110 = 110;
4841+ enum B134 = 134;
4842+ enum B150 = 150;
4843+ enum B200 = 200;
4844+ enum B300 = 300;
4845+ enum B600 = 600;
4846+ enum B1200 = 1200;
4847+ enum B1800 = 1800;
4848+ enum B2400 = 2400;
4849+ enum B4800 = 4800;
4850+ enum B9600 = 9600;
4851+ enum B19200 = 19200;
4852+ enum B38400 = 38400;
4853+
4854+ enum CSIZE = 0x0000300;
4855+ enum CS5 = 0x0000000;
4856+ enum CS6 = 0x0000100;
4857+ enum CS7 = 0x0000200;
4858+ enum CS8 = 0x0000300;
4859+ enum CSTOPB = 0x0000400;
4860+ enum CREAD = 0x0000800;
4861+ enum PARENB = 0x0001000;
4862+ enum PARODD = 0x0002000;
4863+ enum HUPCL = 0x0004000;
4864+ enum CLOCAL = 0x0008000;
4865+
4866+ enum ECHO = 0x00000008;
4867+ enum ECHOE = 0x00000002;
4868+ enum ECHOK = 0x00000004;
4869+ enum ECHONL = 0x00000010;
4870+ enum ICANON = 0x00000100;
4871+ enum IEXTEN = 0x00000400;
4872+ enum ISIG = 0x00000080;
4873+ enum NOFLSH = 0x80000000;
4874+ enum TOSTOP = 0x00400000;
4875+
4876+ enum TCSANOW = 0;
4877+ enum TCSADRAIN = 1;
4878+ enum TCSAFLUSH = 2;
4879+
4880+ enum TCIFLUSH = 0;
4881+ enum TCOFLUSH = 1;
4882+ enum TCIOFLUSH = 2;
4883+
4884+ enum TCIOFF = 3;
4885+ enum TCION = 4;
4886+ enum TCOOFF = 1;
4887+ enum TCOON = 2;
4888+}
4889+else
4890+{
4891+ static assert(false, "Unsupported platform");
4892+}
4893+
4894
4895 /*
4896 speed_t cfgetispeed(const scope termios*);
4897diff --git a/druntime/src/core/sys/posix/time.d b/druntime/src/core/sys/posix/time.d
4898index 4fc73aab8c..4ed44a1b56 100644
4899--- a/druntime/src/core/sys/posix/time.d
4900+++ b/druntime/src/core/sys/posix/time.d
4901@@ -157,6 +157,10 @@ else version (Solaris)
4902 {
4903 enum CLOCK_MONOTONIC = 4;
4904 }
4905+else version (Hurd)
4906+{
4907+ enum CLOCK_MONOTONIC = 1;
4908+}
4909 else
4910 {
4911 static assert(0);
4912@@ -260,6 +264,14 @@ else version (Solaris)
4913
4914 alias timestruc_t = timespec;
4915 }
4916+else version (Hurd)
4917+{
4918+ struct timespec
4919+ {
4920+ time_t tv_sec;
4921+ c_long tv_nsec;
4922+ }
4923+}
4924 else
4925 {
4926 static assert(false, "Unsupported platform");
4927diff --git a/druntime/src/core/thread/fiber/switch_context_asm.S b/druntime/src/core/thread/fiber/switch_context_asm.S
4928index cef64f65f0..ca44874262 100644
4929--- a/druntime/src/core/thread/fiber/switch_context_asm.S
4930+++ b/druntime/src/core/thread/fiber/switch_context_asm.S
4931@@ -13,7 +13,7 @@
4932 * http://www.boost.org/LICENSE_1_0.txt)
4933 */
4934
4935-#if (__linux__ || __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __DragonFly__) && __ELF__
4936+#if (__linux__ || __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __DragonFly__ | __GNU__) && __ELF__
4937 /*
4938 * Mark the resulting object file as not requiring execution permissions on
4939 * stack memory. The absence of this section would mark the whole resulting
4940diff --git a/druntime/src/core/thread/osthread.d b/druntime/src/core/thread/osthread.d
4941index d2e6060a28..628e08015e 100644
4942--- a/druntime/src/core/thread/osthread.d
4943+++ b/druntime/src/core/thread/osthread.d
4944@@ -2280,6 +2280,14 @@ extern (C) void thread_init() @nogc nothrow
4945 enum SIGRTMIN = SIGUSR1;
4946 enum SIGRTMAX = 32;
4947 }
4948+ else version (Hurd)
4949+ {
4950+ // Hurd does not support SIGRTMIN or SIGRTMAX
4951+ // Use SIGUSR1 for SIGRTMIN, SIGUSR2 for SIGRTMIN + 1
4952+ // And use 32 for SIGRTMAX (32 is the max signal number on Hurd)
4953+ enum SIGRTMIN = SIGUSR1;
4954+ enum SIGRTMAX = 32;
4955+ }
4956 else
4957 {
4958 import core.sys.posix.signal : SIGRTMAX, SIGRTMIN;
4959diff --git a/druntime/src/core/time.d b/druntime/src/core/time.d
4960index beb6963486..6f74b709fb 100644
4961--- a/druntime/src/core/time.d
4962+++ b/druntime/src/core/time.d
4963@@ -337,6 +337,17 @@ else version (Solaris) enum ClockType
4964 second = 6,
4965 threadCPUTime = 7,
4966 }
4967+else version (Hurd) enum ClockType
4968+{
4969+ normal = 0,
4970+ coarse = 2,
4971+ precise = 3,
4972+ // processCPUTime = 4,
4973+ raw = 5,
4974+ second = 6,
4975+ // threadCPUTime = 7,
4976+
4977+}
4978 else
4979 {
4980 // It needs to be decided (and implemented in an appropriate version branch
4981@@ -436,6 +447,20 @@ version (Posix)
4982 case second: assert(0);
4983 }
4984 }
4985+ else version (Hurd)
4986+ {
4987+ import core.sys.hurd.time;
4988+ with(ClockType) final switch (clockType)
4989+ {
4990+ case coarse: return CLOCK_MONOTONIC_COARSE;
4991+ case normal: return CLOCK_MONOTONIC;
4992+ case precise: return CLOCK_MONOTONIC;
4993+ // case processCPUTime: return CLOCK_PROCESS_CPUTIME_ID;
4994+ case raw: return CLOCK_MONOTONIC_RAW;
4995+ // case threadCPUTime: return CLOCK_THREAD_CPUTIME_ID;
4996+ case second: assert(0);
4997+ }
4998+ }
4999 else
5000 // It needs to be decided (and implemented in an appropriate
5001 // version branch here) which clock types new platforms are going
5002diff --git a/druntime/src/importc.h b/druntime/src/importc.h
5003index dd2cdb87b4..6e7221ec5b 100644
5004--- a/druntime/src/importc.h
5005+++ b/druntime/src/importc.h
5006@@ -178,7 +178,7 @@ typedef unsigned long long __uint64_t;
5007 #endif
5008
5009 #define _Float16 float
5010-#ifdef __linux__ // Microsoft won't allow the following macro
5011+#if defined(__linux__) || defined(__GNU__) // Microsoft won't allow the following macro
5012 // Ubuntu's assert.h uses this
5013 #define __PRETTY_FUNCTION__ __func__
5014
5015@@ -201,7 +201,7 @@ typedef struct {} __SVFloat32_t;
5016 typedef struct {} __SVFloat64_t;
5017 #endif
5018
5019-#endif // __linux__
5020+#endif // __linux__ || __GNU__
5021
5022 #if __APPLE__
5023 #undef __SIZEOF_INT128__
5024diff --git a/druntime/src/rt/sections_elf_shared.d b/druntime/src/rt/sections_elf_shared.d
5025index aac5b402ae..f16eca5d03 100644
5026--- a/druntime/src/rt/sections_elf_shared.d
5027+++ b/druntime/src/rt/sections_elf_shared.d
5028@@ -64,6 +64,12 @@ else version (DragonFlyBSD)
5029 import core.sys.dragonflybsd.sys.elf : DT_AUXILIARY, DT_FILTER, DT_NEEDED, DT_STRTAB, PF_W, PF_X, PT_DYNAMIC, PT_LOAD, PT_TLS;
5030 import core.sys.dragonflybsd.sys.link_elf : ElfW, link_map;
5031 }
5032+else version (Hurd)
5033+{
5034+ import core.sys.hurd.dlfcn : Dl_info, dladdr, dlclose, dlinfo, dlopen, RTLD_DI_LINKMAP, RTLD_LAZY, RTLD_NOLOAD;
5035+ import core.sys.hurd.elf : DT_AUXILIARY, DT_FILTER, DT_NEEDED, DT_STRTAB, PF_W, PF_X, PT_DYNAMIC, PT_LOAD, PT_TLS;
5036+ import core.sys.hurd.link : ElfW, link_map;
5037+}
5038 else
5039 {
5040 static assert(0, "unimplemented");
5041@@ -744,6 +750,8 @@ version (Shared)
5042 enum relocate = true;
5043 else version (DragonFlyBSD)
5044 enum relocate = true;
5045+ else version (Hurd)
5046+ enum relocate = false;
5047 else
5048 static assert(0, "unimplemented");
5049
5050diff --git a/druntime/test/importc_compare/src/importc_compare.d b/druntime/test/importc_compare/src/importc_compare.d
5051index bf3fd14172..9a7267ca47 100644
5052--- a/druntime/test/importc_compare/src/importc_compare.d
5053+++ b/druntime/test/importc_compare/src/importc_compare.d
5054@@ -37,10 +37,14 @@ immutable ErrorFilter[] knownProblems = [
5055 ErrorFilter("core.stdc.locale.lconv", "", "Windows", 0, "https://issues.dlang.org/show_bug.cgi?id=24652"),
5056 ErrorFilter("core.stdc.math.double_t", "", "linux", 0, ""),
5057 ErrorFilter("core.stdc.math.float_t", "", "linux", 0, ""),
5058+ ErrorFilter("core.stdc.math.double_t", "", "Hurd", 0, ""),
5059+ ErrorFilter("core.stdc.math.float_t", "", "Hurd", 0, ""),
5060 ErrorFilter("core.stdc.signal.sig_atomic_t", "", "FreeBSD", 0, ""),
5061 ErrorFilter("core.stdc.stdio.FILE", "", "FreeBSD", 0, ""),
5062 ErrorFilter("core.stdc.stdio.FILE", "", "linux", 0, ""),
5063 ErrorFilter("core.stdc.stdio._IO_FILE", "", "linux", 0, ""),
5064+ ErrorFilter("core.stdc.stdio.FILE", "", "Hurd", 0, ""),
5065+ ErrorFilter("core.stdc.stdio._IO_FILE", "", "Hurd", 0, ""),
5066 ErrorFilter("core.stdc.stdio.__sFILE", "", "FreeBSD", 0, ""),
5067 ErrorFilter("core.stdc.wchar_.mbstate_t", "", "Apple", 0, ""),
5068 ErrorFilter("core.stdc.wchar_.mbstate_t", "", "Windows", 0, ""),
5069diff --git a/druntime/test/profile/myprofilegc.log.hurd.32.exp b/druntime/test/profile/myprofilegc.log.hurd.32.exp
5070new file mode 100644
5071index 0000000000..bdf8dd0a9b
5072--- /dev/null
5073+++ b/druntime/test/profile/myprofilegc.log.hurd.32.exp
5074@@ -0,0 +1,18 @@
5075+bytes allocated, allocations, type, function, file:line
5076+ 128 1 float profilegc.main src/profilegc.d:18
5077+ 128 1 int profilegc.main src/profilegc.d:15
5078+ 64 1 double[] profilegc.main src/profilegc.d:56
5079+ 48 1 float[] profilegc.main src/profilegc.d:42
5080+ 48 1 int[] profilegc.main src/profilegc.d:41
5081+ 32 1 void[] profilegc.main src/profilegc.d:55
5082+ 16 1 C profilegc.main src/profilegc.d:12
5083+ 16 1 char[] profilegc.main src/profilegc.d:34
5084+ 16 1 char[] profilegc.main src/profilegc.d:36
5085+ 16 1 closure profilegc.main.foo src/profilegc.d:45
5086+ 16 1 float profilegc.main src/profilegc.d:16
5087+ 16 1 float profilegc.main src/profilegc.d:17
5088+ 16 1 int profilegc.main src/profilegc.d:13
5089+ 16 1 int profilegc.main src/profilegc.d:14
5090+ 16 1 int[] profilegc.main src/profilegc.d:22
5091+ 16 1 int[] profilegc.main src/profilegc.d:37
5092+ 16 1 wchar[] profilegc.main src/profilegc.d:35
5093diff --git a/druntime/test/profile/myprofilegc.log.hurd.64.exp b/druntime/test/profile/myprofilegc.log.hurd.64.exp
5094new file mode 100644
5095index 0000000000..0a882256c9
5096--- /dev/null
5097+++ b/druntime/test/profile/myprofilegc.log.hurd.64.exp
5098@@ -0,0 +1,18 @@
5099+bytes allocated, allocations, type, function, file:line
5100+ 160 1 float profilegc.main src/profilegc.d:18
5101+ 160 1 int profilegc.main src/profilegc.d:15
5102+ 64 1 double[] profilegc.main src/profilegc.d:56
5103+ 48 1 float[] profilegc.main src/profilegc.d:42
5104+ 48 1 int[] profilegc.main src/profilegc.d:41
5105+ 32 1 C profilegc.main src/profilegc.d:12
5106+ 32 1 void[] profilegc.main src/profilegc.d:55
5107+ 16 1 char[] profilegc.main src/profilegc.d:34
5108+ 16 1 char[] profilegc.main src/profilegc.d:36
5109+ 16 1 closure profilegc.main.foo src/profilegc.d:45
5110+ 16 1 float profilegc.main src/profilegc.d:16
5111+ 16 1 float profilegc.main src/profilegc.d:17
5112+ 16 1 int profilegc.main src/profilegc.d:13
5113+ 16 1 int profilegc.main src/profilegc.d:14
5114+ 16 1 int[] profilegc.main src/profilegc.d:22
5115+ 16 1 int[] profilegc.main src/profilegc.d:37
5116+ 16 1 wchar[] profilegc.main src/profilegc.d:35
5117diff --git a/druntime/test/shared/src/load.d b/druntime/test/shared/src/load.d
5118index a36fcffefc..61d50f8e37 100644
5119--- a/druntime/test/shared/src/load.d
5120+++ b/druntime/test/shared/src/load.d
5121@@ -8,6 +8,7 @@ version (linux) import core.sys.linux.dlfcn : RTLD_NOLOAD;
5122 version (NetBSD) import core.sys.netbsd.dlfcn : RTLD_NOLOAD;
5123 version (OSX) import core.sys.darwin.dlfcn : RTLD_NOLOAD;
5124 version (Solaris) import core.sys.solaris.dlfcn : RTLD_NOLOAD;
5125+version (Hurd) import core.sys.hurd.dlfcn : RTLD_NOLOAD;
5126
5127 void* openLib(string s)
5128 {
5129--
51302.54.0
5131
5132From 887b98836ca67903323fc4dc2fff9820964d0f17 Mon Sep 17 00:00:00 2001
5133From: Yelninei <[email protected]>
5134Date: Mon, 20 Apr 2026 15:02:46 +0000
5135Subject: [PATCH 3/3] druntime: Add version(linux) to linux/stdio.d.
5136
5137---
5138 druntime/src/core/sys/linux/stdio.d | 1 +
5139 1 file changed, 1 insertion(+)
5140
5141diff --git a/druntime/src/core/sys/linux/stdio.d b/druntime/src/core/sys/linux/stdio.d
5142index 1d18429b03..6fbd7a0b50 100644
5143--- a/druntime/src/core/sys/linux/stdio.d
5144+++ b/druntime/src/core/sys/linux/stdio.d
5145@@ -6,6 +6,7 @@
5146 * Authors: Danny Milosavljevic
5147 */
5148 module core.sys.linux.stdio;
5149+version (linux):
5150 version (CRuntime_Glibc):
5151 public import core.sys.posix.stdio;
5152 import core.sys.posix.sys.types : ssize_t, off64_t = off_t;
5153--
51542.54.0
5155