authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-03-24 09:20:32+01:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-03-24 09:42:32+01:00
log558a5c7913434547c55355af0075a9d34db0d4bc
tree51c561a2e6e8fc43676897f8788e5e80fa1acd17
parent0ee6a79da5a134a57d178edbe1acdd289470c909
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

std.c: audit some time types for non-Linux OSs

Some initial work towards https://codeberg.org/ziglang/zig/issues/31414. Conclusion from this: Only x86-freebsd, x86-haiku, and x86-illumos remain time32 and are currently unfixable. I don't think the upstreams for any of these targets actually care about them anymore (probably why they weren't migrated to time64), so this is not a particularly big concern. I split UTIME constants out from timespec because they were causing unreasonable code duplication by being there.

5 files changed, 56 insertions(+), 123 deletions(-)

lib/std/Io/Threaded.zig+2-2
......@@ -14242,8 +14242,8 @@ fn timestampToPosix(nanoseconds: i96) posix.timespec {
1424214242
1424314243pub fn setTimestampToPosix(set_ts: File.SetTimestamp) posix.timespec {
1424414244 return switch (set_ts) {
14245 .unchanged => .OMIT,
14246 .now => .NOW,
14245 .unchanged => posix.UTIME.OMIT,
14246 .now => posix.UTIME.NOW,
1424714247 .new => |t| timestampToPosix(t.nanoseconds),
1424814248 };
1424914249}
lib/std/c.zig+36-86
......@@ -94,13 +94,36 @@ pub const off_t = switch (native_os) {
9494 else => i64,
9595};
9696
97/// For use with `utimensat` and `futimens`.
98pub const UTIME = switch (native_os) {
99 .dragonfly, .freebsd, .illumos, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos, .wasi => struct {
100 pub const NOW: timespec = .{ .sec = 0, .nsec = -1 };
101 pub const OMIT: timespec = .{ .sec = 0, .nsec = -2 };
102 },
103 .emscripten => emscripten.UTIME,
104 .haiku => struct {
105 pub const NOW: timespec = .{ .sec = 0, .nsec = 1000000000 };
106 pub const OMIT: timespec = .{ .sec = 0, .nsec = 1000000001 };
107 },
108 .linux => linux.UTIME,
109 .netbsd => struct {
110 pub const NOW: timespec = .{ .sec = 0, .nsec = 0x3fffffff };
111 pub const OMIT: timespec = .{ .sec = 0, .nsec = 0x3ffffffe };
112 },
113 .openbsd, .serenity => struct {
114 pub const NOW: timespec = .{ .sec = 0, .nsec = -2 };
115 pub const OMIT: timespec = .{ .sec = 0, .nsec = -1 };
116 },
117 else => void,
118};
119
97120pub const timespec = switch (native_os) {
98121 .linux => linux.timespec,
99122 .emscripten => emscripten.timespec,
100123 // lib/libc/include/wasm-wasi-musl/__struct_timespec.h
101124 .wasi => extern struct {
102125 sec: time_t,
103 nsec: isize,
126 nsec: c_long,
104127
105128 pub fn fromTimestamp(tm: wasi.timestamp_t) timespec {
106129 const sec: wasi.timestamp_t = tm / 1_000_000_000;
......@@ -115,74 +138,12 @@ pub const timespec = switch (native_os) {
115138 return @as(wasi.timestamp_t, @intCast(ts.sec * 1_000_000_000)) +
116139 @as(wasi.timestamp_t, @intCast(ts.nsec));
117140 }
118
119 // lib/libc/include/wasm-wasi-musl/__header_sys_stat.h
120
121 /// For use with `utimensat` and `futimens`.
122 pub const NOW: timespec = .{
123 .sec = 0,
124 .nsec = -1,
125 };
126
127 /// For use with `utimensat` and `futimens`.
128 pub const OMIT: timespec = .{
129 .sec = 0,
130 .nsec = -2,
131 };
132141 },
133142 // https://github.com/SerenityOS/serenity/blob/0a78056453578c18e0a04a0b45ebfb1c96d59005/Kernel/API/POSIX/time.h#L17-L20
134 .windows, .serenity => extern struct {
143 .dragonfly, .freebsd, .netbsd, .openbsd, .illumos, .haiku, .serenity, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos, .windows => extern struct {
135144 sec: time_t,
136145 nsec: c_long,
137146 },
138 .dragonfly, .freebsd, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => extern struct {
139 sec: isize,
140 nsec: isize,
141
142 /// For use with `utimensat` and `futimens`.
143 pub const NOW: timespec = .{
144 .sec = 0,
145 .nsec = -1,
146 };
147
148 /// For use with `utimensat` and `futimens`.
149 pub const OMIT: timespec = .{
150 .sec = 0,
151 .nsec = -2,
152 };
153 },
154 .netbsd, .illumos => extern struct {
155 sec: i64,
156 nsec: isize,
157
158 /// For use with `utimensat` and `futimens`.
159 pub const NOW: timespec = .{
160 .sec = 0,
161 .nsec = 0x3fffffff,
162 };
163
164 /// For use with `utimensat` and `futimens`.
165 pub const OMIT: timespec = .{
166 .sec = 0,
167 .nsec = 0x3ffffffe,
168 };
169 },
170 .openbsd, .haiku => extern struct {
171 sec: time_t,
172 nsec: isize,
173
174 /// For use with `utimensat` and `futimens`.
175 pub const NOW: timespec = .{
176 .sec = 0, // ignored
177 .nsec = -2,
178 };
179
180 /// For use with `utimensat` and `futimens`.
181 pub const OMIT: timespec = .{
182 .sec = 0, // ignored
183 .nsec = -1,
184 };
185 },
186147 else => void,
187148};
188149
......@@ -4128,7 +4089,7 @@ pub const in6_pktinfo = switch (native_os) {
41284089};
41294090pub const itimerspec = switch (native_os) {
41304091 .linux => linux.itimerspec,
4131 .haiku => extern struct {
4092 .dragonfly, .freebsd, .netbsd, .openbsd, .haiku, .illumos, .windows, .wasi => extern struct {
41324093 interval: timespec,
41334094 value: timespec,
41344095 },
......@@ -7037,18 +6998,19 @@ pub const stack_t = switch (native_os) {
70376998};
70386999pub const time_t = switch (native_os) {
70397000 .linux => linux.time_t,
7001 .dragonfly, .illumos, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => c_long,
70407002 .emscripten => emscripten.time_t,
7041 .haiku, .dragonfly => isize,
7042 // lib/libc/include/wasm-wasi-musl/__typedef_time_t.h
7003 .freebsd, .haiku => if (native_arch == .x86) c_int else c_longlong,
70437004 // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L47
7044 else => i64,
7005 // lib/libc/include/wasm-wasi-musl/__typedef_time_t.h
7006 .netbsd, .openbsd, .serenity, .wasi => c_longlong,
7007 else => void,
70457008};
70467009pub const suseconds_t = switch (native_os) {
7010 .dragonfly, .freebsd, .openbsd, .illumos => c_long,
7011 .netbsd, .haiku, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => c_int,
70477012 // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L49
7048 .illumos, .serenity => i64,
7049 .freebsd, .dragonfly => c_long,
7050 .netbsd => c_int,
7051 .haiku => i32,
7013 .serenity, .wasi => c_longlong,
70527014 else => void,
70537015};
70547016
......@@ -7059,32 +7021,20 @@ pub const timeval = switch (native_os) {
70597021 sec: c_long,
70607022 usec: c_long,
70617023 },
7062 .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => extern struct {
7063 sec: c_long,
7064 usec: i32,
7065 },
70667024 // https://github.com/SerenityOS/serenity/blob/6b6eca0631c893c5f8cfb8274cdfe18e2d0637c0/Kernel/API/POSIX/sys/time.h#L15-L18
7067 .dragonfly, .netbsd, .freebsd, .illumos, .serenity => extern struct {
7025 .dragonfly, .freebsd, .netbsd, .openbsd, .haiku, .illumos, .serenity, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos, .wasi => extern struct {
70687026 /// seconds
70697027 sec: time_t,
70707028 /// microseconds
70717029 usec: suseconds_t,
70727030 },
7073 .openbsd => extern struct {
7074 sec: time_t,
7075 usec: c_long,
7076 },
70777031 else => void,
70787032};
70797033pub const timezone = switch (native_os) {
70807034 .linux => linux.timezone,
70817035 .emscripten => emscripten.timezone,
7082 .openbsd, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => extern struct {
7083 minuteswest: i32,
7084 dsttime: i32,
7085 },
70867036 // https://github.com/SerenityOS/serenity/blob/ba776390b5878ec0be1a9e595a3471a6cfe0a0cf/Userland/Libraries/LibC/sys/time.h#L19-L22
7087 .serenity => extern struct {
7037 .dragonfly, .freebsd, .netbsd, .openbsd, .haiku, .illumos, .serenity, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos, .windows, .wasi => extern struct {
70887038 minuteswest: c_int,
70897039 dsttime: c_int,
70907040 },
lib/std/os/emscripten.zig+11-18
......@@ -730,7 +730,7 @@ pub const sockaddr = c.sockaddr;
730730pub const blksize_t = i32;
731731pub const nlink_t = u32;
732732// https://github.com/emscripten-core/emscripten/blob/946ab574ae39401b51e75cd5257d894ae732ab54/system/lib/libc/musl/arch/emscripten/bits/alltypes.h#L140
733pub const time_t = i64;
733pub const time_t = c_longlong;
734734pub const mode_t = u32;
735735pub const off_t = i64;
736736pub const ino_t = u64;
......@@ -766,29 +766,22 @@ pub const stack_t = extern struct {
766766 size: usize,
767767};
768768
769/// For use with `utimensat` and `futimens`.
770// https://github.com/emscripten-core/emscripten/blob/d72d7226f4733af8ff993dec70198cf09a24142d/system/lib/libc/musl/include/sys/stat.h#L77-L78
771pub const UTIME = struct {
772 pub const NOW: timespec = .{ .sec = 0, .nsec = 0x3fffffff };
773 pub const OMIT: timespec = .{ .sec = 0, .nsec = 0x3ffffffe };
774};
775
769776// https://github.com/emscripten-core/emscripten/blob/946ab574ae39401b51e75cd5257d894ae732ab54/system/lib/libc/musl/arch/emscripten/bits/alltypes.h#L284
770777pub const timespec = extern struct {
771778 sec: time_t,
772 nsec: isize,
773
774 // https://github.com/emscripten-core/emscripten/blob/d72d7226f4733af8ff993dec70198cf09a24142d/system/lib/libc/musl/include/sys/stat.h#L77-L78
775
776 /// For use with `utimensat` and `futimens`.
777 pub const NOW: timespec = .{
778 .sec = 0,
779 .nsec = 0x3fffffff,
780 };
781
782 /// For use with `utimensat` and `futimens`.
783 pub const OMIT: timespec = .{
784 .sec = 0,
785 .nsec = 0x3ffffffe,
786 };
779 nsec: c_long,
787780};
788781
789782pub const timezone = extern struct {
790 minuteswest: i32,
791 dsttime: i32,
783 minuteswest: c_int,
784 dsttime: c_int,
792785};
793786
794787pub const utsname = extern struct {
lib/std/os/linux.zig+6-17
......@@ -5950,11 +5950,6 @@ pub const S = struct {
59505950 }
59515951};
59525952
5953pub const UTIME = struct {
5954 pub const NOW = 0x3fffffff;
5955 pub const OMIT = 0x3ffffffe;
5956};
5957
59585953const TFD_TIMER = packed struct(u32) {
59595954 ABSTIME: bool = false,
59605955 CANCEL_ON_SET: bool = false,
......@@ -8705,22 +8700,16 @@ pub const kernel_timespec = extern struct {
87058700 };
87068701};
87078702
8703/// For use with `utimensat` and `futimens`.
8704pub const UTIME = struct {
8705 pub const NOW: timespec = .{ .sec = 0, .nsec = 0x3fffffff };
8706 pub const OMIT: timespec = .{ .sec = 0, .nsec = 0x3ffffffe };
8707};
8708
87088709// https://github.com/ziglang/zig/issues/4726#issuecomment-2190337877
87098710pub const timespec = if (native_arch == .hexagon or native_arch == .riscv32) kernel_timespec else extern struct {
87108711 sec: isize,
87118712 nsec: isize,
8712
8713 /// For use with `utimensat` and `futimens`.
8714 pub const NOW: timespec = .{
8715 .sec = 0,
8716 .nsec = 0x3fffffff,
8717 };
8718
8719 /// For use with `utimensat` and `futimens`.
8720 pub const OMIT: timespec = .{
8721 .sec = 0,
8722 .nsec = 0x3ffffffe,
8723 };
87248713};
87258714
87268715pub const XDP = struct {
lib/std/posix.zig+1
......@@ -174,6 +174,7 @@ pub const timespec = system.timespec;
174174pub const timestamp_t = system.timestamp_t;
175175pub const timeval = system.timeval;
176176pub const timezone = system.timezone;
177pub const UTIME = system.UTIME;
177178pub const uid_t = system.uid_t;
178179pub const user_desc = system.user_desc;
179180pub const utsname = system.utsname;