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 #4019master
parent
a153a972ad
commit
8186211404
|
@ -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"));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue