| author | |
| committer | |
| log | 8186211404552a31eaf2a7bc182a46a7e40eacda |
| tree | 3e93cad370217a1a65fad5b3a91e91300f120123 |
| parent | a153a972adbe783bc8a0d08df0942a3bf0552188 |
| signature | Commit is signed but in an unrecognized format. |
* 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 #40193 files changed, 34 insertions(+), 17 deletions(-)
lib/std/io/test.zig-14| ... | ... | @@ -649,17 +649,3 @@ test "updateTimes" { |
| 649 | 649 | std.testing.expect(stat_new.atime < stat_old.atime); |
| 650 | 650 | std.testing.expect(stat_new.mtime < stat_old.mtime); |
| 651 | 651 | } |
| 652 | ||
| 653 | test "memfd_create" { | |
| 654 | if (builtin.os != .linux) return error.SkipZigTest; | |
| 655 | ||
| 656 | const fd = try std.os.memfd_create("test", 0); | |
| 657 | defer std.os.close(fd); | |
| 658 | try std.os.write(fd, "test"); | |
| 659 | try std.os.lseek_SET(fd, 0); | |
| 660 | ||
| 661 | var buf: [10]u8 = undefined; | |
| 662 | const bytes_read = try std.os.read(fd, &buf); | |
| 663 | expect(bytes_read == 4); | |
| 664 | expect(mem.eql(u8, buf[0..4], "test")); | |
| 665 | } |
lib/std/os.zig+13-3| ... | ... | @@ -3282,9 +3282,19 @@ pub fn setsockopt(fd: fd_t, level: u32, optname: u32, opt: []const u8) SetSockOp |
| 3282 | 3282 | } |
| 3283 | 3283 | } |
| 3284 | 3284 | |
| 3285 | pub const MemFdCreateError = error{ | |
| 3286 | SystemFdQuotaExceeded, | |
| 3287 | ProcessFdQuotaExceeded, | |
| 3288 | OutOfMemory, | |
| 3289 | } || UnexpectedError; | |
| 3290 | ||
| 3285 | 3291 | pub fn memfd_createC(name: [*:0]const u8, flags: u32) !fd_t { |
| 3286 | const rc = system.memfd_create(name, flags); | |
| 3287 | switch (errno(rc)) { | |
| 3292 | // memfd_create is available only in glibc versions starting with 2.27. | |
| 3293 | const use_c = std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 }).ok; | |
| 3294 | const sys = if (use_c) std.c else linux; | |
| 3295 | const getErrno = if (use_c) std.c.getErrno else linux.getErrno; | |
| 3296 | const rc = sys.memfd_create(name, flags); | |
| 3297 | switch (getErrno(rc)) { | |
| 3288 | 3298 | 0 => return @intCast(fd_t, rc), |
| 3289 | 3299 | EFAULT => unreachable, // name has invalid memory |
| 3290 | 3300 | EINVAL => unreachable, // name/flags are faulty |
| ... | ... | @@ -3308,5 +3318,5 @@ fn toMemFdPath(name: []const u8) ![MFD_MAX_NAME_LEN:0]u8 { |
| 3308 | 3318 | |
| 3309 | 3319 | pub fn memfd_create(name: []const u8, flags: u32) !fd_t { |
| 3310 | 3320 | const name_t = try toMemFdPath(name); |
| 3311 | return try memfd_createC(&name_t, flags); | |
| 3321 | return memfd_createC(&name_t, flags); | |
| 3312 | 3322 | } |
lib/std/os/test.zig+21| ... | ... | @@ -237,3 +237,24 @@ test "argsAlloc" { |
| 237 | 237 | var args = try std.process.argsAlloc(std.heap.page_allocator); |
| 238 | 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 | // Zig's CI testing infrastructure uses QEMU. Currently the version is | |
| 245 | // qemu 2.11 from Ubuntu 18.04, which does not have memfd_create support. | |
| 246 | // memfd_create support is introduced in qemu 4.2. To avoid | |
| 247 | // "invalid syscall" errors from qemu, we disable the test when not linking libc. | |
| 248 | // https://github.com/ziglang/zig/issues/4019 | |
| 249 | if (!builtin.link_libc) return error.SkipZigTest; | |
| 250 | ||
| 251 | const fd = try std.os.memfd_create("test", 0); | |
| 252 | defer std.os.close(fd); | |
| 253 | try std.os.write(fd, "test"); | |
| 254 | try std.os.lseek_SET(fd, 0); | |
| 255 | ||
| 256 | var buf: [10]u8 = undefined; | |
| 257 | const bytes_read = try std.os.read(fd, &buf); | |
| 258 | expect(bytes_read == 4); | |
| 259 | expect(mem.eql(u8, buf[0..4], "test")); | |
| 260 | } |