@zigc/lib 0.17.0-dev.56 → 0.17.0-dev.76

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.
package/c/inttypes.zig CHANGED
@@ -24,13 +24,3 @@ fn imaxdiv(a: intmax_t, b: intmax_t) callconv(.c) imaxdiv_t {
24
24
  .rem = @rem(a, b),
25
25
  };
26
26
  }
27
-
28
- test imaxabs {
29
- const val: intmax_t = -10;
30
- try std.testing.expectEqual(10, imaxabs(val));
31
- }
32
-
33
- test imaxdiv {
34
- const expected: imaxdiv_t = .{ .quot = 9, .rem = 0 };
35
- try std.testing.expectEqual(expected, imaxdiv(9, 1));
36
- }
package/c/math.zig CHANGED
@@ -2,10 +2,6 @@ const builtin = @import("builtin");
2
2
 
3
3
  const std = @import("std");
4
4
  const math = std.math;
5
- const expect = std.testing.expect;
6
- const expectEqual = std.testing.expectEqual;
7
- const expectApproxEqAbs = std.testing.expectApproxEqAbs;
8
- const expectApproxEqRel = std.testing.expectApproxEqRel;
9
5
 
10
6
  const symbol = @import("../c.zig").symbol;
11
7
 
@@ -304,59 +300,6 @@ fn modfl(x: c_longdouble, iptr: *c_longdouble) callconv(.c) c_longdouble {
304
300
  };
305
301
  }
306
302
 
307
- fn testModf(comptime T: type) !void {
308
- // Choose the appropriate `modf` impl to test based on type
309
- const f = switch (T) {
310
- f32 => modff,
311
- f64 => modf,
312
- c_longdouble => modfl,
313
- else => @compileError("modf not implemented for " ++ @typeName(T)),
314
- };
315
-
316
- var int: T = undefined;
317
- const iptr = ∫
318
- const eps_val: comptime_float = @max(1e-6, math.floatEps(T));
319
-
320
- const normal_frac = f(@as(T, 1234.567), iptr);
321
- // Account for precision error
322
- const expected = 1234.567 - @as(T, 1234);
323
- try expectApproxEqAbs(expected, normal_frac, eps_val);
324
- try expectApproxEqRel(@as(T, 1234.0), iptr.*, eps_val);
325
-
326
- // When `x` is a NaN, NaN is returned and `*iptr` is set to NaN
327
- const nan_frac = f(math.nan(T), iptr);
328
- try expect(math.isNan(nan_frac));
329
- try expect(math.isNan(iptr.*));
330
-
331
- // When `x` is positive infinity, +0 is returned and `*iptr` is set to
332
- // positive infinity
333
- const pos_zero_frac = f(math.inf(T), iptr);
334
- try expect(math.isPositiveZero(pos_zero_frac));
335
- try expect(math.isPositiveInf(iptr.*));
336
-
337
- // When `x` is negative infinity, -0 is returned and `*iptr` is set to
338
- // negative infinity
339
- const neg_zero_frac = f(-math.inf(T), iptr);
340
- try expect(math.isNegativeZero(neg_zero_frac));
341
- try expect(math.isNegativeInf(iptr.*));
342
-
343
- // Return -0 when `x` is a negative integer
344
- const nz_frac = f(@as(T, -1000.0), iptr);
345
- try expect(math.isNegativeZero(nz_frac));
346
- try expectEqual(@as(T, -1000.0), iptr.*);
347
-
348
- // Return +0 when `x` is a positive integer
349
- const pz_frac = f(@as(T, 1000.0), iptr);
350
- try expect(math.isPositiveZero(pz_frac));
351
- try expectEqual(@as(T, 1000.0), iptr.*);
352
- }
353
-
354
- test "modf" {
355
- try testModf(f32);
356
- try testModf(f64);
357
- try testModf(c_longdouble);
358
- }
359
-
360
303
  fn nan(_: [*:0]const c_char) callconv(.c) f64 {
361
304
  return math.nan(f64);
362
305
  }
@@ -421,49 +364,6 @@ fn rintf(x: f32) callconv(.c) f32 {
421
364
  return y;
422
365
  }
423
366
 
424
- fn testRint(comptime T: type) !void {
425
- const f = switch (T) {
426
- f32 => rintf,
427
- f64 => rint,
428
- else => @compileError("rint not implemented for" ++ @typeName(T)),
429
- };
430
-
431
- // Positive numbers round correctly
432
- try expectEqual(@as(T, 42.0), f(42.2));
433
- try expectEqual(@as(T, 42.0), f(41.8));
434
-
435
- // Negative numbers round correctly
436
- try expectEqual(@as(T, -6.0), f(-5.9));
437
- try expectEqual(@as(T, -6.0), f(-6.1));
438
-
439
- // No rounding needed test
440
- try expectEqual(@as(T, 5.0), f(5.0));
441
- try expectEqual(@as(T, -10.0), f(-10.0));
442
- try expectEqual(@as(T, 0.0), f(0.0));
443
-
444
- // Very large numbers return unchanged
445
- const large: T = 9007199254740992.0; // 2^53
446
- try expectEqual(large, f(large));
447
- try expectEqual(-large, f(-large));
448
-
449
- // Small positive numbers round to zero
450
- const pos_result = f(0.3);
451
- try expect(math.isPositiveZero(pos_result));
452
-
453
- // Small negative numbers round to negative zero
454
- const neg_result = f(-0.3);
455
- try expect(math.isNegativeZero(neg_result));
456
-
457
- // Exact half rounds to nearest even (banker's rounding)
458
- try expectEqual(@as(T, 2.0), f(2.5));
459
- try expectEqual(@as(T, 4.0), f(3.5));
460
- }
461
-
462
- test "rint" {
463
- try testRint(f32);
464
- try testRint(f64);
465
- }
466
-
467
367
  fn tanh(x: f64) callconv(.c) f64 {
468
368
  return math.tanh(x);
469
369
  }
package/c/search.zig CHANGED
@@ -9,6 +9,7 @@ comptime {
9
9
  }
10
10
  }
11
11
 
12
+ /// Not defined in `std.c` because C headers don't either.
12
13
  const Node = extern struct {
13
14
  next: ?*Node,
14
15
  prev: ?*Node,
@@ -38,30 +39,3 @@ fn remque(element: *anyopaque) callconv(.c) void {
38
39
  if (e.next) |next| next.prev = e.prev;
39
40
  if (e.prev) |prev| prev.next = e.next;
40
41
  }
41
-
42
- test "insque and remque" {
43
- var first = Node{ .next = null, .prev = null };
44
- var second = Node{ .next = null, .prev = null };
45
- var third = Node{ .next = null, .prev = null };
46
-
47
- insque(&first, null);
48
- try std.testing.expectEqual(@as(?*Node, null), first.next);
49
- try std.testing.expectEqual(@as(?*Node, null), first.prev);
50
-
51
- insque(&second, &first);
52
- try std.testing.expectEqual(@as(?*Node, &second), first.next);
53
- try std.testing.expectEqual(@as(?*Node, &first), second.prev);
54
-
55
- insque(&third, &first);
56
- try std.testing.expectEqual(@as(?*Node, &third), first.next);
57
- try std.testing.expectEqual(@as(?*Node, &second), third.next);
58
- try std.testing.expectEqual(@as(?*Node, &first), third.prev);
59
- try std.testing.expectEqual(@as(?*Node, &third), second.prev);
60
-
61
- remque(&third);
62
- try std.testing.expectEqual(@as(?*Node, &second), first.next);
63
- try std.testing.expectEqual(@as(?*Node, &first), second.prev);
64
-
65
- remque(&second);
66
- try std.testing.expectEqual(@as(?*Node, null), first.next);
67
- }
@@ -90,60 +90,3 @@ fn srand48(seedval: c_long) callconv(.c) void {
90
90
  const xi = (@as(u32, @truncate(@as(c_ulong, @bitCast(seedval)))) << 16) | 0x330E;
91
91
  lcg = .init(xi, default_multiplier, default_addend);
92
92
  }
93
-
94
- test erand48 {
95
- var xsubi: [3]c_ushort = .{ 37174, 64810, 11603 };
96
-
97
- try std.testing.expectApproxEqAbs(0.8965, erand48(&xsubi), 0.0005);
98
- try std.testing.expectEqualSlices(c_ushort, &.{ 22537, 47966, 58735 }, &xsubi);
99
-
100
- try std.testing.expectApproxEqAbs(0.3375, erand48(&xsubi), 0.0005);
101
- try std.testing.expectEqualSlices(c_ushort, &.{ 37344, 32911, 22119 }, &xsubi);
102
-
103
- try std.testing.expectApproxEqAbs(0.6475, erand48(&xsubi), 0.0005);
104
- try std.testing.expectEqualSlices(c_ushort, &.{ 23659, 29872, 42445 }, &xsubi);
105
-
106
- try std.testing.expectApproxEqAbs(0.5005, erand48(&xsubi), 0.0005);
107
- try std.testing.expectEqualSlices(c_ushort, &.{ 31642, 7875, 32802 }, &xsubi);
108
-
109
- try std.testing.expectApproxEqAbs(0.5065, erand48(&xsubi), 0.0005);
110
- try std.testing.expectEqualSlices(c_ushort, &.{ 64669, 14399, 33170 }, &xsubi);
111
- }
112
-
113
- test jrand48 {
114
- var xsubi: [3]c_ushort = .{ 25175, 11052, 45015 };
115
-
116
- try std.testing.expectEqual(1699503220, jrand48(&xsubi));
117
- try std.testing.expectEqualSlices(c_ushort, &.{ 2326, 23668, 25932 }, &xsubi);
118
-
119
- try std.testing.expectEqual(-992276007, jrand48(&xsubi));
120
- try std.testing.expectEqualSlices(c_ushort, &.{ 41577, 4569, 50395 }, &xsubi);
121
-
122
- try std.testing.expectEqual(-19535776, jrand48(&xsubi));
123
- try std.testing.expectEqualSlices(c_ushort, &.{ 31936, 59488, 65237 }, &xsubi);
124
-
125
- try std.testing.expectEqual(79438377, jrand48(&xsubi));
126
- try std.testing.expectEqualSlices(c_ushort, &.{ 40395, 8745, 1212 }, &xsubi);
127
-
128
- try std.testing.expectEqual(-1258917728, jrand48(&xsubi));
129
- try std.testing.expectEqualSlices(c_ushort, &.{ 37242, 28832, 46326 }, &xsubi);
130
- }
131
-
132
- test nrand48 {
133
- var xsubi: [3]c_ushort = .{ 546, 33817, 23389 };
134
-
135
- try std.testing.expectEqual(914920692, nrand48(&xsubi));
136
- try std.testing.expectEqualSlices(c_ushort, &.{ 29829, 10728, 27921 }, &xsubi);
137
-
138
- try std.testing.expectEqual(754104482, nrand48(&xsubi));
139
- try std.testing.expectEqualSlices(c_ushort, &.{ 6828, 28997, 23013 }, &xsubi);
140
-
141
- try std.testing.expectEqual(609453945, nrand48(&xsubi));
142
- try std.testing.expectEqualSlices(c_ushort, &.{ 58183, 3826, 18599 }, &xsubi);
143
-
144
- try std.testing.expectEqual(1878644360, nrand48(&xsubi));
145
- try std.testing.expectEqualSlices(c_ushort, &.{ 36678, 44304, 57331 }, &xsubi);
146
-
147
- try std.testing.expectEqual(2114923686, nrand48(&xsubi));
148
- try std.testing.expectEqualSlices(c_ushort, &.{ 58585, 22861, 64542 }, &xsubi);
149
- }
package/c/stdlib.zig CHANGED
@@ -294,103 +294,3 @@ fn bsearch(key: *const anyopaque, base: *const anyopaque, n: usize, size: usize,
294
294
  }
295
295
  return null;
296
296
  }
297
-
298
- test abs {
299
- const val: c_int = -10;
300
- try std.testing.expectEqual(10, abs(val));
301
- }
302
-
303
- test labs {
304
- const val: c_long = -10;
305
- try std.testing.expectEqual(10, labs(val));
306
- }
307
-
308
- test llabs {
309
- const val: c_longlong = -10;
310
- try std.testing.expectEqual(10, llabs(val));
311
- }
312
-
313
- test div {
314
- const expected: div_t = .{ .quot = 5, .rem = 5 };
315
- try std.testing.expectEqual(expected, div(55, 10));
316
- }
317
-
318
- test ldiv {
319
- const expected: ldiv_t = .{ .quot = -6, .rem = 2 };
320
- try std.testing.expectEqual(expected, ldiv(38, -6));
321
- }
322
-
323
- test lldiv {
324
- const expected: lldiv_t = .{ .quot = 1, .rem = 2 };
325
- try std.testing.expectEqual(expected, lldiv(5, 3));
326
- }
327
-
328
- test atoi {
329
- try std.testing.expectEqual(0, atoi(@ptrCast("stop42true")));
330
- try std.testing.expectEqual(42, atoi(@ptrCast("42true")));
331
- try std.testing.expectEqual(-1, atoi(@ptrCast("-01")));
332
- try std.testing.expectEqual(1, atoi(@ptrCast("+001")));
333
- try std.testing.expectEqual(100, atoi(@ptrCast(" 100")));
334
- try std.testing.expectEqual(500, atoi(@ptrCast("000000000000500")));
335
- try std.testing.expectEqual(1111, atoi(@ptrCast("0000000000001111_0000")));
336
- try std.testing.expectEqual(0, atoi(@ptrCast("0xAA")));
337
- try std.testing.expectEqual(700, atoi(@ptrCast("700B")));
338
- try std.testing.expectEqual(32453, atoi(@ptrCast("+32453more")));
339
- try std.testing.expectEqual(std.math.maxInt(c_int), atoi(@ptrCast(std.fmt.comptimePrint("{d}", .{std.math.maxInt(c_int)}))));
340
- try std.testing.expectEqual(std.math.minInt(c_int), atoi(@ptrCast(std.fmt.comptimePrint("{d}", .{std.math.minInt(c_int)}))));
341
- }
342
-
343
- test atol {
344
- try std.testing.expectEqual(0, atol(@ptrCast("stop42true")));
345
- try std.testing.expectEqual(42, atol(@ptrCast("42true")));
346
- try std.testing.expectEqual(-1, atol(@ptrCast("-01")));
347
- try std.testing.expectEqual(1, atol(@ptrCast("+001")));
348
- try std.testing.expectEqual(100, atol(@ptrCast(" 100")));
349
- try std.testing.expectEqual(500, atol(@ptrCast("000000000000500")));
350
- try std.testing.expectEqual(1111, atol(@ptrCast("0000000000001111_0000")));
351
- try std.testing.expectEqual(0, atol(@ptrCast("0xAA")));
352
- try std.testing.expectEqual(700, atol(@ptrCast("700B")));
353
- try std.testing.expectEqual(32453, atol(@ptrCast("+32453more")));
354
- try std.testing.expectEqual(std.math.maxInt(c_long), atol(@ptrCast(std.fmt.comptimePrint("{d}", .{std.math.maxInt(c_long)}))));
355
- try std.testing.expectEqual(std.math.minInt(c_long), atol(@ptrCast(std.fmt.comptimePrint("{d}", .{std.math.minInt(c_long)}))));
356
- }
357
-
358
- test atoll {
359
- try std.testing.expectEqual(0, atoll(@ptrCast("stop42true")));
360
- try std.testing.expectEqual(42, atoll(@ptrCast("42true")));
361
- try std.testing.expectEqual(-1, atoll(@ptrCast("-01")));
362
- try std.testing.expectEqual(1, atoll(@ptrCast("+001")));
363
- try std.testing.expectEqual(100, atoll(@ptrCast(" 100")));
364
- try std.testing.expectEqual(500, atoll(@ptrCast("000000000000500")));
365
- try std.testing.expectEqual(1111, atoll(@ptrCast("0000000000001111_0000")));
366
- try std.testing.expectEqual(0, atoll(@ptrCast("0xAA")));
367
- try std.testing.expectEqual(700, atoll(@ptrCast("700B")));
368
- try std.testing.expectEqual(32453, atoll(@ptrCast(" +32453more")));
369
- try std.testing.expectEqual(std.math.maxInt(c_longlong), atoll(@ptrCast(std.fmt.comptimePrint("{d}", .{std.math.maxInt(c_longlong)}))));
370
- try std.testing.expectEqual(std.math.minInt(c_longlong), atoll(@ptrCast(std.fmt.comptimePrint("{d}", .{std.math.minInt(c_longlong)}))));
371
- }
372
-
373
- // FIXME: We cannot test strtol, strtoll, strtoul, etc.. here as it must modify errno and libc is not linked in tests
374
-
375
- test bsearch {
376
- const Comparison = struct {
377
- pub fn compare(a: *const anyopaque, b: *const anyopaque) callconv(.c) c_int {
378
- const a_u16: *const u16 = @ptrCast(@alignCast(a));
379
- const b_u16: *const u16 = @ptrCast(@alignCast(b));
380
-
381
- return switch (std.math.order(a_u16.*, b_u16.*)) {
382
- .gt => 1,
383
- .eq => 0,
384
- .lt => -1,
385
- };
386
- }
387
- };
388
-
389
- const items: []const u16 = &.{ 0, 5, 7, 9, 10, 200, 512, 768 };
390
-
391
- try std.testing.expectEqual(@as(?*anyopaque, null), bsearch(&@as(u16, 2000), items.ptr, items.len, @sizeOf(u16), Comparison.compare));
392
-
393
- for (items) |*value| {
394
- try std.testing.expectEqual(@as(*const anyopaque, value), bsearch(value, items.ptr, items.len, @sizeOf(u16), Comparison.compare));
395
- }
396
- }
package/c/string.zig CHANGED
@@ -290,10 +290,3 @@ fn mempcpy(noalias dst: *anyopaque, noalias src: *const anyopaque, len: usize) c
290
290
  @memcpy(dst_bytes[0..len], src_bytes[0..len]);
291
291
  return dst_bytes + len;
292
292
  }
293
-
294
- test strncmp {
295
- try std.testing.expect(strncmp(@ptrCast("a"), @ptrCast("b"), 1) < 0);
296
- try std.testing.expect(strncmp(@ptrCast("a"), @ptrCast("c"), 1) < 0);
297
- try std.testing.expect(strncmp(@ptrCast("b"), @ptrCast("a"), 1) > 0);
298
- try std.testing.expect(strncmp(@ptrCast("\xff"), @ptrCast("\x02"), 1) > 0);
299
- }
package/c/strings.zig CHANGED
@@ -81,41 +81,3 @@ fn __strncasecmp_l(a: [*:0]const c_char, b: [*:0]const c_char, n: usize, locale:
81
81
  _ = locale;
82
82
  return strncasecmp(a, b, n);
83
83
  }
84
-
85
- test bzero {
86
- var array: [10]u8 = [_]u8{ '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' };
87
- var a = std.mem.zeroes([array.len]u8);
88
- a[9] = '0';
89
- bzero(&array[0], 9);
90
- try std.testing.expect(std.mem.eql(u8, &array, &a));
91
- }
92
-
93
- test firstBitSet {
94
- try std.testing.expectEqual(0, firstBitSet(usize, 0));
95
-
96
- for (0..@bitSizeOf(usize)) |i| {
97
- const bit = @as(usize, 1) << @intCast(i);
98
-
99
- try std.testing.expectEqual(i + 1, firstBitSet(usize, bit));
100
- }
101
- }
102
-
103
- test strcasecmp {
104
- try std.testing.expect(strcasecmp(@ptrCast("a"), @ptrCast("b")) < 0);
105
- try std.testing.expect(strcasecmp(@ptrCast("b"), @ptrCast("a")) > 0);
106
- try std.testing.expect(strcasecmp(@ptrCast("A"), @ptrCast("b")) < 0);
107
- try std.testing.expect(strcasecmp(@ptrCast("b"), @ptrCast("A")) > 0);
108
- try std.testing.expect(strcasecmp(@ptrCast("A"), @ptrCast("A")) == 0);
109
- try std.testing.expect(strcasecmp(@ptrCast("B"), @ptrCast("b")) == 0);
110
- try std.testing.expect(strcasecmp(@ptrCast("bb"), @ptrCast("AA")) > 0);
111
- }
112
-
113
- test strncasecmp {
114
- try std.testing.expect(strncasecmp(@ptrCast("a"), @ptrCast("b"), 1) < 0);
115
- try std.testing.expect(strncasecmp(@ptrCast("b"), @ptrCast("a"), 1) > 0);
116
- try std.testing.expect(strncasecmp(@ptrCast("A"), @ptrCast("b"), 1) < 0);
117
- try std.testing.expect(strncasecmp(@ptrCast("b"), @ptrCast("A"), 1) > 0);
118
- try std.testing.expect(strncasecmp(@ptrCast("A"), @ptrCast("A"), 1) == 0);
119
- try std.testing.expect(strncasecmp(@ptrCast("B"), @ptrCast("b"), 1) == 0);
120
- try std.testing.expect(strncasecmp(@ptrCast("bb"), @ptrCast("AA"), 2) > 0);
121
- }
package/c/unistd.zig CHANGED
@@ -21,6 +21,8 @@ comptime {
21
21
  symbol(&chrootLinux, "chroot");
22
22
  symbol(&ctermidLinux, "ctermid");
23
23
  symbol(&dupLinux, "dup");
24
+ symbol(&dup2Linux, "dup2");
25
+ symbol(&dup3Linux, "dup3");
24
26
 
25
27
  symbol(&getegidLinux, "getegid");
26
28
  symbol(&geteuidLinux, "geteuid");
@@ -101,6 +103,31 @@ fn dupLinux(fd: c_int) callconv(.c) c_int {
101
103
  return errno(linux.dup(fd));
102
104
  }
103
105
 
106
+ fn dup2Linux(old: c_int, new: c_int) callconv(.c) c_int {
107
+ const busy: usize = @bitCast(-@as(isize, @intFromEnum(linux.E.BUSY)));
108
+ var res = busy;
109
+ while (res == busy) res = linux.dup2(old, new);
110
+ return errno(res);
111
+ }
112
+
113
+ fn dup3Linux(old: c_int, new: c_int, flags: c_int) callconv(.c) c_int {
114
+ const busy: usize = @bitCast(-@as(isize, @intFromEnum(linux.E.BUSY)));
115
+ var res = busy;
116
+
117
+ if (@hasField(linux.SYS, "dup3")) {
118
+ while (res == busy) res = linux.dup3(old, new, @intCast(flags));
119
+ } else if (@hasField(linux.SYS, "dup2")) {
120
+ const cloexec: c_int = @bitCast(linux.O{ .CLOEXEC = true });
121
+ const inval: usize = @bitCast(-@as(isize, @intFromEnum(linux.E.INVAL)));
122
+ if (old == new or (flags & ~cloexec != 0)) return errno(inval);
123
+ while (res == busy) res = linux.dup2(old, new);
124
+ _ = if (res >= 0 and (flags & cloexec == cloexec)) linux.fcntl(new, linux.F.SETFD, linux.FD_CLOEXEC);
125
+ } else {
126
+ return errno(@bitCast(-@as(isize, @intFromEnum(linux.E.NOSYS))));
127
+ }
128
+ return errno(res);
129
+ }
130
+
104
131
  fn getegidLinux() callconv(.c) linux.gid_t {
105
132
  return linux.getegid();
106
133
  }
@@ -206,32 +233,6 @@ fn swab(noalias src_ptr: *const anyopaque, noalias dest_ptr: *anyopaque, n: isiz
206
233
  }
207
234
  }
208
235
 
209
- test swab {
210
- var a: [4]u8 = undefined;
211
- @memset(a[0..], '\x00');
212
- swab("abcd", &a, 4);
213
- try std.testing.expectEqualSlices(u8, "badc", &a);
214
-
215
- // Partial copy
216
- @memset(a[0..], '\x00');
217
- swab("abcd", &a, 2);
218
- try std.testing.expectEqualSlices(u8, "ba\x00\x00", &a);
219
-
220
- // n < 1
221
- @memset(a[0..], '\x00');
222
- swab("abcd", &a, 0);
223
- try std.testing.expectEqualSlices(u8, "\x00" ** 4, &a);
224
- swab("abcd", &a, -1);
225
- try std.testing.expectEqualSlices(u8, "\x00" ** 4, &a);
226
-
227
- // Odd n
228
- @memset(a[0..], '\x00');
229
- swab("abcd", &a, 1);
230
- try std.testing.expectEqualSlices(u8, "\x00" ** 4, &a);
231
- swab("abcd", &a, 3);
232
- try std.testing.expectEqualSlices(u8, "ba\x00\x00", &a);
233
- }
234
-
235
236
  fn close(fd: std.c.fd_t) callconv(.c) c_int {
236
237
  const signed: isize = @bitCast(linux.close(fd));
237
238
  if (signed < 0) {
package/c.zig CHANGED
@@ -2,8 +2,7 @@
2
2
  //! bundled libcs.
3
3
  //!
4
4
  //! mingw-w64 libc is not fully statically linked, so some symbols don't need
5
- //! to be exported. However, a future enhancement could be eliminating Zig's
6
- //! dependency on msvcrt dll even when linking libc and targeting Windows.
5
+ //! to be exported.
7
6
 
8
7
  const builtin = @import("builtin");
9
8
  const std = @import("std");
@@ -152,6 +152,10 @@ fn test__addo_limb64(comptime T: type, a: T, b: T, expected: struct { T, bool })
152
152
  }
153
153
 
154
154
  test __addo_limb64 {
155
+ if (builtin.cpu.arch == .aarch64_be) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/31905
156
+ if (builtin.cpu.arch == .mips64) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/31905
157
+ if (builtin.cpu.arch == .powerpc64) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/31905
158
+
155
159
  try test__addo_limb64(u64, 1, 2, .{ 3, false });
156
160
  try test__addo_limb64(u64, maxInt(u64), 2, .{ 1, true });
157
161
  try test__addo_limb64(u65, maxInt(u65), 2, .{ 1, true });
@@ -228,6 +232,10 @@ fn test__subo_limb64(comptime T: type, a: T, b: T, expected: struct { T, bool })
228
232
  }
229
233
 
230
234
  test __subo_limb64 {
235
+ if (builtin.cpu.arch == .aarch64_be) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/31905
236
+ if (builtin.cpu.arch == .mips64) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/31905
237
+ if (builtin.cpu.arch == .powerpc64) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/31905
238
+
231
239
  try test__subo_limb64(u64, 3, 2, .{ 1, false });
232
240
  try test__subo_limb64(u64, 0, 1, .{ maxInt(u64), true });
233
241
  try test__subo_limb64(u65, 0, 1, .{ maxInt(u65), true });
@@ -477,6 +485,10 @@ fn test__not_limb64(comptime T: type, a: T, expected: T) !void {
477
485
  }
478
486
 
479
487
  test __not_limb64 {
488
+ if (builtin.cpu.arch == .aarch64_be) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/31905
489
+ if (builtin.cpu.arch == .mips64) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/31905
490
+ if (builtin.cpu.arch == .powerpc64) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/31905
491
+
480
492
  try test__not_limb64(u64, 1, maxInt(u64) - 1);
481
493
  try test__not_limb64(u64, 3, maxInt(u64) - 3);
482
494
  try test__not_limb64(u65, maxInt(u65), 0);
@@ -555,6 +567,10 @@ fn test__shlo_limb64(comptime T: type, a: T, shift: u16, expected: struct { T, b
555
567
  }
556
568
 
557
569
  test __shlo_limb64 {
570
+ if (builtin.cpu.arch == .aarch64_be) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/31905
571
+ if (builtin.cpu.arch == .mips64) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/31905
572
+ if (builtin.cpu.arch == .powerpc64) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/31905
573
+
558
574
  try test__shlo_limb64(u64, 0x1234_5678_9ABC_DEF0, 4, .{ 0x2345_6789_ABCD_EF00, true });
559
575
  try test__shlo_limb64(u64, 0x8000_0000_0000_0001, 63, .{ 0x8000_0000_0000_0000, true });
560
576
  try test__shlo_limb64(u65, 1, 64, .{ 0x1_0000_0000_0000_0000, false });
@@ -631,6 +647,10 @@ fn test__shr_limb64(comptime T: type, a: T, shift: u16, expected: T) !void {
631
647
  }
632
648
 
633
649
  test __shr_limb64 {
650
+ if (builtin.cpu.arch == .aarch64_be) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/31905
651
+ if (builtin.cpu.arch == .mips64) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/31905
652
+ if (builtin.cpu.arch == .powerpc64) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/31905
653
+
634
654
  try test__shr_limb64(u64, 0x1234_5678_9ABC_DEF0, 4, 0x0123_4567_89AB_CDEF);
635
655
  try test__shr_limb64(u64, 0x8000_0000_0000_0001, 63, 1);
636
656
  try test__shr_limb64(u65, 0x1_0000_0000_0000_0000, 64, 1);
@@ -858,6 +878,10 @@ fn test__bitreverse_limb64(comptime T: type, a: T, expected: T) !void {
858
878
  }
859
879
 
860
880
  test __bitreverse_limb64 {
881
+ if (builtin.cpu.arch == .aarch64_be) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/31905
882
+ if (builtin.cpu.arch == .mips64) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/31905
883
+ if (builtin.cpu.arch == .powerpc64) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/31905
884
+
861
885
  try test__bitreverse_limb64(u64, 1 << 7, 1 << 56);
862
886
  try test__bitreverse_limb64(u65, 1 << 64, 1);
863
887
  try test__bitreverse_limb64(u65, 1 << 9, 1 << 55);
@@ -910,6 +934,10 @@ fn test__byteswap_limb64(comptime T: type, a: T, expected: T) !void {
910
934
  }
911
935
 
912
936
  test __byteswap_limb64 {
937
+ if (builtin.cpu.arch == .aarch64_be) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/31905
938
+ if (builtin.cpu.arch == .mips64) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/31905
939
+ if (builtin.cpu.arch == .powerpc64) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/31905
940
+
913
941
  try test__byteswap_limb64(u64, 0x0123_4567_89AB_CDEF, 0xEFCD_AB89_6745_2301);
914
942
  try test__byteswap_limb64(u72, 0x01_23_45_67_89_AB_CD_EF_11, 0x11_EF_CD_AB_89_67_45_23_01);
915
943
  try test__byteswap_limb64(u128, 1 << 72, 1 << 48);
@@ -1036,6 +1064,10 @@ fn test__mulo_limb64(comptime T: type, a: T, b: T, expected: struct { T, bool })
1036
1064
  }
1037
1065
 
1038
1066
  test __mulo_limb64 {
1067
+ if (builtin.cpu.arch == .aarch64_be) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/31905
1068
+ if (builtin.cpu.arch == .mips64) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/31905
1069
+ if (builtin.cpu.arch == .powerpc64) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/31905
1070
+
1039
1071
  try test__mulo_limb64(u64, 3, 5, .{ 15, false });
1040
1072
  try test__mulo_limb64(u64, maxInt(u64), 2, .{ maxInt(u64) - 1, true });
1041
1073
  try test__mulo_limb64(u65, 1 << 32, 1 << 32, .{ 1 << 64, false });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zigc/lib",
3
- "version": "0.17.0-dev.56",
3
+ "version": "0.17.0-dev.76",
4
4
  "description": "Zig standard library and libc headers (shared across all platforms)",
5
5
  "repository": {
6
6
  "type": "git",
@@ -15,14 +15,42 @@ cond: Io.Condition = .init,
15
15
  /// It is OK to initialize this field to any value.
16
16
  permits: usize = 0,
17
17
 
18
+ /// Blocks until a `permit` is available and consumes a single one.
19
+ /// Unblocks without consuming a `permit` when canceled.
20
+ ///
21
+ /// See also:
22
+ /// * `waitTimeout`
23
+ /// * `waitUncancelable`
18
24
  pub fn wait(s: *Semaphore, io: Io) Io.Cancelable!void {
25
+ s.waitTimeout(io, .none) catch |err| switch (err) {
26
+ error.Timeout => unreachable,
27
+ error.Canceled => |e| return e,
28
+ };
29
+ }
30
+
31
+ pub const WaitTimeoutError = Io.Cancelable || Io.Timeout.Error;
32
+
33
+ /// Blocks until a `permit` is available and consumes a single one.
34
+ /// Unblocks without consuming a `permit` when canceled or when the provided
35
+ /// timeout expires before a `permit` is available.
36
+ ///
37
+ /// See also:
38
+ /// * `wait`
39
+ /// * `waitUncancelable`
40
+ pub fn waitTimeout(s: *Semaphore, io: Io, timeout: Io.Timeout) WaitTimeoutError!void {
41
+ const deadline = timeout.toDeadline(io);
19
42
  try s.mutex.lock(io);
20
43
  defer s.mutex.unlock(io);
21
- while (s.permits == 0) try s.cond.wait(io, &s.mutex);
44
+ while (s.permits == 0) try s.cond.waitTimeout(io, &s.mutex, deadline);
22
45
  s.permits -= 1;
23
46
  if (s.permits > 0) s.cond.signal(io);
24
47
  }
25
48
 
49
+ /// Blocks until a `permit` is available and consumes a single one.
50
+ ///
51
+ /// See also:
52
+ /// * `wait`
53
+ /// * `waitTimeout`
26
54
  pub fn waitUncancelable(s: *Semaphore, io: Io) void {
27
55
  s.mutex.lockUncancelable(io);
28
56
  defer s.mutex.unlock(io);
@@ -31,6 +59,7 @@ pub fn waitUncancelable(s: *Semaphore, io: Io) void {
31
59
  if (s.permits > 0) s.cond.signal(io);
32
60
  }
33
61
 
62
+ /// Makes an additional `permit` available.
34
63
  pub fn post(s: *Semaphore, io: Io) void {
35
64
  s.mutex.lockUncancelable(io);
36
65
  defer s.mutex.unlock(io);
@@ -39,27 +68,93 @@ pub fn post(s: *Semaphore, io: Io) void {
39
68
  s.cond.signal(io);
40
69
  }
41
70
 
42
- test Semaphore {
43
- if (builtin.single_threaded) return error.SkipZigTest;
71
+ test wait {
44
72
  const io = testing.io;
45
73
 
46
- const TestContext = struct {
47
- sem: *Semaphore,
48
- n: *i32,
74
+ const Context = struct {
75
+ sem: Semaphore = .{ .permits = 1 },
76
+ n: u32 = 0,
77
+
49
78
  fn worker(ctx: *@This()) !void {
50
79
  try ctx.sem.wait(io);
51
- ctx.n.* += 1;
80
+ ctx.n += 1;
52
81
  ctx.sem.post(io);
53
82
  }
54
83
  };
55
- const num_threads = 3;
56
- var sem: Semaphore = .{ .permits = 1 };
57
- var threads: [num_threads]std.Thread = undefined;
58
- var n: i32 = 0;
59
- var ctx = TestContext{ .sem = &sem, .n = &n };
60
-
61
- for (&threads) |*t| t.* = try std.Thread.spawn(.{}, TestContext.worker, .{&ctx});
62
- for (threads) |t| t.join();
63
- try sem.wait(io);
64
- try testing.expect(n == num_threads);
84
+
85
+ var ctx: Context = .{};
86
+
87
+ var group: Io.Group = .init;
88
+ defer group.cancel(io);
89
+
90
+ const num_workers = 3;
91
+ for (0..num_workers) |_| group.async(io, Context.worker, .{&ctx});
92
+
93
+ try group.await(io);
94
+ try testing.expectEqual(num_workers, ctx.n);
95
+ }
96
+
97
+ test waitTimeout {
98
+ const io = testing.io;
99
+
100
+ const Context = struct {
101
+ ready: Io.Event = .unset,
102
+ sem: Semaphore = .{ .permits = 0 },
103
+ value: u32 = 0,
104
+
105
+ fn worker(ctx: *@This()) !void {
106
+ defer ctx.ready.set(io);
107
+
108
+ try testing.expectError(error.Timeout, ctx.sem.waitTimeout(io, .{ .duration = .{
109
+ .raw = .fromMilliseconds(1),
110
+ .clock = .awake,
111
+ } }));
112
+ try testing.expectEqual(0, ctx.value);
113
+
114
+ ctx.ready.set(io);
115
+
116
+ while (ctx.value == 0) try ctx.sem.wait(io);
117
+ try testing.expectEqual(1, ctx.value);
118
+ }
119
+ };
120
+
121
+ var ctx: Context = .{};
122
+
123
+ var future = io.concurrent(Context.worker, .{&ctx}) catch |err| switch (err) {
124
+ error.ConcurrencyUnavailable => return error.SkipZigTest,
125
+ };
126
+ defer future.cancel(io) catch {};
127
+
128
+ try ctx.ready.wait(io);
129
+
130
+ ctx.value = 1;
131
+ ctx.sem.post(io);
132
+
133
+ try future.await(io);
134
+ }
135
+
136
+ test waitUncancelable {
137
+ const io = testing.io;
138
+
139
+ const Context = struct {
140
+ sem: Semaphore = .{ .permits = 1 },
141
+ n: u32 = 0,
142
+
143
+ fn worker(ctx: *@This()) !void {
144
+ ctx.sem.waitUncancelable(io);
145
+ ctx.n += 1;
146
+ ctx.sem.post(io);
147
+ }
148
+ };
149
+
150
+ var ctx: Context = .{};
151
+
152
+ var group: Io.Group = .init;
153
+ defer group.cancel(io);
154
+
155
+ const num_workers = 3;
156
+ for (0..num_workers) |_| group.async(io, Context.worker, .{&ctx});
157
+
158
+ try group.await(io);
159
+ try testing.expectEqual(num_workers, ctx.n);
65
160
  }
@@ -2005,7 +2005,7 @@ const have_waitid = switch (native_os) {
2005
2005
 
2006
2006
  const have_wait4 = switch (native_os) {
2007
2007
  .linux => @hasField(std.os.linux.SYS, "wait4"),
2008
- .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,
2009
2009
  else => false,
2010
2010
  };
2011
2011
 
package/std/Io.zig CHANGED
@@ -1681,20 +1681,29 @@ pub const Condition = struct {
1681
1681
  .epoch = .init(0),
1682
1682
  };
1683
1683
 
1684
+ /// Blocks until the condition is signaled or canceled.
1685
+ ///
1686
+ /// See also:
1687
+ /// * `waitUncancelable`
1688
+ /// * `waitTimeout`
1684
1689
  pub fn wait(cond: *Condition, io: Io, mutex: *Mutex) Cancelable!void {
1685
- try waitInner(cond, io, mutex, false);
1690
+ waitTimeout(cond, io, mutex, .none) catch |err| switch (err) {
1691
+ error.Timeout => unreachable,
1692
+ error.Canceled => |e| return e,
1693
+ };
1686
1694
  }
1687
1695
 
1688
- /// Same as `wait`, except does not introduce a cancelation point.
1696
+ pub const WaitTimeoutError = Cancelable || Timeout.Error;
1697
+
1698
+ /// Blocks until the condition is signaled, canceled, or the provided
1699
+ /// timeout expires.
1689
1700
  ///
1690
- /// For a description of cancelation and cancelation points, see `Future.cancel`.
1691
- pub fn waitUncancelable(cond: *Condition, io: Io, mutex: *Mutex) void {
1692
- waitInner(cond, io, mutex, true) catch |err| switch (err) {
1693
- error.Canceled => unreachable,
1694
- };
1695
- }
1701
+ /// See also:
1702
+ /// * `wait`
1703
+ /// * `waitUncancelable`
1704
+ pub fn waitTimeout(cond: *Condition, io: Io, mutex: *Mutex, timeout: Timeout) WaitTimeoutError!void {
1705
+ const deadline = timeout.toDeadline(io);
1696
1706
 
1697
- fn waitInner(cond: *Condition, io: Io, mutex: *Mutex, uncancelable: bool) Cancelable!void {
1698
1707
  var epoch = cond.epoch.load(.acquire); // `.acquire` to ensure ordered before state load
1699
1708
 
1700
1709
  {
@@ -1706,10 +1715,7 @@ pub const Condition = struct {
1706
1715
  defer mutex.lockUncancelable(io);
1707
1716
 
1708
1717
  while (true) {
1709
- const result = if (uncancelable)
1710
- io.futexWaitUncancelable(u32, &cond.epoch.raw, epoch)
1711
- else
1712
- io.futexWait(u32, &cond.epoch.raw, epoch);
1718
+ const result = io.futexWaitTimeout(u32, &cond.epoch.raw, epoch, deadline);
1713
1719
 
1714
1720
  epoch = cond.epoch.load(.acquire); // `.acquire` to ensure ordered before `state` laod
1715
1721
 
@@ -1729,13 +1735,62 @@ pub const Condition = struct {
1729
1735
  }
1730
1736
 
1731
1737
  // There are no more signals available; this was a spurious wakeup or an error. If it
1732
- // was an error, we will remove ourselves as a waiter and return that error. Otherwise,
1733
- // we'll loop back to the futex wait.
1738
+ // was an error, we will remove ourselves as a waiter and return that error. If a
1739
+ // timeout was specified and the deadline has passed, we remove ourselves as a waiter
1740
+ // and return `error.Timeout`. Otherwise, we'll loop back to the futex wait.
1734
1741
  result catch |err| {
1735
1742
  const prev_state = cond.state.fetchSub(.{ .waiters = 1, .signals = 0 }, .monotonic);
1736
1743
  assert(prev_state.waiters > 0); // underflow caused by illegal state
1737
1744
  return err;
1738
1745
  };
1746
+ switch (deadline) {
1747
+ .none => {},
1748
+ .deadline => |d| if (d.untilNow(io).raw.nanoseconds >= 0) {
1749
+ const prev_state = cond.state.fetchSub(.{ .waiters = 1, .signals = 0 }, .monotonic);
1750
+ assert(prev_state.waiters > 0); // underflow caused by illegal state
1751
+ return error.Timeout;
1752
+ },
1753
+ .duration => unreachable,
1754
+ }
1755
+ }
1756
+ }
1757
+
1758
+ /// Same as `wait`, except does not introduce a cancelation point.
1759
+ ///
1760
+ /// See `Future.cancel` for a description of cancelation points.
1761
+ pub fn waitUncancelable(cond: *Condition, io: Io, mutex: *Mutex) void {
1762
+ var epoch = cond.epoch.load(.acquire); // `.acquire` to ensure ordered before state load
1763
+
1764
+ {
1765
+ const prev_state = cond.state.fetchAdd(.{ .waiters = 1, .signals = 0 }, .monotonic);
1766
+ assert(prev_state.waiters < math.maxInt(u16)); // overflow caused by too many waiters
1767
+ }
1768
+
1769
+ mutex.unlock(io);
1770
+ defer mutex.lockUncancelable(io);
1771
+
1772
+ while (true) {
1773
+ io.futexWaitUncancelable(u32, &cond.epoch.raw, epoch);
1774
+
1775
+ epoch = cond.epoch.load(.acquire); // `.acquire` to ensure ordered before `state` laod
1776
+
1777
+ // Even on error, try to consume a pending signal first. Otherwise a race might
1778
+ // cause a signal to get stuck in the state with no corresponding waiter.
1779
+ {
1780
+ var prev_state = cond.state.load(.monotonic);
1781
+ while (prev_state.signals > 0) {
1782
+ prev_state = cond.state.cmpxchgWeak(prev_state, .{
1783
+ .waiters = prev_state.waiters - 1,
1784
+ .signals = prev_state.signals - 1,
1785
+ }, .acquire, .monotonic) orelse {
1786
+ // We successfully consumed a signal.
1787
+ return;
1788
+ };
1789
+ }
1790
+ }
1791
+
1792
+ // There are no more signals available; this was a spurious wakeup,
1793
+ // so we'll loop back to the futex wait.
1739
1794
  }
1740
1795
  }
1741
1796
 
@@ -53,9 +53,7 @@ pub extern "c" fn profiling_enable(pid: pid_t, event_mask: PERF_EVENT) c_int;
53
53
  pub extern "c" fn profiling_disable(pid: pid_t) c_int;
54
54
  pub extern "c" fn profiling_free_buffer(pid: pid_t) c_int;
55
55
 
56
- pub extern "c" fn futex(userspace_address: *u32, futex_op: c_int, value: u32, timeout: *const timespec, userspace_address2: *u32, value3: u32) c_int;
57
- pub extern "c" fn futex_wait(userspace_address: *u32, value: u32, abstime: *const timespec, clockid: clockid_t, process_shared: c_int) c_int;
58
- pub extern "c" fn futex_wake(userspace_address: *u32, count: u32, process_shared: c_int) c_int;
56
+ pub extern "c" fn futex(userspace_address: *u32, futex_op: c_int, value: u32, timeout: ?*const timespec, userspace_address2: ?*u32, value3: u32) c_int;
59
57
 
60
58
  pub extern "c" fn purge(mode: c_int) c_int;
61
59
 
@@ -66,9 +64,6 @@ pub extern "c" fn get_stack_bounds(user_stack_base: *usize, user_stack_size: *us
66
64
 
67
65
  pub extern "c" fn anon_create(size: usize, options: O) c_int;
68
66
 
69
- pub extern "c" fn serenity_readlink(path: [*]const u8, path_length: usize, buffer: [*]u8, buffer_size: usize) c_int;
70
- pub extern "c" fn serenity_open(path: [*]const u8, path_length: usize, options: c_int, ...) c_int;
71
-
72
67
  pub extern "c" fn getkeymap(name_buffer: [*]u8, name_buffer_size: usize, map: [*]u32, shift_map: [*]u32, alt_map: [*]u32, altgr_map: [*]u32, shift_altgr_map: [*]u32) c_int;
73
68
  pub extern "c" fn setkeymap(name: [*]const u8, map: [*]const u32, shift_map: [*]const u32, alt_map: [*]const u32, altgr_map: [*]const u32, shift_altgr_map: [*]const u32) c_int;
74
69
 
package/std/c.zig CHANGED
@@ -11102,13 +11102,60 @@ pub const ioctl = switch (native_os) {
11102
11102
  else => private.ioctl,
11103
11103
  };
11104
11104
 
11105
+ pub extern "c" fn bzero(s: *anyopaque, n: usize) void;
11106
+
11107
+ pub extern "c" fn swab(noalias from: *const anyopaque, noalias to: *anyopaque, n: isize) void;
11108
+
11109
+ pub extern "c" fn strncmp(a: [*:0]const c_char, b: [*:0]const c_char, max: usize) c_int;
11110
+ pub extern "c" fn strcasecmp(a: [*:0]const c_char, b: [*:0]const c_char) c_int;
11111
+ pub extern "c" fn strncasecmp(a: [*:0]const c_char, b: [*:0]const c_char, max: usize) c_int;
11112
+
11113
+ pub extern "c" fn ffs(i: c_int) c_int;
11114
+ pub extern "c" fn ffsl(i: c_long) c_long;
11115
+ pub extern "c" fn ffsll(i: c_longlong) c_longlong;
11116
+
11117
+ pub extern "c" fn erand48(xsubi: *[3]c_ushort) f64;
11118
+ pub extern "c" fn jrand48(xsubi: *[3]c_ushort) c_long;
11119
+ pub extern "c" fn nrand48(xsubi: *[3]c_ushort) c_long;
11120
+
11121
+ pub extern "c" fn insque(element: *anyopaque, pred: ?*anyopaque) void;
11122
+ pub extern "c" fn remque(element: *anyopaque) void;
11123
+
11124
+ pub extern "c" fn imaxabs(a: intmax_t) intmax_t;
11125
+ pub extern "c" fn imaxdiv(a: intmax_t, b: intmax_t) imaxdiv_t;
11126
+
11127
+ pub extern "c" fn abs(a: c_int) c_int;
11128
+ pub extern "c" fn labs(a: c_long) c_long;
11129
+ pub extern "c" fn llabs(a: c_longlong) c_longlong;
11130
+
11131
+ pub extern "c" fn div(a: c_int, b: c_int) div_t;
11132
+ pub extern "c" fn ldiv(a: c_long, b: c_long) ldiv_t;
11133
+ pub extern "c" fn lldiv(a: c_longlong, b: c_longlong) lldiv_t;
11134
+
11135
+ pub extern "c" fn atoi(str: [*:0]const c_char) c_int;
11136
+ pub extern "c" fn atol(str: [*:0]const c_char) c_long;
11137
+ pub extern "c" fn atoll(str: [*:0]const c_char) c_longlong;
11138
+
11139
+ pub extern "c" fn bsearch(
11140
+ key: *const anyopaque,
11141
+ base: *const anyopaque,
11142
+ n: usize,
11143
+ size: usize,
11144
+ compare: *const fn (a: *const anyopaque, b: *const anyopaque) callconv(.c) c_int,
11145
+ ) ?*anyopaque;
11146
+
11105
11147
  // Math
11106
- pub extern "c" fn atan(x: f64) callconv(.c) f64;
11107
- pub extern "c" fn copysign(x: f64, y: f64) callconv(.c) f64;
11108
- pub extern "c" fn fdim(x: f64, y: f64) callconv(.c) f64;
11109
- pub extern "c" fn frexp(x: f64, e: *c_int) callconv(.c) f64;
11110
- pub extern "c" fn hypot(x: f64, y: f64) callconv(.c) f64;
11111
- pub extern "c" fn modf(x: f64, iptr: *f64) callconv(.c) f64;
11148
+ pub extern "c" fn atan(x: f64) f64;
11149
+ pub extern "c" fn copysign(x: f64, y: f64) f64;
11150
+ pub extern "c" fn fdim(x: f64, y: f64) f64;
11151
+ pub extern "c" fn frexp(x: f64, e: *c_int) f64;
11152
+ pub extern "c" fn hypot(x: f64, y: f64) f64;
11153
+ pub extern "c" fn modff(x: f32, iptr: *f32) f32;
11154
+ pub extern "c" fn modf(x: f64, iptr: *f64) f64;
11155
+ pub extern "c" fn modfl(x: c_longdouble, iptr: *c_longdouble) c_longdouble;
11156
+ pub extern "c" fn rintf(x: f32) f32;
11157
+ pub extern "c" fn rint(x: f64) f64;
11158
+ pub extern "c" fn rintl(x: c_longdouble) c_longdouble;
11112
11159
 
11113
11160
  // OS-specific bits. These are protected from being used on the wrong OS by
11114
11161
  // comptime assertions inside each OS-specific file.
@@ -11459,15 +11506,11 @@ pub const disown = serenity.disown;
11459
11506
  pub const profiling_enable = serenity.profiling_enable;
11460
11507
  pub const profiling_disable = serenity.profiling_disable;
11461
11508
  pub const profiling_free_buffer = serenity.profiling_free_buffer;
11462
- pub const futex_wait = serenity.futex_wait;
11463
- pub const futex_wake = serenity.futex_wake;
11464
11509
  pub const purge = serenity.purge;
11465
11510
  pub const perf_event = serenity.perf_event;
11466
11511
  pub const perf_register_string = serenity.perf_register_string;
11467
11512
  pub const get_stack_bounds = serenity.get_stack_bounds;
11468
11513
  pub const anon_create = serenity.anon_create;
11469
- pub const serenity_readlink = serenity.serenity_readlink;
11470
- pub const serenity_open = serenity.serenity_open;
11471
11514
  pub const getkeymap = serenity.getkeymap;
11472
11515
  pub const setkeymap = serenity.setkeymap;
11473
11516
 
package/std/os.zig CHANGED
@@ -1,4 +1,5 @@
1
1
  const builtin = @import("builtin");
2
+ const std = @import("std.zig");
2
3
  const native_os = builtin.os.tag;
3
4
 
4
5
  pub const linux = @import("os/linux.zig");
@@ -8,6 +9,46 @@ pub const wasi = @import("os/wasi.zig");
8
9
  pub const emscripten = @import("os/emscripten.zig");
9
10
  pub const windows = @import("os/windows.zig");
10
11
 
12
+ /// Returns whether the Zig standard library requires libc in order to interface
13
+ /// with the operating system on the given target.
14
+ pub fn targetRequiresLibC(target: *const std.Target) bool {
15
+ if (target.requiresLibC()) return true;
16
+ return switch (target.os.tag) {
17
+ .linux => switch (target.cpu.arch) {
18
+ // https://codeberg.org/ziglang/zig/issues/30940
19
+ .alpha,
20
+ // https://codeberg.org/ziglang/zig/issues/30942
21
+ .csky,
22
+ // https://codeberg.org/ziglang/zig/issues/30943
23
+ .hppa,
24
+ .hppa64,
25
+ // https://codeberg.org/ziglang/zig/issues/30944
26
+ .microblaze,
27
+ .microblazeel,
28
+ // https://codeberg.org/ziglang/zig/issues/30946
29
+ .sh,
30
+ .sheb,
31
+ // https://codeberg.org/ziglang/zig/issues/30945
32
+ .sparc,
33
+ // https://codeberg.org/ziglang/zig/issues/30947
34
+ .xtensa,
35
+ .xtensaeb,
36
+ => true,
37
+ else => false,
38
+ },
39
+ .freebsd => true, // https://codeberg.org/ziglang/zig/issues/30981
40
+ .netbsd => true, // https://codeberg.org/ziglang/zig/issues/30980
41
+ .openbsd => true, // https://codeberg.org/ziglang/zig/issues/30982
42
+ else => false,
43
+ };
44
+ }
45
+
46
+ /// Returns whether the Zig standard library requires libc in order to interface
47
+ /// with the operating system on the current target.
48
+ pub fn requiresLibC() bool {
49
+ return targetRequiresLibC(&builtin.target);
50
+ }
51
+
11
52
  test {
12
53
  _ = linux;
13
54
  if (native_os == .uefi) _ = uefi;
@@ -1,20 +0,0 @@
1
- #include <unistd.h>
2
- #include <errno.h>
3
- #include <fcntl.h>
4
- #include "syscall.h"
5
-
6
- int dup2(int old, int new)
7
- {
8
- int r;
9
- #ifdef SYS_dup2
10
- while ((r=__syscall(SYS_dup2, old, new))==-EBUSY);
11
- #else
12
- if (old==new) {
13
- r = __syscall(SYS_fcntl, old, F_GETFD);
14
- if (r >= 0) return old;
15
- } else {
16
- while ((r=__syscall(SYS_dup3, old, new, 0))==-EBUSY);
17
- }
18
- #endif
19
- return __syscall_ret(r);
20
- }
@@ -1,26 +0,0 @@
1
- #define _GNU_SOURCE
2
- #include <unistd.h>
3
- #include <errno.h>
4
- #include <fcntl.h>
5
- #include "syscall.h"
6
-
7
- int __dup3(int old, int new, int flags)
8
- {
9
- int r;
10
- #ifdef SYS_dup2
11
- if (old==new) return __syscall_ret(-EINVAL);
12
- if (flags) {
13
- while ((r=__syscall(SYS_dup3, old, new, flags))==-EBUSY);
14
- if (r!=-ENOSYS) return __syscall_ret(r);
15
- if (flags & ~O_CLOEXEC) return __syscall_ret(-EINVAL);
16
- }
17
- while ((r=__syscall(SYS_dup2, old, new))==-EBUSY);
18
- if (r >= 0 && (flags & O_CLOEXEC))
19
- __syscall(SYS_fcntl, new, F_SETFD, FD_CLOEXEC);
20
- #else
21
- while ((r=__syscall(SYS_dup3, old, new, flags))==-EBUSY);
22
- #endif
23
- return __syscall_ret(r);
24
- }
25
-
26
- weak_alias(__dup3, dup3);