| author | |
| committer | |
| log | 0fb3e6608c160a0cd9db75fe1ba3d5bb7dac8fa8 |
| tree | 763b53d7ddba82762ee32f4e7b724ffe9f97103d |
| parent | c8c65b0168ae18f8bd8bf8f38590109a30df73a8 |
| parent | 0c8ec369f051d616434cff309fe737c52fd98199 |
| signature | Commit is signed but in an unrecognized format. |
Closes #36876 files changed, 111 insertions(+), 0 deletions(-)
lib/std/c/linux.zig+2| ... | @@ -76,6 +76,8 @@ pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_ | ... | @@ -76,6 +76,8 @@ pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_ |
| 76 | 76 | ||
| 77 | pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int; | 77 | pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int; |
| 78 | 78 | ||
| 79 | pub extern "c" fn memfd_create(name: [*:0]const u8, flags: c_uint) c_int; | ||
| 80 | |||
| 79 | pub const pthread_attr_t = extern struct { | 81 | pub const pthread_attr_t = extern struct { |
| 80 | __size: [56]u8, | 82 | __size: [56]u8, |
| 81 | __align: c_long, | 83 | __align: c_long, |
lib/std/os.zig+44| ... | @@ -3281,3 +3281,47 @@ pub fn setsockopt(fd: fd_t, level: u32, optname: u32, opt: []const u8) SetSockOp | ... | @@ -3281,3 +3281,47 @@ pub fn setsockopt(fd: fd_t, level: u32, optname: u32, opt: []const u8) SetSockOp |
| 3281 | else => |err| return unexpectedErrno(err), | 3281 | else => |err| return unexpectedErrno(err), |
| 3282 | } | 3282 | } |
| 3283 | } | 3283 | } |
| 3284 | |||
| 3285 | pub const MemFdCreateError = error{ | ||
| 3286 | SystemFdQuotaExceeded, | ||
| 3287 | ProcessFdQuotaExceeded, | ||
| 3288 | OutOfMemory, | ||
| 3289 | |||
| 3290 | /// memfd_create is available in Linux 3.17 and later. This error is returned | ||
| 3291 | /// for older kernel versions. | ||
| 3292 | SystemOutdated, | ||
| 3293 | } || UnexpectedError; | ||
| 3294 | |||
| 3295 | pub fn memfd_createC(name: [*:0]const u8, flags: u32) MemFdCreateError!fd_t { | ||
| 3296 | // memfd_create is available only in glibc versions starting with 2.27. | ||
| 3297 | const use_c = std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 }).ok; | ||
| 3298 | const sys = if (use_c) std.c else linux; | ||
| 3299 | const getErrno = if (use_c) std.c.getErrno else linux.getErrno; | ||
| 3300 | const rc = sys.memfd_create(name, flags); | ||
| 3301 | switch (getErrno(rc)) { | ||
| 3302 | 0 => return @intCast(fd_t, rc), | ||
| 3303 | EFAULT => unreachable, // name has invalid memory | ||
| 3304 | EINVAL => unreachable, // name/flags are faulty | ||
| 3305 | ENFILE => return error.SystemFdQuotaExceeded, | ||
| 3306 | EMFILE => return error.ProcessFdQuotaExceeded, | ||
| 3307 | ENOMEM => return error.OutOfMemory, | ||
| 3308 | ENOSYS => return error.SystemOutdated, | ||
| 3309 | else => |err| return unexpectedErrno(err), | ||
| 3310 | } | ||
| 3311 | } | ||
| 3312 | |||
| 3313 | pub const MFD_NAME_PREFIX = "memfd:"; | ||
| 3314 | pub const MFD_MAX_NAME_LEN = NAME_MAX - MFD_NAME_PREFIX.len; | ||
| 3315 | fn toMemFdPath(name: []const u8) ![MFD_MAX_NAME_LEN:0]u8 { | ||
| 3316 | var path_with_null: [MFD_MAX_NAME_LEN:0]u8 = undefined; | ||
| 3317 | // >= rather than > to make room for the null byte | ||
| 3318 | if (name.len >= MFD_MAX_NAME_LEN) return error.NameTooLong; | ||
| 3319 | mem.copy(u8, &path_with_null, name); | ||
| 3320 | path_with_null[name.len] = 0; | ||
| 3321 | return path_with_null; | ||
| 3322 | } | ||
| 3323 | |||
| 3324 | pub fn memfd_create(name: []const u8, flags: u32) !fd_t { | ||
| 3325 | const name_t = try toMemFdPath(name); | ||
| 3326 | return memfd_createC(&name_t, flags); | ||
| 3327 | } |
lib/std/os/bits/linux.zig+36| ... | @@ -26,6 +26,7 @@ pub const uid_t = i32; | ... | @@ -26,6 +26,7 @@ pub const uid_t = i32; |
| 26 | pub const gid_t = u32; | 26 | pub const gid_t = u32; |
| 27 | pub const clock_t = isize; | 27 | pub const clock_t = isize; |
| 28 | 28 | ||
| 29 | pub const NAME_MAX = 255; | ||
| 29 | pub const PATH_MAX = 4096; | 30 | pub const PATH_MAX = 4096; |
| 30 | pub const IOV_MAX = 1024; | 31 | pub const IOV_MAX = 1024; |
| 31 | 32 | ||
| ... | @@ -1417,3 +1418,38 @@ pub const POLLHUP = 0x010; | ... | @@ -1417,3 +1418,38 @@ pub const POLLHUP = 0x010; |
| 1417 | pub const POLLNVAL = 0x020; | 1418 | pub const POLLNVAL = 0x020; |
| 1418 | pub const POLLRDNORM = 0x040; | 1419 | pub const POLLRDNORM = 0x040; |
| 1419 | pub const POLLRDBAND = 0x080; | 1420 | pub const POLLRDBAND = 0x080; |
| 1421 | |||
| 1422 | pub const MFD_CLOEXEC = 0x0001; | ||
| 1423 | pub const MFD_ALLOW_SEALING = 0x0002; | ||
| 1424 | pub const MFD_HUGETLB = 0x0004; | ||
| 1425 | pub const MFD_ALL_FLAGS = MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_HUGETLB; | ||
| 1426 | |||
| 1427 | pub const HUGETLB_FLAG_ENCODE_SHIFT = 26; | ||
| 1428 | pub const HUGETLB_FLAG_ENCODE_MASK = 0x3f; | ||
| 1429 | pub const HUGETLB_FLAG_ENCODE_64KB = 16 << HUGETLB_FLAG_ENCODE_SHIFT; | ||
| 1430 | pub const HUGETLB_FLAG_ENCODE_512KB = 19 << HUGETLB_FLAG_ENCODE_SHIFT; | ||
| 1431 | pub const HUGETLB_FLAG_ENCODE_1MB = 20 << HUGETLB_FLAG_ENCODE_SHIFT; | ||
| 1432 | pub const HUGETLB_FLAG_ENCODE_2MB = 21 << HUGETLB_FLAG_ENCODE_SHIFT; | ||
| 1433 | pub const HUGETLB_FLAG_ENCODE_8MB = 23 << HUGETLB_FLAG_ENCODE_SHIFT; | ||
| 1434 | pub const HUGETLB_FLAG_ENCODE_16MB = 24 << HUGETLB_FLAG_ENCODE_SHIFT; | ||
| 1435 | pub const HUGETLB_FLAG_ENCODE_32MB = 25 << HUGETLB_FLAG_ENCODE_SHIFT; | ||
| 1436 | pub const HUGETLB_FLAG_ENCODE_256MB = 28 << HUGETLB_FLAG_ENCODE_SHIFT; | ||
| 1437 | pub const HUGETLB_FLAG_ENCODE_512MB = 29 << HUGETLB_FLAG_ENCODE_SHIFT; | ||
| 1438 | pub const HUGETLB_FLAG_ENCODE_1GB = 30 << HUGETLB_FLAG_ENCODE_SHIFT; | ||
| 1439 | pub const HUGETLB_FLAG_ENCODE_2GB = 31 << HUGETLB_FLAG_ENCODE_SHIFT; | ||
| 1440 | pub const HUGETLB_FLAG_ENCODE_16GB = 34 << HUGETLB_FLAG_ENCODE_SHIFT; | ||
| 1441 | |||
| 1442 | pub const MFD_HUGE_SHIFT = HUGETLB_FLAG_ENCODE_SHIFT; | ||
| 1443 | pub const MFD_HUGE_MASK = HUGETLB_FLAG_ENCODE_MASK; | ||
| 1444 | pub const MFD_HUGE_64KB = HUGETLB_FLAG_ENCODE_64KB; | ||
| 1445 | pub const MFD_HUGE_512KB = HUGETLB_FLAG_ENCODE_512KB; | ||
| 1446 | pub const MFD_HUGE_1MB = HUGETLB_FLAG_ENCODE_1MB; | ||
| 1447 | pub const MFD_HUGE_2MB = HUGETLB_FLAG_ENCODE_2MB; | ||
| 1448 | pub const MFD_HUGE_8MB = HUGETLB_FLAG_ENCODE_8MB; | ||
| 1449 | pub const MFD_HUGE_16MB = HUGETLB_FLAG_ENCODE_16MB; | ||
| 1450 | pub const MFD_HUGE_32MB = HUGETLB_FLAG_ENCODE_32MB; | ||
| 1451 | pub const MFD_HUGE_256MB = HUGETLB_FLAG_ENCODE_256MB; | ||
| 1452 | pub const MFD_HUGE_512MB = HUGETLB_FLAG_ENCODE_512MB; | ||
| 1453 | pub const MFD_HUGE_1GB = HUGETLB_FLAG_ENCODE_1GB; | ||
| 1454 | pub const MFD_HUGE_2GB = HUGETLB_FLAG_ENCODE_2GB; | ||
| 1455 | pub const MFD_HUGE_16GB = HUGETLB_FLAG_ENCODE_16GB; |
lib/std/os/linux.zig+4| ... | @@ -1110,6 +1110,10 @@ pub fn io_uring_register(fd: i32, opcode: u32, arg: ?*const c_void, nr_args: u32 | ... | @@ -1110,6 +1110,10 @@ pub fn io_uring_register(fd: i32, opcode: u32, arg: ?*const c_void, nr_args: u32 |
| 1110 | return syscall4(SYS_io_uring_register, @bitCast(usize, @as(isize, fd)), opcode, @ptrToInt(arg), nr_args); | 1110 | return syscall4(SYS_io_uring_register, @bitCast(usize, @as(isize, fd)), opcode, @ptrToInt(arg), nr_args); |
| 1111 | } | 1111 | } |
| 1112 | 1112 | ||
| 1113 | pub fn memfd_create(name: [*:0]const u8, flags: u32) usize { | ||
| 1114 | return syscall2(SYS_memfd_create, @ptrToInt(name), flags); | ||
| 1115 | } | ||
| 1116 | |||
| 1113 | test "" { | 1117 | test "" { |
| 1114 | if (builtin.os == .linux) { | 1118 | if (builtin.os == .linux) { |
| 1115 | _ = @import("linux/test.zig"); | 1119 | _ = @import("linux/test.zig"); |
lib/std/os/test.zig+18| ... | @@ -237,3 +237,21 @@ test "argsAlloc" { | ... | @@ -237,3 +237,21 @@ test "argsAlloc" { |
| 237 | var args = try std.process.argsAlloc(std.heap.page_allocator); | 237 | var args = try std.process.argsAlloc(std.heap.page_allocator); |
| 238 | std.process.argsFree(std.heap.page_allocator, args); | 238 | std.process.argsFree(std.heap.page_allocator, args); |
| 239 | } | 239 | } |
| 240 | |||
| 241 | test "memfd_create" { | ||
| 242 | // memfd_create is linux specific. | ||
| 243 | if (builtin.os != .linux) return error.SkipZigTest; | ||
| 244 | const fd = std.os.memfd_create("test", 0) catch |err| switch (err) { | ||
| 245 | // Related: https://github.com/ziglang/zig/issues/4019 | ||
| 246 | error.SystemOutdated => return error.SkipZigTest, | ||
| 247 | else => |e| return e, | ||
| 248 | }; | ||
| 249 | defer std.os.close(fd); | ||
| 250 | try std.os.write(fd, "test"); | ||
| 251 | try std.os.lseek_SET(fd, 0); | ||
| 252 | |||
| 253 | var buf: [10]u8 = undefined; | ||
| 254 | const bytes_read = try std.os.read(fd, &buf); | ||
| 255 | expect(bytes_read == 4); | ||
| 256 | expect(mem.eql(u8, buf[0..4], "test")); | ||
| 257 | } |
lib/std/target.zig+7| ... | @@ -597,6 +597,13 @@ pub const Target = union(enum) { | ... | @@ -597,6 +597,13 @@ pub const Target = union(enum) { |
| 597 | }; | 597 | }; |
| 598 | } | 598 | } |
| 599 | 599 | ||
| 600 | pub fn isMusl(self: Target) bool { | ||
| 601 | return switch (self.getAbi()) { | ||
| 602 | .musl, .musleabi, .musleabihf => true, | ||
| 603 | else => false, | ||
| 604 | }; | ||
| 605 | } | ||
| 606 | |||
| 600 | pub fn isDarwin(self: Target) bool { | 607 | pub fn isDarwin(self: Target) bool { |
| 601 | return switch (self.getOs()) { | 608 | return switch (self.getOs()) { |
| 602 | .ios, .macosx, .watchos, .tvos => true, | 609 | .ios, .macosx, .watchos, .tvos => true, |