authorgravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2022-05-14 14:16:19+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-05-16 17:43:44-04:00
log1392c24166f9edc1dd22c979689dcec456292ef4
tree08d7f0be23e22252d9e4649a40357f8dcd6aa30c
parent5b03d55c5ecf697086db7c454e0f3982fec42408

std.os: Add memfd_create for FreeBSD

This is minorly breaking as e.g. std.os.linux.MFD_CLOEXEC is now std.os.linux.MFD.CLOEXEC.

4 files changed, 65 insertions(+), 35 deletions(-)

lib/std/c/freebsd.zig+9
......@@ -1640,3 +1640,12 @@ pub const POLL = struct {
16401640
16411641 pub const STANDARD = IN | PRI | OUT | RDNORM | RDBAND | WRBAND | ERR | HUP | NVAL;
16421642};
1643
1644pub const NAME_MAX = 255;
1645
1646pub const MFD = struct {
1647 pub const CLOEXEC = 0x0001;
1648 pub const ALLOW_SEALING = 0x0002;
1649};
1650
1651pub extern "c" fn memfd_create(name: [*:0]const u8, flags: c_uint) c_int;
lib/std/os.zig+32-14
......@@ -97,6 +97,7 @@ pub const MADV = system.MADV;
9797pub const MAP = system.MAP;
9898pub const MSF = system.MSF;
9999pub const MAX_ADDR_LEN = system.MAX_ADDR_LEN;
100pub const MFD = system.MFD;
100101pub const MMAP2_UNIT = system.MMAP2_UNIT;
101102pub const MSG = system.MSG;
102103pub const NAME_MAX = system.NAME_MAX;
......@@ -6522,20 +6523,37 @@ pub const MemFdCreateError = error{
65226523} || UnexpectedError;
65236524
65246525pub fn memfd_createZ(name: [*:0]const u8, flags: u32) MemFdCreateError!fd_t {
6525 // memfd_create is available only in glibc versions starting with 2.27.
6526 const use_c = std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 }).ok;
6527 const sys = if (use_c) std.c else linux;
6528 const getErrno = if (use_c) std.c.getErrno else linux.getErrno;
6529 const rc = sys.memfd_create(name, flags);
6530 switch (getErrno(rc)) {
6531 .SUCCESS => return @intCast(fd_t, rc),
6532 .FAULT => unreachable, // name has invalid memory
6533 .INVAL => unreachable, // name/flags are faulty
6534 .NFILE => return error.SystemFdQuotaExceeded,
6535 .MFILE => return error.ProcessFdQuotaExceeded,
6536 .NOMEM => return error.OutOfMemory,
6537 .NOSYS => return error.SystemOutdated,
6538 else => |err| return unexpectedErrno(err),
6526 switch (builtin.os.tag) {
6527 .linux => {
6528 // memfd_create is available only in glibc versions starting with 2.27.
6529 const use_c = std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 }).ok;
6530 const sys = if (use_c) std.c else linux;
6531 const getErrno = if (use_c) std.c.getErrno else linux.getErrno;
6532 const rc = sys.memfd_create(name, flags);
6533 switch (getErrno(rc)) {
6534 .SUCCESS => return @intCast(fd_t, rc),
6535 .FAULT => unreachable, // name has invalid memory
6536 .INVAL => unreachable, // name/flags are faulty
6537 .NFILE => return error.SystemFdQuotaExceeded,
6538 .MFILE => return error.ProcessFdQuotaExceeded,
6539 .NOMEM => return error.OutOfMemory,
6540 .NOSYS => return error.SystemOutdated,
6541 else => |err| return unexpectedErrno(err),
6542 }
6543 },
6544 .freebsd => {
6545 const rc = system.memfd_create(name, flags);
6546 switch (errno(rc)) {
6547 .SUCCESS => return rc,
6548 .BADF => unreachable, // name argument NULL
6549 .INVAL => unreachable, // name too long or invalid/unsupported flags.
6550 .MFILE => return error.ProcessFdQuotaExceeded,
6551 .NFILE => return error.SystemFdQuotaExceeded,
6552 .NOSYS => return error.SystemOutdated,
6553 else => |err| return unexpectedErrno(err),
6554 }
6555 },
6556 else => @compileError("target OS does not support memfd_create()"),
65396557 }
65406558}
65416559
lib/std/os/linux.zig+21-19
......@@ -3972,11 +3972,6 @@ pub const POLL = struct {
39723972 pub const RDBAND = 0x080;
39733973};
39743974
3975pub const MFD_CLOEXEC = 0x0001;
3976pub const MFD_ALLOW_SEALING = 0x0002;
3977pub const MFD_HUGETLB = 0x0004;
3978pub const MFD_ALL_FLAGS = MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_HUGETLB;
3979
39803975pub const HUGETLB_FLAG_ENCODE_SHIFT = 26;
39813976pub const HUGETLB_FLAG_ENCODE_MASK = 0x3f;
39823977pub const HUGETLB_FLAG_ENCODE_64KB = 16 << HUGETLB_FLAG_ENCODE_SHIFT;
......@@ -3992,20 +3987,27 @@ pub const HUGETLB_FLAG_ENCODE_1GB = 30 << HUGETLB_FLAG_ENCODE_SHIFT;
39923987pub const HUGETLB_FLAG_ENCODE_2GB = 31 << HUGETLB_FLAG_ENCODE_SHIFT;
39933988pub const HUGETLB_FLAG_ENCODE_16GB = 34 << HUGETLB_FLAG_ENCODE_SHIFT;
39943989
3995pub const MFD_HUGE_SHIFT = HUGETLB_FLAG_ENCODE_SHIFT;
3996pub const MFD_HUGE_MASK = HUGETLB_FLAG_ENCODE_MASK;
3997pub const MFD_HUGE_64KB = HUGETLB_FLAG_ENCODE_64KB;
3998pub const MFD_HUGE_512KB = HUGETLB_FLAG_ENCODE_512KB;
3999pub const MFD_HUGE_1MB = HUGETLB_FLAG_ENCODE_1MB;
4000pub const MFD_HUGE_2MB = HUGETLB_FLAG_ENCODE_2MB;
4001pub const MFD_HUGE_8MB = HUGETLB_FLAG_ENCODE_8MB;
4002pub const MFD_HUGE_16MB = HUGETLB_FLAG_ENCODE_16MB;
4003pub const MFD_HUGE_32MB = HUGETLB_FLAG_ENCODE_32MB;
4004pub const MFD_HUGE_256MB = HUGETLB_FLAG_ENCODE_256MB;
4005pub const MFD_HUGE_512MB = HUGETLB_FLAG_ENCODE_512MB;
4006pub const MFD_HUGE_1GB = HUGETLB_FLAG_ENCODE_1GB;
4007pub const MFD_HUGE_2GB = HUGETLB_FLAG_ENCODE_2GB;
4008pub const MFD_HUGE_16GB = HUGETLB_FLAG_ENCODE_16GB;
3990pub const MFD = struct {
3991 pub const CLOEXEC = 0x0001;
3992 pub const ALLOW_SEALING = 0x0002;
3993 pub const HUGETLB = 0x0004;
3994 pub const ALL_FLAGS = CLOEXEC | ALLOW_SEALING | HUGETLB;
3995
3996 pub const HUGE_SHIFT = HUGETLB_FLAG_ENCODE_SHIFT;
3997 pub const HUGE_MASK = HUGETLB_FLAG_ENCODE_MASK;
3998 pub const HUGE_64KB = HUGETLB_FLAG_ENCODE_64KB;
3999 pub const HUGE_512KB = HUGETLB_FLAG_ENCODE_512KB;
4000 pub const HUGE_1MB = HUGETLB_FLAG_ENCODE_1MB;
4001 pub const HUGE_2MB = HUGETLB_FLAG_ENCODE_2MB;
4002 pub const HUGE_8MB = HUGETLB_FLAG_ENCODE_8MB;
4003 pub const HUGE_16MB = HUGETLB_FLAG_ENCODE_16MB;
4004 pub const HUGE_32MB = HUGETLB_FLAG_ENCODE_32MB;
4005 pub const HUGE_256MB = HUGETLB_FLAG_ENCODE_256MB;
4006 pub const HUGE_512MB = HUGETLB_FLAG_ENCODE_512MB;
4007 pub const HUGE_1GB = HUGETLB_FLAG_ENCODE_1GB;
4008 pub const HUGE_2GB = HUGETLB_FLAG_ENCODE_2GB;
4009 pub const HUGE_16GB = HUGETLB_FLAG_ENCODE_16GB;
4010};
40094011
40104012pub const rusage = extern struct {
40114013 utime: timeval,
lib/std/os/test.zig+3-2
......@@ -495,8 +495,9 @@ test "argsAlloc" {
495495}
496496
497497test "memfd_create" {
498 // memfd_create is linux specific.
499 if (native_os != .linux) return error.SkipZigTest;
498 // memfd_create is only supported by linux and freebsd.
499 if (native_os != .linux and native_os != .freebsd) return error.SkipZigTest;
500
500501 const fd = std.os.memfd_create("test", 0) catch |err| switch (err) {
501502 // Related: https://github.com/ziglang/zig/issues/4019
502503 error.SystemOutdated => return error.SkipZigTest,