@zigc/lib 0.16.0-test.1 → 0.17.0-dev.131

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (352) hide show
  1. package/LICENSE +19 -0
  2. package/c/fcntl.zig +6 -1
  3. package/c/inttypes.zig +0 -10
  4. package/c/math.zig +138 -114
  5. package/c/pthread.zig +57 -0
  6. package/c/search.zig +1 -27
  7. package/c/stdlib/drand48.zig +0 -57
  8. package/c/stdlib.zig +0 -100
  9. package/c/string.zig +20 -7
  10. package/c/strings.zig +0 -38
  11. package/c/stropts.zig +17 -0
  12. package/c/unistd.zig +27 -26
  13. package/c/wchar.zig +10 -0
  14. package/c.zig +3 -2
  15. package/compiler/aro/aro/Attribute/names.zig +604 -589
  16. package/compiler/aro/aro/Attribute.zig +202 -116
  17. package/compiler/aro/aro/Builtins/common.zig +874 -863
  18. package/compiler/aro/aro/Builtins/eval.zig +15 -7
  19. package/compiler/aro/aro/Builtins.zig +0 -1
  20. package/compiler/aro/aro/CodeGen.zig +8 -7
  21. package/compiler/aro/aro/Compilation.zig +137 -111
  22. package/compiler/aro/aro/Diagnostics.zig +21 -17
  23. package/compiler/aro/aro/Driver/GCCDetector.zig +635 -0
  24. package/compiler/aro/aro/Driver.zig +138 -63
  25. package/compiler/aro/aro/LangOpts.zig +12 -2
  26. package/compiler/aro/aro/Parser/Diagnostic.zig +79 -19
  27. package/compiler/aro/aro/Parser.zig +352 -153
  28. package/compiler/aro/aro/Pragma.zig +3 -2
  29. package/compiler/aro/aro/Preprocessor/Diagnostic.zig +21 -0
  30. package/compiler/aro/aro/Preprocessor.zig +136 -62
  31. package/compiler/aro/aro/Target.zig +17 -12
  32. package/compiler/aro/aro/Tokenizer.zig +31 -14
  33. package/compiler/aro/aro/Toolchain.zig +4 -7
  34. package/compiler/aro/aro/Tree.zig +178 -148
  35. package/compiler/aro/aro/TypeStore.zig +82 -24
  36. package/compiler/aro/aro/Value.zig +13 -17
  37. package/compiler/aro/aro/features.zig +1 -0
  38. package/compiler/aro/aro/pragmas/message.zig +3 -2
  39. package/compiler/aro/aro/pragmas/once.zig +0 -1
  40. package/compiler/aro/aro/record_layout.zig +3 -3
  41. package/compiler/aro/aro/text_literal.zig +3 -2
  42. package/compiler/aro/assembly_backend/x86_64.zig +7 -8
  43. package/compiler/aro/backend/Assembly.zig +1 -2
  44. package/compiler/aro/backend/Interner.zig +2 -2
  45. package/compiler/aro/backend/Ir.zig +100 -92
  46. package/compiler/aro/include/ptrcheck.h +49 -0
  47. package/compiler/aro/main.zig +26 -10
  48. package/compiler/build_runner.zig +1 -2
  49. package/compiler/objdump.zig +93 -0
  50. package/compiler/reduce/Walk.zig +7 -7
  51. package/compiler/reduce.zig +5 -1
  52. package/compiler/resinator/compile.zig +2 -2
  53. package/compiler/resinator/main.zig +7 -1
  54. package/compiler/resinator/preprocess.zig +1 -3
  55. package/compiler/std-docs.zig +8 -1
  56. package/compiler/test_runner.zig +194 -62
  57. package/compiler/translate-c/MacroTranslator.zig +80 -11
  58. package/compiler/translate-c/PatternList.zig +1 -9
  59. package/compiler/translate-c/Scope.zig +43 -6
  60. package/compiler/translate-c/Translator.zig +369 -127
  61. package/compiler/translate-c/ast.zig +19 -11
  62. package/compiler/translate-c/main.zig +76 -17
  63. package/compiler_rt/cos.zig +140 -53
  64. package/compiler_rt/divmodei4.zig +40 -17
  65. package/compiler_rt/exp.zig +1 -6
  66. package/compiler_rt/exp2.zig +1 -6
  67. package/compiler_rt/exp_f128.zig +377 -0
  68. package/compiler_rt/fabs.zig +0 -2
  69. package/compiler_rt/fma.zig +0 -2
  70. package/compiler_rt/fmax.zig +0 -2
  71. package/compiler_rt/fmin.zig +0 -2
  72. package/compiler_rt/fmod.zig +0 -2
  73. package/compiler_rt/limb64.zig +1127 -0
  74. package/compiler_rt/log.zig +0 -2
  75. package/compiler_rt/log10.zig +0 -2
  76. package/compiler_rt/log2.zig +0 -2
  77. package/compiler_rt/long_double.zig +37 -0
  78. package/compiler_rt/mulXi3.zig +1 -1
  79. package/compiler_rt/mulo.zig +6 -1
  80. package/compiler_rt/rem_pio2l.zig +173 -0
  81. package/compiler_rt/round.zig +0 -2
  82. package/compiler_rt/sin.zig +139 -56
  83. package/compiler_rt/sincos.zig +277 -72
  84. package/compiler_rt/sqrt.zig +0 -2
  85. package/compiler_rt/ssp.zig +1 -1
  86. package/compiler_rt/tan.zig +117 -48
  87. package/compiler_rt/trig.zig +256 -6
  88. package/compiler_rt/trunc.zig +0 -2
  89. package/compiler_rt/udivmodei4.zig +28 -0
  90. package/compiler_rt.zig +2 -0
  91. package/fuzzer.zig +857 -307
  92. package/libc/musl/arch/mipsn32/syscall_arch.h +35 -32
  93. package/libc/musl/src/math/pow.c +343 -0
  94. package/package.json +1 -1
  95. package/std/Build/Cache.zig +6 -6
  96. package/std/Build/Fuzz.zig +6 -19
  97. package/std/Build/Module.zig +1 -1
  98. package/std/Build/Step/CheckObject.zig +3 -3
  99. package/std/Build/Step/Compile.zig +18 -1
  100. package/std/Build/Step/ConfigHeader.zig +49 -33
  101. package/std/Build/Step/InstallArtifact.zig +18 -0
  102. package/std/Build/Step/Run.zig +538 -89
  103. package/std/Build/Step/TranslateC.zig +0 -6
  104. package/std/Build/Step.zig +10 -19
  105. package/std/Build/WebServer.zig +31 -19
  106. package/std/Build/abi.zig +47 -11
  107. package/std/Build.zig +17 -17
  108. package/std/Io/Dir.zig +7 -2
  109. package/std/Io/Dispatch.zig +5 -13
  110. package/std/Io/File/Reader.zig +3 -1
  111. package/std/Io/File/Writer.zig +8 -6
  112. package/std/Io/File.zig +1 -0
  113. package/std/Io/Kqueue.zig +2 -2
  114. package/std/Io/Reader.zig +8 -9
  115. package/std/Io/Semaphore.zig +112 -17
  116. package/std/Io/Terminal.zig +1 -1
  117. package/std/Io/Threaded.zig +352 -180
  118. package/std/Io/Uring.zig +15 -16
  119. package/std/Io/Writer.zig +46 -42
  120. package/std/Io/net.zig +11 -11
  121. package/std/Io.zig +1052 -20
  122. package/std/SemanticVersion.zig +1 -1
  123. package/std/Target/Query.zig +2 -2
  124. package/std/Target.zig +53 -7
  125. package/std/Thread.zig +8 -3
  126. package/std/array_hash_map.zig +105 -573
  127. package/std/array_list.zig +22 -31
  128. package/std/bit_set.zig +22 -6
  129. package/std/builtin/assembly.zig +68 -0
  130. package/std/builtin.zig +4 -0
  131. package/std/c/haiku.zig +3 -0
  132. package/std/c/serenity.zig +1 -6
  133. package/std/c.zig +106 -24
  134. package/std/compress/flate/Compress.zig +3 -3
  135. package/std/compress/flate/Decompress.zig +2 -3
  136. package/std/compress/zstd/Decompress.zig +2 -4
  137. package/std/crypto/Certificate/Bundle.zig +15 -1
  138. package/std/crypto/Certificate.zig +13 -1
  139. package/std/crypto/ascon.zig +75 -33
  140. package/std/crypto/codecs/asn1/Oid.zig +12 -1
  141. package/std/crypto/codecs/asn1.zig +33 -18
  142. package/std/crypto/codecs/base64_hex_ct.zig +16 -8
  143. package/std/crypto/ml_kem.zig +2 -9
  144. package/std/crypto/tls/Client.zig +79 -4
  145. package/std/crypto/tls.zig +1 -1
  146. package/std/crypto.zig +1 -0
  147. package/std/debug/Dwarf.zig +29 -9
  148. package/std/debug/Info.zig +4 -0
  149. package/std/debug/MachOFile.zig +46 -8
  150. package/std/debug/Pdb.zig +540 -37
  151. package/std/debug/SelfInfo/Elf.zig +19 -18
  152. package/std/debug/SelfInfo/MachO.zig +18 -7
  153. package/std/debug/SelfInfo/Windows.zig +138 -36
  154. package/std/debug.zig +181 -66
  155. package/std/enums.zig +25 -19
  156. package/std/fmt.zig +8 -3
  157. package/std/fs/path.zig +6 -4
  158. package/std/heap/ArenaAllocator.zig +145 -154
  159. package/std/heap/BufferFirstAllocator.zig +165 -0
  160. package/std/heap/debug_allocator.zig +7 -7
  161. package/std/heap.zig +2 -126
  162. package/std/http/Client.zig +31 -30
  163. package/std/http.zig +14 -13
  164. package/std/json/Scanner.zig +2 -2
  165. package/std/json/Stringify.zig +3 -3
  166. package/std/json/dynamic.zig +4 -4
  167. package/std/math/big/int.zig +16 -17
  168. package/std/mem/Allocator.zig +4 -5
  169. package/std/mem.zig +48 -0
  170. package/std/os/emscripten.zig +2 -18
  171. package/std/os/linux/IoUring.zig +2 -0
  172. package/std/os/linux/aarch64.zig +41 -12
  173. package/std/os/linux/arc.zig +173 -0
  174. package/std/os/linux/arm.zig +41 -12
  175. package/std/os/linux/hexagon.zig +33 -11
  176. package/std/os/linux/loongarch32.zig +41 -13
  177. package/std/os/linux/loongarch64.zig +41 -12
  178. package/std/os/linux/m68k.zig +41 -13
  179. package/std/os/linux/mips.zig +67 -36
  180. package/std/os/linux/mips64.zig +60 -29
  181. package/std/os/linux/mipsn32.zig +60 -29
  182. package/std/os/linux/or1k.zig +41 -12
  183. package/std/os/linux/powerpc.zig +41 -12
  184. package/std/os/linux/powerpc64.zig +41 -12
  185. package/std/os/linux/riscv32.zig +41 -12
  186. package/std/os/linux/riscv64.zig +41 -12
  187. package/std/os/linux/s390x.zig +44 -7
  188. package/std/os/linux/sparc64.zig +83 -52
  189. package/std/os/linux/thumb.zig +52 -36
  190. package/std/os/linux/x32.zig +41 -12
  191. package/std/os/linux/x86.zig +42 -13
  192. package/std/os/linux/x86_64.zig +41 -12
  193. package/std/os/linux.zig +419 -438
  194. package/std/os/uefi/tables/boot_services.zig +9 -8
  195. package/std/os/windows.zig +2 -2
  196. package/std/os.zig +41 -0
  197. package/std/pdb.zig +143 -4
  198. package/std/posix.zig +6 -12
  199. package/std/priority_dequeue.zig +13 -12
  200. package/std/priority_queue.zig +5 -4
  201. package/std/process/Child.zig +1 -1
  202. package/std/process/Environ.zig +1 -1
  203. package/std/process.zig +1 -1
  204. package/std/sort.zig +3 -3
  205. package/std/start.zig +17 -4
  206. package/std/std.zig +19 -6
  207. package/std/testing/FailingAllocator.zig +4 -4
  208. package/std/testing/Smith.zig +37 -2
  209. package/std/zig/Ast/Render.zig +187 -459
  210. package/std/zig/Ast.zig +0 -4
  211. package/std/zig/AstGen.zig +86 -103
  212. package/std/zig/AstRlAnnotate.zig +0 -11
  213. package/std/zig/AstSmith.zig +2602 -0
  214. package/std/zig/BuiltinFn.zig +0 -32
  215. package/std/zig/Client.zig +8 -3
  216. package/std/zig/LibCInstallation.zig +4 -3
  217. package/std/zig/Parse.zig +90 -81
  218. package/std/zig/Server.zig +26 -0
  219. package/std/zig/WindowsSdk.zig +13 -13
  220. package/std/zig/Zir.zig +66 -62
  221. package/std/zig/ZonGen.zig +6 -5
  222. package/std/zig/c_translation/helpers.zig +14 -9
  223. package/std/zig/llvm/Builder.zig +119 -60
  224. package/std/zig/system.zig +20 -4
  225. package/std/zig/tokenizer.zig +2 -1
  226. package/std/zig.zig +7 -10
  227. package/std/zip.zig +5 -5
  228. package/zig.h +340 -1
  229. package/compiler/aro/aro/Driver/Filesystem.zig +0 -241
  230. package/libc/mingw/complex/cabs.c +0 -48
  231. package/libc/mingw/complex/cabsf.c +0 -48
  232. package/libc/mingw/complex/cacos.c +0 -50
  233. package/libc/mingw/complex/cacosf.c +0 -50
  234. package/libc/mingw/complex/carg.c +0 -48
  235. package/libc/mingw/complex/cargf.c +0 -48
  236. package/libc/mingw/complex/casin.c +0 -50
  237. package/libc/mingw/complex/casinf.c +0 -50
  238. package/libc/mingw/complex/catan.c +0 -50
  239. package/libc/mingw/complex/catanf.c +0 -50
  240. package/libc/mingw/complex/ccos.c +0 -50
  241. package/libc/mingw/complex/ccosf.c +0 -50
  242. package/libc/mingw/complex/cexp.c +0 -48
  243. package/libc/mingw/complex/cexpf.c +0 -48
  244. package/libc/mingw/complex/cimag.c +0 -48
  245. package/libc/mingw/complex/cimagf.c +0 -48
  246. package/libc/mingw/complex/clog.c +0 -48
  247. package/libc/mingw/complex/clog10.c +0 -49
  248. package/libc/mingw/complex/clog10f.c +0 -49
  249. package/libc/mingw/complex/clogf.c +0 -48
  250. package/libc/mingw/complex/conj.c +0 -48
  251. package/libc/mingw/complex/conjf.c +0 -48
  252. package/libc/mingw/complex/cpow.c +0 -48
  253. package/libc/mingw/complex/cpowf.c +0 -48
  254. package/libc/mingw/complex/cproj.c +0 -48
  255. package/libc/mingw/complex/cprojf.c +0 -48
  256. package/libc/mingw/complex/creal.c +0 -48
  257. package/libc/mingw/complex/crealf.c +0 -48
  258. package/libc/mingw/complex/csin.c +0 -50
  259. package/libc/mingw/complex/csinf.c +0 -50
  260. package/libc/mingw/complex/csqrt.c +0 -48
  261. package/libc/mingw/complex/csqrtf.c +0 -48
  262. package/libc/mingw/complex/ctan.c +0 -50
  263. package/libc/mingw/complex/ctanf.c +0 -50
  264. package/libc/mingw/math/arm/s_rint.c +0 -86
  265. package/libc/mingw/math/arm/s_rintf.c +0 -51
  266. package/libc/mingw/math/arm/sincos.S +0 -30
  267. package/libc/mingw/math/arm-common/sincosl.c +0 -13
  268. package/libc/mingw/math/arm64/rint.c +0 -12
  269. package/libc/mingw/math/arm64/rintf.c +0 -12
  270. package/libc/mingw/math/arm64/sincos.S +0 -32
  271. package/libc/mingw/math/bsd_private_base.h +0 -148
  272. package/libc/mingw/math/fdiml.c +0 -24
  273. package/libc/mingw/math/frexpf.c +0 -13
  274. package/libc/mingw/math/frexpl.c +0 -71
  275. package/libc/mingw/math/x86/acosf.c +0 -29
  276. package/libc/mingw/math/x86/atanf.c +0 -23
  277. package/libc/mingw/math/x86/atanl.c +0 -18
  278. package/libc/mingw/math/x86/cos.def.h +0 -65
  279. package/libc/mingw/math/x86/cosl.c +0 -46
  280. package/libc/mingw/math/x86/cosl_internal.S +0 -55
  281. package/libc/mingw/math/x86/ldexp.c +0 -23
  282. package/libc/mingw/math/x86/scalbn.S +0 -41
  283. package/libc/mingw/math/x86/scalbnf.S +0 -40
  284. package/libc/mingw/math/x86/sin.def.h +0 -65
  285. package/libc/mingw/math/x86/sinl.c +0 -46
  286. package/libc/mingw/math/x86/sinl_internal.S +0 -58
  287. package/libc/mingw/math/x86/tanl.S +0 -62
  288. package/libc/mingw/misc/btowc.c +0 -28
  289. package/libc/mingw/misc/wcstof.c +0 -66
  290. package/libc/mingw/misc/wcstoimax.c +0 -132
  291. package/libc/mingw/misc/wcstoumax.c +0 -126
  292. package/libc/mingw/misc/wctob.c +0 -29
  293. package/libc/mingw/misc/winbs_uint64.c +0 -6
  294. package/libc/mingw/misc/winbs_ulong.c +0 -6
  295. package/libc/mingw/misc/winbs_ushort.c +0 -6
  296. package/libc/mingw/stdio/_Exit.c +0 -10
  297. package/libc/mingw/stdio/_findfirst64i32.c +0 -21
  298. package/libc/mingw/stdio/_findnext64i32.c +0 -21
  299. package/libc/mingw/stdio/_fstat64i32.c +0 -37
  300. package/libc/mingw/stdio/_stat64i32.c +0 -37
  301. package/libc/mingw/stdio/_wfindfirst64i32.c +0 -21
  302. package/libc/mingw/stdio/_wfindnext64i32.c +0 -21
  303. package/libc/mingw/stdio/_wstat64i32.c +0 -37
  304. package/libc/mingw/winpthreads/spinlock.c +0 -82
  305. package/libc/musl/src/legacy/isastream.c +0 -7
  306. package/libc/musl/src/legacy/valloc.c +0 -8
  307. package/libc/musl/src/linux/tee.c +0 -8
  308. package/libc/musl/src/math/__cosl.c +0 -96
  309. package/libc/musl/src/math/__sinl.c +0 -78
  310. package/libc/musl/src/math/__tanl.c +0 -143
  311. package/libc/musl/src/math/aarch64/lrint.c +0 -10
  312. package/libc/musl/src/math/aarch64/lrintf.c +0 -10
  313. package/libc/musl/src/math/aarch64/rintf.c +0 -7
  314. package/libc/musl/src/math/cosl.c +0 -39
  315. package/libc/musl/src/math/fdim.c +0 -10
  316. package/libc/musl/src/math/fdimf.c +0 -10
  317. package/libc/musl/src/math/fdiml.c +0 -18
  318. package/libc/musl/src/math/finite.c +0 -7
  319. package/libc/musl/src/math/finitef.c +0 -7
  320. package/libc/musl/src/math/frexp.c +0 -23
  321. package/libc/musl/src/math/frexpf.c +0 -23
  322. package/libc/musl/src/math/frexpl.c +0 -29
  323. package/libc/musl/src/math/i386/lrint.c +0 -8
  324. package/libc/musl/src/math/i386/lrintf.c +0 -8
  325. package/libc/musl/src/math/i386/rintf.c +0 -7
  326. package/libc/musl/src/math/lrint.c +0 -72
  327. package/libc/musl/src/math/lrintf.c +0 -8
  328. package/libc/musl/src/math/powerpc64/lrint.c +0 -16
  329. package/libc/musl/src/math/powerpc64/lrintf.c +0 -16
  330. package/libc/musl/src/math/rintf.c +0 -30
  331. package/libc/musl/src/math/s390x/rintf.c +0 -15
  332. package/libc/musl/src/math/sincosl.c +0 -60
  333. package/libc/musl/src/math/sinl.c +0 -41
  334. package/libc/musl/src/math/tanl.c +0 -29
  335. package/libc/musl/src/math/x32/lrint.s +0 -5
  336. package/libc/musl/src/math/x32/lrintf.s +0 -5
  337. package/libc/musl/src/math/x86_64/lrint.c +0 -8
  338. package/libc/musl/src/math/x86_64/lrintf.c +0 -8
  339. package/libc/musl/src/string/strdup.c +0 -10
  340. package/libc/musl/src/string/strndup.c +0 -12
  341. package/libc/musl/src/string/wcsdup.c +0 -10
  342. package/libc/musl/src/thread/pthread_spin_destroy.c +0 -6
  343. package/libc/musl/src/thread/pthread_spin_init.c +0 -6
  344. package/libc/musl/src/thread/pthread_spin_lock.c +0 -8
  345. package/libc/musl/src/thread/pthread_spin_trylock.c +0 -7
  346. package/libc/musl/src/thread/pthread_spin_unlock.c +0 -7
  347. package/libc/musl/src/unistd/dup2.c +0 -20
  348. package/libc/musl/src/unistd/dup3.c +0 -26
  349. package/libc/wasi/libc-bottom-half/sources/reallocarray.c +0 -14
  350. package/libc/wasi/thread-stub/pthread_spin_lock.c +0 -8
  351. package/libc/wasi/thread-stub/pthread_spin_trylock.c +0 -8
  352. package/libc/wasi/thread-stub/pthread_spin_unlock.c +0 -7
@@ -1671,20 +1671,23 @@ pub fn init(
1671
1671
  /// When initialized this way:
1672
1672
  /// * cancel requests have no effect.
1673
1673
  /// * `deinit` is safe, but unnecessary to call.
1674
- pub const init_single_threaded: Threaded = .{
1675
- .allocator = .failing,
1676
- .stack_size = std.Thread.SpawnConfig.default_stack_size,
1677
- .async_limit = .nothing,
1678
- .cpu_count_error = null,
1679
- .concurrent_limit = .nothing,
1680
- .old_sig_io = undefined,
1681
- .old_sig_pipe = undefined,
1682
- .have_signal_handler = false,
1683
- .argv0 = .empty,
1684
- .environ_initialized = true,
1685
- .environ = .empty,
1686
- .worker_threads = .init(null),
1687
- .disable_memory_mapping = false,
1674
+ pub const init_single_threaded: Threaded = init: {
1675
+ const env_block: process.Environ.Block = if (is_windows) .global else .empty;
1676
+ break :init .{
1677
+ .allocator = .failing,
1678
+ .stack_size = std.Thread.SpawnConfig.default_stack_size,
1679
+ .async_limit = .nothing,
1680
+ .cpu_count_error = null,
1681
+ .concurrent_limit = .nothing,
1682
+ .old_sig_io = undefined,
1683
+ .old_sig_pipe = undefined,
1684
+ .have_signal_handler = false,
1685
+ .argv0 = .empty,
1686
+ .environ_initialized = env_block.isEmpty(),
1687
+ .environ = .{ .process_environ = .{ .block = env_block } },
1688
+ .worker_threads = .init(null),
1689
+ .disable_memory_mapping = false,
1690
+ };
1688
1691
  };
1689
1692
 
1690
1693
  var global_single_threaded_instance: Threaded = .init_single_threaded;
@@ -1940,10 +1943,6 @@ pub fn io(t: *Threaded) Io {
1940
1943
  .windows => netShutdownWindows,
1941
1944
  else => netShutdownPosix,
1942
1945
  },
1943
- .netRead = switch (native_os) {
1944
- .windows => netReadWindows,
1945
- else => netReadPosix,
1946
- },
1947
1946
  .netWrite = switch (native_os) {
1948
1947
  .windows => netWriteWindows,
1949
1948
  else => netWritePosix,
@@ -2006,7 +2005,7 @@ const have_waitid = switch (native_os) {
2006
2005
 
2007
2006
  const have_wait4 = switch (native_os) {
2008
2007
  .linux => @hasField(std.os.linux.SYS, "wait4"),
2009
- .dragonfly, .freebsd, .netbsd, .openbsd, .illumos, .serenity, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => true,
2008
+ .dragonfly, .freebsd, .netbsd, .openbsd, .illumos, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => true,
2010
2009
  else => false,
2011
2010
  };
2012
2011
 
@@ -2563,6 +2562,12 @@ fn operate(userdata: ?*anyopaque, operation: Io.Operation) Io.Cancelable!Io.Oper
2563
2562
  };
2564
2563
  break :o .{ null, 1 };
2565
2564
  } },
2565
+ .net_read => |o| return .{
2566
+ .net_read = netRead(o.socket_handle, o.data) catch |err| switch (err) {
2567
+ error.Canceled => |e| return e,
2568
+ else => |e| e,
2569
+ },
2570
+ },
2566
2571
  }
2567
2572
  }
2568
2573
 
@@ -2618,6 +2623,14 @@ fn batchAwaitAsync(userdata: ?*anyopaque, b: *Io.Batch) Io.Cancelable!void {
2618
2623
  };
2619
2624
  poll_len += 1;
2620
2625
  },
2626
+ .net_read => |o| {
2627
+ poll_buffer[poll_len] = .{
2628
+ .fd = o.socket_handle,
2629
+ .events = posix.POLL.IN | posix.POLL.ERR,
2630
+ .revents = 0,
2631
+ };
2632
+ poll_len += 1;
2633
+ },
2621
2634
  }
2622
2635
  index = submission.node.next;
2623
2636
  }
@@ -2795,6 +2808,7 @@ fn batchAwaitConcurrent(userdata: ?*anyopaque, b: *Io.Batch, timeout: Io.Timeout
2795
2808
  storage.* = .{ .completion = .{ .node = .{ .next = .none }, .result = result } };
2796
2809
  b.completed.tail = index;
2797
2810
  },
2811
+ .net_read => |o| try poll_storage.add(o.socket_handle, posix.POLL.IN | posix.POLL.ERR),
2798
2812
  }
2799
2813
  index = submission.node.next;
2800
2814
  }
@@ -2990,6 +3004,7 @@ fn batchApc(
2990
3004
  .file_write_streaming => .{ .file_write_streaming = ntWriteFileResult(iosb) },
2991
3005
  .device_io_control => .{ .device_io_control = iosb.* },
2992
3006
  .net_receive => unreachable,
3007
+ .net_read => unreachable,
2993
3008
  };
2994
3009
  storage.* = .{ .completion = .{ .node = .{ .next = .none }, .result = result } };
2995
3010
  },
@@ -3198,6 +3213,16 @@ fn batchDrainSubmittedWindows(t: *Threaded, b: *Io.Batch, concurrency: bool) (Io
3198
3213
  .net_receive = netReceiveWindows(t, o.socket_handle, o.message_buffer, o.data_buffer, o.flags),
3199
3214
  });
3200
3215
  },
3216
+ .net_read => |*o| {
3217
+ // TODO integrate with overlapped I/O or equivalent to avoid this error
3218
+ if (concurrency) return error.ConcurrencyUnavailable;
3219
+ batchCompleteBlockingWindows(b, operation_userdata, .{
3220
+ .net_read = netRead(o.socket_handle, o.data) catch |err| switch (err) {
3221
+ error.Canceled => |e| return e,
3222
+ else => |e| e,
3223
+ },
3224
+ });
3225
+ },
3201
3226
  }
3202
3227
  index = submission.node.next;
3203
3228
  }
@@ -4290,6 +4315,7 @@ fn dirCreateFilePosix(
4290
4315
  .AGAIN => return error.WouldBlock,
4291
4316
  .TXTBSY => return error.FileBusy,
4292
4317
  .NXIO => return error.NoDevice,
4318
+ .ROFS => return error.ReadOnlyFileSystem,
4293
4319
  .ILSEQ => return error.BadPathName,
4294
4320
  else => |err| return posix.unexpectedErrno(err),
4295
4321
  }
@@ -4871,6 +4897,7 @@ fn dirOpenFilePosix(
4871
4897
  .AGAIN => return error.WouldBlock,
4872
4898
  .TXTBSY => return error.FileBusy,
4873
4899
  .NXIO => return error.NoDevice,
4900
+ .ROFS => return error.ReadOnlyFileSystem,
4874
4901
  .ILSEQ => return error.BadPathName,
4875
4902
  else => |err| return posix.unexpectedErrno(err),
4876
4903
  }
@@ -5340,7 +5367,7 @@ fn dirOpenDirHaiku(
5340
5367
  .NOMEM => return error.SystemResources,
5341
5368
  .NOTDIR => return error.NotDir,
5342
5369
  .PERM => return error.PermissionDenied,
5343
- .BUSY => return error.DeviceBusy,
5370
+ .BUSY => |err| return errnoBug(err),
5344
5371
  else => |err| return posix.unexpectedErrno(err),
5345
5372
  }
5346
5373
  },
@@ -5457,7 +5484,7 @@ fn dirReadLinux(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir
5457
5484
  }
5458
5485
  const syscall: Syscall = try .start();
5459
5486
  const n = while (true) {
5460
- const rc = linux.getdents64(dr.dir.handle, dr.buffer.ptr, dr.buffer.len);
5487
+ const rc = linux.getdents64(dr.dir.handle, dr.buffer.ptr, @min(dr.buffer.len, std.math.maxInt(c_uint)));
5461
5488
  switch (linux.errno(rc)) {
5462
5489
  .SUCCESS => {
5463
5490
  syscall.finish();
@@ -5786,10 +5813,119 @@ fn dirReadIllumos(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) D
5786
5813
  }
5787
5814
 
5788
5815
  fn dirReadHaiku(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.Reader.Error!usize {
5789
- _ = userdata;
5790
- _ = dr;
5791
- _ = buffer;
5792
- @panic("TODO implement dirReadHaiku");
5816
+ const t: *Threaded = @ptrCast(@alignCast(userdata));
5817
+ _ = t;
5818
+ var buffer_index: usize = 0;
5819
+ while (buffer.len - buffer_index != 0) {
5820
+ if (dr.end - dr.index == 0) {
5821
+ // Refill the buffer, unless we've already created references to
5822
+ // buffered data.
5823
+ if (buffer_index != 0) break;
5824
+ if (dr.state == .reset) {
5825
+ const syscall: Syscall = try .start();
5826
+ while (true) {
5827
+ const rc = posix.system._kern_rewind_dir(dr.dir.handle);
5828
+ switch (@as(posix.E, @enumFromInt(@min(rc, 0)))) {
5829
+ .SUCCESS => {
5830
+ syscall.finish();
5831
+ break;
5832
+ },
5833
+ .INTR => {
5834
+ try syscall.checkCancel();
5835
+ continue;
5836
+ },
5837
+ else => |e| {
5838
+ syscall.finish();
5839
+ switch (e) {
5840
+ else => |err| return posix.unexpectedErrno(err),
5841
+ }
5842
+ },
5843
+ }
5844
+ }
5845
+ dr.state = .reading;
5846
+ }
5847
+ const syscall: Syscall = try .start();
5848
+ const n: usize = while (true) {
5849
+ const rc = posix.system._kern_read_dir(dr.dir.handle, dr.buffer.ptr, dr.buffer.len, @truncate(dr.buffer.len / @sizeOf(posix.system.DirEnt)));
5850
+ switch (@as(posix.E, @enumFromInt(@min(rc, 0)))) {
5851
+ .SUCCESS => {
5852
+ syscall.finish();
5853
+ break @intCast(rc);
5854
+ },
5855
+ .INTR => {
5856
+ try syscall.checkCancel();
5857
+ continue;
5858
+ },
5859
+ else => |e| {
5860
+ syscall.finish();
5861
+ switch (e) {
5862
+ else => |err| return posix.unexpectedErrno(err),
5863
+ }
5864
+ },
5865
+ }
5866
+ };
5867
+ if (n == 0) {
5868
+ dr.state = .finished;
5869
+ return 0;
5870
+ }
5871
+ dr.index = 0;
5872
+ // _kern_read_dir returns entry count, but Dir.Reader is designed for byte count
5873
+ dr.end = 0;
5874
+ var i: usize = 0;
5875
+ while (i < n) : (i += 1) {
5876
+ const entry = @as(*align(1) posix.system.DirEnt, @ptrCast(&dr.buffer[dr.end]));
5877
+ dr.end += entry.reclen;
5878
+ }
5879
+ }
5880
+ const entry = @as(*align(1) posix.system.DirEnt, @ptrCast(&dr.buffer[dr.index]));
5881
+ const next_index = dr.index + entry.reclen;
5882
+ dr.index = next_index;
5883
+
5884
+ const name = std.mem.sliceTo(@as([*:0]u8, @ptrCast(&entry.name)), 0);
5885
+ if (std.mem.eql(u8, name, ".") or std.mem.eql(u8, name, "..") or entry.ino == 0) continue;
5886
+
5887
+ // haiku dirent doesn't expose type, so we have to call stat to get it.
5888
+ var stat: std.c.Stat = undefined;
5889
+ {
5890
+ const syscall: Syscall = try .start();
5891
+ while (true) {
5892
+ const rc = posix.system._kern_read_stat(dr.dir.handle, name, false, &stat, @sizeOf(std.c.Stat));
5893
+ switch (@as(posix.E, @enumFromInt(@min(rc, 0)))) {
5894
+ .SUCCESS => {
5895
+ syscall.finish();
5896
+ break;
5897
+ },
5898
+ .INTR => {
5899
+ try syscall.checkCancel();
5900
+ continue;
5901
+ },
5902
+ else => |e| {
5903
+ syscall.finish();
5904
+ switch (e) {
5905
+ else => |err| return posix.unexpectedErrno(err),
5906
+ }
5907
+ },
5908
+ }
5909
+ }
5910
+ }
5911
+
5912
+ const entry_kind: File.Kind = switch (stat.mode & posix.S.IFMT) {
5913
+ posix.S.IFBLK => .block_device,
5914
+ posix.S.IFCHR => .character_device,
5915
+ posix.S.IFDIR => .directory,
5916
+ posix.S.IFIFO => .named_pipe,
5917
+ posix.S.IFLNK => .sym_link,
5918
+ posix.S.IFREG => .file,
5919
+ else => .unknown,
5920
+ };
5921
+ buffer[buffer_index] = .{
5922
+ .name = name,
5923
+ .kind = entry_kind,
5924
+ .inode = entry.ino,
5925
+ };
5926
+ buffer_index += 1;
5927
+ }
5928
+ return buffer_index;
5793
5929
  }
5794
5930
 
5795
5931
  fn dirReadWindows(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.Reader.Error!usize {
@@ -6088,12 +6224,19 @@ fn dirRealPathFileWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8,
6088
6224
  }
6089
6225
  };
6090
6226
  defer windows.CloseHandle(h_file);
6091
- return realPathWindows(h_file, out_buffer);
6227
+
6228
+ // We can re-use the path buffer for the WTF-16 representation since
6229
+ // we don't need the prefixed path anymore
6230
+ return realPathWindowsBuf(h_file, out_buffer, &path_name_w.data);
6092
6231
  }
6093
6232
 
6094
6233
  fn realPathWindows(h_file: windows.HANDLE, out_buffer: []u8) File.RealPathError!usize {
6095
6234
  var wide_buf: [windows.PATH_MAX_WIDE]u16 = undefined;
6096
- const wide_slice = try GetFinalPathNameByHandle(h_file, .{}, &wide_buf);
6235
+ return realPathWindowsBuf(h_file, out_buffer, &wide_buf);
6236
+ }
6237
+
6238
+ fn realPathWindowsBuf(h_file: windows.HANDLE, out_buffer: []u8, wtf16_buffer: []u16) File.RealPathError!usize {
6239
+ const wide_slice = try GetFinalPathNameByHandle(h_file, .{}, wtf16_buffer);
6097
6240
 
6098
6241
  const len = std.unicode.calcWtf8Len(wide_slice);
6099
6242
  if (len > out_buffer.len)
@@ -8720,13 +8863,6 @@ fn supportsAnsiEscapeCodes(file: File) Io.Cancelable!bool {
8720
8863
  }
8721
8864
  }
8722
8865
 
8723
- if (native_os == .wasi) {
8724
- // WASI sanitizes stdout when fd is a tty so ANSI escape codes will not
8725
- // be interpreted as actual cursor commands, and stderr is always
8726
- // sanitized.
8727
- return false;
8728
- }
8729
-
8730
8866
  if (try isTty(file)) return true;
8731
8867
 
8732
8868
  return false;
@@ -9807,7 +9943,10 @@ fn fileReadPositionalPosix(file: File, data: []const []u8, offset: u64) File.Rea
9807
9943
  if (have_preadv) {
9808
9944
  const syscall: Syscall = try .start();
9809
9945
  while (true) {
9810
- const rc = preadv_sym(file.handle, dest.ptr, @intCast(dest.len), @bitCast(offset));
9946
+ const rc = if (native_os == .haiku)
9947
+ posix.system.readv_pos(file.handle, @bitCast(offset), dest.ptr, @intCast(dest.len))
9948
+ else
9949
+ preadv_sym(file.handle, dest.ptr, @intCast(dest.len), @bitCast(offset));
9811
9950
  switch (posix.errno(rc)) {
9812
9951
  .SUCCESS => {
9813
9952
  syscall.finish();
@@ -9841,7 +9980,7 @@ fn fileReadPositionalPosix(file: File, data: []const []u8, offset: u64) File.Rea
9841
9980
 
9842
9981
  const syscall: Syscall = try .start();
9843
9982
  while (true) {
9844
- const rc = posix.pread(file.handle, dest[0].ptr, @intCast(dest[0].len), @bitCast(offset));
9983
+ const rc = pread_sym(file.handle, dest[0].base, @intCast(dest[0].len), @bitCast(offset));
9845
9984
  switch (posix.errno(rc)) {
9846
9985
  .SUCCESS => {
9847
9986
  syscall.finish();
@@ -10030,10 +10169,10 @@ fn fileSeekBy(userdata: ?*anyopaque, file: File, offset: i64) File.SeekError!voi
10030
10169
  if (posix.SEEK == void) return error.Unseekable;
10031
10170
 
10032
10171
  if (native_os == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {
10033
- var result: u64 = undefined;
10172
+ var result: i64 = undefined;
10034
10173
  const syscall: Syscall = try .start();
10035
10174
  while (true) {
10036
- switch (posix.errno(posix.system.llseek(file.handle, @bitCast(offset), &result, posix.SEEK.CUR))) {
10175
+ switch (posix.errno(posix.system.llseek(file.handle, offset, &result, posix.SEEK.CUR))) {
10037
10176
  .SUCCESS => {
10038
10177
  syscall.finish();
10039
10178
  return;
@@ -10144,8 +10283,8 @@ fn posixSeekTo(fd: posix.fd_t, offset: u64) File.SeekError!void {
10144
10283
  if (native_os == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {
10145
10284
  const syscall: Syscall = try .start();
10146
10285
  while (true) {
10147
- var result: u64 = undefined;
10148
- switch (posix.errno(posix.system.llseek(fd, offset, &result, posix.SEEK.SET))) {
10286
+ var result: i64 = undefined;
10287
+ switch (posix.errno(posix.system.llseek(fd, @bitCast(offset), &result, posix.SEEK.SET))) {
10149
10288
  .SUCCESS => {
10150
10289
  syscall.finish();
10151
10290
  return;
@@ -10545,7 +10684,10 @@ fn fileWritePositional(
10545
10684
 
10546
10685
  const syscall: Syscall = try .start();
10547
10686
  while (true) {
10548
- const rc = pwritev_sym(file.handle, &iovecs, @intCast(iovlen), @bitCast(offset));
10687
+ const rc = if (native_os == .haiku)
10688
+ posix.system.writev_pos(file.handle, @bitCast(offset), &iovecs, @intCast(iovlen))
10689
+ else
10690
+ pwritev_sym(file.handle, &iovecs, @intCast(iovlen), @bitCast(offset));
10549
10691
  switch (posix.errno(rc)) {
10550
10692
  .SUCCESS => {
10551
10693
  syscall.finish();
@@ -12544,11 +12686,14 @@ fn deferAcceptAfd(t: *Threaded, listen_handle: net.Socket.Handle, info: windows.
12544
12686
  }
12545
12687
  }
12546
12688
 
12547
- fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {
12689
+ fn netRead(socket_handle: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {
12548
12690
  if (!have_networking) return error.NetworkDown;
12549
- const t: *Threaded = @ptrCast(@alignCast(userdata));
12550
- _ = t;
12551
12691
 
12692
+ if (is_windows) return netReadWindows(socket_handle, data);
12693
+ return netReadPosix(socket_handle, data);
12694
+ }
12695
+
12696
+ fn netReadPosix(fd: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {
12552
12697
  var iovecs_buffer: [max_iovecs_len]posix.iovec = undefined;
12553
12698
  var i: usize = 0;
12554
12699
  for (data) |buf| {
@@ -12585,7 +12730,6 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
12585
12730
  .NOMEM => return error.SystemResources,
12586
12731
  .NOTCONN => return error.SocketUnconnected,
12587
12732
  .CONNRESET => return error.ConnectionResetByPeer,
12588
- .TIMEDOUT => return error.Timeout,
12589
12733
  .NOTCAPABLE => return error.AccessDenied,
12590
12734
  else => |err| return posix.unexpectedErrno(err),
12591
12735
  }
@@ -12617,7 +12761,6 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
12617
12761
  .NOMEM => return error.SystemResources,
12618
12762
  .NOTCONN => return error.SocketUnconnected,
12619
12763
  .CONNRESET => return error.ConnectionResetByPeer,
12620
- .TIMEDOUT => return error.Timeout,
12621
12764
  .PIPE => return error.SocketUnconnected,
12622
12765
  .NETDOWN => return error.NetworkDown,
12623
12766
  else => |err| return posix.unexpectedErrno(err),
@@ -12627,11 +12770,7 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
12627
12770
  }
12628
12771
  }
12629
12772
 
12630
- fn netReadWindows(userdata: ?*anyopaque, socket_handle: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {
12631
- if (!have_networking) return error.NetworkDown;
12632
- const t: *Threaded = @ptrCast(@alignCast(userdata));
12633
- _ = t;
12634
-
12773
+ fn netReadWindows(socket_handle: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {
12635
12774
  var iovecs: [max_iovecs_len]windows.AFD.WSABUF(.@"var") = undefined;
12636
12775
  var len: u32 = 0;
12637
12776
  for (data) |buf| {
@@ -13008,6 +13147,7 @@ fn netReceiveOneWindows(
13008
13147
  .CANCELLED => unreachable,
13009
13148
  .INSUFFICIENT_RESOURCES => return error.SystemResources,
13010
13149
  .BUFFER_OVERFLOW => return error.MessageOversize,
13150
+ .PORT_UNREACHABLE => return error.PortUnreachable,
13011
13151
  else => |status| return windows.unexpectedStatus(status),
13012
13152
  }
13013
13153
  }
@@ -13482,21 +13622,80 @@ fn netLookupFallible(
13482
13622
  const name = host_name.bytes;
13483
13623
  assert(name.len <= HostName.max_len);
13484
13624
 
13485
- if (is_windows) {
13486
- if (options.family == null) {
13487
- if (IpAddress.parseIp4(name, options.port)) |addr| {
13488
- if (copyCanon(options.canonical_name_buffer, name)) |canon| {
13489
- try resolved.putAll(t_io, &.{
13490
- .{ .address = addr },
13491
- .{ .canonical_name = canon },
13492
- });
13493
- } else {
13494
- try resolved.putOne(t_io, .{ .address = addr });
13495
- }
13496
- return;
13497
- } else |_| {}
13625
+ // On Linux, glibc provides getaddrinfo_a which is capable of supporting our semantics.
13626
+ // However, musl's POSIX-compliant getaddrinfo is not, so we bypass it.
13627
+
13628
+ if (builtin.target.isGnuLibC()) {
13629
+ // TODO use getaddrinfo_a / gai_cancel
13630
+ }
13631
+
13632
+ if (native_os == .linux or is_windows) {
13633
+ if (IpAddress.parseIp6(name, options.port)) |addr| {
13634
+ if (options.family == .ip4) return error.UnknownHostName;
13635
+ if (copyCanon(options.canonical_name_buffer, name)) |canon| {
13636
+ try resolved.putAll(t_io, &.{
13637
+ .{ .address = addr },
13638
+ .{ .canonical_name = canon },
13639
+ });
13640
+ } else {
13641
+ try resolved.putOne(t_io, .{ .address = addr });
13642
+ }
13643
+ return;
13644
+ } else |_| {}
13645
+
13646
+ if (IpAddress.parseIp4(name, options.port)) |addr| {
13647
+ if (options.family == .ip6) return error.UnknownHostName;
13648
+ if (copyCanon(options.canonical_name_buffer, name)) |canon| {
13649
+ try resolved.putAll(t_io, &.{
13650
+ .{ .address = addr },
13651
+ .{ .canonical_name = canon },
13652
+ });
13653
+ } else {
13654
+ try resolved.putOne(t_io, .{ .address = addr });
13655
+ }
13656
+ return;
13657
+ } else |_| {}
13658
+
13659
+ if (t.lookupHosts(host_name, resolved, options)) return else |err| switch (err) {
13660
+ error.UnknownHostName => {},
13661
+ else => |e| return e,
13498
13662
  }
13499
13663
 
13664
+ // RFC 6761 Section 6.3.3
13665
+ // Name resolution APIs and libraries SHOULD recognize
13666
+ // localhost names as special and SHOULD always return the IP
13667
+ // loopback address for address queries and negative responses
13668
+ // for all other query types.
13669
+
13670
+ // Check for equal to "localhost(.)" or ends in ".localhost(.)"
13671
+ const localhost = if (name[name.len - 1] == '.') "localhost." else "localhost";
13672
+ if (std.mem.endsWith(u8, name, localhost) and
13673
+ (name.len == localhost.len or name[name.len - localhost.len] == '.'))
13674
+ {
13675
+ var results_buffer: [3]HostName.LookupResult = undefined;
13676
+ var results_index: usize = 0;
13677
+ if (options.family != .ip4) {
13678
+ results_buffer[results_index] = .{ .address = .{ .ip6 = .loopback(options.port) } };
13679
+ results_index += 1;
13680
+ }
13681
+ if (options.family != .ip6) {
13682
+ results_buffer[results_index] = .{ .address = .{ .ip4 = .loopback(options.port) } };
13683
+ results_index += 1;
13684
+ }
13685
+ if (options.canonical_name_buffer) |buf| {
13686
+ const canon_name = "localhost";
13687
+ const canon_name_dest = buf[0..canon_name.len];
13688
+ canon_name_dest.* = canon_name.*;
13689
+ results_buffer[results_index] = .{ .canonical_name = .{ .bytes = canon_name_dest } };
13690
+ results_index += 1;
13691
+ }
13692
+ try resolved.putAll(t_io, results_buffer[0..results_index]);
13693
+ return;
13694
+ }
13695
+
13696
+ if (native_os == .linux) return t.lookupDnsSearch(host_name, resolved, options);
13697
+
13698
+ comptime assert(is_windows);
13500
13699
  var DnsQueryEx = t.dl.DnsQueryEx.load(.acquire);
13501
13700
  //var DnsCancelQuery = t.dl.DnsCancelQuery.load(.acquire);
13502
13701
  var DnsFree = t.dl.DnsFree.load(.acquire);
@@ -13540,6 +13739,7 @@ fn netLookupFallible(
13540
13739
  else => |status| return windows.unexpectedStatus(status),
13541
13740
  }
13542
13741
  }
13742
+ try Thread.checkCancel();
13543
13743
  const current_thread = Thread.current;
13544
13744
  var lookup_dns: LookupDnsWindows = .{
13545
13745
  .threaded = t,
@@ -13562,126 +13762,71 @@ fn netLookupFallible(
13562
13762
  }
13563
13763
  ] = 0;
13564
13764
  //var cancel_token: windows.DNS.QUERY.CANCEL = undefined;
13765
+ // Workaround various bugs by attempting a synchronous non-wire query first
13565
13766
  switch (DnsQueryEx.?(&.{
13566
13767
  .Version = 1,
13567
13768
  .QueryName = &host_name_w,
13568
13769
  .QueryType = if (options.family == .ip4) .A else .AAAA,
13569
13770
  .QueryOptions = .{
13771
+ .NO_WIRE_QUERY = true,
13772
+ .NO_HOSTS_FILE = true, // handled above
13570
13773
  .ADDRCONFIG = true,
13571
13774
  .DUAL_ADDR = options.family == null,
13572
- .MULTICAST_WAIT = true,
13573
13775
  },
13574
- .pQueryCompletionCallback = if (current_thread) |_| &LookupDnsWindows.completed else null,
13575
- }, &lookup_dns.results,
13576
- //&cancel_token,
13577
- null)) {
13776
+ }, &lookup_dns.results, null)) {
13777
+ .SUCCESS => try lookup_dns.completedFallible(),
13578
13778
  // We must wait for the APC routine.
13579
- .SUCCESS, .DNS_REQUEST_PENDING => |status| if (current_thread) |_| {
13580
- while (!@atomicLoad(bool, &lookup_dns.done, .acquire)) {
13581
- // Once we get here we must not return from the function until the
13582
- // operation completes, thereby releasing references to `host_name_w`,
13583
- // `lookup_dns.results`, and `cancel_token`.
13584
- const alertable_syscall = AlertableSyscall.start() catch |err| switch (err) {
13585
- error.Canceled => |e| {
13586
- //_ = DnsCancelQuery.?(&cancel_token);
13587
- while (!@atomicLoad(bool, &lookup_dns.done, .acquire)) waitForApcOrAlert();
13588
- return e;
13589
- },
13590
- };
13591
- waitForApcOrAlert();
13592
- alertable_syscall.finish();
13593
- }
13594
- } else switch (status) {
13779
+ .DNS_REQUEST_PENDING => unreachable, // `pQueryCompletionCallback` was `null`
13780
+ .DNS_ERROR_RECORD_DOES_NOT_EXIST => switch (DnsQueryEx.?(&.{
13781
+ .Version = 1,
13782
+ .QueryName = &host_name_w,
13783
+ .QueryType = if (options.family == .ip4) .A else .AAAA,
13784
+ .QueryOptions = .{
13785
+ .NO_HOSTS_FILE = true, // handled above
13786
+ .ADDRCONFIG = true,
13787
+ .DUAL_ADDR = options.family == null,
13788
+ .MULTICAST_WAIT = true,
13789
+ },
13790
+ .pQueryCompletionCallback = if (current_thread) |_| &LookupDnsWindows.completed else null,
13791
+ }, &lookup_dns.results,
13792
+ //&cancel_token,
13793
+ null)) {
13595
13794
  .SUCCESS => try lookup_dns.completedFallible(),
13596
- .DNS_REQUEST_PENDING => unreachable, // `pQueryCompletionCallback` was `null`
13597
- else => unreachable,
13795
+ // We must wait for the APC routine.
13796
+ .DNS_REQUEST_PENDING => {
13797
+ assert(current_thread != null); // `pQueryCompletionCallback` was `null`
13798
+ while (!@atomicLoad(bool, &lookup_dns.done, .acquire)) {
13799
+ // Once we get here we must not return from the function until the
13800
+ // operation completes, thereby releasing references to `host_name_w`,
13801
+ // `lookup_dns.results`, and `cancel_token`.
13802
+ const alertable_syscall = AlertableSyscall.start() catch |err| switch (err) {
13803
+ error.Canceled => |e| {
13804
+ //_ = DnsCancelQuery.?(&cancel_token);
13805
+ while (!@atomicLoad(bool, &lookup_dns.done, .acquire)) waitForApcOrAlert();
13806
+ return e;
13807
+ },
13808
+ };
13809
+ waitForApcOrAlert();
13810
+ alertable_syscall.finish();
13811
+ }
13812
+ },
13813
+ else => |status| lookup_dns.results.QueryStatus = status,
13598
13814
  },
13599
13815
  else => |status| lookup_dns.results.QueryStatus = status,
13600
13816
  }
13601
13817
  switch (lookup_dns.results.QueryStatus) {
13602
13818
  .SUCCESS => return,
13603
13819
  .DNS_REQUEST_PENDING => unreachable, // already handled
13604
- .INVALID_NAME, .DNS_INFO_NO_RECORDS => return error.UnknownHostName,
13820
+ .INVALID_NAME,
13821
+ .DNS_ERROR_RCODE_NAME_ERROR,
13822
+ .DNS_INFO_NO_RECORDS,
13823
+ .DNS_ERROR_INVALID_NAME_CHAR,
13824
+ .DNS_ERROR_RECORD_DOES_NOT_EXIST,
13825
+ => return error.UnknownHostName,
13605
13826
  else => |err| return windows.unexpectedError(err),
13606
13827
  }
13607
13828
  }
13608
13829
 
13609
- // On Linux, glibc provides getaddrinfo_a which is capable of supporting our semantics.
13610
- // However, musl's POSIX-compliant getaddrinfo is not, so we bypass it.
13611
-
13612
- if (builtin.target.isGnuLibC()) {
13613
- // TODO use getaddrinfo_a / gai_cancel
13614
- }
13615
-
13616
- if (native_os == .linux) {
13617
- if (options.family != .ip4) {
13618
- if (IpAddress.parseIp6(name, options.port)) |addr| {
13619
- if (copyCanon(options.canonical_name_buffer, name)) |canon| {
13620
- try resolved.putAll(t_io, &.{
13621
- .{ .address = addr },
13622
- .{ .canonical_name = canon },
13623
- });
13624
- } else {
13625
- try resolved.putOne(t_io, .{ .address = addr });
13626
- }
13627
- return;
13628
- } else |_| {}
13629
- }
13630
-
13631
- if (options.family != .ip6) {
13632
- if (IpAddress.parseIp4(name, options.port)) |addr| {
13633
- if (copyCanon(options.canonical_name_buffer, name)) |canon| {
13634
- try resolved.putAll(t_io, &.{
13635
- .{ .address = addr },
13636
- .{ .canonical_name = canon },
13637
- });
13638
- } else {
13639
- try resolved.putOne(t_io, .{ .address = addr });
13640
- }
13641
- return;
13642
- } else |_| {}
13643
- }
13644
-
13645
- t.lookupHosts(host_name, resolved, options) catch |err| switch (err) {
13646
- error.UnknownHostName => {},
13647
- else => |e| return e,
13648
- };
13649
-
13650
- // RFC 6761 Section 6.3.3
13651
- // Name resolution APIs and libraries SHOULD recognize
13652
- // localhost names as special and SHOULD always return the IP
13653
- // loopback address for address queries and negative responses
13654
- // for all other query types.
13655
-
13656
- // Check for equal to "localhost(.)" or ends in ".localhost(.)"
13657
- const localhost = if (name[name.len - 1] == '.') "localhost." else "localhost";
13658
- if (std.mem.endsWith(u8, name, localhost) and
13659
- (name.len == localhost.len or name[name.len - localhost.len] == '.'))
13660
- {
13661
- var results_buffer: [3]HostName.LookupResult = undefined;
13662
- var results_index: usize = 0;
13663
- if (options.family != .ip4) {
13664
- results_buffer[results_index] = .{ .address = .{ .ip6 = .loopback(options.port) } };
13665
- results_index += 1;
13666
- }
13667
- if (options.family != .ip6) {
13668
- results_buffer[results_index] = .{ .address = .{ .ip4 = .loopback(options.port) } };
13669
- results_index += 1;
13670
- }
13671
- if (options.canonical_name_buffer) |buf| {
13672
- const canon_name = "localhost";
13673
- const canon_name_dest = buf[0..canon_name.len];
13674
- canon_name_dest.* = canon_name.*;
13675
- results_buffer[results_index] = .{ .canonical_name = .{ .bytes = canon_name_dest } };
13676
- results_index += 1;
13677
- }
13678
- try resolved.putAll(t_io, results_buffer[0..results_index]);
13679
- return;
13680
- }
13681
-
13682
- return t.lookupDnsSearch(host_name, resolved, options);
13683
- }
13684
-
13685
13830
  if (native_os == .openbsd) {
13686
13831
  // TODO use getaddrinfo_async / asr_abort
13687
13832
  }
@@ -14052,7 +14197,7 @@ pub fn posixSocketModeProtocol(family: posix.sa_family_t, mode: net.Socket.Mode,
14052
14197
  .dgram => posix.SOCK.DGRAM,
14053
14198
  .seqpacket => posix.SOCK.SEQPACKET,
14054
14199
  .raw => posix.SOCK.RAW,
14055
- .rdm => posix.SOCK.RDM,
14200
+ .rdm => if (@hasDecl(posix.SOCK, "RDM")) posix.SOCK.RDM else return error.OptionUnsupported,
14056
14201
  },
14057
14202
  if (protocol) |p| @intFromEnum(p) else if (is_windows) switch (family) {
14058
14203
  posix.AF.UNIX => switch (mode) {
@@ -14444,7 +14589,7 @@ fn lookupDns(
14444
14589
  }
14445
14590
  }
14446
14591
  if (recv_err) |err| switch (err) {
14447
- error.Canceled => return error.Canceled,
14592
+ error.Canceled => |e| return e,
14448
14593
  error.Timeout => continue :send,
14449
14594
  else => continue,
14450
14595
  };
@@ -14510,8 +14655,32 @@ fn lookupHosts(
14510
14655
  resolved: *Io.Queue(HostName.LookupResult),
14511
14656
  options: HostName.LookupOptions,
14512
14657
  ) !void {
14513
- const t_io = io(t);
14514
- const file = Dir.openFileAbsolute(t_io, "/etc/hosts", .{}) catch |err| switch (err) {
14658
+ const path_w = if (is_windows) path_w: {
14659
+ var path_w_buf: [windows.PATH_MAX_WIDE:0]u16 = undefined;
14660
+ const system_dir = windows.getSystemDirectoryWtf16Le();
14661
+ const suffix = [_]u16{
14662
+ '\\', 'd', 'r', 'i', 'v', 'e', 'r', 's', '\\', 'e', 't', 'c', '\\', 'h', 'o', 's', 't', 's',
14663
+ };
14664
+ @memcpy(path_w_buf[0..system_dir.len], system_dir);
14665
+ @memcpy(path_w_buf[system_dir.len..][0..suffix.len], &suffix);
14666
+ path_w_buf[system_dir.len + suffix.len] = 0;
14667
+ break :path_w wToPrefixedFileW(null, &path_w_buf, .{}) catch |err| switch (err) {
14668
+ error.FileNotFound,
14669
+ error.AccessDenied,
14670
+ => return error.UnknownHostName,
14671
+
14672
+ error.Canceled => |e| return e,
14673
+
14674
+ else => {
14675
+ // Here we could add more detailed diagnostics to the results queue.
14676
+ return error.DetectingNetworkConfigurationFailed;
14677
+ },
14678
+ };
14679
+ };
14680
+ const file = (if (is_windows)
14681
+ dirOpenFileWtf16(null, path_w.span(), .{})
14682
+ else
14683
+ dirOpenFile(t, .cwd(), "/etc/hosts", .{})) catch |err| switch (err) {
14515
14684
  error.FileNotFound,
14516
14685
  error.NotDir,
14517
14686
  error.AccessDenied,
@@ -14524,10 +14693,10 @@ fn lookupHosts(
14524
14693
  return error.DetectingNetworkConfigurationFailed;
14525
14694
  },
14526
14695
  };
14527
- defer file.close(t_io);
14696
+ defer fileClose(t, &.{file});
14528
14697
 
14529
14698
  var line_buf: [512]u8 = undefined;
14530
- var file_reader = file.reader(t_io, &line_buf);
14699
+ var file_reader = file.reader(t.io(), &line_buf);
14531
14700
  return t.lookupHostsReader(host_name, resolved, options, &file_reader.interface) catch |err| switch (err) {
14532
14701
  error.ReadFailed => switch (file_reader.err.?) {
14533
14702
  error.Canceled => |e| return e,
@@ -14557,24 +14726,27 @@ fn lookupHostsReader(
14557
14726
  const line = reader.takeDelimiterExclusive('\n') catch |err| switch (err) {
14558
14727
  error.StreamTooLong => {
14559
14728
  // Skip lines that are too long.
14560
- _ = reader.discardDelimiterInclusive('\n') catch |e| switch (e) {
14729
+ _ = reader.discardDelimiterInclusive('\n') catch |er| switch (er) {
14561
14730
  error.EndOfStream => break,
14562
- error.ReadFailed => return error.ReadFailed,
14731
+ error.ReadFailed => |e| return e,
14563
14732
  };
14564
14733
  continue;
14565
14734
  },
14566
- error.ReadFailed => return error.ReadFailed,
14735
+ error.ReadFailed => |e| return e,
14567
14736
  error.EndOfStream => break,
14568
14737
  };
14569
14738
  reader.toss(@min(1, reader.bufferedLen()));
14570
- var split_it = std.mem.splitScalar(u8, line, '#');
14739
+ var split_it = std.mem.splitScalar(u8, if (is_windows and std.mem.endsWith(u8, line, "\r"))
14740
+ line[0 .. line.len - 1]
14741
+ else
14742
+ line, '#');
14571
14743
  const no_comment_line = split_it.first();
14572
14744
 
14573
14745
  var line_it = std.mem.tokenizeAny(u8, no_comment_line, " \t");
14574
14746
  const ip_text = line_it.next() orelse continue;
14575
14747
  var first_name_text: ?[]const u8 = null;
14576
14748
  while (line_it.next()) |name_text| {
14577
- if (std.mem.eql(u8, name_text, host_name.bytes)) {
14749
+ if (std.ascii.eqlIgnoreCase(name_text, host_name.bytes)) {
14578
14750
  if (first_name_text == null) first_name_text = name_text;
14579
14751
  break;
14580
14752
  }
@@ -15209,7 +15381,7 @@ fn childWaitPosix(child: *process.Child) process.Child.WaitError!process.Child.T
15209
15381
  const ru_ptr = if (child.request_resource_usage_statistics) &ru else null;
15210
15382
 
15211
15383
  if (have_wait4) {
15212
- var status: if (builtin.link_libc) c_int else u32 = undefined;
15384
+ var status: if (builtin.link_libc) c_int else i32 = undefined;
15213
15385
  const syscall: Syscall = try .start();
15214
15386
  while (true) switch (posix.errno(posix.system.wait4(pid, &status, 0, ru_ptr))) {
15215
15387
  .SUCCESS => {
@@ -15239,7 +15411,7 @@ fn childWaitPosix(child: *process.Child) process.Child.WaitError!process.Child.T
15239
15411
  return switch (code) {
15240
15412
  .EXITED => .{ .exited = @truncate(status) },
15241
15413
  .KILLED, .DUMPED => .{ .signal = @enumFromInt(status) },
15242
- .TRAPPED, .STOPPED => .{ .stopped = status },
15414
+ .TRAPPED, .STOPPED => .{ .stopped = @enumFromInt(status) },
15243
15415
  _, .CONTINUED => .{ .unknown = status },
15244
15416
  };
15245
15417
  },
@@ -15252,7 +15424,7 @@ fn childWaitPosix(child: *process.Child) process.Child.WaitError!process.Child.T
15252
15424
  };
15253
15425
  }
15254
15426
 
15255
- var status: if (builtin.link_libc) c_int else u32 = undefined;
15427
+ var status: if (builtin.link_libc) c_int else i32 = undefined;
15256
15428
  const syscall: Syscall = try .start();
15257
15429
  while (true) switch (posix.errno(posix.system.waitpid(pid, &status, 0))) {
15258
15430
  .SUCCESS => {
@@ -15294,7 +15466,7 @@ fn childKillPosix(child: *process.Child) !void {
15294
15466
  };
15295
15467
 
15296
15468
  if (have_wait4) {
15297
- var status: if (builtin.link_libc) c_int else u32 = undefined;
15469
+ var status: if (builtin.link_libc) c_int else i32 = undefined;
15298
15470
  while (true) switch (posix.errno(posix.system.wait4(pid, &status, 0, null))) {
15299
15471
  .SUCCESS => return,
15300
15472
  .INTR => continue,
@@ -15314,7 +15486,7 @@ fn childKillPosix(child: *process.Child) !void {
15314
15486
  };
15315
15487
  }
15316
15488
 
15317
- var status: if (builtin.link_libc) c_int else u32 = undefined;
15489
+ var status: if (builtin.link_libc) c_int else i32 = undefined;
15318
15490
  while (true) switch (posix.errno(posix.system.waitpid(pid, &status, 0))) {
15319
15491
  .SUCCESS => return,
15320
15492
  .INTR => continue,