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 {...@@ -14242,8 +14242,8 @@ fn timestampToPosix(nanoseconds: i96) posix.timespec {
1424214242
14243pub fn setTimestampToPosix(set_ts: File.SetTimestamp) posix.timespec {14243pub fn setTimestampToPosix(set_ts: File.SetTimestamp) posix.timespec {
14244 return switch (set_ts) {14244 return switch (set_ts) {
14245 .unchanged => .OMIT,14245 .unchanged => posix.UTIME.OMIT,
14246 .now => .NOW,14246 .now => posix.UTIME.NOW,
14247 .new => |t| timestampToPosix(t.nanoseconds),14247 .new => |t| timestampToPosix(t.nanoseconds),
14248 };14248 };
14249}14249}
lib/std/c.zig+36-86
...@@ -94,13 +94,36 @@ pub const off_t = switch (native_os) {...@@ -94,13 +94,36 @@ pub const off_t = switch (native_os) {
94 else => i64,94 else => i64,
95};95};
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
97pub const timespec = switch (native_os) {120pub const timespec = switch (native_os) {
98 .linux => linux.timespec,121 .linux => linux.timespec,
99 .emscripten => emscripten.timespec,122 .emscripten => emscripten.timespec,
100 // lib/libc/include/wasm-wasi-musl/__struct_timespec.h123 // lib/libc/include/wasm-wasi-musl/__struct_timespec.h
101 .wasi => extern struct {124 .wasi => extern struct {
102 sec: time_t,125 sec: time_t,
103 nsec: isize,126 nsec: c_long,
104127
105 pub fn fromTimestamp(tm: wasi.timestamp_t) timespec {128 pub fn fromTimestamp(tm: wasi.timestamp_t) timespec {
106 const sec: wasi.timestamp_t = tm / 1_000_000_000;129 const sec: wasi.timestamp_t = tm / 1_000_000_000;
...@@ -115,74 +138,12 @@ pub const timespec = switch (native_os) {...@@ -115,74 +138,12 @@ pub const timespec = switch (native_os) {
115 return @as(wasi.timestamp_t, @intCast(ts.sec * 1_000_000_000)) +138 return @as(wasi.timestamp_t, @intCast(ts.sec * 1_000_000_000)) +
116 @as(wasi.timestamp_t, @intCast(ts.nsec));139 @as(wasi.timestamp_t, @intCast(ts.nsec));
117 }140 }
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 };
132 },141 },
133 // https://github.com/SerenityOS/serenity/blob/0a78056453578c18e0a04a0b45ebfb1c96d59005/Kernel/API/POSIX/time.h#L17-L20142 // 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 {
135 sec: time_t,144 sec: time_t,
136 nsec: c_long,145 nsec: c_long,
137 },146 },
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 },
186 else => void,147 else => void,
187};148};
188149
...@@ -4128,7 +4089,7 @@ pub const in6_pktinfo = switch (native_os) {...@@ -4128,7 +4089,7 @@ pub const in6_pktinfo = switch (native_os) {
4128};4089};
4129pub const itimerspec = switch (native_os) {4090pub const itimerspec = switch (native_os) {
4130 .linux => linux.itimerspec,4091 .linux => linux.itimerspec,
4131 .haiku => extern struct {4092 .dragonfly, .freebsd, .netbsd, .openbsd, .haiku, .illumos, .windows, .wasi => extern struct {
4132 interval: timespec,4093 interval: timespec,
4133 value: timespec,4094 value: timespec,
4134 },4095 },
...@@ -7037,18 +6998,19 @@ pub const stack_t = switch (native_os) {...@@ -7037,18 +6998,19 @@ pub const stack_t = switch (native_os) {
7037};6998};
7038pub const time_t = switch (native_os) {6999pub const time_t = switch (native_os) {
7039 .linux => linux.time_t,7000 .linux => linux.time_t,
7001 .dragonfly, .illumos, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => c_long,
7040 .emscripten => emscripten.time_t,7002 .emscripten => emscripten.time_t,
7041 .haiku, .dragonfly => isize,7003 .freebsd, .haiku => if (native_arch == .x86) c_int else c_longlong,
7042 // lib/libc/include/wasm-wasi-musl/__typedef_time_t.h
7043 // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L477004 // 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,
7045};7008};
7046pub const suseconds_t = switch (native_os) {7009pub 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,
7047 // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L497012 // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L49
7048 .illumos, .serenity => i64,7013 .serenity, .wasi => c_longlong,
7049 .freebsd, .dragonfly => c_long,
7050 .netbsd => c_int,
7051 .haiku => i32,
7052 else => void,7014 else => void,
7053};7015};
70547016
...@@ -7059,32 +7021,20 @@ pub const timeval = switch (native_os) {...@@ -7059,32 +7021,20 @@ pub const timeval = switch (native_os) {
7059 sec: c_long,7021 sec: c_long,
7060 usec: c_long,7022 usec: c_long,
7061 },7023 },
7062 .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => extern struct {
7063 sec: c_long,
7064 usec: i32,
7065 },
7066 // https://github.com/SerenityOS/serenity/blob/6b6eca0631c893c5f8cfb8274cdfe18e2d0637c0/Kernel/API/POSIX/sys/time.h#L15-L187024 // 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 {
7068 /// seconds7026 /// seconds
7069 sec: time_t,7027 sec: time_t,
7070 /// microseconds7028 /// microseconds
7071 usec: suseconds_t,7029 usec: suseconds_t,
7072 },7030 },
7073 .openbsd => extern struct {
7074 sec: time_t,
7075 usec: c_long,
7076 },
7077 else => void,7031 else => void,
7078};7032};
7079pub const timezone = switch (native_os) {7033pub const timezone = switch (native_os) {
7080 .linux => linux.timezone,7034 .linux => linux.timezone,
7081 .emscripten => emscripten.timezone,7035 .emscripten => emscripten.timezone,
7082 .openbsd, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => extern struct {
7083 minuteswest: i32,
7084 dsttime: i32,
7085 },
7086 // https://github.com/SerenityOS/serenity/blob/ba776390b5878ec0be1a9e595a3471a6cfe0a0cf/Userland/Libraries/LibC/sys/time.h#L19-L227036 // 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 {
7088 minuteswest: c_int,7038 minuteswest: c_int,
7089 dsttime: c_int,7039 dsttime: c_int,
7090 },7040 },
lib/std/os/emscripten.zig+11-18
...@@ -730,7 +730,7 @@ pub const sockaddr = c.sockaddr;...@@ -730,7 +730,7 @@ pub const sockaddr = c.sockaddr;
730pub const blksize_t = i32;730pub const blksize_t = i32;
731pub const nlink_t = u32;731pub const nlink_t = u32;
732// https://github.com/emscripten-core/emscripten/blob/946ab574ae39401b51e75cd5257d894ae732ab54/system/lib/libc/musl/arch/emscripten/bits/alltypes.h#L140732// 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;
734pub const mode_t = u32;734pub const mode_t = u32;
735pub const off_t = i64;735pub const off_t = i64;
736pub const ino_t = u64;736pub const ino_t = u64;
...@@ -766,29 +766,22 @@ pub const stack_t = extern struct {...@@ -766,29 +766,22 @@ pub const stack_t = extern struct {
766 size: usize,766 size: usize,
767};767};
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
769// https://github.com/emscripten-core/emscripten/blob/946ab574ae39401b51e75cd5257d894ae732ab54/system/lib/libc/musl/arch/emscripten/bits/alltypes.h#L284776// https://github.com/emscripten-core/emscripten/blob/946ab574ae39401b51e75cd5257d894ae732ab54/system/lib/libc/musl/arch/emscripten/bits/alltypes.h#L284
770pub const timespec = extern struct {777pub const timespec = extern struct {
771 sec: time_t,778 sec: time_t,
772 nsec: isize,779 nsec: c_long,
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 };
787};780};
788781
789pub const timezone = extern struct {782pub const timezone = extern struct {
790 minuteswest: i32,783 minuteswest: c_int,
791 dsttime: i32,784 dsttime: c_int,
792};785};
793786
794pub const utsname = extern struct {787pub const utsname = extern struct {
lib/std/os/linux.zig+6-17
...@@ -5950,11 +5950,6 @@ pub const S = struct {...@@ -5950,11 +5950,6 @@ pub const S = struct {
5950 }5950 }
5951};5951};
59525952
5953pub const UTIME = struct {
5954 pub const NOW = 0x3fffffff;
5955 pub const OMIT = 0x3ffffffe;
5956};
5957
5958const TFD_TIMER = packed struct(u32) {5953const TFD_TIMER = packed struct(u32) {
5959 ABSTIME: bool = false,5954 ABSTIME: bool = false,
5960 CANCEL_ON_SET: bool = false,5955 CANCEL_ON_SET: bool = false,
...@@ -8705,22 +8700,16 @@ pub const kernel_timespec = extern struct {...@@ -8705,22 +8700,16 @@ pub const kernel_timespec = extern struct {
8705 };8700 };
8706};8701};
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
8708// https://github.com/ziglang/zig/issues/4726#issuecomment-21903378778709// https://github.com/ziglang/zig/issues/4726#issuecomment-2190337877
8709pub const timespec = if (native_arch == .hexagon or native_arch == .riscv32) kernel_timespec else extern struct {8710pub const timespec = if (native_arch == .hexagon or native_arch == .riscv32) kernel_timespec else extern struct {
8710 sec: isize,8711 sec: isize,
8711 nsec: isize,8712 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 };
8724};8713};
87258714
8726pub const XDP = struct {8715pub const XDP = struct {
lib/std/posix.zig+1
...@@ -174,6 +174,7 @@ pub const timespec = system.timespec;...@@ -174,6 +174,7 @@ pub const timespec = system.timespec;
174pub const timestamp_t = system.timestamp_t;174pub const timestamp_t = system.timestamp_t;
175pub const timeval = system.timeval;175pub const timeval = system.timeval;
176pub const timezone = system.timezone;176pub const timezone = system.timezone;
177pub const UTIME = system.UTIME;
177pub const uid_t = system.uid_t;178pub const uid_t = system.uid_t;
178pub const user_desc = system.user_desc;179pub const user_desc = system.user_desc;
179pub const utsname = system.utsname;180pub const utsname = system.utsname;