diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/compiler/aro/aro/target.zig | 6 | ||||
| -rw-r--r-- | lib/compiler_rt/int_from_float.zig | 6 | ||||
| -rw-r--r-- | lib/compiler_rt/int_from_float_test.zig | 40 | ||||
| -rw-r--r-- | lib/std/Build/Cache.zig | 20 | ||||
| -rw-r--r-- | lib/std/Target.zig | 4 | ||||
| -rw-r--r-- | lib/std/Target/Query.zig | 2 | ||||
| -rw-r--r-- | lib/std/Thread.zig | 31 | ||||
| -rw-r--r-- | lib/std/array_list.zig | 132 | ||||
| -rw-r--r-- | lib/std/c.zig | 1012 | ||||
| -rw-r--r-- | lib/std/c/serenity.zig | 75 | ||||
| -rw-r--r-- | lib/std/crypto/Certificate.zig | 3 | ||||
| -rw-r--r-- | lib/std/crypto/Certificate/Bundle.zig | 16 | ||||
| -rw-r--r-- | lib/std/fs.zig | 8 | ||||
| -rw-r--r-- | lib/std/fs/get_app_data_dir.zig | 2 | ||||
| -rw-r--r-- | lib/std/fs/test.zig | 103 | ||||
| -rw-r--r-- | lib/std/io/test.zig | 16 | ||||
| -rw-r--r-- | lib/std/mem/Allocator.zig | 3 | ||||
| -rw-r--r-- | lib/std/multi_array_list.zig | 4 | ||||
| -rw-r--r-- | lib/std/os.zig | 3 | ||||
| -rw-r--r-- | lib/std/os/uefi.zig | 3 | ||||
| -rw-r--r-- | lib/std/os/uefi/status.zig | 46 | ||||
| -rw-r--r-- | lib/std/posix/test.zig | 343 | ||||
| -rw-r--r-- | lib/std/process.zig | 1 | ||||
| -rw-r--r-- | lib/std/time/epoch.zig | 15 | ||||
| -rw-r--r-- | lib/std/zig/system.zig | 4 | ||||
| -rw-r--r-- | lib/std/zig/target.zig | 11 |
26 files changed, 1483 insertions, 426 deletions
diff --git a/lib/compiler/aro/aro/target.zig b/lib/compiler/aro/aro/target.zig index 7495eb5d9a..bea982daa2 100644 --- a/lib/compiler/aro/aro/target.zig +++ b/lib/compiler/aro/aro/target.zig @@ -204,7 +204,7 @@ pub fn unnamedFieldAffectsAlignment(target: std.Target) bool { }, .armeb => { if (std.Target.arm.featureSetHas(target.cpu.features, .has_v7)) { - if (std.Target.Abi.default(target.cpu.arch, target.os) == .eabi) return true; + if (std.Target.Abi.default(target.cpu.arch, target.os.tag) == .eabi) return true; } }, .arm => return true, @@ -716,7 +716,7 @@ test "alignment functions - smoke test" { const x86 = std.Target.Cpu.Arch.x86_64; target.os = std.Target.Os.Tag.defaultVersionRange(.linux, x86, .none); target.cpu = std.Target.Cpu.baseline(x86, target.os); - target.abi = std.Target.Abi.default(x86, target.os); + target.abi = std.Target.Abi.default(x86, target.os.tag); try std.testing.expect(isTlsSupported(target)); try std.testing.expect(!ignoreNonZeroSizedBitfieldTypeAlignment(target)); @@ -729,7 +729,7 @@ test "alignment functions - smoke test" { const arm = std.Target.Cpu.Arch.arm; target.os = std.Target.Os.Tag.defaultVersionRange(.ios, arm, .none); target.cpu = std.Target.Cpu.baseline(arm, target.os); - target.abi = std.Target.Abi.default(arm, target.os); + target.abi = std.Target.Abi.default(arm, target.os.tag); try std.testing.expect(!isTlsSupported(target)); try std.testing.expect(ignoreNonZeroSizedBitfieldTypeAlignment(target)); diff --git a/lib/compiler_rt/int_from_float.zig b/lib/compiler_rt/int_from_float.zig index 7bbcd90893..0c2c73bb42 100644 --- a/lib/compiler_rt/int_from_float.zig +++ b/lib/compiler_rt/int_from_float.zig @@ -72,10 +72,12 @@ pub inline fn bigIntFromFloat(comptime signedness: std.builtin.Signedness, resul } }); const parts = math.frexp(a); - const exponent = @max(parts.exponent - significand_bits, 0); + const significand_bits_adjusted_to_handle_smin = @as(i32, significand_bits) + + @intFromBool(signedness == .signed and parts.exponent == 32 * result.len); + const exponent = @max(parts.exponent - significand_bits_adjusted_to_handle_smin, 0); const int: I = @intFromFloat(switch (exponent) { 0 => a, - else => math.ldexp(parts.significand, significand_bits), + else => math.ldexp(parts.significand, significand_bits_adjusted_to_handle_smin), }); switch (signedness) { .signed => { diff --git a/lib/compiler_rt/int_from_float_test.zig b/lib/compiler_rt/int_from_float_test.zig index e10ed1ec00..5305ecf2a0 100644 --- a/lib/compiler_rt/int_from_float_test.zig +++ b/lib/compiler_rt/int_from_float_test.zig @@ -24,6 +24,8 @@ const __fixdfdi = @import("fixdfdi.zig").__fixdfdi; const __fixunsdfdi = @import("fixunsdfdi.zig").__fixunsdfdi; const __fixdfti = @import("fixdfti.zig").__fixdfti; const __fixunsdfti = @import("fixunsdfti.zig").__fixunsdfti; +const __fixdfei = @import("fixdfei.zig").__fixdfei; +const __fixunsdfei = @import("fixunsdfei.zig").__fixunsdfei; // Conversion from f128 const __fixtfsi = @import("fixtfsi.zig").__fixtfsi; @@ -681,6 +683,44 @@ test "fixunsdfti" { try test__fixunsdfti(-0x1.FFFFFFFFFFFFEp+62, 0); } +fn test_fixdfei(comptime T: type, expected: T, a: f64) !void { + const int = @typeInfo(T).int; + var expected_buf: [@divExact(int.bits, 32)]u32 = undefined; + std.mem.writeInt(T, std.mem.asBytes(&expected_buf), expected, endian); + var actual_buf: [@divExact(int.bits, 32)]u32 = undefined; + _ = switch (int.signedness) { + .signed => __fixdfei, + .unsigned => __fixunsdfei, + }(&actual_buf, int.bits, a); + try testing.expect(std.mem.eql(u32, &expected_buf, &actual_buf)); +} + +test "fixdfei" { + try test_fixdfei(i256, -1 << 255, -0x1p255); + try test_fixdfei(i256, -1 << 127, -0x1p127); + try test_fixdfei(i256, -1 << 100, -0x1p100); + try test_fixdfei(i256, -1 << 50, -0x1p50); + try test_fixdfei(i256, -1 << 1, -0x1p1); + try test_fixdfei(i256, -1 << 0, -0x1p0); + try test_fixdfei(i256, 0, 0); + try test_fixdfei(i256, 1 << 0, 0x1p0); + try test_fixdfei(i256, 1 << 1, 0x1p1); + try test_fixdfei(i256, 1 << 50, 0x1p50); + try test_fixdfei(i256, 1 << 100, 0x1p100); + try test_fixdfei(i256, 1 << 127, 0x1p127); + try test_fixdfei(i256, 1 << 254, 0x1p254); +} + +test "fixundfei" { + try test_fixdfei(u256, 0, 0); + try test_fixdfei(u256, 1 << 0, 0x1p0); + try test_fixdfei(u256, 1 << 1, 0x1p1); + try test_fixdfei(u256, 1 << 50, 0x1p50); + try test_fixdfei(u256, 1 << 100, 0x1p100); + try test_fixdfei(u256, 1 << 127, 0x1p127); + try test_fixdfei(u256, 1 << 255, 0x1p255); +} + fn test__fixtfsi(a: f128, expected: i32) !void { const x = __fixtfsi(a); try testing.expect(x == expected); diff --git a/lib/std/Build/Cache.zig b/lib/std/Build/Cache.zig index 24edee37a8..932ec00517 100644 --- a/lib/std/Build/Cache.zig +++ b/lib/std/Build/Cache.zig @@ -1254,11 +1254,6 @@ fn testGetCurrentFileTimestamp(dir: fs.Dir) !i128 { } test "cache file and then recall it" { - if (builtin.os.tag == .wasi) { - // https://github.com/ziglang/zig/issues/5437 - return error.SkipZigTest; - } - var tmp = testing.tmpDir(.{}); defer tmp.cleanup(); @@ -1320,11 +1315,6 @@ test "cache file and then recall it" { } test "check that changing a file makes cache fail" { - if (builtin.os.tag == .wasi) { - // https://github.com/ziglang/zig/issues/5437 - return error.SkipZigTest; - } - var tmp = testing.tmpDir(.{}); defer tmp.cleanup(); @@ -1394,11 +1384,6 @@ test "check that changing a file makes cache fail" { } test "no file inputs" { - if (builtin.os.tag == .wasi) { - // https://github.com/ziglang/zig/issues/5437 - return error.SkipZigTest; - } - var tmp = testing.tmpDir(.{}); defer tmp.cleanup(); @@ -1442,11 +1427,6 @@ test "no file inputs" { } test "Manifest with files added after initial hash work" { - if (builtin.os.tag == .wasi) { - // https://github.com/ziglang/zig/issues/5437 - return error.SkipZigTest; - } - var tmp = testing.tmpDir(.{}); defer tmp.cleanup(); diff --git a/lib/std/Target.zig b/lib/std/Target.zig index 8e78e4dc29..79a78a41df 100644 --- a/lib/std/Target.zig +++ b/lib/std/Target.zig @@ -803,8 +803,8 @@ pub const Abi = enum { // - raygeneration // - vertex - pub fn default(arch: Cpu.Arch, os: Os) Abi { - return switch (os.tag) { + pub fn default(arch: Cpu.Arch, os_tag: Os.Tag) Abi { + return switch (os_tag) { .freestanding, .other => switch (arch) { // Soft float is usually a sane default for freestanding. .arm, diff --git a/lib/std/Target/Query.zig b/lib/std/Target/Query.zig index 2d5c734108..cf53a8175b 100644 --- a/lib/std/Target/Query.zig +++ b/lib/std/Target/Query.zig @@ -102,7 +102,7 @@ pub fn fromTarget(target: Target) Query { .os_version_min = undefined, .os_version_max = undefined, .abi = target.abi, - .glibc_version = target.os.versionRange().gnuLibCVersion(), + .glibc_version = if (target.abi.isGnu()) target.os.versionRange().gnuLibCVersion() else null, .android_api_level = if (target.abi.isAndroid()) target.os.version_range.linux.android else null, }; result.updateOsVersionRange(target.os); diff --git a/lib/std/Thread.zig b/lib/std/Thread.zig index 27b2b11c4a..fe3bf0fcea 100644 --- a/lib/std/Thread.zig +++ b/lib/std/Thread.zig @@ -122,6 +122,8 @@ pub const max_name_len = switch (native_os) { .openbsd => 23, .dragonfly => 1023, .solaris, .illumos => 31, + // https://github.com/SerenityOS/serenity/blob/6b4c300353da49d3508b5442cf61da70bd04d757/Kernel/Tasks/Thread.h#L102 + .serenity => 63, else => 0, }; @@ -201,6 +203,15 @@ pub fn setName(self: Thread, name: []const u8) SetNameError!void { else => |e| return posix.unexpectedErrno(e), } }, + .serenity => if (use_pthreads) { + const err = std.c.pthread_setname_np(self.getHandle(), name_with_terminator.ptr); + switch (@as(posix.E, @enumFromInt(err))) { + .SUCCESS => return, + .NAMETOOLONG => unreachable, + .SRCH => unreachable, + else => |e| return posix.unexpectedErrno(e), + } + }, .netbsd, .solaris, .illumos => if (use_pthreads) { const err = std.c.pthread_setname_np(self.getHandle(), name_with_terminator.ptr, null); switch (@as(posix.E, @enumFromInt(err))) { @@ -302,6 +313,16 @@ pub fn getName(self: Thread, buffer_ptr: *[max_name_len:0]u8) GetNameError!?[]co else => |e| return posix.unexpectedErrno(e), } }, + .serenity => if (use_pthreads) { + const err = std.c.pthread_getname_np(self.getHandle(), buffer.ptr, max_name_len + 1); + switch (@as(posix.E, @enumFromInt(err))) { + .SUCCESS => return, + .NAMETOOLONG => unreachable, + .SRCH => unreachable, + .FAULT => unreachable, + else => |e| return posix.unexpectedErrno(e), + } + }, .netbsd, .solaris, .illumos => if (use_pthreads) { const err = std.c.pthread_getname_np(self.getHandle(), buffer.ptr, max_name_len + 1); switch (@as(posix.E, @enumFromInt(err))) { @@ -342,6 +363,7 @@ pub const Id = switch (native_os) { .openbsd, .haiku, .wasi, + .serenity, => u32, .macos, .ios, .watchos, .tvos, .visionos => u64, .windows => windows.DWORD, @@ -692,6 +714,9 @@ const PosixThreadImpl = struct { .haiku => { return @as(u32, @bitCast(c.find_thread(null))); }, + .serenity => { + return @as(u32, @bitCast(c.pthread_self())); + }, else => { return @intFromPtr(c.pthread_self()); }, @@ -713,11 +738,11 @@ const PosixThreadImpl = struct { }; return @as(usize, @intCast(count)); }, - .solaris, .illumos => { + .solaris, .illumos, .serenity => { // The "proper" way to get the cpu count would be to query // /dev/kstat via ioctls, and traverse a linked list for each - // cpu. - const rc = c.sysconf(std.c._SC.NPROCESSORS_ONLN); + // cpu. (solaris, illumos) + const rc = c.sysconf(@intFromEnum(std.c._SC.NPROCESSORS_ONLN)); return switch (posix.errno(rc)) { .SUCCESS => @as(usize, @intCast(rc)), else => |err| posix.unexpectedErrno(err), diff --git a/lib/std/array_list.zig b/lib/std/array_list.zig index 7849e98b42..bedba88a73 100644 --- a/lib/std/array_list.zig +++ b/lib/std/array_list.zig @@ -50,19 +50,19 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { } /// Deinitialize with `deinit` or use `toOwnedSlice`. - pub fn init(allocator: Allocator) Self { + pub fn init(gpa: Allocator) Self { return Self{ .items = &[_]T{}, .capacity = 0, - .allocator = allocator, + .allocator = gpa, }; } /// Initialize with capacity to hold `num` elements. /// The resulting capacity will equal `num` exactly. /// Deinitialize with `deinit` or use `toOwnedSlice`. - pub fn initCapacity(allocator: Allocator, num: usize) Allocator.Error!Self { - var self = Self.init(allocator); + pub fn initCapacity(gpa: Allocator, num: usize) Allocator.Error!Self { + var self = Self.init(gpa); try self.ensureTotalCapacityPrecise(num); return self; } @@ -75,24 +75,24 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { } /// ArrayList takes ownership of the passed in slice. The slice must have been - /// allocated with `allocator`. + /// allocated with `gpa`. /// Deinitialize with `deinit` or use `toOwnedSlice`. - pub fn fromOwnedSlice(allocator: Allocator, slice: Slice) Self { + pub fn fromOwnedSlice(gpa: Allocator, slice: Slice) Self { return Self{ .items = slice, .capacity = slice.len, - .allocator = allocator, + .allocator = gpa, }; } /// ArrayList takes ownership of the passed in slice. The slice must have been - /// allocated with `allocator`. + /// allocated with `gpa`. /// Deinitialize with `deinit` or use `toOwnedSlice`. - pub fn fromOwnedSliceSentinel(allocator: Allocator, comptime sentinel: T, slice: [:sentinel]T) Self { + pub fn fromOwnedSliceSentinel(gpa: Allocator, comptime sentinel: T, slice: [:sentinel]T) Self { return Self{ .items = slice, .capacity = slice.len + 1, - .allocator = allocator, + .allocator = gpa, }; } @@ -646,9 +646,9 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ /// Initialize with capacity to hold `num` elements. /// The resulting capacity will equal `num` exactly. /// Deinitialize with `deinit` or use `toOwnedSlice`. - pub fn initCapacity(allocator: Allocator, num: usize) Allocator.Error!Self { + pub fn initCapacity(gpa: Allocator, num: usize) Allocator.Error!Self { var self = Self{}; - try self.ensureTotalCapacityPrecise(allocator, num); + try self.ensureTotalCapacityPrecise(gpa, num); return self; } @@ -664,19 +664,18 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ } /// Release all allocated memory. - pub fn deinit(self: *Self, allocator: Allocator) void { - allocator.free(self.allocatedSlice()); + pub fn deinit(self: *Self, gpa: Allocator) void { + gpa.free(self.allocatedSlice()); self.* = undefined; } /// Convert this list into an analogous memory-managed one. /// The returned list has ownership of the underlying memory. - pub fn toManaged(self: *Self, allocator: Allocator) ArrayListAligned(T, alignment) { - return .{ .items = self.items, .capacity = self.capacity, .allocator = allocator }; + pub fn toManaged(self: *Self, gpa: Allocator) ArrayListAligned(T, alignment) { + return .{ .items = self.items, .capacity = self.capacity, .allocator = gpa }; } - /// ArrayListUnmanaged takes ownership of the passed in slice. The slice must have been - /// allocated with `allocator`. + /// ArrayListUnmanaged takes ownership of the passed in slice. /// Deinitialize with `deinit` or use `toOwnedSlice`. pub fn fromOwnedSlice(slice: Slice) Self { return Self{ @@ -685,8 +684,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ }; } - /// ArrayListUnmanaged takes ownership of the passed in slice. The slice must have been - /// allocated with `allocator`. + /// ArrayListUnmanaged takes ownership of the passed in slice. /// Deinitialize with `deinit` or use `toOwnedSlice`. pub fn fromOwnedSliceSentinel(comptime sentinel: T, slice: [:sentinel]T) Self { return Self{ @@ -697,31 +695,31 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ /// The caller owns the returned memory. Empties this ArrayList. /// Its capacity is cleared, making deinit() safe but unnecessary to call. - pub fn toOwnedSlice(self: *Self, allocator: Allocator) Allocator.Error!Slice { + pub fn toOwnedSlice(self: *Self, gpa: Allocator) Allocator.Error!Slice { const old_memory = self.allocatedSlice(); - if (allocator.remap(old_memory, self.items.len)) |new_items| { + if (gpa.remap(old_memory, self.items.len)) |new_items| { self.* = .empty; return new_items; } - const new_memory = try allocator.alignedAlloc(T, alignment, self.items.len); + const new_memory = try gpa.alignedAlloc(T, alignment, self.items.len); @memcpy(new_memory, self.items); - self.clearAndFree(allocator); + self.clearAndFree(gpa); return new_memory; } /// The caller owns the returned memory. ArrayList becomes empty. - pub fn toOwnedSliceSentinel(self: *Self, allocator: Allocator, comptime sentinel: T) Allocator.Error!SentinelSlice(sentinel) { + pub fn toOwnedSliceSentinel(self: *Self, gpa: Allocator, comptime sentinel: T) Allocator.Error!SentinelSlice(sentinel) { // This addition can never overflow because `self.items` can never occupy the whole address space - try self.ensureTotalCapacityPrecise(allocator, self.items.len + 1); + try self.ensureTotalCapacityPrecise(gpa, self.items.len + 1); self.appendAssumeCapacity(sentinel); - const result = try self.toOwnedSlice(allocator); + const result = try self.toOwnedSlice(gpa); return result[0 .. result.len - 1 :sentinel]; } /// Creates a copy of this ArrayList. - pub fn clone(self: Self, allocator: Allocator) Allocator.Error!Self { - var cloned = try Self.initCapacity(allocator, self.capacity); + pub fn clone(self: Self, gpa: Allocator) Allocator.Error!Self { + var cloned = try Self.initCapacity(gpa, self.capacity); cloned.appendSliceAssumeCapacity(self.items); return cloned; } @@ -731,8 +729,8 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ /// This operation is O(N). /// Invalidates element pointers if additional memory is needed. /// Asserts that the index is in bounds or equal to the length. - pub fn insert(self: *Self, allocator: Allocator, i: usize, item: T) Allocator.Error!void { - const dst = try self.addManyAt(allocator, i, 1); + pub fn insert(self: *Self, gpa: Allocator, i: usize, item: T) Allocator.Error!void { + const dst = try self.addManyAt(gpa, i, 1); dst[0] = item; } @@ -759,11 +757,11 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ /// Asserts that the index is in bounds or equal to the length. pub fn addManyAt( self: *Self, - allocator: Allocator, + gpa: Allocator, index: usize, count: usize, ) Allocator.Error![]T { - var managed = self.toManaged(allocator); + var managed = self.toManaged(gpa); defer self.* = managed.moveToUnmanaged(); return managed.addManyAt(index, count); } @@ -795,12 +793,12 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ /// Asserts that the index is in bounds or equal to the length. pub fn insertSlice( self: *Self, - allocator: Allocator, + gpa: Allocator, index: usize, items: []const T, ) Allocator.Error!void { const dst = try self.addManyAt( - allocator, + gpa, index, items.len, ); @@ -812,7 +810,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ /// Asserts that the range is in bounds. pub fn replaceRange( self: *Self, - allocator: Allocator, + gpa: Allocator, start: usize, len: usize, new_items: []const T, @@ -823,7 +821,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ const first = new_items[0..range.len]; const rest = new_items[range.len..]; @memcpy(range[0..first.len], first); - try self.insertSlice(allocator, after_range, rest); + try self.insertSlice(gpa, after_range, rest); } else { self.replaceRangeAssumeCapacity(start, len, new_items); } @@ -859,8 +857,8 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ /// Extend the list by 1 element. Allocates more memory as necessary. /// Invalidates element pointers if additional memory is needed. - pub fn append(self: *Self, allocator: Allocator, item: T) Allocator.Error!void { - const new_item_ptr = try self.addOne(allocator); + pub fn append(self: *Self, gpa: Allocator, item: T) Allocator.Error!void { + const new_item_ptr = try self.addOne(gpa); new_item_ptr.* = item; } @@ -899,8 +897,8 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ /// Append the slice of items to the list. Allocates more /// memory as necessary. /// Invalidates element pointers if additional memory is needed. - pub fn appendSlice(self: *Self, allocator: Allocator, items: []const T) Allocator.Error!void { - try self.ensureUnusedCapacity(allocator, items.len); + pub fn appendSlice(self: *Self, gpa: Allocator, items: []const T) Allocator.Error!void { + try self.ensureUnusedCapacity(gpa, items.len); self.appendSliceAssumeCapacity(items); } @@ -918,8 +916,8 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ /// memory as necessary. Only call this function if a call to `appendSlice` instead would /// be a compile error. /// Invalidates element pointers if additional memory is needed. - pub fn appendUnalignedSlice(self: *Self, allocator: Allocator, items: []align(1) const T) Allocator.Error!void { - try self.ensureUnusedCapacity(allocator, items.len); + pub fn appendUnalignedSlice(self: *Self, gpa: Allocator, items: []align(1) const T) Allocator.Error!void { + try self.ensureUnusedCapacity(gpa, items.len); self.appendUnalignedSliceAssumeCapacity(items); } @@ -947,8 +945,8 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ std.io.Writer(WriterContext, Allocator.Error, appendWrite); /// Initializes a Writer which will append to the list. - pub fn writer(self: *Self, allocator: Allocator) Writer { - return .{ .context = .{ .self = self, .allocator = allocator } }; + pub fn writer(self: *Self, gpa: Allocator) Writer { + return .{ .context = .{ .self = self, .allocator = gpa } }; } /// Same as `append` except it returns the number of bytes written, @@ -983,9 +981,9 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ /// Invalidates element pointers if additional memory is needed. /// The function is inline so that a comptime-known `value` parameter will /// have a more optimal memset codegen in case it has a repeated byte pattern. - pub inline fn appendNTimes(self: *Self, allocator: Allocator, value: T, n: usize) Allocator.Error!void { + pub inline fn appendNTimes(self: *Self, gpa: Allocator, value: T, n: usize) Allocator.Error!void { const old_len = self.items.len; - try self.resize(allocator, try addOrOom(old_len, n)); + try self.resize(gpa, try addOrOom(old_len, n)); @memset(self.items[old_len..self.items.len], value); } @@ -1004,15 +1002,15 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ /// Adjust the list length to `new_len`. /// Additional elements contain the value `undefined`. /// Invalidates element pointers if additional memory is needed. - pub fn resize(self: *Self, allocator: Allocator, new_len: usize) Allocator.Error!void { - try self.ensureTotalCapacity(allocator, new_len); + pub fn resize(self: *Self, gpa: Allocator, new_len: usize) Allocator.Error!void { + try self.ensureTotalCapacity(gpa, new_len); self.items.len = new_len; } /// Reduce allocated capacity to `new_len`. /// May invalidate element pointers. /// Asserts that the new length is less than or equal to the previous length. - pub fn shrinkAndFree(self: *Self, allocator: Allocator, new_len: usize) void { + pub fn shrinkAndFree(self: *Self, gpa: Allocator, new_len: usize) void { assert(new_len <= self.items.len); if (@sizeOf(T) == 0) { @@ -1021,13 +1019,13 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ } const old_memory = self.allocatedSlice(); - if (allocator.remap(old_memory, new_len)) |new_items| { + if (gpa.remap(old_memory, new_len)) |new_items| { self.capacity = new_items.len; self.items = new_items; return; } - const new_memory = allocator.alignedAlloc(T, alignment, new_len) catch |e| switch (e) { + const new_memory = gpa.alignedAlloc(T, alignment, new_len) catch |e| switch (e) { error.OutOfMemory => { // No problem, capacity is still correct then. self.items.len = new_len; @@ -1036,7 +1034,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ }; @memcpy(new_memory, self.items[0..new_len]); - allocator.free(old_memory); + gpa.free(old_memory); self.items = new_memory; self.capacity = new_memory.len; } @@ -1056,8 +1054,8 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ } /// Invalidates all element pointers. - pub fn clearAndFree(self: *Self, allocator: Allocator) void { - allocator.free(self.allocatedSlice()); + pub fn clearAndFree(self: *Self, gpa: Allocator) void { + gpa.free(self.allocatedSlice()); self.items.len = 0; self.capacity = 0; } @@ -1073,7 +1071,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ /// If the current capacity is less than `new_capacity`, this function will /// modify the array so that it can hold exactly `new_capacity` items. /// Invalidates element pointers if additional memory is needed. - pub fn ensureTotalCapacityPrecise(self: *Self, allocator: Allocator, new_capacity: usize) Allocator.Error!void { + pub fn ensureTotalCapacityPrecise(self: *Self, gpa: Allocator, new_capacity: usize) Allocator.Error!void { if (@sizeOf(T) == 0) { self.capacity = math.maxInt(usize); return; @@ -1087,13 +1085,13 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ // the allocator implementation would pointlessly copy our // extra capacity. const old_memory = self.allocatedSlice(); - if (allocator.remap(old_memory, new_capacity)) |new_memory| { + if (gpa.remap(old_memory, new_capacity)) |new_memory| { self.items.ptr = new_memory.ptr; self.capacity = new_memory.len; } else { - const new_memory = try allocator.alignedAlloc(T, alignment, new_capacity); + const new_memory = try gpa.alignedAlloc(T, alignment, new_capacity); @memcpy(new_memory[0..self.items.len], self.items); - allocator.free(old_memory); + gpa.free(old_memory); self.items.ptr = new_memory.ptr; self.capacity = new_memory.len; } @@ -1103,10 +1101,10 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ /// Invalidates element pointers if additional memory is needed. pub fn ensureUnusedCapacity( self: *Self, - allocator: Allocator, + gpa: Allocator, additional_count: usize, ) Allocator.Error!void { - return self.ensureTotalCapacity(allocator, try addOrOom(self.items.len, additional_count)); + return self.ensureTotalCapacity(gpa, try addOrOom(self.items.len, additional_count)); } /// Increases the array's length to match the full capacity that is already allocated. @@ -1118,10 +1116,10 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ /// Increase length by 1, returning pointer to the new item. /// The returned element pointer becomes invalid when the list is resized. - pub fn addOne(self: *Self, allocator: Allocator) Allocator.Error!*T { + pub fn addOne(self: *Self, gpa: Allocator) Allocator.Error!*T { // This can never overflow because `self.items` can never occupy the whole address space const newlen = self.items.len + 1; - try self.ensureTotalCapacity(allocator, newlen); + try self.ensureTotalCapacity(gpa, newlen); return self.addOneAssumeCapacity(); } @@ -1139,9 +1137,9 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ /// Resize the array, adding `n` new elements, which have `undefined` values. /// The return value is an array pointing to the newly allocated elements. /// The returned pointer becomes invalid when the list is resized. - pub fn addManyAsArray(self: *Self, allocator: Allocator, comptime n: usize) Allocator.Error!*[n]T { + pub fn addManyAsArray(self: *Self, gpa: Allocator, comptime n: usize) Allocator.Error!*[n]T { const prev_len = self.items.len; - try self.resize(allocator, try addOrOom(self.items.len, n)); + try self.resize(gpa, try addOrOom(self.items.len, n)); return self.items[prev_len..][0..n]; } @@ -1161,9 +1159,9 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ /// The return value is a slice pointing to the newly allocated elements. /// The returned pointer becomes invalid when the list is resized. /// Resizes list if `self.capacity` is not large enough. - pub fn addManyAsSlice(self: *Self, allocator: Allocator, n: usize) Allocator.Error![]T { + pub fn addManyAsSlice(self: *Self, gpa: Allocator, n: usize) Allocator.Error![]T { const prev_len = self.items.len; - try self.resize(allocator, try addOrOom(self.items.len, n)); + try self.resize(gpa, try addOrOom(self.items.len, n)); return self.items[prev_len..][0..n]; } diff --git a/lib/std/c.zig b/lib/std/c.zig index 9b7d36cb32..53cd75f789 100644 --- a/lib/std/c.zig +++ b/lib/std/c.zig @@ -19,6 +19,7 @@ const netbsd = @import("c/netbsd.zig"); const dragonfly = @import("c/dragonfly.zig"); const haiku = @import("c/haiku.zig"); const openbsd = @import("c/openbsd.zig"); +const serenity = @import("c/serenity.zig"); // These constants are shared among all operating systems even when not linking // libc. @@ -75,12 +76,14 @@ pub const ino_t = switch (native_os) { .wasi => wasi.inode_t, .windows => windows.LARGE_INTEGER, .haiku => i64, + // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L38 else => u64, }; pub const off_t = switch (native_os) { .linux => linux.off_t, .emscripten => emscripten.off_t, + // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L39 else => i64, }; @@ -105,7 +108,8 @@ pub const timespec = switch (native_os) { @as(wasi.timestamp_t, @intCast(ts.nsec)); } }, - .windows => extern struct { + // https://github.com/SerenityOS/serenity/blob/0a78056453578c18e0a04a0b45ebfb1c96d59005/Kernel/API/POSIX/time.h#L17-L20 + .windows, .serenity => extern struct { sec: time_t, nsec: c_long, }, @@ -129,7 +133,8 @@ pub const dev_t = switch (native_os) { .emscripten => emscripten.dev_t, .wasi => wasi.device_t, .openbsd, .haiku, .solaris, .illumos, .macos, .ios, .tvos, .watchos, .visionos => i32, - .netbsd, .freebsd => u64, + // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L43 + .netbsd, .freebsd, .serenity => u64, else => void, }; @@ -137,7 +142,8 @@ pub const mode_t = switch (native_os) { .linux => linux.mode_t, .emscripten => emscripten.mode_t, .openbsd, .haiku, .netbsd, .solaris, .illumos, .wasi, .windows => u32, - .freebsd, .macos, .ios, .tvos, .watchos, .visionos, .dragonfly => u16, + // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L44 + .freebsd, .macos, .ios, .tvos, .watchos, .visionos, .dragonfly, .serenity => u16, else => u0, }; @@ -145,7 +151,8 @@ pub const nlink_t = switch (native_os) { .linux => linux.nlink_t, .emscripten => emscripten.nlink_t, .wasi => c_ulonglong, - .freebsd => u64, + // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L45 + .freebsd, .serenity => u64, .openbsd, .netbsd, .solaris, .illumos => u32, .haiku => i32, else => void, @@ -154,12 +161,14 @@ pub const nlink_t = switch (native_os) { pub const uid_t = switch (native_os) { .linux => linux.uid_t, .emscripten => emscripten.uid_t, + // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L28 else => u32, }; pub const gid_t = switch (native_os) { .linux => linux.gid_t, .emscripten => emscripten.gid_t, + // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L29 else => u32, }; @@ -167,11 +176,14 @@ pub const blksize_t = switch (native_os) { .linux => linux.blksize_t, .emscripten => emscripten.blksize_t, .wasi => c_long, + // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L42 + .serenity => u64, else => i32, }; pub const passwd = switch (native_os) { - .linux => extern struct { + // https://github.com/SerenityOS/serenity/blob/7442cfb5072b74a62c0e061e6e9ff44fda08780d/Userland/Libraries/LibC/pwd.h#L15-L23 + .linux, .serenity => extern struct { name: ?[*:0]const u8, // username passwd: ?[*:0]const u8, // user password uid: uid_t, // user ID @@ -199,6 +211,8 @@ pub const blkcnt_t = switch (native_os) { .linux => linux.blkcnt_t, .emscripten => emscripten.blkcnt_t, .wasi => c_longlong, + // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L41 + .serenity => u64, else => i64, }; @@ -206,6 +220,7 @@ pub const fd_t = switch (native_os) { .linux => linux.fd_t, .wasi => wasi.fd_t, .windows => windows.HANDLE, + .serenity => c_int, else => i32, }; @@ -309,6 +324,14 @@ pub const clockid_t = switch (native_os) { MONOTONIC = 3, THREAD_CPUTIME_ID = 4, }, + // https://github.com/SerenityOS/serenity/blob/0a78056453578c18e0a04a0b45ebfb1c96d59005/Kernel/API/POSIX/time.h#L24-L36 + .serenity => enum(c_int) { + REALTIME = 0, + MONOTONIC = 1, + MONOTONIC_RAW = 2, + REALTIME_COARSE = 3, + MONOTONIC_COARSE = 4, + }, else => void, }; pub const CPU_COUNT = switch (native_os) { @@ -681,6 +704,93 @@ pub const E = switch (native_os) { .dragonfly => dragonfly.E, .haiku => haiku.E, .openbsd => openbsd.E, + // https://github.com/SerenityOS/serenity/blob/dd59fe35c7e5bbaf6b6b3acb3f9edc56619d4b66/Kernel/API/POSIX/errno.h + .serenity => enum(c_int) { + SUCCESS = 0, + PERM = 1, + NOENT = 2, + SRCH = 3, + INTR = 4, + IO = 5, + NXIO = 6, + @"2BIG" = 7, + NOEXEC = 8, + BADF = 9, + CHILD = 10, + AGAIN = 11, + NOMEM = 12, + ACCES = 13, + FAULT = 14, + NOTBLK = 15, + BUSY = 16, + EXIST = 17, + XDEV = 18, + NODEV = 19, + NOTDIR = 20, + ISDIR = 21, + INVAL = 22, + NFILE = 23, + MFILE = 24, + NOTTY = 25, + TXTBSY = 26, + FBIG = 27, + NOSPC = 28, + SPIPE = 29, + ROFS = 30, + MLINK = 31, + PIPE = 32, + RANGE = 33, + NAMETOOLONG = 34, + LOOP = 35, + OVERFLOW = 36, + OPNOTSUPP = 37, + NOSYS = 38, + NOTIMPL = 39, + AFNOSUPPORT = 40, + NOTSOCK = 41, + ADDRINUSE = 42, + NOTEMPTY = 43, + DOM = 44, + CONNREFUSED = 45, + HOSTDOWN = 46, + ADDRNOTAVAIL = 47, + ISCONN = 48, + CONNABORTED = 49, + ALREADY = 50, + CONNRESET = 51, + DESTADDRREQ = 52, + HOSTUNREACH = 53, + ILSEQ = 54, + MSGSIZE = 55, + NETDOWN = 56, + NETUNREACH = 57, + NETRESET = 58, + NOBUFS = 59, + NOLCK = 60, + NOMSG = 61, + NOPROTOOPT = 62, + NOTCONN = 63, + SHUTDOWN = 64, + TOOMANYREFS = 65, + SOCKTNOSUPPORT = 66, + PROTONOSUPPORT = 67, + DEADLK = 68, + TIMEDOUT = 69, + PROTOTYPE = 70, + INPROGRESS = 71, + NOTHREAD = 72, + PROTO = 73, + NOTSUP = 74, + PFNOSUPPORT = 75, + DIRINTOSELF = 76, + DQUOT = 77, + NOTRECOVERABLE = 78, + CANCELED = 79, + PROMISEVIOLATION = 80, + STALE = 81, + SRCNOTFOUND = 82, + _, + }, else => void, }; pub const Elf_Symndx = switch (native_os) { @@ -1054,6 +1164,24 @@ pub const F = switch (native_os) { pub const UNLCK = 2; pub const WRLCK = 3; }, + .serenity => struct { + // https://github.com/SerenityOS/serenity/blob/2808b0376406a40e31293bb3bcb9170374e90506/Kernel/API/POSIX/fcntl.h#L15-L24 + pub const DUPFD = 0; + pub const GETFD = 1; + pub const SETFD = 2; + pub const GETFL = 3; + pub const SETFL = 4; + pub const ISTTY = 5; + pub const GETLK = 6; + pub const SETLK = 7; + pub const SETLKW = 8; + pub const DUPFD_CLOEXEC = 9; + + // https://github.com/SerenityOS/serenity/blob/2808b0376406a40e31293bb3bcb9170374e90506/Kernel/API/POSIX/fcntl.h#L45-L47 + pub const RDLCK = 0; + pub const WRLCK = 1; + pub const UNLCK = 2; + }, else => void, }; pub const FD_CLOEXEC = switch (native_os) { @@ -1129,18 +1257,29 @@ pub const Flock = switch (native_os) { len: off_t, pid: pid_t, }, + // https://github.com/SerenityOS/serenity/blob/2808b0376406a40e31293bb3bcb9170374e90506/Kernel/API/POSIX/fcntl.h#L54-L60 + .serenity => extern struct { + type: c_short, + whence: c_short, + start: off_t, + len: off_t, + pid: pid_t, + }, else => void, }; pub const HOST_NAME_MAX = switch (native_os) { .linux => linux.HOST_NAME_MAX, .macos, .ios, .tvos, .watchos, .visionos => 72, .openbsd, .haiku, .dragonfly, .netbsd, .solaris, .illumos, .freebsd => 255, + // https://github.com/SerenityOS/serenity/blob/c87557e9c1865fa1a6440de34ff6ce6fc858a2b7/Kernel/API/POSIX/sys/limits.h#L22 + .serenity => 64, else => {}, }; pub const IOV_MAX = switch (native_os) { .linux => linux.IOV_MAX, .emscripten => emscripten.IOV_MAX, - .openbsd, .haiku, .solaris, .illumos, .wasi => 1024, + // https://github.com/SerenityOS/serenity/blob/098af0f846a87b651731780ff48420205fd33754/Kernel/API/POSIX/sys/uio.h#L16 + .openbsd, .haiku, .solaris, .illumos, .wasi, .serenity => 1024, .macos, .ios, .tvos, .watchos, .visionos => 16, .dragonfly, .netbsd, .freebsd => KERN.IOV_MAX, else => {}, @@ -1425,6 +1564,16 @@ pub const MADV = switch (native_os) { pub const INVAL = 10; pub const SETMAP = 11; }, + // https://github.com/SerenityOS/serenity/blob/6d59d4d3d9e76e39112842ec487840828f1c9bfe/Kernel/API/POSIX/sys/mman.h#L35-L41 + .serenity => struct { + pub const NORMAL = 0x0; + pub const SET_VOLATILE = 0x1; + pub const SET_NONVOLATILE = 0x2; + pub const DONTNEED = 0x3; + pub const WILLNEED = 0x4; + pub const SEQUENTIAL = 0x5; + pub const RANDOM = 0x6; + }, else => void, }; pub const MSF = switch (native_os) { @@ -1444,6 +1593,12 @@ pub const MSF = switch (native_os) { pub const INVALIDATE = 2; pub const SYNC = 4; }, + // https://github.com/SerenityOS/serenity/blob/6d59d4d3d9e76e39112842ec487840828f1c9bfe/Kernel/API/POSIX/sys/mman.h#L50-L52 + .serenity => struct { + pub const SYNC = 1; + pub const ASYNC = 2; + pub const INVALIDATE = 4; + }, else => void, }; pub const MMAP2_UNIT = switch (native_os) { @@ -1456,7 +1611,8 @@ pub const NAME_MAX = switch (native_os) { // Haiku's headers make this 256, to contain room for the terminating null // character, but POSIX definition says that NAME_MAX does not include the // terminating null. - .haiku, .openbsd, .dragonfly, .netbsd, .solaris, .illumos, .freebsd, .macos, .ios, .tvos, .watchos, .visionos => 255, + // https://github.com/SerenityOS/serenity/blob/c87557e9c1865fa1a6440de34ff6ce6fc858a2b7/Kernel/API/POSIX/sys/limits.h#L20 + .haiku, .openbsd, .dragonfly, .netbsd, .solaris, .illumos, .freebsd, .macos, .ios, .tvos, .watchos, .visionos, .serenity => 255, else => {}, }; pub const PATH_MAX = switch (native_os) { @@ -1464,7 +1620,7 @@ pub const PATH_MAX = switch (native_os) { .emscripten => emscripten.PATH_MAX, .wasi => 4096, .windows => 260, - .openbsd, .haiku, .dragonfly, .netbsd, .solaris, .illumos, .freebsd, .macos, .ios, .tvos, .watchos, .visionos => 1024, + .openbsd, .haiku, .dragonfly, .netbsd, .solaris, .illumos, .freebsd, .macos, .ios, .tvos, .watchos, .visionos, .serenity => 1024, else => {}, }; @@ -1597,6 +1753,19 @@ pub const POLL = switch (native_os) { pub const RDBAND = 0x0080; pub const WRBAND = 0x0100; }, + // https://github.com/SerenityOS/serenity/blob/265764ff2fec038855193296588a887fc322d76a/Kernel/API/POSIX/poll.h#L15-L24 + .serenity => struct { + pub const IN = 0x0001; + pub const PRI = 0x0002; + pub const OUT = 0x0004; + pub const ERR = 0x0008; + pub const HUP = 0x0010; + pub const NVAL = 0x0020; + pub const RDNORM = IN; + pub const WRNORM = OUT; + pub const WRBAND = 0x1000; + pub const RDHUP = 0x2000; + }, else => void, }; @@ -1604,7 +1773,8 @@ pub const POLL = switch (native_os) { pub const PROT = switch (native_os) { .linux => linux.PROT, .emscripten => emscripten.PROT, - .openbsd, .haiku, .dragonfly, .netbsd, .solaris, .illumos, .freebsd, .windows => struct { + // https://github.com/SerenityOS/serenity/blob/6d59d4d3d9e76e39112842ec487840828f1c9bfe/Kernel/API/POSIX/sys/mman.h#L28-L31 + .openbsd, .haiku, .dragonfly, .netbsd, .solaris, .illumos, .freebsd, .windows, .serenity => struct { /// page can not be accessed pub const NONE = 0x0; /// page can be read @@ -1719,7 +1889,8 @@ pub const REG = switch (native_os) { pub const RLIM = switch (native_os) { .linux => linux.RLIM, .emscripten => emscripten.RLIM, - .openbsd, .haiku, .dragonfly, .netbsd, .freebsd, .macos, .ios, .tvos, .watchos, .visionos => struct { + // https://github.com/SerenityOS/serenity/blob/aae106e37b48f2158e68902293df1e4bf7b80c0f/Userland/Libraries/LibC/sys/resource.h#L52 + .openbsd, .haiku, .dragonfly, .netbsd, .freebsd, .macos, .ios, .tvos, .watchos, .visionos, .serenity => struct { /// No limit pub const INFINITY: rlim_t = (1 << 63) - 1; @@ -2174,6 +2345,66 @@ pub const S = switch (native_os) { return m & IFMT == IFSOCK; } }, + // https://github.com/SerenityOS/serenity/blob/ec492a1a0819e6239ea44156825c4ee7234ca3db/Kernel/API/POSIX/sys/stat.h#L16-L51 + .serenity => struct { + pub const IFMT = 0o170000; + pub const IFDIR = 0o040000; + pub const IFCHR = 0o020000; + pub const IFBLK = 0o060000; + pub const IFREG = 0o100000; + pub const IFIFO = 0o010000; + pub const IFLNK = 0o120000; + pub const IFSOCK = 0o140000; + + pub const ISUID = 0o4000; + pub const ISGID = 0o2000; + pub const ISVTX = 0o1000; + pub const IRUSR = 0o400; + pub const IWUSR = 0o200; + pub const IXUSR = 0o100; + pub const IREAD = IRUSR; + pub const IWRITE = IWUSR; + pub const IEXEC = IXUSR; + pub const IRGRP = 0o040; + pub const IWGRP = 0o020; + pub const IXGRP = 0o010; + pub const IROTH = 0o004; + pub const IWOTH = 0o002; + pub const IXOTH = 0o001; + + pub const IRWXU = IRUSR | IWUSR | IXUSR; + + pub const IRWXG = IRWXU >> 3; + pub const IRWXO = IRWXG >> 3; + + pub fn ISDIR(m: u32) bool { + return m & IFMT == IFDIR; + } + + pub fn ISCHR(m: u32) bool { + return m & IFMT == IFCHR; + } + + pub fn ISBLK(m: u32) bool { + return m & IFMT == IFBLK; + } + + pub fn ISREG(m: u32) bool { + return m & IFMT == IFREG; + } + + pub fn ISFIFO(m: u32) bool { + return m & IFMT == IFIFO; + } + + pub fn ISLNK(m: u32) bool { + return m & IFMT == IFLNK; + } + + pub fn ISSOCK(m: u32) bool { + return m & IFMT == IFSOCK; + } + }, else => void, }; pub const SA = switch (native_os) { @@ -2254,6 +2485,18 @@ pub const SA = switch (native_os) { pub const NOCLDWAIT = 0x0020; pub const SIGINFO = 0x0040; }, + // https://github.com/SerenityOS/serenity/blob/ec492a1a0819e6239ea44156825c4ee7234ca3db/Kernel/API/POSIX/signal.h#L65-L71 + .serenity => struct { + pub const NOCLDSTOP = 1; + pub const NOCLDWAIT = 2; + pub const SIGINFO = 4; + pub const ONSTACK = 0x08000000; + pub const RESTART = 0x10000000; + pub const NODEFER = 0x40000000; + pub const RESETHAND = 0x80000000; + pub const NOMASK = NODEFER; + pub const ONESHOT = RESETHAND; + }, else => void, }; pub const sigval_t = switch (native_os) { @@ -2269,7 +2512,10 @@ pub const SC = switch (native_os) { else => void, }; -pub const _SC = switch (native_os) { +pub const _SC = if (builtin.abi.isAndroid()) enum(c_int) { + PAGESIZE = 39, + NPROCESSORS_ONLN = 97, +} else switch (native_os) { .driverkit, .ios, .macos, .tvos, .visionos, .watchos => enum(c_int) { PAGESIZE = 29, }, @@ -2298,6 +2544,24 @@ pub const _SC = switch (native_os) { PAGESIZE = 11, NPROCESSORS_ONLN = 15, }, + // https://github.com/SerenityOS/serenity/blob/1dfc9e2df39dd23f1de92530677c845aae4345f2/Kernel/API/POSIX/unistd.h#L36-L52 + .serenity => enum(c_int) { + MONOTONIC_CLOCK = 0, + NPROCESSORS_CONF = 1, + NPROCESSORS_ONLN = 2, + OPEN_MAX = 3, + HOST_NAME_MAX = 4, + TTY_NAME_MAX = 5, + PAGESIZE = 6, + GETPW_R_SIZE_MAX = 7, + GETGR_R_SIZE_MAX = 8, + CLK_TCK = 9, + SYMLOOP_MAX = 10, + MAPPED_FILES = 11, + ARG_MAX = 12, + IOV_MAX = 13, + PHYS_PAGES = 14, + }, else => void, }; @@ -2309,7 +2573,8 @@ pub const SEEK = switch (native_os) { pub const CUR: wasi.whence_t = .CUR; pub const END: wasi.whence_t = .END; }, - .openbsd, .haiku, .netbsd, .freebsd, .macos, .ios, .tvos, .watchos, .visionos, .windows => struct { + // https://github.com/SerenityOS/serenity/blob/808ce594db1f2190e5212a250e900bde2ffe710b/Kernel/API/POSIX/stdio.h#L15-L17 + .openbsd, .haiku, .netbsd, .freebsd, .macos, .ios, .tvos, .watchos, .visionos, .windows, .serenity => struct { pub const SET = 0; pub const CUR = 1; pub const END = 2; @@ -2326,6 +2591,7 @@ pub const SEEK = switch (native_os) { pub const SHUT = switch (native_os) { .linux => linux.SHUT, .emscripten => emscripten.SHUT, + // https://github.com/SerenityOS/serenity/blob/ac44ec5ebc707f9dd0c3d4759a1e17e91db5d74f/Kernel/API/POSIX/sys/socket.h#L40-L42 else => struct { pub const RD = 0; pub const WR = 1; @@ -2785,6 +3051,42 @@ pub const SIG = switch (native_os) { pub const UNBLOCK = 2; pub const SETMASK = 3; }, + // https://github.com/SerenityOS/serenity/blob/046c23f567a17758d762a33bdf04bacbfd088f9f/Kernel/API/POSIX/signal_numbers.h + .serenity => struct { + pub const INVAL = 0; + pub const HUP = 1; + pub const INT = 2; + pub const QUIT = 3; + pub const ILL = 4; + pub const TRAP = 5; + pub const ABRT = 6; + pub const BUS = 7; + pub const FPE = 8; + pub const KILL = 9; + pub const USR1 = 10; + pub const SEGV = 11; + pub const USR2 = 12; + pub const PIPE = 13; + pub const ALRM = 14; + pub const TERM = 15; + pub const STKFLT = 16; + pub const CHLD = 17; + pub const CONT = 18; + pub const STOP = 19; + pub const TSTP = 20; + pub const TTIN = 21; + pub const TTOU = 22; + pub const URG = 23; + pub const XCPU = 24; + pub const XFSZ = 25; + pub const VTALRM = 26; + pub const PROF = 27; + pub const WINCH = 28; + pub const IO = 29; + pub const INFO = 30; + pub const SYS = 31; + pub const CANCEL = 32; + }, else => void, }; @@ -2792,6 +3094,8 @@ pub const SIOCGIFINDEX = switch (native_os) { .linux => linux.SIOCGIFINDEX, .emscripten => emscripten.SIOCGIFINDEX, .solaris, .illumos => solaris.SIOCGLIFINDEX, + // https://github.com/SerenityOS/serenity/blob/cb10f70394fb7e9cfc77f827adb2e46d199bc3a5/Kernel/API/Ioctl.h#L118 + .serenity => 34, else => void, }; @@ -2936,6 +3240,18 @@ pub const Sigaction = switch (native_os) { /// signal options flags: c_uint, }, + // https://github.com/SerenityOS/serenity/blob/ec492a1a0819e6239ea44156825c4ee7234ca3db/Kernel/API/POSIX/signal.h#L39-L46 + .serenity => extern struct { + pub const handler_fn = *align(1) const fn (c_int) callconv(.c) void; + pub const sigaction_fn = *const fn (c_int, *const siginfo_t, ?*anyopaque) callconv(.c) void; + + handler: extern union { + handler: ?handler_fn, + sigaction: ?sigaction_fn, + }, + mask: sigset_t, + flags: c_int, + }, else => void, }; pub const T = switch (native_os) { @@ -3311,6 +3627,22 @@ pub const T = switch (native_os) { pub const IOCGDRAINWAIT = 0x40047456; pub const IOCISPTMASTER = 0x20007455; }, + // https://github.com/SerenityOS/serenity/blob/cb10f70394fb7e9cfc77f827adb2e46d199bc3a5/Kernel/API/Ioctl.h#L84-L96 + .serenity => struct { + pub const IOCGPGRP = 0; + pub const IOCSPGRP = 1; + pub const CGETS = 2; + pub const CSETS = 3; + pub const CSETSW = 4; + pub const CSETSF = 5; + pub const CFLSH = 6; + pub const IOCGWINSZ = 7; + pub const IOCSCTTY = 8; + pub const IOCSTI = 9; + pub const IOCNOTTY = 10; + pub const IOCSWINSZ = 11; + pub const IOCGPTN = 12; + }, else => void, }; pub const IOCPARM_MASK = switch (native_os) { @@ -3546,6 +3878,43 @@ pub const W = switch (native_os) { return (((s) & 0o177) != 0o177) and (((s) & 0o177) != 0); } }, + // https://github.com/SerenityOS/serenity/blob/ec492a1a0819e6239ea44156825c4ee7234ca3db/Kernel/API/POSIX/sys/wait.h + .serenity => struct { + pub const NOHANG = 1; + pub const UNTRACED = 2; + pub const STOPPED = UNTRACED; + pub const EXITED = 4; + pub const CONTINUED = 8; + pub const NOWAIT = 0x1000000; + + pub fn EXITSTATUS(s: u32) u8 { + return @intCast((s & 0xff00) >> 8); + } + + pub fn STOPSIG(s: u32) u32 { + return EXITSTATUS(s); + } + + pub fn TERMSIG(s: u32) u32 { + return s & 0x7f; + } + + pub fn IFEXITED(s: u32) bool { + return TERMSIG(s) == 0; + } + + pub fn IFSTOPPED(s: u32) bool { + return (s & 0xff) == 0x7f; + } + + pub fn IFSIGNALED(s: u32) bool { + return (((s & 0x7f) + 1) >> 1) > 0; + } + + pub fn IFCONTINUED(s: u32) bool { + return s == 0xffff; + } + }, else => void, }; pub const clock_t = switch (native_os) { @@ -3556,6 +3925,8 @@ pub const clock_t = switch (native_os) { .openbsd, .solaris, .illumos => i64, .netbsd => u32, .haiku => i32, + // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L50 + .serenity => u64, else => void, }; pub const cpu_set_t = switch (native_os) { @@ -3568,7 +3939,7 @@ pub const dl_phdr_info = switch (native_os) { .emscripten => emscripten.dl_phdr_info, .freebsd => extern struct { /// Module relocation base. - addr: if (builtin.target.ptrBitWidth() == 32) std.elf.Elf32_Addr else std.elf.Elf64_Addr, + addr: std.elf.Addr, /// Module name. name: ?[*:0]const u8, /// Pointer to module's phdr. @@ -3592,11 +3963,12 @@ pub const dl_phdr_info = switch (native_os) { /// Incremented when an object is unmapped from the process. subs: u64, }, - .openbsd, .haiku, .dragonfly, .netbsd => extern struct { + // https://github.com/SerenityOS/serenity/blob/45d81dceed81df0c8ef75b440b20cc0938195faa/Userland/Libraries/LibC/link.h#L15-L20 + .openbsd, .haiku, .dragonfly, .netbsd, .serenity => extern struct { addr: usize, name: ?[*:0]const u8, phdr: [*]std.elf.Phdr, - phnum: u16, + phnum: std.elf.Half, }, else => void, }; @@ -3608,6 +3980,26 @@ pub const ifreq = switch (native_os) { .linux => linux.ifreq, .emscripten => emscripten.ifreq, .solaris, .illumos => lifreq, + // https://github.com/SerenityOS/serenity/blob/9882848e0bf783dfc8e8a6d887a848d70d9c58f4/Kernel/API/POSIX/net/if.h#L49-L82 + .serenity => extern struct { + // Not actually in a union, but the stdlib expects one for ifreq + ifrn: extern union { + name: [IFNAMESIZE]u8, + }, + ifru: extern union { + addr: sockaddr, + dstaddr: sockaddr, + broadaddr: sockaddr, + netmask: sockaddr, + hwaddr: sockaddr, + flags: c_short, + metric: c_int, + vnetid: i64, + media: u64, + data: ?*anyopaque, + index: c_uint, + }, + }, else => void, }; pub const itimerspec = switch (native_os) { @@ -3650,6 +4042,16 @@ pub const msghdr = switch (native_os) { /// flags on received message flags: i32, }, + // https://github.com/SerenityOS/serenity/blob/ac44ec5ebc707f9dd0c3d4759a1e17e91db5d74f/Kernel/API/POSIX/sys/socket.h#L74-L82 + .serenity => extern struct { + name: ?*anyopaque, + namelen: socklen_t, + iov: [*]iovec, + iovlen: c_int, + control: ?*anyopaque, + controllen: socklen_t, + flags: c_int, + }, else => void, }; pub const msghdr_const = switch (native_os) { @@ -3684,6 +4086,15 @@ pub const msghdr_const = switch (native_os) { /// flags on received message flags: i32, }, + .serenity => extern struct { + name: ?*const anyopaque, + namelen: socklen_t, + iov: [*]const iovec, + iovlen: c_int, + control: ?*const anyopaque, + controllen: socklen_t, + flags: c_int, + }, else => void, }; pub const nfds_t = switch (native_os) { @@ -3692,6 +4103,8 @@ pub const nfds_t = switch (native_os) { .haiku, .solaris, .illumos, .wasi => usize, .windows => c_ulong, .openbsd, .dragonfly, .netbsd, .freebsd, .macos, .ios, .tvos, .watchos, .visionos => u32, + // https://github.com/SerenityOS/serenity/blob/265764ff2fec038855193296588a887fc322d76a/Kernel/API/POSIX/poll.h#L32 + .serenity => c_uint, else => void, }; pub const perf_event_attr = switch (native_os) { @@ -3702,12 +4115,20 @@ pub const pid_t = switch (native_os) { .linux => linux.pid_t, .emscripten => emscripten.pid_t, .windows => windows.HANDLE, + // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L31-L32 + .serenity => c_int, else => i32, }; pub const pollfd = switch (native_os) { .linux => linux.pollfd, .emscripten => emscripten.pollfd, .windows => ws2_32.pollfd, + // https://github.com/SerenityOS/serenity/blob/265764ff2fec038855193296588a887fc322d76a/Kernel/API/POSIX/poll.h#L26-L30 + .serenity => extern struct { + fd: fd_t, + events: c_short, + revents: c_short, + }, else => extern struct { fd: fd_t, events: i16, @@ -3719,11 +4140,14 @@ pub const rlim_t = switch (native_os) { .emscripten => emscripten.rlim_t, .openbsd, .netbsd, .solaris, .illumos, .macos, .ios, .tvos, .watchos, .visionos => u64, .haiku, .dragonfly, .freebsd => i64, + // https://github.com/SerenityOS/serenity/blob/aae106e37b48f2158e68902293df1e4bf7b80c0f/Userland/Libraries/LibC/sys/resource.h#L54 + .serenity => usize, else => void, }; pub const rlimit = switch (native_os) { .linux, .emscripten => linux.rlimit, .windows => void, + // https://github.com/SerenityOS/serenity/blob/aae106e37b48f2158e68902293df1e4bf7b80c0f/Userland/Libraries/LibC/sys/resource.h#L56-L59 else => extern struct { /// Soft limit cur: rlim_t, @@ -3825,6 +4249,17 @@ pub const rlimit_resource = switch (native_os) { NOVMON = 7, _, }, + // https://github.com/SerenityOS/serenity/blob/aae106e37b48f2158e68902293df1e4bf7b80c0f/Userland/Libraries/LibC/sys/resource.h#L42-L48 + .serenity => enum(c_int) { + CORE = 1, + CPU = 2, + DATA = 3, + FSIZE = 4, + NOFILE = 5, + STACK = 6, + AS = 7, + _, + }, else => void, }; pub const rusage = switch (native_os) { @@ -3873,6 +4308,28 @@ pub const rusage = switch (native_os) { pub const CHILDREN = -1; pub const THREAD = 1; }, + // https://github.com/SerenityOS/serenity/blob/aae106e37b48f2158e68902293df1e4bf7b80c0f/Userland/Libraries/LibC/sys/resource.h#L18-L38 + .serenity => extern struct { + utime: timeval, + stime: timeval, + maxrss: c_long, + ixrss: c_long, + idrss: c_long, + isrss: c_long, + minflt: c_long, + majflt: c_long, + nswap: c_long, + inblock: c_long, + oublock: c_long, + msgsnd: c_long, + msgrcv: c_long, + nsignals: c_long, + nvcsw: c_long, + nivcsw: c_long, + + pub const SELF = 1; + pub const CHILDREN = 2; + }, else => void, }; @@ -4050,12 +4507,25 @@ pub const siginfo_t = switch (native_os) { assert(@sizeOf(@This()) == 136); } }, + // https://github.com/SerenityOS/serenity/blob/ec492a1a0819e6239ea44156825c4ee7234ca3db/Kernel/API/POSIX/signal.h#L27-L37 + .serenity => extern struct { + signo: c_int, + code: c_int, + errno: c_int, + pid: pid_t, + uid: uid_t, + addr: ?*anyopaque, + status: c_int, + band: c_int, + value: sigval, + }, else => void, }; pub const sigset_t = switch (native_os) { .linux => linux.sigset_t, .emscripten => emscripten.sigset_t, - .openbsd, .macos, .ios, .tvos, .watchos, .visionos => u32, + // https://github.com/SerenityOS/serenity/blob/ec492a1a0819e6239ea44156825c4ee7234ca3db/Kernel/API/POSIX/signal.h#L19 + .openbsd, .macos, .ios, .tvos, .watchos, .visionos, .serenity => u32, .dragonfly, .netbsd, .solaris, .illumos, .freebsd => extern struct { __bits: [SIG.WORDS]u32, }, @@ -4075,7 +4545,8 @@ pub const filled_sigset = switch (native_os) { }; pub const sigval = switch (native_os) { .linux => linux.sigval, - .openbsd, .dragonfly, .freebsd => extern union { + // https://github.com/SerenityOS/serenity/blob/ec492a1a0819e6239ea44156825c4ee7234ca3db/Kernel/API/POSIX/signal.h#L22-L25 + .openbsd, .dragonfly, .freebsd, .serenity => extern union { int: c_int, ptr: ?*anyopaque, }, @@ -4144,7 +4615,8 @@ pub const addrinfo = if (builtin.abi.isAndroid()) extern struct { addr: ?*sockaddr, next: ?*addrinfo, }, - .openbsd => extern struct { + // https://github.com/SerenityOS/serenity/blob/d510d2aeb2facbd8f6c383d70fd1b033e1fee5dd/Userland/Libraries/LibC/netdb.h#L66-L75 + .openbsd, .serenity => extern struct { flags: AI, family: c_int, socktype: c_int, @@ -4460,11 +4932,41 @@ pub const sockaddr = switch (native_os) { path: [104]u8, }; }, + // https://github.com/SerenityOS/serenity/blob/ac44ec5ebc707f9dd0c3d4759a1e17e91db5d74f/Kernel/API/POSIX/sys/socket.h#L110-L114 + .serenity => extern struct { + family: sa_family_t, + data: [26]u8, + + // https://github.com/SerenityOS/serenity/blob/ec492a1a0819e6239ea44156825c4ee7234ca3db/Kernel/API/POSIX/netinet/in.h + const in_addr = u32; + const in6_addr = [16]u8; + pub const in = extern struct { + family: sa_family_t = AF.INET, + port: in_port_t, + addr: in_addr, + zero: [8]u8 = @splat(0), + }; + pub const in6 = extern struct { + family: sa_family_t = AF.INET6, + port: in_port_t, + flowinfo: u32, + addr: in6_addr, + scope_id: u32, + }; + + // https://github.com/SerenityOS/serenity/blob/b92e6b02e53b2927732f31b1442cad420b62d1ef/Kernel/API/POSIX/sys/un.h + const UNIX_PATH_MAX = 108; + pub const un = extern struct { + family: sa_family_t = AF.LOCAL, + path: [UNIX_PATH_MAX]u8, + }; + }, else => void, }; pub const socklen_t = switch (native_os) { .linux, .emscripten => linux.socklen_t, .windows => ws2_32.socklen_t, + // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L57 else => u32, }; pub const in_port_t = u16; @@ -4472,7 +4974,8 @@ pub const sa_family_t = switch (native_os) { .linux, .emscripten => linux.sa_family_t, .windows => ws2_32.ADDRESS_FAMILY, .openbsd, .haiku, .dragonfly, .netbsd, .freebsd, .macos, .ios, .tvos, .watchos, .visionos => u8, - .solaris, .illumos => u16, + // https://github.com/SerenityOS/serenity/blob/ac44ec5ebc707f9dd0c3d4759a1e17e91db5d74f/Kernel/API/POSIX/sys/socket.h#L66 + .solaris, .illumos, .serenity => u16, else => void, }; pub const AF = if (builtin.abi.isAndroid()) struct { @@ -4751,6 +5254,15 @@ pub const AF = if (builtin.abi.isAndroid()) struct { pub const ISDN = 26; pub const MAX = 36; }, + // https://github.com/SerenityOS/serenity/blob/ac44ec5ebc707f9dd0c3d4759a1e17e91db5d74f/Kernel/API/POSIX/sys/socket.h#L17-L22 + .serenity => struct { + pub const UNSPEC = 0; + pub const LOCAL = 1; + pub const UNIX = LOCAL; + pub const INET = 2; + pub const INET6 = 3; + pub const MAX = 4; + }, else => void, }; pub const PF = if (builtin.abi.isAndroid()) struct { @@ -5020,11 +5532,21 @@ pub const PF = if (builtin.abi.isAndroid()) struct { pub const ISDN = AF.ISDN; pub const MAX = AF.MAX; }, + // https://github.com/SerenityOS/serenity/blob/ac44ec5ebc707f9dd0c3d4759a1e17e91db5d74f/Kernel/API/POSIX/sys/socket.h#L24-L29 + .serenity => struct { + pub const LOCAL = AF.LOCAL; + pub const UNIX = AF.LOCAL; + pub const INET = AF.INET; + pub const INET6 = AF.INET6; + pub const UNSPEC = AF.UNSPEC; + pub const MAX = AF.MAX; + }, else => void, }; pub const DT = switch (native_os) { .linux => linux.DT, - .netbsd, .freebsd, .macos, .ios, .tvos, .watchos, .visionos => struct { + // https://github.com/SerenityOS/serenity/blob/1262a7d1424d0d2e89d80644409721cbf056ab17/Kernel/API/POSIX/dirent.h#L16-L35 + .netbsd, .freebsd, .openbsd, .macos, .ios, .tvos, .watchos, .visionos, .serenity => struct { pub const UNKNOWN = 0; pub const FIFO = 1; pub const CHR = 2; @@ -5047,17 +5569,6 @@ pub const DT = switch (native_os) { pub const WHT = 14; pub const DBF = 15; }, - .openbsd => struct { - pub const UNKNOWN = 0; - pub const FIFO = 1; - pub const CHR = 2; - pub const DIR = 4; - pub const BLK = 6; - pub const REG = 8; - pub const LNK = 10; - pub const SOCK = 12; - pub const WHT = 14; // XXX - }, else => void, }; pub const MSG = switch (native_os) { @@ -5078,6 +5589,18 @@ pub const MSG = switch (native_os) { pub const EOF = 0x0400; pub const NOSIGNAL = 0x0800; }, + // https://github.com/SerenityOS/serenity/blob/ac44ec5ebc707f9dd0c3d4759a1e17e91db5d74f/Kernel/API/POSIX/sys/socket.h#L56-L64 + .serenity => struct { + pub const TRUNC = 0x1; + pub const CTRUNC = 0x2; + pub const PEEK = 0x4; + pub const OOB = 0x8; + pub const DONTROUTE = 0x10; + pub const WAITALL = 0x20; + pub const DONTWAIT = 0x40; + pub const NOSIGNAL = 0x80; + pub const EOR = 0x100; + }, else => void, }; pub const SOCK = switch (native_os) { @@ -5168,6 +5691,17 @@ pub const SOCK = switch (native_os) { pub const CLOEXEC = 0x8000; pub const NONBLOCK = 0x4000; }, + // https://github.com/SerenityOS/serenity/blob/ac44ec5ebc707f9dd0c3d4759a1e17e91db5d74f/Kernel/API/POSIX/sys/socket.h#L31-L38 + .serenity => struct { + pub const STREAM = 1; + pub const DGRAM = 2; + pub const RAW = 3; + pub const RDM = 4; + pub const SEQPACKET = 5; + + pub const NONBLOCK = 0o4000; + pub const CLOEXEC = 0o2000000; + }, else => void, }; pub const TCP = switch (native_os) { @@ -5175,6 +5709,11 @@ pub const TCP = switch (native_os) { .linux => linux.TCP, .emscripten => emscripten.TCP, .windows => ws2_32.TCP, + // https://github.com/SerenityOS/serenity/blob/61ac554a3403838f79ca746bd1c65ded6f97d124/Kernel/API/POSIX/netinet/tcp.h#L13-L14 + .serenity => struct { + pub const NODELAY = 10; + pub const MAXSEG = 11; + }, else => void, }; pub const IPPROTO = switch (native_os) { @@ -5759,6 +6298,20 @@ pub const IPPROTO = switch (native_os) { /// raw IP packet pub const RAW = 255; }, + // https://github.com/SerenityOS/serenity/blob/ac44ec5ebc707f9dd0c3d4759a1e17e91db5d74f/Kernel/API/POSIX/sys/socket.h#L44-L54 + .serenity => struct { + pub const IP = 0; + pub const ICMP = 1; + pub const IGMP = 2; + pub const IPIP = 4; + pub const TCP = 6; + pub const UDP = 17; + pub const IPV6 = 41; + pub const ESP = 50; + pub const AH = 51; + pub const ICMPV6 = 58; + pub const RAW = 255; + }, else => void, }; pub const SOL = switch (native_os) { @@ -5774,6 +6327,10 @@ pub const SOL = switch (native_os) { pub const PACKET = 0xfffd; pub const FILTER = 0xfffc; }, + // https://github.com/SerenityOS/serenity/blob/ac44ec5ebc707f9dd0c3d4759a1e17e91db5d74f/Kernel/API/POSIX/sys/socket.h#L127 + .serenity => struct { + pub const SOCKET = 1; + }, else => void, }; pub const SO = switch (native_os) { @@ -5991,12 +6548,35 @@ pub const SO = switch (native_os) { pub const DOMAIN = 0x1024; pub const PROTOCOL = 0x1025; }, + // https://github.com/SerenityOS/serenity/blob/ac44ec5ebc707f9dd0c3d4759a1e17e91db5d74f/Kernel/API/POSIX/sys/socket.h#L130-L150 + .serenity => struct { + pub const RCVTIMEO = 0; + pub const SNDTIMEO = 1; + pub const TYPE = 2; + pub const ERROR = 3; + pub const PEERCRED = 4; + pub const RCVBUF = 5; + pub const SNDBUF = 6; + pub const DEBUG = 7; + pub const REUSEADDR = 8; + pub const BINDTODEVICE = 9; + pub const KEEPALIVE = 10; + pub const TIMESTAMP = 11; + pub const BROADCAST = 12; + pub const LINGER = 13; + pub const ACCEPTCONN = 14; + pub const DONTROUTE = 15; + pub const OOBINLINE = 16; + pub const SNDLOWAT = 17; + pub const RCVLOWAT = 18; + }, else => void, }; pub const SOMAXCONN = switch (native_os) { .linux => linux.SOMAXCONN, .windows => ws2_32.SOMAXCONN, - .solaris, .illumos => 128, + // https://github.com/SerenityOS/serenity/blob/ac44ec5ebc707f9dd0c3d4759a1e17e91db5d74f/Kernel/API/POSIX/sys/socket.h#L128 + .solaris, .illumos, .serenity => 128, .openbsd => 28, else => void, }; @@ -6004,7 +6584,8 @@ pub const IFNAMESIZE = switch (native_os) { .linux => linux.IFNAMESIZE, .emscripten => emscripten.IFNAMESIZE, .windows => 30, - .openbsd, .dragonfly, .netbsd, .freebsd, .macos, .ios, .tvos, .watchos, .visionos => 16, + // https://github.com/SerenityOS/serenity/blob/9882848e0bf783dfc8e8a6d887a848d70d9c58f4/Kernel/API/POSIX/net/if.h#L50 + .openbsd, .dragonfly, .netbsd, .freebsd, .macos, .ios, .tvos, .watchos, .visionos, .serenity => 16, .solaris, .illumos => 32, else => void, }; @@ -6020,6 +6601,12 @@ pub const stack_t = switch (native_os) { /// SS_DISABLE and/or SS_ONSTACK. flags: i32, }, + // https://github.com/SerenityOS/serenity/blob/ec492a1a0819e6239ea44156825c4ee7234ca3db/Kernel/API/POSIX/signal.h#L48-L52 + .serenity => extern struct { + sp: *anyopaque, + flags: c_int, + size: usize, + }, else => extern struct { sp: [*]u8, size: isize, @@ -6030,10 +6617,12 @@ pub const time_t = switch (native_os) { .linux => linux.time_t, .emscripten => emscripten.time_t, .haiku, .dragonfly => isize, + // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L47 else => i64, }; pub const suseconds_t = switch (native_os) { - .solaris, .illumos => i64, + // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L49 + .solaris, .illumos, .serenity => i64, .freebsd, .dragonfly => c_long, .netbsd => c_int, .haiku => i32, @@ -6051,7 +6640,8 @@ pub const timeval = switch (native_os) { sec: c_long, usec: i32, }, - .dragonfly, .netbsd, .freebsd, .solaris, .illumos => extern struct { + // https://github.com/SerenityOS/serenity/blob/6b6eca0631c893c5f8cfb8274cdfe18e2d0637c0/Kernel/API/POSIX/sys/time.h#L15-L18 + .dragonfly, .netbsd, .freebsd, .solaris, .illumos, .serenity => extern struct { /// seconds sec: time_t, /// microseconds @@ -6070,6 +6660,11 @@ pub const timezone = switch (native_os) { minuteswest: i32, dsttime: i32, }, + // https://github.com/SerenityOS/serenity/blob/ba776390b5878ec0be1a9e595a3471a6cfe0a0cf/Userland/Libraries/LibC/sys/time.h#L19-L22 + .serenity => extern struct { + minuteswest: c_int, + dsttime: c_int, + }, else => void, }; @@ -6127,7 +6722,8 @@ pub const ucontext_t = switch (native_os) { arg: ?*void, _spare: [4]c_int, }, - .haiku => extern struct { + // https://github.com/SerenityOS/serenity/blob/87eac0e424cff4a1f941fb704b9362a08654c24d/Kernel/API/POSIX/ucontext.h#L19-L24 + .haiku, .serenity => extern struct { link: ?*ucontext_t, sigmask: sigset_t, stack: stack_t, @@ -6222,6 +6818,47 @@ pub const mcontext_t = switch (native_os) { }, .dragonfly => dragonfly.mcontext_t, .haiku => haiku.mcontext_t, + .serenity => switch (native_arch) { + // https://github.com/SerenityOS/serenity/blob/200e91cd7f1ec5453799a2720d4dc114a59cc289/Kernel/Arch/aarch64/mcontext.h#L15-L19 + .aarch64 => extern struct { + x: [31]u64, + sp: u64, + pc: u64, + }, + // https://github.com/SerenityOS/serenity/blob/66f8d0f031ef25c409dbb4fecaa454800fecae0f/Kernel/Arch/riscv64/mcontext.h#L15-L18 + .riscv64 => extern struct { + x: [31]u64, + pc: u64, + }, + // https://github.com/SerenityOS/serenity/blob/7b9ea3efdec9f86a1042893e8107d0b23aad8727/Kernel/Arch/x86_64/mcontext.h#L15-L40 + .x86_64 => extern struct { + rax: u64, + rcx: u64, + rdx: u64, + rbx: u64, + rsp: u64, + rbp: u64, + rsi: u64, + rdi: u64, + rip: u64, + r8: u64, + r9: u64, + r10: u64, + r11: u64, + r12: u64, + r13: u64, + r14: u64, + r15: u64, + rflags: u64, + cs: u32, + ss: u32, + ds: u32, + es: u32, + fs: u32, + gs: u32, + }, + else => struct {}, + }, else => void, }; @@ -6247,6 +6884,16 @@ pub const utsname = switch (native_os) { version: [256:0]u8, machine: [256:0]u8, }, + // https://github.com/SerenityOS/serenity/blob/d794ed1de7a46482272683f8dc4c858806390f29/Kernel/API/POSIX/sys/utsname.h#L17-L23 + .serenity => extern struct { + sysname: [UTSNAME_ENTRY_LEN:0]u8, + nodename: [UTSNAME_ENTRY_LEN:0]u8, + release: [UTSNAME_ENTRY_LEN:0]u8, + version: [UTSNAME_ENTRY_LEN:0]u8, + machine: [UTSNAME_ENTRY_LEN:0]u8, + + const UTSNAME_ENTRY_LEN = 65; + }, else => void, }; pub const PR = switch (native_os) { @@ -6265,6 +6912,8 @@ pub const _errno = switch (native_os) { .solaris, .illumos => private.___errno, .openbsd, .netbsd => private.__errno, .haiku => haiku._errnop, + // https://github.com/SerenityOS/serenity/blob/a353ceecf13b6f156a078e32f1ddf1d21366934c/Userland/Libraries/LibC/errno.h#L33 + .serenity => private.__errno_location, else => {}, }; @@ -6340,6 +6989,16 @@ pub const RTLD = switch (native_os) { FIRST: bool = false, _: u23 = 0, }, + // https://github.com/SerenityOS/serenity/blob/36a26d7fa80bc9c72b19442912d8967f448368ff/Userland/Libraries/LibC/dlfcn.h#L13-L17 + .serenity => packed struct(c_int) { + DEFAULT: bool = false, + _1: u1, + LAZY: bool = false, + NOW: bool = false, + GLOBAL: bool = false, + LOCAL: bool = false, + _: std.meta.Int(.unsigned, @bitSizeOf(c_int) - 6) = 0, + }, else => void, }; @@ -6413,11 +7072,20 @@ pub const dirent = switch (native_os) { _: u32 align(1) = 0, name: [MAXNAMLEN:0]u8, }, + // https://github.com/SerenityOS/serenity/blob/abc150085f532f123b598949218893cb272ccc4c/Userland/Libraries/LibC/dirent.h#L14-L20 + .serenity => extern struct { + ino: ino_t, + off: off_t, + reclen: c_ushort, + type: u8, + name: [256:0]u8, + }, else => void, }; pub const MAXNAMLEN = switch (native_os) { .netbsd, .solaris, .illumos => 511, - .haiku => NAME_MAX, + // https://github.com/SerenityOS/serenity/blob/1262a7d1424d0d2e89d80644409721cbf056ab17/Kernel/API/POSIX/dirent.h#L37 + .haiku, .serenity => NAME_MAX, .openbsd => 255, else => {}, }; @@ -6499,6 +7167,17 @@ pub const AI = if (builtin.abi.isAndroid()) packed struct(u32) { _: u19 = 0, }, .windows => ws2_32.AI, + // https://github.com/SerenityOS/serenity/blob/d510d2aeb2facbd8f6c383d70fd1b033e1fee5dd/Userland/Libraries/LibC/netdb.h#L90-L96 + .serenity => packed struct(c_int) { + PASSIVE: bool = false, + CANONNAME: bool = false, + NUMERICHOST: bool = false, + NUMERICSERV: bool = false, + V4MAPPED: bool = false, + ALL: bool = false, + ADDRCONFIG: bool = false, + _: std.meta.Int(.unsigned, @bitSizeOf(c_int) - 7) = 0, + }, else => void, }; @@ -6523,6 +7202,15 @@ pub const NI = switch (native_os) { NUMERICSCOPE: bool = false, _: u25 = 0, }, + // https://github.com/SerenityOS/serenity/blob/d510d2aeb2facbd8f6c383d70fd1b033e1fee5dd/Userland/Libraries/LibC/netdb.h#L101-L105 + .serenity => packed struct(c_int) { + NUMERICHOST: bool = false, + NUMERICSERV: bool = false, + NAMEREQD: bool = false, + NOFQDN: bool = false, + DGRAM: bool = false, + _: std.meta.Int(.unsigned, @bitSizeOf(c_int) - 5) = 0, + }, else => void, }; @@ -6675,6 +7363,22 @@ pub const EAI = if (builtin.abi.isAndroid()) enum(c_int) { OVERFLOW = -14, _, }, + // https://github.com/SerenityOS/serenity/blob/d510d2aeb2facbd8f6c383d70fd1b033e1fee5dd/Userland/Libraries/LibC/netdb.h#L77-L88 + .serenity => enum(c_int) { + ADDRFAMILY = 1, + AGAIN = 2, + BADFLAGS = 3, + FAIL = 4, + FAMILY = 5, + MEMORY = 6, + NODATA = 7, + NONAME = 8, + SERVICE = 9, + SOCKTYPE = 10, + SYSTEM = 11, + OVERFLOW = 12, + _, + }, else => void, }; @@ -7097,6 +7801,34 @@ pub const Stat = switch (native_os) { return self.birthtim; } }, + // https://github.com/SerenityOS/serenity/blob/ec492a1a0819e6239ea44156825c4ee7234ca3db/Kernel/API/POSIX/sys/stat.h#L53-L67 + .serenity => extern struct { + dev: dev_t, + ino: ino_t, + mode: mode_t, + nlink: nlink_t, + uid: uid_t, + gid: gid_t, + rdev: dev_t, + size: off_t, + blksize: blksize_t, + blocks: blkcnt_t, + atim: timespec, + mtim: timespec, + ctim: timespec, + + pub fn atime(self: @This()) timespec { + return self.atim; + } + + pub fn mtime(self: @This()) timespec { + return self.mtim; + } + + pub fn ctime(self: @This()) timespec { + return self.ctim; + } + }, else => void, }; @@ -7159,6 +7891,13 @@ pub const pthread_mutex_t = switch (native_os) { .emscripten => extern struct { data: [24]u8 align(4) = [_]u8{0} ** 24, }, + // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L68-L73 + .serenity => extern struct { + lock: u32 = 0, + owner: pthread_t = 0, + level: c_int = 0, + type: c_int = 0, + }, else => void, }; @@ -7201,6 +7940,12 @@ pub const pthread_cond_t = switch (native_os) { .fuchsia, .emscripten => extern struct { data: [48]u8 align(@alignOf(usize)) = [_]u8{0} ** 48, }, + // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L80-L84 + .serenity => extern struct { + mutex: ?*pthread_mutex_t = null, + value: u32 = 0, + clockid: clockid_t = .REALTIME_COARSE, + }, else => void, }; @@ -7258,6 +8003,10 @@ pub const pthread_rwlock_t = switch (native_os) { .emscripten => extern struct { size: [32]u8 align(4) = [_]u8{0} ** 32, }, + // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L86 + .serenity => extern struct { + inner: u64 = 0, + }, else => void, }; @@ -7270,7 +8019,8 @@ pub const pthread_attr_t = switch (native_os) { __sig: c_long, __opaque: [56]u8, }, - .freebsd => extern struct { + // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L75 + .freebsd, .openbsd, .serenity => extern struct { inner: ?*anyopaque = null, }, .solaris, .illumos => extern struct { @@ -7288,16 +8038,14 @@ pub const pthread_attr_t = switch (native_os) { guard_size: i32, stack_address: ?*anyopaque, }, - .openbsd => extern struct { - inner: ?*anyopaque = null, - }, else => void, }; pub const pthread_key_t = switch (native_os) { .linux, .emscripten => c_uint, .macos, .ios, .tvos, .watchos, .visionos => c_ulong, - .openbsd, .solaris, .illumos => c_int, + // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L65 + .openbsd, .solaris, .illumos, .serenity => c_int, else => void, }; @@ -7353,6 +8101,12 @@ pub const sem_t = switch (native_os) { }, padding: [2]i32, }, + // https://github.com/SerenityOS/serenity/blob/aae106e37b48f2158e68902293df1e4bf7b80c0f/Userland/Libraries/LibC/semaphore.h#L23-L27 + .serenity => extern struct { + magic: u32, + value: u32, + flags: u8, + }, else => void, }; @@ -7556,6 +8310,13 @@ pub const AT = switch (native_os) { /// file. pub const FDCWD: fd_t = if (builtin.link_libc) -2 else 3; }, + // https://github.com/SerenityOS/serenity/blob/2808b0376406a40e31293bb3bcb9170374e90506/Kernel/API/POSIX/fcntl.h#L49-L52 + .serenity => struct { + pub const FDCWD = -100; + pub const SYMLINK_NOFOLLOW = 0x100; + pub const REMOVEDIR = 0x200; + pub const EACCESS = 0x400; + }, else => void, }; @@ -7771,6 +8532,23 @@ pub const O = switch (native_os) { TMPFILE: bool = false, _: u9 = 0, }, + // https://github.com/SerenityOS/serenity/blob/2808b0376406a40e31293bb3bcb9170374e90506/Kernel/API/POSIX/fcntl.h#L28-L43 + .serenity => packed struct(c_int) { + ACCMODE: std.posix.ACCMODE = .RDONLY, + EXEC: bool = false, + CREAT: bool = false, + EXCL: bool = false, + NOCTTY: bool = false, + TRUNC: bool = false, + APPEND: bool = false, + NONBLOCK: bool = false, + DIRECTORY: bool = false, + NOFOLLOW: bool = false, + CLOEXEC: bool = false, + DIRECT: bool = false, + SYNC: bool = false, + _: std.meta.Int(.unsigned, @bitSizeOf(c_int) - 14) = 0, + }, else => void, }; @@ -7910,6 +8688,21 @@ pub const MAP = switch (native_os) { @"32BIT": bool = false, _: u12 = 0, }, + // https://github.com/SerenityOS/serenity/blob/6d59d4d3d9e76e39112842ec487840828f1c9bfe/Kernel/API/POSIX/sys/mman.h#L16-L26 + .serenity => packed struct(c_int) { + FILE: bool = false, + SHARED: bool = false, + PRIVATE: bool = false, + _3: u2 = 0, + FIXED: bool = false, + ANONYMOUS: bool = false, + STACK: bool = false, + NORESERVE: bool = false, + RANDOMIZED: bool = false, + PURGEABLE: bool = false, + FIXED_NOREPLACE: bool = false, + _: std.meta.Int(.unsigned, @bitSizeOf(c_int) - 12) = 0, + }, else => void, }; @@ -8020,6 +8813,27 @@ pub const V = switch (native_os) { LNEXT, EOL2, }, + // https://github.com/SerenityOS/serenity/blob/d277cdfd4c7ed21d5248a83217ae03b9f890c3c8/Kernel/API/POSIX/termios.h#L32-L49 + .serenity => enum { + INTR, + QUIT, + ERASE, + KILL, + EOF, + TIME, + MIN, + SWTC, + START, + STOP, + SUSP, + EOL, + REPRINT, + DISCARD, + WERASE, + LNEXT, + EOL2, + INFO, + }, else => void, }; @@ -8028,7 +8842,8 @@ pub const NCCS = switch (native_os) { .macos, .ios, .tvos, .watchos, .visionos, .freebsd, .netbsd, .openbsd, .dragonfly => 20, .haiku => 11, .solaris, .illumos => 19, - .emscripten, .wasi => 32, + // https://github.com/SerenityOS/serenity/blob/d277cdfd4c7ed21d5248a83217ae03b9f890c3c8/Kernel/API/POSIX/termios.h#L15 + .emscripten, .wasi, .serenity => 32, else => void, }; @@ -8043,7 +8858,8 @@ pub const termios = switch (native_os) { ispeed: speed_t align(8), ospeed: speed_t, }, - .freebsd, .netbsd, .dragonfly, .openbsd => extern struct { + // https://github.com/SerenityOS/serenity/blob/d277cdfd4c7ed21d5248a83217ae03b9f890c3c8/Kernel/API/POSIX/termios.h#L21-L29 + .freebsd, .netbsd, .dragonfly, .openbsd, .serenity => extern struct { iflag: tc_iflag_t, oflag: tc_oflag_t, cflag: tc_cflag_t, @@ -8171,7 +8987,8 @@ pub const tc_iflag_t = switch (native_os) { DOSMODE: bool = false, _: u16 = 0, }, - .emscripten, .wasi => packed struct(u32) { + // https://github.com/SerenityOS/serenity/blob/d277cdfd4c7ed21d5248a83217ae03b9f890c3c8/Kernel/API/POSIX/termios.h#L52-L66 + .emscripten, .wasi, .serenity => packed struct(u32) { IGNBRK: bool = false, BRKINT: bool = false, IGNPAR: bool = false, @@ -8263,7 +9080,8 @@ pub const tc_oflag_t = switch (native_os) { WRAP: bool = false, _: u14 = 0, }, - .haiku, .wasi, .emscripten => packed struct(u32) { + // https://github.com/SerenityOS/serenity/blob/d277cdfd4c7ed21d5248a83217ae03b9f890c3c8/Kernel/API/POSIX/termios.h#L69-L97 + .haiku, .wasi, .emscripten, .serenity => packed struct(u32) { OPOST: bool = false, OLCUC: bool = false, ONLCR: bool = false, @@ -8422,6 +9240,19 @@ pub const tc_cflag_t = switch (native_os) { CLOCAL: bool = false, _: u20 = 0, }, + // https://github.com/SerenityOS/serenity/blob/d277cdfd4c7ed21d5248a83217ae03b9f890c3c8/Kernel/API/POSIX/termios.h#L131-L141 + .serenity => packed struct(u32) { + _0: u4 = 0, + CSIZE: CSIZE = .CS5, + CSTOPB: bool = false, + CREAD: bool = false, + PARENB: bool = false, + PARODD: bool = false, + HUPCL: bool = false, + CLOCAL: bool = false, + CBAUDEX: bool = false, + _: u19 = 0, + }, else => void, }; @@ -8548,6 +9379,27 @@ pub const tc_lflag_t = switch (native_os) { IEXTEN: bool = false, _: u16 = 0, }, + // https://github.com/SerenityOS/serenity/blob/d277cdfd4c7ed21d5248a83217ae03b9f890c3c8/Kernel/API/POSIX/termios.h#L168-L189 + .serenity => packed struct(u32) { + ISIG: bool = false, + ICANON: bool = false, + XCASE: bool = false, + ECHO: bool = false, + ECHOE: bool = false, + ECHOK: bool = false, + ECHONL: bool = false, + NOFLSH: bool = false, + TOSTOP: bool = false, + ECHOCTL: bool = false, + ECHOPRT: bool = false, + ECHOKE: bool = false, + FLUSHO: bool = false, + PENDIN: bool = false, + _14: u6 = 0, + IEXTEN: bool = false, + EXTPROC: bool = false, + _: u15 = 0, + }, else => void, }; @@ -8696,7 +9548,8 @@ pub const speed_t = switch (native_os) { B3500000 = 30, B4000000 = 31, }, - .emscripten, .wasi => enum(u32) { + // https://github.com/SerenityOS/serenity/blob/d277cdfd4c7ed21d5248a83217ae03b9f890c3c8/Kernel/API/POSIX/termios.h#L111-L159 + .emscripten, .wasi, .serenity => enum(u32) { B0 = 0o0000000, B50 = 0o0000001, B75 = 0o0000002, @@ -8735,7 +9588,11 @@ pub const speed_t = switch (native_os) { pub const whence_t = if (native_os == .wasi) std.os.wasi.whence_t else c_int; -pub const sig_atomic_t = c_int; +pub const sig_atomic_t = switch (native_os) { + // https://github.com/SerenityOS/serenity/blob/ec492a1a0819e6239ea44156825c4ee7234ca3db/Kernel/API/POSIX/signal.h#L20 + .serenity => u32, + else => c_int, +}; /// maximum signal number + 1 pub const NSIG = switch (native_os) { @@ -8744,7 +9601,8 @@ pub const NSIG = switch (native_os) { .haiku => 65, .netbsd, .freebsd => 32, .solaris, .illumos => 75, - .openbsd => 33, + // https://github.com/SerenityOS/serenity/blob/046c23f567a17758d762a33bdf04bacbfd088f9f/Kernel/API/POSIX/signal_numbers.h#L42 + .openbsd, .serenity => 33, else => {}, }; @@ -8758,6 +9616,8 @@ pub const MINSIGSTKSZ = switch (native_os) { .solaris, .illumos => 2048, .haiku, .netbsd => 8192, .openbsd => 1 << openbsd.MAX_PAGE_SHIFT, + // https://github.com/SerenityOS/serenity/blob/ec492a1a0819e6239ea44156825c4ee7234ca3db/Kernel/API/POSIX/signal.h#L58 + .serenity => 4096, else => {}, }; pub const SIGSTKSZ = switch (native_os) { @@ -8766,6 +9626,8 @@ pub const SIGSTKSZ = switch (native_os) { .solaris, .illumos => 8192, .haiku => 16384, .openbsd => MINSIGSTKSZ + (1 << openbsd.MAX_PAGE_SHIFT) * 4, + // https://github.com/SerenityOS/serenity/blob/ec492a1a0819e6239ea44156825c4ee7234ca3db/Kernel/API/POSIX/signal.h#L59 + .serenity => 32768, else => {}, }; pub const SS = switch (native_os) { @@ -8774,7 +9636,8 @@ pub const SS = switch (native_os) { pub const ONSTACK = 1; pub const DISABLE = 4; }, - .haiku, .solaris, .illumos => struct { + // https://github.com/SerenityOS/serenity/blob/ec492a1a0819e6239ea44156825c4ee7234ca3db/Kernel/API/POSIX/signal.h#L54-L55 + .haiku, .solaris, .illumos, .serenity => struct { pub const ONSTACK = 0x1; pub const DISABLE = 0x2; }, @@ -9267,6 +10130,12 @@ pub const NOTE = switch (native_os) { else => void, }; +pub const FUTEX = switch (native_os) { + .openbsd => openbsd.FUTEX, + .serenity => serenity.FUTEX, + else => void, +}; + // Unix-like systems pub const DIR = opaque {}; pub extern "c" fn opendir(pathname: [*:0]const u8) ?*DIR; @@ -9327,7 +10196,7 @@ pub extern "c" fn sendfile64(out_fd: fd_t, in_fd: fd_t, offset: ?*i64, count: us pub extern "c" fn setrlimit64(resource: rlimit_resource, rlim: *const rlimit) c_int; pub const arc4random_buf = switch (native_os) { - .dragonfly, .netbsd, .freebsd, .solaris, .openbsd, .macos, .ios, .tvos, .watchos, .visionos => private.arc4random_buf, + .dragonfly, .netbsd, .freebsd, .solaris, .openbsd, .macos, .ios, .tvos, .watchos, .visionos, .serenity => private.arc4random_buf, else => {}, }; pub const getentropy = switch (native_os) { @@ -9395,7 +10264,7 @@ pub const sigaltstack = switch (native_os) { pub extern "c" fn memfd_create(name: [*:0]const u8, flags: c_uint) c_int; pub const pipe2 = switch (native_os) { - .dragonfly, .emscripten, .netbsd, .freebsd, .solaris, .illumos, .openbsd, .linux => private.pipe2, + .dragonfly, .emscripten, .netbsd, .freebsd, .solaris, .illumos, .openbsd, .linux, .serenity => private.pipe2, else => {}, }; pub const copy_file_range = switch (native_os) { @@ -9501,15 +10370,15 @@ pub const _msize = switch (native_os) { else => {}, }; pub const malloc_size = switch (native_os) { - .macos, .ios, .tvos, .watchos, .visionos => private.malloc_size, + .macos, .ios, .tvos, .watchos, .visionos, .serenity => private.malloc_size, else => {}, }; pub const malloc_usable_size = switch (native_os) { - .freebsd, .linux => private.malloc_usable_size, + .freebsd, .linux, .serenity => private.malloc_usable_size, else => {}, }; pub const posix_memalign = switch (native_os) { - .dragonfly, .netbsd, .freebsd, .solaris, .openbsd, .linux, .macos, .ios, .tvos, .watchos, .visionos => private.posix_memalign, + .dragonfly, .netbsd, .freebsd, .solaris, .openbsd, .linux, .macos, .ios, .tvos, .watchos, .visionos, .serenity => private.posix_memalign, else => {}, }; pub const sysconf = switch (native_os) { @@ -9532,6 +10401,12 @@ pub const flock = switch (native_os) { else => private.flock, }; +pub const futex = switch (native_os) { + .openbsd => openbsd.futex, + .serenity => serenity.futex, + else => {}, +}; + pub extern "c" var environ: [*:null]?[*:0]u8; pub extern "c" fn fopen(noalias filename: [*:0]const u8, noalias modes: [*:0]const u8) ?*FILE; @@ -9582,6 +10457,7 @@ pub const fork = switch (native_os) { .watchos, .visionos, .haiku, + .serenity, => private.fork, else => {}, }; @@ -9825,7 +10701,11 @@ pub extern "c" fn pthread_rwlock_tryrdlock(rwl: *pthread_rwlock_t) callconv(.c) pub extern "c" fn pthread_rwlock_trywrlock(rwl: *pthread_rwlock_t) callconv(.c) E; pub extern "c" fn pthread_rwlock_unlock(rwl: *pthread_rwlock_t) callconv(.c) E; -pub const pthread_t = *opaque {}; +pub const pthread_t = switch (native_os) { + // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L64 + .serenity => c_int, + else => *opaque {}, +}; pub const FILE = opaque {}; pub extern "c" fn dlopen(path: ?[*:0]const u8, mode: RTLD) ?*anyopaque; @@ -9958,7 +10838,6 @@ pub const thread_id = haiku.thread_id; pub const AUTH = openbsd.AUTH; pub const BI = openbsd.BI; -pub const FUTEX = openbsd.FUTEX; pub const HW = openbsd.HW; pub const PTHREAD_STACK_MIN = openbsd.PTHREAD_STACK_MIN; pub const TCFLUSH = openbsd.TCFLUSH; @@ -9999,7 +10878,6 @@ pub const bcrypt_checkpass = openbsd.bcrypt_checkpass; pub const bcrypt_gensalt = openbsd.bcrypt_gensalt; pub const bcrypt_newhash = openbsd.bcrypt_newhash; pub const endpwent = openbsd.endpwent; -pub const futex = openbsd.futex; pub const getpwent = openbsd.getpwent; pub const getpwnam_r = openbsd.getpwnam_r; pub const getpwnam_shadow = openbsd.getpwnam_shadow; @@ -10226,6 +11104,24 @@ pub const lwp_gettid = dragonfly.lwp_gettid; pub const umtx_sleep = dragonfly.umtx_sleep; pub const umtx_wakeup = dragonfly.umtx_wakeup; +pub const PERF_EVENT = serenity.PERF_EVENT; +pub const disown = serenity.disown; +pub const profiling_enable = serenity.profiling_enable; +pub const profiling_disable = serenity.profiling_disable; +pub const profiling_free_buffer = serenity.profiling_free_buffer; +pub const futex_wait = serenity.futex_wait; +pub const futex_wake = serenity.futex_wake; +pub const purge = serenity.purge; +pub const perf_event = serenity.perf_event; +pub const perf_register_string = serenity.perf_register_string; +pub const get_stack_bounds = serenity.get_stack_bounds; +pub const anon_create = serenity.anon_create; +pub const serenity_readlink = serenity.serenity_readlink; +pub const serenity_open = serenity.serenity_open; +pub const getkeymap = serenity.getkeymap; +pub const setkeymap = serenity.setkeymap; +pub const internet_checksum = serenity.internet_checksum; + /// External definitions shared by two or more operating systems. const private = struct { extern "c" fn close(fd: fd_t) c_int; diff --git a/lib/std/c/serenity.zig b/lib/std/c/serenity.zig new file mode 100644 index 0000000000..e64bef98a7 --- /dev/null +++ b/lib/std/c/serenity.zig @@ -0,0 +1,75 @@ +const std = @import("../std.zig"); +const assert = std.debug.assert; +const builtin = @import("builtin"); +const O = std.c.O; +const clockid_t = std.c.clockid_t; +const pid_t = std.c.pid_t; +const timespec = std.c.timespec; + +comptime { + assert(builtin.os.tag == .serenity); // Prevent access of std.c symbols on wrong OS. +} + +// https://github.com/SerenityOS/serenity/blob/ec492a1a0819e6239ea44156825c4ee7234ca3db/Kernel/API/POSIX/futex.h#L46-L53 +pub const FUTEX = struct { + pub const WAIT = 1; + pub const WAKE = 2; + pub const REQUEUE = 3; + pub const CMP_REQUEUE = 4; + pub const WAKE_OP = 5; + pub const WAIT_BITSET = 9; + pub const WAKE_BITSET = 10; + + pub const CLOCK_REALTIME = 1 << 8; + pub const PRIVATE_FLAG = 1 << 9; +}; + +// https://github.com/SerenityOS/serenity/blob/54e79aa1d90bbcb69014255a59afb085802719d3/Kernel/API/POSIX/serenity.h#L18-L36 +pub const PERF_EVENT = packed struct(c_int) { + SAMPLE: bool = false, + MALLOC: bool = false, + FREE: bool = false, + MMAP: bool = false, + MUNMAP: bool = false, + PROCESS_CREATE: bool = false, + PROCESS_EXEC: bool = false, + PROCESS_EXIT: bool = false, + THREAD_CREATE: bool = false, + THREAD_EXIT: bool = false, + CONTEXT_SWITCH: bool = false, + KMALLOC: bool = false, + KFREE: bool = false, + PAGE_FAULT: bool = false, + SYSCALL: bool = false, + SIGNPOST: bool = false, + FILESYSTEM: bool = false, +}; + +// https://github.com/SerenityOS/serenity/blob/abc150085f532f123b598949218893cb272ccc4c/Userland/Libraries/LibC/serenity.h + +pub extern "c" fn disown(pid: pid_t) c_int; + +pub extern "c" fn profiling_enable(pid: pid_t, event_mask: PERF_EVENT) c_int; +pub extern "c" fn profiling_disable(pid: pid_t) c_int; +pub extern "c" fn profiling_free_buffer(pid: pid_t) c_int; + +pub extern "c" fn futex(userspace_address: *u32, futex_op: c_int, value: u32, timeout: *const timespec, userspace_address2: *u32, value3: u32) c_int; +pub extern "c" fn futex_wait(userspace_address: *u32, value: u32, abstime: *const timespec, clockid: clockid_t, process_shared: c_int) c_int; +pub extern "c" fn futex_wake(userspace_address: *u32, count: u32, process_shared: c_int) c_int; + +pub extern "c" fn purge(mode: c_int) c_int; + +pub extern "c" fn perf_event(type: PERF_EVENT, arg1: usize, arg2: usize) c_int; +pub extern "c" fn perf_register_string(string: [*]const u8, string_length: usize) c_int; + +pub extern "c" fn get_stack_bounds(user_stack_base: *usize, user_stack_size: *usize) c_int; + +pub extern "c" fn anon_create(size: usize, options: O) c_int; + +pub extern "c" fn serenity_readlink(path: [*]const u8, path_length: usize, buffer: [*]u8, buffer_size: usize) c_int; +pub extern "c" fn serenity_open(path: [*]const u8, path_length: usize, options: c_int, ...) c_int; + +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; +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; + +pub extern "c" fn internet_checksum(ptr: *const anyopaque, count: usize) u16; diff --git a/lib/std/crypto/Certificate.zig b/lib/std/crypto/Certificate.zig index 9ca6aa5e48..c89141ec7d 100644 --- a/lib/std/crypto/Certificate.zig +++ b/lib/std/crypto/Certificate.zig @@ -607,11 +607,10 @@ const Date = struct { } { - const is_leap = std.time.epoch.isLeapYear(date.year); var month: u4 = 1; while (month < date.month) : (month += 1) { const days: u64 = std.time.epoch.getDaysInMonth( - @as(std.time.epoch.YearLeapKind, @enumFromInt(@intFromBool(is_leap))), + date.year, @as(std.time.epoch.Month, @enumFromInt(month)), ); sec += days * std.time.epoch.secs_per_day; diff --git a/lib/std/crypto/Certificate/Bundle.zig b/lib/std/crypto/Certificate/Bundle.zig index 627cd4172b..a74eb44a91 100644 --- a/lib/std/crypto/Certificate/Bundle.zig +++ b/lib/std/crypto/Certificate/Bundle.zig @@ -50,7 +50,7 @@ pub fn deinit(cb: *Bundle, gpa: Allocator) void { cb.* = undefined; } -pub const RescanError = RescanLinuxError || RescanMacError || RescanBSDError || RescanWindowsError; +pub const RescanError = RescanLinuxError || RescanMacError || RescanWithPathError || RescanWindowsError; /// Clears the set of certificates and then scans the host operating system /// file system standard locations for certificates. @@ -60,10 +60,12 @@ pub fn rescan(cb: *Bundle, gpa: Allocator) RescanError!void { switch (builtin.os.tag) { .linux => return rescanLinux(cb, gpa), .macos => return rescanMac(cb, gpa), - .freebsd, .openbsd => return rescanBSD(cb, gpa, "/etc/ssl/cert.pem"), - .netbsd => return rescanBSD(cb, gpa, "/etc/openssl/certs/ca-certificates.crt"), - .dragonfly => return rescanBSD(cb, gpa, "/usr/local/etc/ssl/cert.pem"), - .solaris, .illumos => return rescanBSD(cb, gpa, "/etc/ssl/cacert.pem"), + .freebsd, .openbsd => return rescanWithPath(cb, gpa, "/etc/ssl/cert.pem"), + .netbsd => return rescanWithPath(cb, gpa, "/etc/openssl/certs/ca-certificates.crt"), + .dragonfly => return rescanWithPath(cb, gpa, "/usr/local/etc/ssl/cert.pem"), + .solaris, .illumos => return rescanWithPath(cb, gpa, "/etc/ssl/cacert.pem"), + // https://github.com/SerenityOS/serenity/blob/222acc9d389bc6b490d4c39539761b043a4bfcb0/Ports/ca-certificates/package.sh#L19 + .serenity => return rescanWithPath(cb, gpa, "/etc/ssl/certs/ca-certificates.crt"), .windows => return rescanWindows(cb, gpa), else => {}, } @@ -116,9 +118,9 @@ fn rescanLinux(cb: *Bundle, gpa: Allocator) RescanLinuxError!void { cb.bytes.shrinkAndFree(gpa, cb.bytes.items.len); } -const RescanBSDError = AddCertsFromFilePathError; +const RescanWithPathError = AddCertsFromFilePathError; -fn rescanBSD(cb: *Bundle, gpa: Allocator, cert_file_path: []const u8) RescanBSDError!void { +fn rescanWithPath(cb: *Bundle, gpa: Allocator, cert_file_path: []const u8) RescanWithPathError!void { cb.bytes.clearRetainingCapacity(); cb.map.clearRetainingCapacity(); try addCertsFromFilePathAbsolute(cb, gpa, cert_file_path); diff --git a/lib/std/fs.zig b/lib/std/fs.zig index 99936e9abd..fc2da3de72 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -52,7 +52,7 @@ pub const MAX_PATH_BYTES = @compileError("deprecated; renamed to max_path_bytes" /// * On other platforms, `[]u8` file paths are opaque sequences of bytes with /// no particular encoding. pub const max_path_bytes = switch (native_os) { - .linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly, .haiku, .solaris, .illumos, .plan9, .emscripten, .wasi => posix.PATH_MAX, + .linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly, .haiku, .solaris, .illumos, .plan9, .emscripten, .wasi, .serenity => posix.PATH_MAX, // Each WTF-16LE code unit may be expanded to 3 WTF-8 bytes. // If it would require 4 WTF-8 bytes, then there would be a surrogate // pair in the WTF-16LE, and we (over)account 3 bytes for it that way. @@ -73,7 +73,7 @@ pub const max_path_bytes = switch (native_os) { /// On WASI, file name components are encoded as valid UTF-8. /// On other platforms, `[]u8` components are an opaque sequence of bytes with no particular encoding. pub const max_name_bytes = switch (native_os) { - .linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly, .solaris, .illumos => posix.NAME_MAX, + .linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly, .solaris, .illumos, .serenity => posix.NAME_MAX, // Haiku's NAME_MAX includes the null terminator, so subtract one. .haiku => posix.NAME_MAX - 1, // Each WTF-16LE character may be expanded to 3 WTF-8 bytes. @@ -466,7 +466,7 @@ pub fn symLinkAbsoluteZ( pub const OpenSelfExeError = posix.OpenError || SelfExePathError || posix.FlockError; pub fn openSelfExe(flags: File.OpenFlags) OpenSelfExeError!File { - if (native_os == .linux) { + if (native_os == .linux or native_os == .serenity) { return openFileAbsoluteZ("/proc/self/exe", flags); } if (native_os == .windows) { @@ -572,7 +572,7 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 { return result; } switch (native_os) { - .linux => return posix.readlinkZ("/proc/self/exe", out_buffer) catch |err| switch (err) { + .linux, .serenity => return posix.readlinkZ("/proc/self/exe", out_buffer) catch |err| switch (err) { error.InvalidUtf8 => unreachable, // WASI-only error.InvalidWtf8 => unreachable, // Windows-only error.UnsupportedReparsePointType => unreachable, // Windows-only diff --git a/lib/std/fs/get_app_data_dir.zig b/lib/std/fs/get_app_data_dir.zig index cce99ea8cc..a256758a07 100644 --- a/lib/std/fs/get_app_data_dir.zig +++ b/lib/std/fs/get_app_data_dir.zig @@ -30,7 +30,7 @@ pub fn getAppDataDir(allocator: mem.Allocator, appname: []const u8) GetAppDataDi }; return fs.path.join(allocator, &[_][]const u8{ home_dir, "Library", "Application Support", appname }); }, - .linux, .freebsd, .netbsd, .dragonfly, .openbsd, .solaris, .illumos => { + .linux, .freebsd, .netbsd, .dragonfly, .openbsd, .solaris, .illumos, .serenity => { if (posix.getenv("XDG_DATA_HOME")) |xdg| { if (xdg.len > 0) { return fs.path.join(allocator, &[_][]const u8{ xdg, appname }); diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index 98fef1b2ce..546435f4ab 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -320,14 +320,8 @@ test "accessAbsolute" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - var arena = ArenaAllocator.init(testing.allocator); - defer arena.deinit(); - const allocator = arena.allocator(); - - const base_path = blk: { - const relative_path = try fs.path.join(allocator, &.{ ".zig-cache", "tmp", tmp.sub_path[0..] }); - break :blk try fs.realpathAlloc(allocator, relative_path); - }; + const base_path = try tmp.dir.realpathAlloc(testing.allocator, "."); + defer testing.allocator.free(base_path); try fs.accessAbsolute(base_path, .{}); } @@ -338,25 +332,52 @@ test "openDirAbsolute" { var tmp = tmpDir(.{}); defer tmp.cleanup(); + const tmp_ino = (try tmp.dir.stat()).inode; + try tmp.dir.makeDir("subdir"); - var arena = ArenaAllocator.init(testing.allocator); - defer arena.deinit(); - const allocator = arena.allocator(); + const sub_path = try tmp.dir.realpathAlloc(testing.allocator, "subdir"); + defer testing.allocator.free(sub_path); - const base_path = blk: { - const relative_path = try fs.path.join(allocator, &.{ ".zig-cache", "tmp", tmp.sub_path[0..], "subdir" }); - break :blk try fs.realpathAlloc(allocator, relative_path); - }; + // Can open sub_path + var tmp_sub = try fs.openDirAbsolute(sub_path, .{}); + defer tmp_sub.close(); + + const sub_ino = (try tmp_sub.stat()).inode; { - var dir = try fs.openDirAbsolute(base_path, .{}); + // Can open sub_path + ".." + const dir_path = try fs.path.join(testing.allocator, &.{ sub_path, ".." }); + defer testing.allocator.free(dir_path); + + var dir = try fs.openDirAbsolute(dir_path, .{}); defer dir.close(); + + const ino = (try dir.stat()).inode; + try testing.expectEqual(tmp_ino, ino); } - for ([_][]const u8{ ".", ".." }) |sub_path| { - const dir_path = try fs.path.join(allocator, &.{ base_path, sub_path }); + { + // Can open sub_path + "." + const dir_path = try fs.path.join(testing.allocator, &.{ sub_path, "." }); + defer testing.allocator.free(dir_path); + var dir = try fs.openDirAbsolute(dir_path, .{}); defer dir.close(); + + const ino = (try dir.stat()).inode; + try testing.expectEqual(sub_ino, ino); + } + + { + // Can open subdir + "..", with some extra "." + const dir_path = try fs.path.join(testing.allocator, &.{ sub_path, ".", "..", "." }); + defer testing.allocator.free(dir_path); + + var dir = try fs.openDirAbsolute(dir_path, .{}); + defer dir.close(); + + const ino = (try dir.stat()).inode; + try testing.expectEqual(tmp_ino, ino); } } @@ -409,10 +430,7 @@ test "readLinkAbsolute" { defer arena.deinit(); const allocator = arena.allocator(); - const base_path = blk: { - const relative_path = try fs.path.join(allocator, &.{ ".zig-cache", "tmp", tmp.sub_path[0..] }); - break :blk try fs.realpathAlloc(allocator, relative_path); - }; + const base_path = try tmp.dir.realpathAlloc(allocator, "."); { const target_path = try fs.path.join(allocator, &.{ base_path, "file.txt" }); @@ -748,7 +766,6 @@ test "directory operations on files" { test "file operations on directories" { // TODO: fix this test on FreeBSD. https://github.com/ziglang/zig/issues/1759 if (native_os == .freebsd) return error.SkipZigTest; - if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/20747 try testWithAllSupportedPathTypes(struct { fn impl(ctx: *TestContext) !void { @@ -759,18 +776,30 @@ test "file operations on directories" { try testing.expectError(error.IsDir, ctx.dir.createFile(test_dir_name, .{})); try testing.expectError(error.IsDir, ctx.dir.deleteFile(test_dir_name)); switch (native_os) { - // no error when reading a directory. - .dragonfly, .netbsd => {}, - // Currently, WASI will return error.Unexpected (via ENOTCAPABLE) when attempting fd_read on a directory handle. - // TODO: Re-enable on WASI once https://github.com/bytecodealliance/wasmtime/issues/1935 is resolved. - .wasi => {}, + .dragonfly, .netbsd => { + // no error when reading a directory. See https://github.com/ziglang/zig/issues/5732 + const buf = try ctx.dir.readFileAlloc(testing.allocator, test_dir_name, std.math.maxInt(usize)); + testing.allocator.free(buf); + }, + .wasi => { + // WASI return EBADF, which gets mapped to NotOpenForReading. + // See https://github.com/bytecodealliance/wasmtime/issues/1935 + try testing.expectError(error.NotOpenForReading, ctx.dir.readFileAlloc(testing.allocator, test_dir_name, std.math.maxInt(usize))); + }, else => { try testing.expectError(error.IsDir, ctx.dir.readFileAlloc(testing.allocator, test_dir_name, std.math.maxInt(usize))); }, } - // Note: The `.mode = .read_write` is necessary to ensure the error occurs on all platforms. - // TODO: Add a read-only test as well, see https://github.com/ziglang/zig/issues/5732 - try testing.expectError(error.IsDir, ctx.dir.openFile(test_dir_name, .{ .mode = .read_write })); + + if (native_os == .wasi and builtin.link_libc) { + // wasmtime unexpectedly succeeds here, see https://github.com/ziglang/zig/issues/20747 + const handle = try ctx.dir.openFile(test_dir_name, .{ .mode = .read_write }); + handle.close(); + } else { + // Note: The `.mode = .read_write` is necessary to ensure the error occurs on all platforms. + // TODO: Add a read-only test as well, see https://github.com/ziglang/zig/issues/5732 + try testing.expectError(error.IsDir, ctx.dir.openFile(test_dir_name, .{ .mode = .read_write })); + } if (ctx.path_type == .absolute and comptime PathType.absolute.isSupported(builtin.os)) { try testing.expectError(error.IsDir, fs.createFileAbsolute(test_dir_name, .{})); @@ -993,10 +1022,7 @@ test "renameAbsolute" { defer arena.deinit(); const allocator = arena.allocator(); - const base_path = blk: { - const relative_path = try fs.path.join(allocator, &.{ ".zig-cache", "tmp", tmp_dir.sub_path[0..] }); - break :blk try fs.realpathAlloc(allocator, relative_path); - }; + const base_path = try tmp_dir.dir.realpathAlloc(allocator, "."); try testing.expectError(error.FileNotFound, fs.renameAbsolute( try fs.path.join(allocator, &.{ base_path, "missing_file_name" }), @@ -1386,7 +1412,6 @@ test "sendfile" { defer tmp.cleanup(); try tmp.dir.makePath("os_test_tmp"); - defer tmp.dir.deleteTree("os_test_tmp") catch {}; var dir = try tmp.dir.openDir("os_test_tmp", .{}); defer dir.close(); @@ -1451,7 +1476,6 @@ test "copyRangeAll" { defer tmp.cleanup(); try tmp.dir.makePath("os_test_tmp"); - defer tmp.dir.deleteTree("os_test_tmp") catch {}; var dir = try tmp.dir.openDir("os_test_tmp", .{}); defer dir.close(); @@ -1800,10 +1824,7 @@ test "'.' and '..' in absolute functions" { defer arena.deinit(); const allocator = arena.allocator(); - const base_path = blk: { - const relative_path = try fs.path.join(allocator, &.{ ".zig-cache", "tmp", tmp.sub_path[0..] }); - break :blk try fs.realpathAlloc(allocator, relative_path); - }; + const base_path = try tmp.dir.realpathAlloc(allocator, "."); const subdir_path = try fs.path.join(allocator, &.{ base_path, "./subdir" }); try fs.makeDirAbsolute(subdir_path); diff --git a/lib/std/io/test.zig b/lib/std/io/test.zig index 6505fcd4fa..523b25c9c8 100644 --- a/lib/std/io/test.zig +++ b/lib/std/io/test.zig @@ -108,10 +108,7 @@ test "File seek ops" { const tmp_file_name = "temp_test_file.txt"; var file = try tmp.dir.createFile(tmp_file_name, .{}); - defer { - file.close(); - tmp.dir.deleteFile(tmp_file_name) catch {}; - } + defer file.close(); try file.writeAll(&([_]u8{0x55} ** 8192)); @@ -135,10 +132,7 @@ test "setEndPos" { const tmp_file_name = "temp_test_file.txt"; var file = try tmp.dir.createFile(tmp_file_name, .{}); - defer { - file.close(); - tmp.dir.deleteFile(tmp_file_name) catch {}; - } + defer file.close(); // Verify that the file size changes and the file offset is not moved try std.testing.expect((try file.getEndPos()) == 0); @@ -161,10 +155,8 @@ test "updateTimes" { const tmp_file_name = "just_a_temporary_file.txt"; var file = try tmp.dir.createFile(tmp_file_name, .{ .read = true }); - defer { - file.close(); - tmp.dir.deleteFile(tmp_file_name) catch {}; - } + defer file.close(); + const stat_old = try file.stat(); // Set atime and mtime to 5s before try file.updateTimes( diff --git a/lib/std/mem/Allocator.zig b/lib/std/mem/Allocator.zig index 1ad9533116..8ca7ed669b 100644 --- a/lib/std/mem/Allocator.zig +++ b/lib/std/mem/Allocator.zig @@ -308,7 +308,8 @@ pub fn resize(self: Allocator, allocation: anytype, new_len: usize) bool { /// In such case, it is more efficient for the caller to perform those /// operations. /// -/// `allocation` may be an empty slice, in which case a new allocation is made. +/// `allocation` may be an empty slice, in which case `null` is returned, +/// unless `new_len` is also 0, in which case `allocation` is returned. /// /// `new_len` may be zero, in which case the allocation is freed. pub fn remap(self: Allocator, allocation: anytype, new_len: usize) t: { diff --git a/lib/std/multi_array_list.zig b/lib/std/multi_array_list.zig index 7d68322c90..0df825187b 100644 --- a/lib/std/multi_array_list.zig +++ b/lib/std/multi_array_list.zig @@ -248,8 +248,8 @@ pub fn MultiArrayList(comptime T: type) type { /// Extend the list by 1 element, returning the newly reserved /// index with uninitialized data. /// Allocates more memory as necesasry. - pub fn addOne(self: *Self, allocator: Allocator) Allocator.Error!usize { - try self.ensureUnusedCapacity(allocator, 1); + pub fn addOne(self: *Self, gpa: Allocator) Allocator.Error!usize { + try self.ensureUnusedCapacity(gpa, 1); return self.addOneAssumeCapacity(); } diff --git a/lib/std/os.zig b/lib/std/os.zig index 80f45dd59d..45568caf3c 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -82,6 +82,7 @@ pub fn isGetFdPathSupportedOnTarget(os: std.Target.Os) bool { .solaris, .illumos, .freebsd, + .serenity, => true, .dragonfly => os.version_range.semver.max.order(.{ .major = 6, .minor = 0, .patch = 0 }) != .lt, @@ -127,7 +128,7 @@ pub fn getFdPath(fd: std.posix.fd_t, out_buffer: *[max_path_bytes]u8) std.posix. const len = mem.indexOfScalar(u8, out_buffer[0..], 0) orelse max_path_bytes; return out_buffer[0..len]; }, - .linux => { + .linux, .serenity => { var procfs_buf: ["/proc/self/fd/-2147483648\x00".len]u8 = undefined; const proc_path = std.fmt.bufPrintZ(procfs_buf[0..], "/proc/self/fd/{d}", .{fd}) catch unreachable; diff --git a/lib/std/os/uefi.zig b/lib/std/os/uefi.zig index f7e51c63aa..9674e704dc 100644 --- a/lib/std/os/uefi.zig +++ b/lib/std/os/uefi.zig @@ -141,11 +141,10 @@ pub const Time = extern struct { pub const unspecified_timezone: i16 = 0x7ff; fn daysInYear(year: u16, max_month: u4) u9 { - const leap_year: std.time.epoch.YearLeapKind = if (std.time.epoch.isLeapYear(year)) .leap else .not_leap; var days: u9 = 0; var month: u4 = 0; while (month < max_month) : (month += 1) { - days += std.time.epoch.getDaysInMonth(leap_year, @enumFromInt(month + 1)); + days += std.time.epoch.getDaysInMonth(year, @enumFromInt(month + 1)); } return days; } diff --git a/lib/std/os/uefi/status.zig b/lib/std/os/uefi/status.zig index 5c86520194..2e17ef64c9 100644 --- a/lib/std/os/uefi/status.zig +++ b/lib/std/os/uefi/status.zig @@ -231,11 +231,57 @@ pub const Status = enum(usize) { else => {}, } } + + pub fn fromError(e: Error) Status { + return switch (e) { + Error.Aborted => .aborted, + Error.AccessDenied => .access_denied, + Error.AlreadyStarted => .already_started, + Error.BadBufferSize => .bad_buffer_size, + Error.BufferTooSmall => .buffer_too_small, + Error.CompromisedData => .compromised_data, + Error.ConnectionFin => .connection_fin, + Error.ConnectionRefused => .connection_refused, + Error.ConnectionReset => .connection_reset, + Error.CrcError => .crc_error, + Error.DeviceError => .device_error, + Error.EndOfFile => .end_of_file, + Error.EndOfMedia => .end_of_media, + Error.HostUnreachable => .host_unreachable, + Error.HttpError => .http_error, + Error.IcmpError => .icmp_error, + Error.IncompatibleVersion => .incompatible_version, + Error.InvalidLanguage => .invalid_language, + Error.InvalidParameter => .invalid_parameter, + Error.IpAddressConflict => .ip_address_conflict, + Error.LoadError => .load_error, + Error.MediaChanged => .media_changed, + Error.NetworkUnreachable => .network_unreachable, + Error.NoMapping => .no_mapping, + Error.NoMedia => .no_media, + Error.NoResponse => .no_response, + Error.NotFound => .not_found, + Error.NotReady => .not_ready, + Error.NotStarted => .not_started, + Error.OutOfResources => .out_of_resources, + Error.PortUnreachable => .port_unreachable, + Error.ProtocolError => .protocol_error, + Error.ProtocolUnreachable => .protocol_unreachable, + Error.SecurityViolation => .security_violation, + Error.TftpError => .tftp_error, + Error.Timeout => .timeout, + Error.Unsupported => .unsupported, + Error.VolumeCorrupted => .volume_corrupted, + Error.VolumeFull => .volume_full, + Error.WriteProtected => .write_protected, + }; + } }; test "status" { var st: Status = .device_error; try testing.expectError(error.DeviceError, st.err()); + try testing.expectEqual(st, Status.fromError(st.err())); st = .success; try st.err(); diff --git a/lib/std/posix/test.zig b/lib/std/posix/test.zig index 29756cae69..9678bfb261 100644 --- a/lib/std/posix/test.zig +++ b/lib/std/posix/test.zig @@ -8,7 +8,6 @@ const io = std.io; const fs = std.fs; const mem = std.mem; const elf = std.elf; -const File = std.fs.File; const Thread = std.Thread; const linux = std.os.linux; @@ -19,8 +18,6 @@ const AtomicRmwOp = std.builtin.AtomicRmwOp; const AtomicOrder = std.builtin.AtomicOrder; const native_os = builtin.target.os.tag; const tmpDir = std.testing.tmpDir; -const Dir = std.fs.Dir; -const ArenaAllocator = std.heap.ArenaAllocator; // https://github.com/ziglang/zig/issues/20288 test "WTF-8 to WTF-16 conversion buffer overflows" { @@ -115,50 +112,62 @@ test "open smoke test" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - // Get base abs path - var arena = ArenaAllocator.init(testing.allocator); - defer arena.deinit(); - const allocator = arena.allocator(); + const base_path = try tmp.dir.realpathAlloc(a, "."); + defer a.free(base_path); - const base_path = blk: { - const relative_path = try fs.path.join(allocator, &[_][]const u8{ ".zig-cache", "tmp", tmp.sub_path[0..] }); - break :blk try fs.realpathAlloc(allocator, relative_path); - }; - - var file_path: []u8 = undefined; - var fd: posix.fd_t = undefined; const mode: posix.mode_t = if (native_os == .windows) 0 else 0o666; - // Create some file using `open`. - file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" }); - fd = try posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode); - posix.close(fd); + { + // Create some file using `open`. + const file_path = try fs.path.join(a, &.{ base_path, "some_file" }); + defer a.free(file_path); + const fd = try posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode); + posix.close(fd); + } - // Try this again with the same flags. This op should fail with error.PathAlreadyExists. - file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" }); - try expectError(error.PathAlreadyExists, posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode)); + { + // Try this again with the same flags. This op should fail with error.PathAlreadyExists. + const file_path = try fs.path.join(a, &.{ base_path, "some_file" }); + defer a.free(file_path); + try expectError(error.PathAlreadyExists, posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode)); + } - // Try opening without `EXCL` flag. - file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" }); - fd = try posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true }, mode); - posix.close(fd); + { + // Try opening without `EXCL` flag. + const file_path = try fs.path.join(a, &.{ base_path, "some_file" }); + defer a.free(file_path); + const fd = try posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true }, mode); + posix.close(fd); + } - // Try opening as a directory which should fail. - file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" }); - try expectError(error.NotDir, posix.open(file_path, .{ .ACCMODE = .RDWR, .DIRECTORY = true }, mode)); + { + // Try opening as a directory which should fail. + const file_path = try fs.path.join(a, &.{ base_path, "some_file" }); + defer a.free(file_path); + try expectError(error.NotDir, posix.open(file_path, .{ .ACCMODE = .RDWR, .DIRECTORY = true }, mode)); + } - // Create some directory - file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" }); - try posix.mkdir(file_path, mode); + { + // Create some directory + const file_path = try fs.path.join(a, &.{ base_path, "some_dir" }); + defer a.free(file_path); + try posix.mkdir(file_path, mode); + } - // Open dir using `open` - file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" }); - fd = try posix.open(file_path, .{ .ACCMODE = .RDONLY, .DIRECTORY = true }, mode); - posix.close(fd); + { + // Open dir using `open` + const file_path = try fs.path.join(a, &.{ base_path, "some_dir" }); + defer a.free(file_path); + const fd = try posix.open(file_path, .{ .ACCMODE = .RDONLY, .DIRECTORY = true }, mode); + posix.close(fd); + } - // Try opening as file which should fail. - file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" }); - try expectError(error.IsDir, posix.open(file_path, .{ .ACCMODE = .RDWR }, mode)); + { + // Try opening as file which should fail. + const file_path = try fs.path.join(a, &.{ base_path, "some_dir" }); + defer a.free(file_path); + try expectError(error.IsDir, posix.open(file_path, .{ .ACCMODE = .RDWR }, mode)); + } } test "openat smoke test" { @@ -705,8 +714,6 @@ test "mmap" { try testing.expectEqual(i, try stream.readInt(u32, .little)); } } - - try tmp.dir.deleteFile(test_out_file); } test "getenv" { @@ -732,10 +739,7 @@ test "fcntl" { const test_out_file = "os_tmp_test"; const file = try tmp.dir.createFile(test_out_file, .{}); - defer { - file.close(); - tmp.dir.deleteFile(test_out_file) catch {}; - } + defer file.close(); // Note: The test assumes createFile opens the file with CLOEXEC { @@ -771,10 +775,7 @@ test "sync" { const test_out_file = "os_tmp_test"; const file = try tmp.dir.createFile(test_out_file, .{}); - defer { - file.close(); - tmp.dir.deleteFile(test_out_file) catch {}; - } + defer file.close(); posix.sync(); try posix.syncfs(file.handle); @@ -791,10 +792,7 @@ test "fsync" { const test_out_file = "os_tmp_test"; const file = try tmp.dir.createFile(test_out_file, .{}); - defer { - file.close(); - tmp.dir.deleteFile(test_out_file) catch {}; - } + defer file.close(); try posix.fsync(file.handle); try posix.fdatasync(file.handle); @@ -1041,54 +1039,65 @@ test "rename smoke test" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - // Get base abs path - var arena = ArenaAllocator.init(testing.allocator); - defer arena.deinit(); - const allocator = arena.allocator(); - - const base_path = blk: { - const relative_path = try fs.path.join(allocator, &[_][]const u8{ ".zig-cache", "tmp", tmp.sub_path[0..] }); - break :blk try fs.realpathAlloc(allocator, relative_path); - }; + const base_path = try tmp.dir.realpathAlloc(a, "."); + defer a.free(base_path); - var file_path: []u8 = undefined; - var fd: posix.fd_t = undefined; const mode: posix.mode_t = if (native_os == .windows) 0 else 0o666; - // Create some file using `open`. - file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" }); - fd = try posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode); - posix.close(fd); - - // Rename the file - var new_file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_other_file" }); - try posix.rename(file_path, new_file_path); - - // Try opening renamed file - file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_other_file" }); - fd = try posix.open(file_path, .{ .ACCMODE = .RDWR }, mode); - posix.close(fd); + { + // Create some file using `open`. + const file_path = try fs.path.join(a, &.{ base_path, "some_file" }); + defer a.free(file_path); + const fd = try posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode); + posix.close(fd); + + // Rename the file + const new_file_path = try fs.path.join(a, &.{ base_path, "some_other_file" }); + defer a.free(new_file_path); + try posix.rename(file_path, new_file_path); + } - // Try opening original file - should fail with error.FileNotFound - file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" }); - try expectError(error.FileNotFound, posix.open(file_path, .{ .ACCMODE = .RDWR }, mode)); + { + // Try opening renamed file + const file_path = try fs.path.join(a, &.{ base_path, "some_other_file" }); + defer a.free(file_path); + const fd = try posix.open(file_path, .{ .ACCMODE = .RDWR }, mode); + posix.close(fd); + } - // Create some directory - file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" }); - try posix.mkdir(file_path, mode); + { + // Try opening original file - should fail with error.FileNotFound + const file_path = try fs.path.join(a, &.{ base_path, "some_file" }); + defer a.free(file_path); + try expectError(error.FileNotFound, posix.open(file_path, .{ .ACCMODE = .RDWR }, mode)); + } - // Rename the directory - new_file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_other_dir" }); - try posix.rename(file_path, new_file_path); + { + // Create some directory + const file_path = try fs.path.join(a, &.{ base_path, "some_dir" }); + defer a.free(file_path); + try posix.mkdir(file_path, mode); + + // Rename the directory + const new_file_path = try fs.path.join(a, &.{ base_path, "some_other_dir" }); + defer a.free(new_file_path); + try posix.rename(file_path, new_file_path); + } - // Try opening renamed directory - file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_other_dir" }); - fd = try posix.open(file_path, .{ .ACCMODE = .RDONLY, .DIRECTORY = true }, mode); - posix.close(fd); + { + // Try opening renamed directory + const file_path = try fs.path.join(a, &.{ base_path, "some_other_dir" }); + defer a.free(file_path); + const fd = try posix.open(file_path, .{ .ACCMODE = .RDONLY, .DIRECTORY = true }, mode); + posix.close(fd); + } - // Try opening original directory - should fail with error.FileNotFound - file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" }); - try expectError(error.FileNotFound, posix.open(file_path, .{ .ACCMODE = .RDONLY, .DIRECTORY = true }, mode)); + { + // Try opening original directory - should fail with error.FileNotFound + const file_path = try fs.path.join(a, &.{ base_path, "some_dir" }); + defer a.free(file_path); + try expectError(error.FileNotFound, posix.open(file_path, .{ .ACCMODE = .RDONLY, .DIRECTORY = true }, mode)); + } } test "access smoke test" { @@ -1098,44 +1107,50 @@ test "access smoke test" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - // Get base abs path - var arena = ArenaAllocator.init(testing.allocator); - defer arena.deinit(); - const allocator = arena.allocator(); - - const base_path = blk: { - const relative_path = try fs.path.join(allocator, &[_][]const u8{ ".zig-cache", "tmp", tmp.sub_path[0..] }); - break :blk try fs.realpathAlloc(allocator, relative_path); - }; + const base_path = try tmp.dir.realpathAlloc(a, "."); + defer a.free(base_path); - var file_path: []u8 = undefined; - var fd: posix.fd_t = undefined; const mode: posix.mode_t = if (native_os == .windows) 0 else 0o666; + { + // Create some file using `open`. + const file_path = try fs.path.join(a, &.{ base_path, "some_file" }); + defer a.free(file_path); + const fd = try posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode); + posix.close(fd); + } - // Create some file using `open`. - file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" }); - fd = try posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode); - posix.close(fd); + { + // Try to access() the file + const file_path = try fs.path.join(a, &.{ base_path, "some_file" }); + defer a.free(file_path); + if (native_os == .windows) { + try posix.access(file_path, posix.F_OK); + } else { + try posix.access(file_path, posix.F_OK | posix.W_OK | posix.R_OK); + } + } - // Try to access() the file - file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" }); - if (native_os == .windows) { - try posix.access(file_path, posix.F_OK); - } else { - try posix.access(file_path, posix.F_OK | posix.W_OK | posix.R_OK); + { + // Try to access() a non-existent file - should fail with error.FileNotFound + const file_path = try fs.path.join(a, &.{ base_path, "some_other_file" }); + defer a.free(file_path); + try expectError(error.FileNotFound, posix.access(file_path, posix.F_OK)); } - // Try to access() a non-existent file - should fail with error.FileNotFound - file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_other_file" }); - try expectError(error.FileNotFound, posix.access(file_path, posix.F_OK)); + { + // Create some directory + const file_path = try fs.path.join(a, &.{ base_path, "some_dir" }); + defer a.free(file_path); + try posix.mkdir(file_path, mode); + } - // Create some directory - file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" }); - try posix.mkdir(file_path, mode); + { + // Try to access() the directory + const file_path = try fs.path.join(a, &.{ base_path, "some_dir" }); + defer a.free(file_path); - // Try to access() the directory - file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" }); - try posix.access(file_path, posix.F_OK); + try posix.access(file_path, posix.F_OK); + } } test "timerfd" { @@ -1167,103 +1182,59 @@ test "isatty" { } test "read with empty buffer" { - if (native_os == .wasi) return error.SkipZigTest; - var tmp = tmpDir(.{}); defer tmp.cleanup(); - var arena = ArenaAllocator.init(testing.allocator); - defer arena.deinit(); - const allocator = arena.allocator(); - - // Get base abs path - const base_path = blk: { - const relative_path = try fs.path.join(allocator, &[_][]const u8{ ".zig-cache", "tmp", tmp.sub_path[0..] }); - break :blk try fs.realpathAlloc(allocator, relative_path); - }; - - const file_path: []u8 = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" }); - var file = try fs.cwd().createFile(file_path, .{ .read = true }); + var file = try tmp.dir.createFile("read_empty", .{ .read = true }); defer file.close(); - const bytes = try allocator.alloc(u8, 0); + const bytes = try a.alloc(u8, 0); + defer a.free(bytes); - _ = try posix.read(file.handle, bytes); + const rc = try posix.read(file.handle, bytes); + try expectEqual(rc, 0); } test "pread with empty buffer" { - if (native_os == .wasi) return error.SkipZigTest; - var tmp = tmpDir(.{}); defer tmp.cleanup(); - var arena = ArenaAllocator.init(testing.allocator); - defer arena.deinit(); - const allocator = arena.allocator(); - - // Get base abs path - const base_path = blk: { - const relative_path = try fs.path.join(allocator, &[_][]const u8{ ".zig-cache", "tmp", tmp.sub_path[0..] }); - break :blk try fs.realpathAlloc(allocator, relative_path); - }; - - const file_path: []u8 = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" }); - var file = try fs.cwd().createFile(file_path, .{ .read = true }); + var file = try tmp.dir.createFile("pread_empty", .{ .read = true }); defer file.close(); - const bytes = try allocator.alloc(u8, 0); + const bytes = try a.alloc(u8, 0); + defer a.free(bytes); - _ = try posix.pread(file.handle, bytes, 0); + const rc = try posix.pread(file.handle, bytes, 0); + try expectEqual(rc, 0); } test "write with empty buffer" { - if (native_os == .wasi) return error.SkipZigTest; - var tmp = tmpDir(.{}); defer tmp.cleanup(); - var arena = ArenaAllocator.init(testing.allocator); - defer arena.deinit(); - const allocator = arena.allocator(); - - // Get base abs path - const base_path = blk: { - const relative_path = try fs.path.join(allocator, &[_][]const u8{ ".zig-cache", "tmp", tmp.sub_path[0..] }); - break :blk try fs.realpathAlloc(allocator, relative_path); - }; - - const file_path: []u8 = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" }); - var file = try fs.cwd().createFile(file_path, .{}); + var file = try tmp.dir.createFile("write_empty", .{}); defer file.close(); - const bytes = try allocator.alloc(u8, 0); + const bytes = try a.alloc(u8, 0); + defer a.free(bytes); - _ = try posix.write(file.handle, bytes); + const rc = try posix.write(file.handle, bytes); + try expectEqual(rc, 0); } test "pwrite with empty buffer" { - if (native_os == .wasi) return error.SkipZigTest; - var tmp = tmpDir(.{}); defer tmp.cleanup(); - var arena = ArenaAllocator.init(testing.allocator); - defer arena.deinit(); - const allocator = arena.allocator(); - - // Get base abs path - const base_path = blk: { - const relative_path = try fs.path.join(allocator, &[_][]const u8{ ".zig-cache", "tmp", tmp.sub_path[0..] }); - break :blk try fs.realpathAlloc(allocator, relative_path); - }; - - const file_path: []u8 = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" }); - var file = try fs.cwd().createFile(file_path, .{}); + var file = try tmp.dir.createFile("pwrite_empty", .{}); defer file.close(); - const bytes = try allocator.alloc(u8, 0); + const bytes = try a.alloc(u8, 0); + defer a.free(bytes); - _ = try posix.pwrite(file.handle, bytes, 0); + const rc = try posix.pwrite(file.handle, bytes, 0); + try expectEqual(rc, 0); } fn expectMode(dir: posix.fd_t, file: []const u8, mode: posix.mode_t) !void { diff --git a/lib/std/process.zig b/lib/std/process.zig index dd08e88af2..b734276444 100644 --- a/lib/std/process.zig +++ b/lib/std/process.zig @@ -1539,6 +1539,7 @@ pub fn getUserInfo(name: []const u8) !UserInfo { .haiku, .solaris, .illumos, + .serenity, => posixGetUserInfo(name), else => @compileError("Unsupported OS"), }; diff --git a/lib/std/time/epoch.zig b/lib/std/time/epoch.zig index b409d3e9eb..fa7499aec7 100644 --- a/lib/std/time/epoch.zig +++ b/lib/std/time/epoch.zig @@ -64,8 +64,6 @@ pub fn getDaysInYear(year: Year) u9 { return if (isLeapYear(year)) 366 else 365; } -pub const YearLeapKind = enum(u1) { not_leap, leap }; - pub const Month = enum(u4) { jan = 1, feb, @@ -87,13 +85,13 @@ pub const Month = enum(u4) { } }; -/// Get the number of days in the given month -pub fn getDaysInMonth(leap_year: YearLeapKind, month: Month) u5 { +/// Get the number of days in the given month and year +pub fn getDaysInMonth(year: Year, month: Month) u5 { return switch (month) { .jan => 31, - .feb => @as(u5, switch (leap_year) { - .leap => 29, - .not_leap => 28, + .feb => @as(u5, switch (isLeapYear(year)) { + true => 29, + false => 28, }), .mar => 31, .apr => 30, @@ -116,9 +114,8 @@ pub const YearAndDay = struct { pub fn calculateMonthDay(self: YearAndDay) MonthAndDay { var month: Month = .jan; var days_left = self.day; - const leap_kind: YearLeapKind = if (isLeapYear(self.year)) .leap else .not_leap; while (true) { - const days_in_month = getDaysInMonth(leap_kind, month); + const days_in_month = getDaysInMonth(self.year, month); if (days_left < days_in_month) break; days_left -= days_in_month; diff --git a/lib/std/zig/system.zig b/lib/std/zig/system.zig index 84f9cf7330..a4b16d6c46 100644 --- a/lib/std/zig/system.zig +++ b/lib/std/zig/system.zig @@ -539,7 +539,7 @@ pub fn abiAndDynamicLinkerFromFile( var result: Target = .{ .cpu = cpu, .os = os, - .abi = query.abi orelse Target.Abi.default(cpu.arch, os), + .abi = query.abi orelse Target.Abi.default(cpu.arch, os.tag), .ofmt = query.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch), .dynamic_linker = query.dynamic_linker, }; @@ -1213,7 +1213,7 @@ fn detectAbiAndDynamicLinker( } fn defaultAbiAndDynamicLinker(cpu: Target.Cpu, os: Target.Os, query: Target.Query) Target { - const abi = query.abi orelse Target.Abi.default(cpu.arch, os); + const abi = query.abi orelse Target.Abi.default(cpu.arch, os.tag); return .{ .cpu = cpu, .os = os, diff --git a/lib/std/zig/target.zig b/lib/std/zig/target.zig index f4c6ae6885..ee46288903 100644 --- a/lib/std/zig/target.zig +++ b/lib/std/zig/target.zig @@ -318,6 +318,17 @@ pub fn isLibCLibName(target: std.Target, name: []const u8) bool { return true; } + if (target.os.tag == .serenity) { + if (eqlIgnoreCase(ignore_case, name, "dl")) + return true; + if (eqlIgnoreCase(ignore_case, name, "m")) + return true; + if (eqlIgnoreCase(ignore_case, name, "pthread")) + return true; + if (eqlIgnoreCase(ignore_case, name, "ssp")) + return true; + } + return false; } |
