diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2019-12-31 16:34:14 -0500 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2019-12-31 16:34:14 -0500 |
| commit | 8186211404552a31eaf2a7bc182a46a7e40eacda (patch) | |
| tree | 3e93cad370217a1a65fad5b3a91e91300f120123 /lib/std | |
| parent | a153a972adbe783bc8a0d08df0942a3bf0552188 (diff) | |
| download | zig-8186211404552a31eaf2a7bc182a46a7e40eacda.tar.gz zig-8186211404552a31eaf2a7bc182a46a7e40eacda.zip | |
improvements to memfd_create
* move test from std/io/test.zig to std/os/test.zig
* do glibc version check, and make direct system call if
glibc is too old
* disable test when not linking libc, to avoid not working
with outdated qemu version on the CI server. see #4019
Diffstat (limited to 'lib/std')
| -rw-r--r-- | lib/std/io/test.zig | 14 | ||||
| -rw-r--r-- | lib/std/os.zig | 16 | ||||
| -rw-r--r-- | lib/std/os/test.zig | 21 |
3 files changed, 34 insertions, 17 deletions
diff --git a/lib/std/io/test.zig b/lib/std/io/test.zig index b572a7bf92..92259fd6e9 100644 --- a/lib/std/io/test.zig +++ b/lib/std/io/test.zig @@ -649,17 +649,3 @@ test "updateTimes" { std.testing.expect(stat_new.atime < stat_old.atime); std.testing.expect(stat_new.mtime < stat_old.mtime); } - -test "memfd_create" { - if (builtin.os != .linux) return error.SkipZigTest; - - const fd = try std.os.memfd_create("test", 0); - defer std.os.close(fd); - try std.os.write(fd, "test"); - try std.os.lseek_SET(fd, 0); - - var buf: [10]u8 = undefined; - const bytes_read = try std.os.read(fd, &buf); - expect(bytes_read == 4); - expect(mem.eql(u8, buf[0..4], "test")); -} diff --git a/lib/std/os.zig b/lib/std/os.zig index 31212e9b8b..b51dbe7d2a 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -3282,9 +3282,19 @@ pub fn setsockopt(fd: fd_t, level: u32, optname: u32, opt: []const u8) SetSockOp } } +pub const MemFdCreateError = error{ + SystemFdQuotaExceeded, + ProcessFdQuotaExceeded, + OutOfMemory, +} || UnexpectedError; + pub fn memfd_createC(name: [*:0]const u8, flags: u32) !fd_t { - const rc = system.memfd_create(name, flags); - switch (errno(rc)) { + // memfd_create is available only in glibc versions starting with 2.27. + const use_c = std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 }).ok; + const sys = if (use_c) std.c else linux; + const getErrno = if (use_c) std.c.getErrno else linux.getErrno; + const rc = sys.memfd_create(name, flags); + switch (getErrno(rc)) { 0 => return @intCast(fd_t, rc), EFAULT => unreachable, // name has invalid memory EINVAL => unreachable, // name/flags are faulty @@ -3308,5 +3318,5 @@ fn toMemFdPath(name: []const u8) ![MFD_MAX_NAME_LEN:0]u8 { pub fn memfd_create(name: []const u8, flags: u32) !fd_t { const name_t = try toMemFdPath(name); - return try memfd_createC(&name_t, flags); + return memfd_createC(&name_t, flags); } diff --git a/lib/std/os/test.zig b/lib/std/os/test.zig index f61e8b4657..16946660e4 100644 --- a/lib/std/os/test.zig +++ b/lib/std/os/test.zig @@ -237,3 +237,24 @@ test "argsAlloc" { var args = try std.process.argsAlloc(std.heap.page_allocator); std.process.argsFree(std.heap.page_allocator, args); } + +test "memfd_create" { + // memfd_create is linux specific. + if (builtin.os != .linux) return error.SkipZigTest; + // Zig's CI testing infrastructure uses QEMU. Currently the version is + // qemu 2.11 from Ubuntu 18.04, which does not have memfd_create support. + // memfd_create support is introduced in qemu 4.2. To avoid + // "invalid syscall" errors from qemu, we disable the test when not linking libc. + // https://github.com/ziglang/zig/issues/4019 + if (!builtin.link_libc) return error.SkipZigTest; + + const fd = try std.os.memfd_create("test", 0); + defer std.os.close(fd); + try std.os.write(fd, "test"); + try std.os.lseek_SET(fd, 0); + + var buf: [10]u8 = undefined; + const bytes_read = try std.os.read(fd, &buf); + expect(bytes_read == 4); + expect(mem.eql(u8, buf[0..4], "test")); +} |
