Skip to content

Commit 373453c

Browse files
committed
Fix macOS test failures and ensure z
1 parent 71fa408 commit 373453c

7 files changed

Lines changed: 144 additions & 29 deletions

File tree

build.zig

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -422,9 +422,11 @@ pub fn build(b: *std.Build) void {
422422
const run_step = addRunArtifactCompat(b, test_env_exe);
423423
addArtifactArgCompat(run_step, b, exe);
424424
configureExternalHelperRunner(run_step, exe);
425-
// Keep block markers opt-in for manual repro only. Injecting extra env
426-
// into the emulator path changes the execution surface enough to create
427-
// Darling-only harness failures that do not reproduce on native macOS.
425+
// Diagnostic markers only write labeled stderr lines. They do not alter
426+
// libc behavior, and keeping them enabled in CI makes native-only Darwin
427+
// failures line up with emulator runs instead of collapsing into a blank
428+
// SIGSEGV with no block context.
429+
run_step.setEnvironmentVariable("ZIGLIBC_TEST_MARKERS", "1");
428430
run_step.addCheck(.{ .expect_stdout_exact = "Success!\n" });
429431
test_step.dependOn(&run_step.step);
430432
}
@@ -469,6 +471,7 @@ pub fn build(b: *std.Build) void {
469471
addArtifactArgCompat(run_step, b, system_exe);
470472
addArtifactArgCompat(run_step, b, zig_exe);
471473
configureExternalHelperRunner(run_step, zig_exe);
474+
run_step.setEnvironmentVariable("ZIGLIBC_TEST_MARKERS", "1");
472475
run_step.addCheck(.{ .expect_stdout_exact = "Success!\n" });
473476
test_step.dependOn(&run_step.step);
474477
break :blk run_step;

inc/posix/private/dev_t.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
#ifndef _PRIVATE_DEV_T_H
22
#define _PRIVATE_DEV_T_H
33

4+
#ifdef __APPLE__
5+
typedef int dev_t;
6+
#else
47
typedef unsigned long long dev_t;
8+
#endif
59

610
#endif /* _PRIVATE_DEV_T_H */

src/posix.zig

Lines changed: 77 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,14 @@ fn exportInternalSymbol(comptime f: anytype, comptime name: []const u8) void {
115115
}
116116
}
117117

118+
fn darwinSysSigned(value: anytype) c_long {
119+
return @as(c_long, @intCast(value));
120+
}
121+
122+
fn darwinSysUnsigned(value: anytype) usize {
123+
return @as(usize, @intCast(value));
124+
}
125+
118126
const darwin = if (builtin.os.tag.isDarwin()) struct {
119127
const mach_port_t = c_uint;
120128
const kern_return_t = c_int;
@@ -536,7 +544,10 @@ export fn getopt(argc: c_int, argv: [*][*:0]u8, optstring: [*:0]const u8) callco
536544

537545
fn zwriteRaw(fd: c_int, buf: [*]const u8, nbyte: usize) isize {
538546
if (builtin.os.tag.isDarwin()) {
539-
const rc = syscall(darwin_syscall.write, fd, buf, nbyte);
547+
// Keep Darwin syscall arguments widened to full slot width. Native arm64
548+
// is much less forgiving than Darling when narrow integers cross the
549+
// variadic syscall(2) ABI boundary.
550+
const rc = syscall(darwin_syscall.write, darwinSysSigned(fd), buf, darwinSysUnsigned(nbyte));
540551
if (rc == -1) {
541552
c.errno = darwin.__error().*;
542553
return -1;
@@ -578,7 +589,7 @@ fn zwriteRaw(fd: c_int, buf: [*]const u8, nbyte: usize) isize {
578589

579590
fn zreadRaw(fd: c_int, buf: [*]u8, len: usize) isize {
580591
if (builtin.os.tag.isDarwin()) {
581-
const rc = syscall(darwin_syscall.read, fd, buf, len);
592+
const rc = syscall(darwin_syscall.read, darwinSysSigned(fd), buf, darwinSysUnsigned(len));
582593
if (rc == -1) {
583594
c.errno = darwin.__error().*;
584595
return -1;
@@ -739,7 +750,13 @@ fn zopenAtRaw(dirfd: c_int, path: [*:0]const u8, oflag: c_int, mode: c_uint) c_i
739750
if (builtin.os.tag.isDarwin()) {
740751
const darwin_flags = translateDarwinOpenFlags(oflag);
741752
if (darwin_flags == -1) return -1;
742-
const rc = syscall(darwin_syscall.openat, dirfd, path, darwin_flags, create_mode);
753+
const rc = syscall(
754+
darwin_syscall.openat,
755+
darwinSysSigned(dirfd),
756+
path,
757+
darwinSysSigned(darwin_flags),
758+
darwinSysUnsigned(create_mode),
759+
);
743760
if (rc == -1) {
744761
c.errno = darwin.__error().*;
745762
return -1;
@@ -860,7 +877,7 @@ fn _fcntlArgInt(fd: c_int, cmd: c_int, arg: c_int) callconv(.c) c_int {
860877
}
861878

862879
if (builtin.os.tag.isDarwin()) {
863-
const rc = syscall(darwin_syscall.fcntl, fd, cmd, arg);
880+
const rc = syscall(darwin_syscall.fcntl, darwinSysSigned(fd), darwinSysSigned(cmd), darwinSysSigned(arg));
864881
if (rc == -1) {
865882
c.errno = darwin.__error().*;
866883
return -1;
@@ -1391,7 +1408,12 @@ export fn socket(domain: c_int, sock_type: c_int, protocol: c_int) callconv(.c)
13911408
};
13921409
}
13931410
if (builtin.os.tag.isDarwin()) {
1394-
const rc = syscall(darwin_syscall.socket, domain, sock_type, protocol);
1411+
const rc = syscall(
1412+
darwin_syscall.socket,
1413+
darwinSysSigned(domain),
1414+
darwinSysSigned(sock_type),
1415+
darwinSysSigned(protocol),
1416+
);
13951417
if (rc == -1) {
13961418
c.errno = darwin.__error().*;
13971419
return -1;
@@ -1432,7 +1454,7 @@ export fn bind(sockfd: c_int, addr: ?*const c.struct_sockaddr, addrlen: c.sockle
14321454
c.errno = c.EINVAL;
14331455
return -1;
14341456
};
1435-
const rc = syscall(darwin_syscall.bind, sock, name, addrlen);
1457+
const rc = syscall(darwin_syscall.bind, darwinSysSigned(sock), name, darwinSysUnsigned(addrlen));
14361458
if (rc == -1) {
14371459
c.errno = darwin.__error().*;
14381460
return -1;
@@ -1472,7 +1494,7 @@ export fn connect(sockfd: c_int, address: ?*const c.struct_sockaddr, address_len
14721494
c.errno = c.EINVAL;
14731495
return -1;
14741496
};
1475-
const rc = syscall(darwin_syscall.connect, sock, name, address_len);
1497+
const rc = syscall(darwin_syscall.connect, darwinSysSigned(sock), name, darwinSysUnsigned(address_len));
14761498
if (rc == -1) {
14771499
c.errno = darwin.__error().*;
14781500
return -1;
@@ -1520,7 +1542,7 @@ export fn getsockname(sockfd: c_int, address: ?*c.struct_sockaddr, address_len:
15201542
c.errno = c.EINVAL;
15211543
return -1;
15221544
};
1523-
const rc = syscall(darwin_syscall.getsockname, sock, name, len_ptr);
1545+
const rc = syscall(darwin_syscall.getsockname, darwinSysSigned(sock), name, len_ptr);
15241546
if (rc == -1) {
15251547
c.errno = darwin.__error().*;
15261548
return -1;
@@ -1571,7 +1593,7 @@ export fn getpeername(sockfd: c_int, address: ?*c.struct_sockaddr, address_len:
15711593
c.errno = c.EINVAL;
15721594
return -1;
15731595
};
1574-
const rc = syscall(darwin_syscall.getpeername, sock, name, len_ptr);
1596+
const rc = syscall(darwin_syscall.getpeername, darwinSysSigned(sock), name, len_ptr);
15751597
if (rc == -1) {
15761598
c.errno = darwin.__error().*;
15771599
return -1;
@@ -1615,7 +1637,14 @@ export fn getsockopt(sockfd: c_int, level: c_int, option_name: c_int, option_val
16151637
return 0;
16161638
}
16171639
if (builtin.os.tag.isDarwin()) {
1618-
const rc = syscall(darwin_syscall.getsockopt, sock, level, option_name, out_ptr, len_ptr);
1640+
const rc = syscall(
1641+
darwin_syscall.getsockopt,
1642+
darwinSysSigned(sock),
1643+
darwinSysSigned(level),
1644+
darwinSysSigned(option_name),
1645+
out_ptr,
1646+
len_ptr,
1647+
);
16191648
if (rc == -1) {
16201649
c.errno = darwin.__error().*;
16211650
return -1;
@@ -1649,7 +1678,14 @@ export fn setsockopt(sockfd: c_int, level: c_int, option_name: c_int, option_val
16491678
return 0;
16501679
}
16511680
if (builtin.os.tag.isDarwin()) {
1652-
const rc = syscall(darwin_syscall.setsockopt, sock, level, option_name, in_ptr, option_len);
1681+
const rc = syscall(
1682+
darwin_syscall.setsockopt,
1683+
darwinSysSigned(sock),
1684+
darwinSysSigned(level),
1685+
darwinSysSigned(option_name),
1686+
in_ptr,
1687+
darwinSysUnsigned(option_len),
1688+
);
16531689
if (rc == -1) {
16541690
c.errno = darwin.__error().*;
16551691
return -1;
@@ -1695,12 +1731,12 @@ export fn sendto(sockfd: c_int, message: ?*const anyopaque, len: usize, flags: c
16951731
if (builtin.os.tag.isDarwin()) {
16961732
const rc = syscall(
16971733
darwin_syscall.sendto,
1698-
sock,
1734+
darwinSysSigned(sock),
16991735
data_ptr,
1700-
len,
1701-
flags,
1736+
darwinSysUnsigned(len),
1737+
darwinSysSigned(flags),
17021738
dest_addr,
1703-
dest_len,
1739+
darwinSysUnsigned(dest_len),
17041740
);
17051741
if (rc == -1) {
17061742
c.errno = darwin.__error().*;
@@ -1742,7 +1778,15 @@ export fn recv(sockfd: c_int, buffer: ?*anyopaque, length: usize, flags: c_int)
17421778
return @as(isize, @intCast(rc));
17431779
}
17441780
if (builtin.os.tag.isDarwin()) {
1745-
const rc = syscall(darwin_syscall.recvfrom, sock, buf_ptr, length, flags, @as(?*c.struct_sockaddr, null), @as(?*c.socklen_t, null));
1781+
const rc = syscall(
1782+
darwin_syscall.recvfrom,
1783+
darwinSysSigned(sock),
1784+
buf_ptr,
1785+
darwinSysUnsigned(length),
1786+
darwinSysSigned(flags),
1787+
@as(?*c.struct_sockaddr, null),
1788+
@as(?*c.socklen_t, null),
1789+
);
17461790
if (rc == -1) {
17471791
c.errno = darwin.__error().*;
17481792
return -1;
@@ -1790,7 +1834,15 @@ export fn recvfrom(sockfd: c_int, buffer: ?*anyopaque, length: usize, flags: c_i
17901834
return @as(isize, @intCast(rc));
17911835
}
17921836
if (builtin.os.tag.isDarwin()) {
1793-
const rc = syscall(darwin_syscall.recvfrom, sock, buf_ptr, length, flags, address, address_len);
1837+
const rc = syscall(
1838+
darwin_syscall.recvfrom,
1839+
darwinSysSigned(sock),
1840+
buf_ptr,
1841+
darwinSysUnsigned(length),
1842+
darwinSysSigned(flags),
1843+
address,
1844+
address_len,
1845+
);
17941846
if (rc == -1) {
17951847
c.errno = darwin.__error().*;
17961848
return -1;
@@ -1819,7 +1871,7 @@ export fn shutdown(sockfd: c_int, how: c_int) callconv(.c) c_int {
18191871
return 0;
18201872
}
18211873
if (builtin.os.tag.isDarwin()) {
1822-
const rc = syscall(darwin_syscall.shutdown, sock, how);
1874+
const rc = syscall(darwin_syscall.shutdown, darwinSysSigned(sock), darwinSysSigned(how));
18231875
if (rc == -1) {
18241876
c.errno = darwin.__error().*;
18251877
return -1;
@@ -2460,7 +2512,7 @@ export fn getitimer(which: c_int, value: *c.itimerval) callconv(.c) c_int {
24602512
}
24612513
if (builtin.os.tag.isDarwin()) {
24622514
var native_value: DarwinItimerval = undefined;
2463-
const rc = syscall(darwin_syscall.getitimer, which, &native_value);
2515+
const rc = syscall(darwin_syscall.getitimer, darwinSysSigned(which), &native_value);
24642516
if (rc == -1) {
24652517
c.errno = darwin.__error().*;
24662518
return -1;
@@ -2528,7 +2580,7 @@ export fn setitimer(which: c_int, value: *const c.itimerval, avalue: *c.itimerva
25282580
var native_old: DarwinItimerval = undefined;
25292581
const rc = syscall(
25302582
darwin_syscall.setitimer,
2531-
which,
2583+
darwinSysSigned(which),
25322584
&native_value,
25332585
if (!cPtrIsNull(avalue)) &native_old else @as(?*DarwinItimerval, null),
25342586
);
@@ -2703,7 +2755,7 @@ export fn sigaction(sig: c_int, act: *const c.struct_sigaction, oact: *c.struct_
27032755

27042756
var native_old = std.mem.zeroes(std.c.Sigaction);
27052757
const native_old_ptr: ?*std.c.Sigaction = if (!cPtrIsNull(oact)) &native_old else null;
2706-
const rc = syscall(darwin_syscall.sigaction, sig, native_act_ptr, native_old_ptr);
2758+
const rc = syscall(darwin_syscall.sigaction, darwinSysSigned(sig), native_act_ptr, native_old_ptr);
27072759
if (rc == -1) {
27082760
c.errno = darwin.__error().*;
27092761
return -1;
@@ -2825,7 +2877,7 @@ export fn stat(path: [*:0]const u8, buf: *c.struct_stat) callconv(.c) c_int {
28252877
export fn chmod(path: [*:0]const u8, mode: c.mode_t) callconv(.c) c_int {
28262878
trace.log("chmod '{s}' mode=0x{x}", .{ path, mode });
28272879
if (builtin.os.tag.isDarwin()) {
2828-
const rc = syscall(darwin_syscall.chmod, path, @as(c_uint, @intCast(mode)));
2880+
const rc = syscall(darwin_syscall.chmod, path, darwinSysUnsigned(mode));
28292881
if (rc == -1) {
28302882
c.errno = darwin.__error().*;
28312883
return -1;
@@ -3418,7 +3470,7 @@ export fn strncasecmp_l(a: [*:0]const u8, b: [*:0]const u8, n: usize, locale: c.
34183470
fn _ioctlArgPtr(fd: c_int, request: c_ulong, arg_ptr: *anyopaque) callconv(.c) c_int {
34193471
trace.log("ioctl fd={} request=0x{x} arg={*}", .{ fd, request, arg_ptr });
34203472
if (builtin.os.tag.isDarwin()) {
3421-
const rc = syscall(darwin_syscall.ioctl, fd, request, arg_ptr);
3473+
const rc = syscall(darwin_syscall.ioctl, darwinSysSigned(fd), darwinSysUnsigned(request), arg_ptr);
34223474
if (rc == -1) {
34233475
c.errno = darwin.__error().*;
34243476
return -1;
@@ -3666,7 +3718,7 @@ export fn select(
36663718
if (builtin.os.tag.isDarwin()) {
36673719
const rc = syscall(
36683720
darwin_syscall.select,
3669-
nfds,
3721+
darwinSysSigned(nfds),
36703722
readfds,
36713723
writefds,
36723724
errorfds,
@@ -3762,7 +3814,7 @@ export fn pselect(
37623814
// the timeout-only case look equivalent.
37633815
const rc = syscall(
37643816
darwin_syscall.pselect,
3765-
nfds,
3817+
darwinSysSigned(nfds),
37663818
readfds,
37673819
writefds,
37683820
errorfds,

test/darwin_abi.zig

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,19 @@ fn abiAlignMismatch(comptime name: []const u8, comptime got: usize, comptime exp
2020
@compileError(std.fmt.comptimePrint("{s} ABI alignment mismatch: got {d}, expected {d}", .{ name, got, expected }));
2121
}
2222

23+
fn abiOffsetMismatch(comptime name: []const u8, comptime field: []const u8, comptime got: usize, comptime expected: usize) noreturn {
24+
@compileError(std.fmt.comptimePrint("{s}.{s} offset mismatch: got {d}, expected {d}", .{ name, field, got, expected }));
25+
}
26+
2327
fn expectAbi(comptime name: []const u8, comptime T: type, comptime U: type) void {
2428
if (@sizeOf(T) != @sizeOf(U)) abiMismatch(name, @sizeOf(T), @sizeOf(U));
2529
if (@alignOf(T) != @alignOf(U)) abiAlignMismatch(name, @alignOf(T), @alignOf(U));
2630
}
2731

32+
fn expectOffset(comptime name: []const u8, comptime field: []const u8, comptime got: usize, comptime expected: usize) void {
33+
if (got != expected) abiOffsetMismatch(name, field, got, expected);
34+
}
35+
2836
comptime {
2937
if (!builtin.target.os.tag.isDarwin()) @compileError("darwin_abi.zig only applies to Darwin targets");
3038

@@ -37,12 +45,19 @@ comptime {
3745
expectAbi("pthread_attr_t", c.pthread_attr_t, std.c.pthread_attr_t);
3846
expectAbi("pthread_mutex_t", c.pthread_mutex_t, std.c.pthread_mutex_t);
3947
expectAbi("pthread_cond_t", c.pthread_cond_t, std.c.pthread_cond_t);
48+
expectAbi("dev_t", c.dev_t, std.posix.dev_t);
4049
expectAbi("mode_t", c.mode_t, std.posix.mode_t);
4150
expectAbi("off_t", c.off_t, std.posix.off_t);
4251
expectAbi("time_t", c.time_t, std.posix.time_t);
4352
expectAbi("struct stat", c.struct_stat, std.c.Stat);
4453
expectAbi("struct timeval", c.struct_timeval, std.posix.timeval);
4554
expectAbi("struct sockaddr", c.struct_sockaddr, std.posix.sockaddr);
55+
expectOffset("struct sigaction", "sa_mask", @offsetOf(c.struct_sigaction, "sa_mask"), @offsetOf(std.c.Sigaction, "mask"));
56+
expectOffset("struct sigaction", "sa_flags", @offsetOf(c.struct_sigaction, "sa_flags"), @offsetOf(std.c.Sigaction, "flags"));
57+
expectOffset("struct timeval", "tv_sec", @offsetOf(c.struct_timeval, "tv_sec"), @offsetOf(std.posix.timeval, "sec"));
58+
expectOffset("struct timeval", "tv_usec", @offsetOf(c.struct_timeval, "tv_usec"), @offsetOf(std.posix.timeval, "usec"));
59+
expectOffset("struct stat", "st_size", @offsetOf(c.struct_stat, "st_size"), @offsetOf(std.c.Stat, "size"));
60+
expectOffset("struct stat", "st_mtimespec", @offsetOf(c.struct_stat, "st_mtimespec"), @offsetOf(std.c.Stat, "mtimespec"));
4661
}
4762

4863
pub fn main() void {}

0 commit comments

Comments
 (0)