| author | |
| committer | |
| log | 7998e2b0f41bff86d8fbbb8112dd6c629d47e849 |
| tree | 9f7bca5991f9fcdb291da10e2c830a749769dfad |
| parent | 5656f5090d8646e076db50da03cfc6ae686eb76b |
| parent | 8ebcca6734e07aea29098ca4c63c0216b3099d0e |
8 files changed, 78 insertions(+), 27 deletions(-)
ci/azure/linux_script+1-1| ... | ... | @@ -14,7 +14,7 @@ sudo apt-get remove -y llvm-* |
| 14 | 14 | sudo rm -rf /usr/local/* |
| 15 | 15 | sudo apt-get install -y libxml2-dev libclang-10-dev llvm-10 llvm-10-dev liblld-10-dev cmake s3cmd gcc-7 g++-7 |
| 16 | 16 | |
| 17 | QEMUBASE="qemu-linux-x86_64-5.0.0" | |
| 17 | QEMUBASE="qemu-linux-x86_64-5.0.0-z2" | |
| 18 | 18 | wget https://ziglang.org/deps/$QEMUBASE.tar.xz |
| 19 | 19 | tar xf $QEMUBASE.tar.xz |
| 20 | 20 | PATH=$PWD/$QEMUBASE/bin:$PATH |
lib/std/c/netbsd.zig+1| ... | ... | @@ -9,6 +9,7 @@ pub const _errno = __errno; |
| 9 | 9 | pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int; |
| 10 | 10 | pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int; |
| 11 | 11 | |
| 12 | pub extern "c" fn arc4random_buf(buf: [*]u8, len: usize) void; | |
| 12 | 13 | pub extern "c" fn __fstat50(fd: fd_t, buf: *Stat) c_int; |
| 13 | 14 | pub extern "c" fn __stat50(path: [*:0]const u8, buf: *Stat) c_int; |
| 14 | 15 | pub extern "c" fn __clock_gettime50(clk_id: c_int, tp: *timespec) c_int; |
lib/std/event/loop.zig+40-18| ... | ... | @@ -467,18 +467,43 @@ pub const Loop = struct { |
| 467 | 467 | } |
| 468 | 468 | |
| 469 | 469 | pub fn waitUntilFdReadable(self: *Loop, fd: os.fd_t) void { |
| 470 | return self.linuxWaitFd(fd, os.EPOLLET | os.EPOLLONESHOT | os.EPOLLIN); | |
| 470 | switch (builtin.os.tag) { | |
| 471 | .linux => { | |
| 472 | self.linuxWaitFd(fd, os.EPOLLET | os.EPOLLONESHOT | os.EPOLLIN); | |
| 473 | }, | |
| 474 | .macosx, .freebsd, .netbsd, .dragonfly => { | |
| 475 | self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_READ, os.EV_ONESHOT); | |
| 476 | }, | |
| 477 | else => @compileError("Unsupported OS"), | |
| 478 | } | |
| 471 | 479 | } |
| 472 | 480 | |
| 473 | 481 | pub fn waitUntilFdWritable(self: *Loop, fd: os.fd_t) void { |
| 474 | return self.linuxWaitFd(fd, os.EPOLLET | os.EPOLLONESHOT | os.EPOLLOUT); | |
| 482 | switch (builtin.os.tag) { | |
| 483 | .linux => { | |
| 484 | self.linuxWaitFd(fd, os.EPOLLET | os.EPOLLONESHOT | os.EPOLLOUT); | |
| 485 | }, | |
| 486 | .macosx, .freebsd, .netbsd, .dragonfly => { | |
| 487 | self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_WRITE, os.EV_ONESHOT); | |
| 488 | }, | |
| 489 | else => @compileError("Unsupported OS"), | |
| 490 | } | |
| 475 | 491 | } |
| 476 | 492 | |
| 477 | 493 | pub fn waitUntilFdWritableOrReadable(self: *Loop, fd: os.fd_t) void { |
| 478 | return self.linuxWaitFd(fd, os.EPOLLET | os.EPOLLONESHOT | os.EPOLLOUT | os.EPOLLIN); | |
| 494 | switch (builtin.os.tag) { | |
| 495 | .linux => { | |
| 496 | self.linuxWaitFd(@intCast(usize, fd), os.EPOLLET | os.EPOLLONESHOT | os.EPOLLOUT | os.EPOLLIN); | |
| 497 | }, | |
| 498 | .macosx, .freebsd, .netbsd, .dragonfly => { | |
| 499 | self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_READ, os.EV_ONESHOT); | |
| 500 | self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_WRITE, os.EV_ONESHOT); | |
| 501 | }, | |
| 502 | else => @compileError("Unsupported OS"), | |
| 503 | } | |
| 479 | 504 | } |
| 480 | 505 | |
| 481 | pub async fn bsdWaitKev(self: *Loop, ident: usize, filter: i16, fflags: u32) !os.Kevent { | |
| 506 | pub async fn bsdWaitKev(self: *Loop, ident: usize, filter: i16, fflags: u32) void { | |
| 482 | 507 | var resume_node = ResumeNode.Basic{ |
| 483 | 508 | .base = ResumeNode{ |
| 484 | 509 | .id = ResumeNode.Id.Basic, |
| ... | ... | @@ -489,40 +514,37 @@ pub const Loop = struct { |
| 489 | 514 | }; |
| 490 | 515 | defer self.bsdRemoveKev(ident, filter); |
| 491 | 516 | suspend { |
| 492 | try self.bsdAddKev(&resume_node, ident, filter, fflags); | |
| 517 | self.bsdAddKev(&resume_node, ident, filter, fflags) catch unreachable; | |
| 493 | 518 | } |
| 494 | return resume_node.kev; | |
| 495 | 519 | } |
| 496 | 520 | |
| 497 | 521 | /// resume_node must live longer than the anyframe that it holds a reference to. |
| 498 | 522 | pub fn bsdAddKev(self: *Loop, resume_node: *ResumeNode.Basic, ident: usize, filter: i16, fflags: u32) !void { |
| 499 | 523 | self.beginOneEvent(); |
| 500 | 524 | errdefer self.finishOneEvent(); |
| 501 | var kev = os.Kevent{ | |
| 525 | var kev = [1]os.Kevent{os.Kevent{ | |
| 502 | 526 | .ident = ident, |
| 503 | 527 | .filter = filter, |
| 504 | 528 | .flags = os.EV_ADD | os.EV_ENABLE | os.EV_CLEAR, |
| 505 | 529 | .fflags = fflags, |
| 506 | 530 | .data = 0, |
| 507 | 531 | .udata = @ptrToInt(&resume_node.base), |
| 508 | }; | |
| 509 | const kevent_array = (*const [1]os.Kevent)(&kev); | |
| 510 | const empty_kevs = ([*]os.Kevent)(undefined)[0..0]; | |
| 511 | _ = try os.kevent(self.os_data.kqfd, kevent_array, empty_kevs, null); | |
| 532 | }}; | |
| 533 | const empty_kevs = &[0]os.Kevent{}; | |
| 534 | _ = try os.kevent(self.os_data.kqfd, &kev, empty_kevs, null); | |
| 512 | 535 | } |
| 513 | 536 | |
| 514 | 537 | pub fn bsdRemoveKev(self: *Loop, ident: usize, filter: i16) void { |
| 515 | var kev = os.Kevent{ | |
| 538 | var kev = [1]os.Kevent{os.Kevent{ | |
| 516 | 539 | .ident = ident, |
| 517 | 540 | .filter = filter, |
| 518 | 541 | .flags = os.EV_DELETE, |
| 519 | 542 | .fflags = 0, |
| 520 | 543 | .data = 0, |
| 521 | 544 | .udata = 0, |
| 522 | }; | |
| 523 | const kevent_array = (*const [1]os.Kevent)(&kev); | |
| 524 | const empty_kevs = ([*]os.Kevent)(undefined)[0..0]; | |
| 525 | _ = os.kevent(self.os_data.kqfd, kevent_array, empty_kevs, null) catch undefined; | |
| 545 | }}; | |
| 546 | const empty_kevs = &[0]os.Kevent{}; | |
| 547 | _ = os.kevent(self.os_data.kqfd, &kev, empty_kevs, null) catch undefined; | |
| 526 | 548 | self.finishOneEvent(); |
| 527 | 549 | } |
| 528 | 550 | |
| ... | ... | @@ -679,7 +701,7 @@ pub const Loop = struct { |
| 679 | 701 | } |
| 680 | 702 | |
| 681 | 703 | /// Performs an async `os.open` using a separate thread. |
| 682 | pub fn openZ(self: *Loop, file_path: [*:0]const u8, flags: u32, mode: usize) os.OpenError!os.fd_t { | |
| 704 | pub fn openZ(self: *Loop, file_path: [*:0]const u8, flags: u32, mode: os.mode_t) os.OpenError!os.fd_t { | |
| 683 | 705 | var req_node = Request.Node{ |
| 684 | 706 | .data = .{ |
| 685 | 707 | .msg = .{ |
| ... | ... | @@ -700,7 +722,7 @@ pub const Loop = struct { |
| 700 | 722 | } |
| 701 | 723 | |
| 702 | 724 | /// Performs an async `os.opent` using a separate thread. |
| 703 | pub fn openatZ(self: *Loop, fd: os.fd_t, file_path: [*:0]const u8, flags: u32, mode: usize) os.OpenError!os.fd_t { | |
| 725 | pub fn openatZ(self: *Loop, fd: os.fd_t, file_path: [*:0]const u8, flags: u32, mode: os.mode_t) os.OpenError!os.fd_t { | |
| 704 | 726 | var req_node = Request.Node{ |
| 705 | 727 | .data = .{ |
| 706 | 728 | .msg = .{ |
lib/std/fs.zig+3-3| ... | ... | @@ -1449,7 +1449,7 @@ pub fn createFileAbsoluteW(absolute_path_w: [*:0]const u16, flags: File.CreateFl |
| 1449 | 1449 | /// Asserts that the path is absolute. See `Dir.deleteFile` for a function that |
| 1450 | 1450 | /// operates on both absolute and relative paths. |
| 1451 | 1451 | /// Asserts that the path parameter has no null bytes. |
| 1452 | pub fn deleteFileAbsolute(absolute_path: []const u8) DeleteFileError!void { | |
| 1452 | pub fn deleteFileAbsolute(absolute_path: []const u8) Dir.DeleteFileError!void { | |
| 1453 | 1453 | assert(path.isAbsolute(absolute_path)); |
| 1454 | 1454 | return cwd().deleteFile(absolute_path); |
| 1455 | 1455 | } |
| ... | ... | @@ -1457,13 +1457,13 @@ pub fn deleteFileAbsolute(absolute_path: []const u8) DeleteFileError!void { |
| 1457 | 1457 | pub const deleteFileAbsoluteC = @compileError("deprecated: renamed to deleteFileAbsoluteZ"); |
| 1458 | 1458 | |
| 1459 | 1459 | /// Same as `deleteFileAbsolute` except the parameter is null-terminated. |
| 1460 | pub fn deleteFileAbsoluteZ(absolute_path_c: [*:0]const u8) DeleteFileError!void { | |
| 1460 | pub fn deleteFileAbsoluteZ(absolute_path_c: [*:0]const u8) Dir.DeleteFileError!void { | |
| 1461 | 1461 | assert(path.isAbsoluteZ(absolute_path_c)); |
| 1462 | 1462 | return cwd().deleteFileZ(absolute_path_c); |
| 1463 | 1463 | } |
| 1464 | 1464 | |
| 1465 | 1465 | /// Same as `deleteFileAbsolute` except the parameter is WTF-16 encoded. |
| 1466 | pub fn deleteFileAbsoluteW(absolute_path_w: [*:0]const u16) DeleteFileError!void { | |
| 1466 | pub fn deleteFileAbsoluteW(absolute_path_w: [*:0]const u16) Dir.DeleteFileError!void { | |
| 1467 | 1467 | assert(path.isAbsoluteWindowsW(absolute_path_w)); |
| 1468 | 1468 | return cwd().deleteFileW(absolute_path_w); |
| 1469 | 1469 | } |
lib/std/fs/test.zig+16| ... | ... | @@ -110,6 +110,22 @@ test "create file, lock and read from multiple process at once" { |
| 110 | 110 | }; |
| 111 | 111 | } |
| 112 | 112 | |
| 113 | test "open file with exclusive nonblocking lock twice (absolute paths)" { | |
| 114 | const allocator = std.testing.allocator; | |
| 115 | ||
| 116 | const file_paths: [1][]const u8 = .{"zig-test-absolute-paths.txt"}; | |
| 117 | const filename = try fs.path.resolve(allocator, &file_paths); | |
| 118 | defer allocator.free(filename); | |
| 119 | ||
| 120 | const file1 = try fs.createFileAbsolute(filename, .{ .lock = .Exclusive, .lock_nonblocking = true }); | |
| 121 | ||
| 122 | const file2 = fs.createFileAbsolute(filename, .{ .lock = .Exclusive, .lock_nonblocking = true }); | |
| 123 | file1.close(); | |
| 124 | std.testing.expectError(error.WouldBlock, file2); | |
| 125 | ||
| 126 | try fs.deleteFileAbsolute(filename); | |
| 127 | } | |
| 128 | ||
| 113 | 129 | const FileLockTestContext = struct { |
| 114 | 130 | filename: []const u8, |
| 115 | 131 | pid: if (builtin.os.tag == .windows) ?void else ?std.os.pid_t = null, |
lib/std/os.zig+6-2| ... | ... | @@ -153,6 +153,10 @@ pub fn getrandom(buffer: []u8) GetRandomError!void { |
| 153 | 153 | } |
| 154 | 154 | return; |
| 155 | 155 | } |
| 156 | if (builtin.os.tag == .netbsd) { | |
| 157 | netbsd.arc4random_buf(buffer.ptr, buffer.len); | |
| 158 | return; | |
| 159 | } | |
| 156 | 160 | if (builtin.os.tag == .wasi) { |
| 157 | 161 | switch (wasi.random_get(buffer.ptr, buffer.len)) { |
| 158 | 162 | 0 => return, |
| ... | ... | @@ -854,7 +858,7 @@ pub const OpenError = error{ |
| 854 | 858 | |
| 855 | 859 | /// Open and possibly create a file. Keeps trying if it gets interrupted. |
| 856 | 860 | /// See also `openC`. |
| 857 | pub fn open(file_path: []const u8, flags: u32, perm: usize) OpenError!fd_t { | |
| 861 | pub fn open(file_path: []const u8, flags: u32, perm: mode_t) OpenError!fd_t { | |
| 858 | 862 | if (std.Target.current.os.tag == .windows) { |
| 859 | 863 | const file_path_w = try windows.sliceToPrefixedFileW(file_path); |
| 860 | 864 | return openW(file_path_w.span(), flags, perm); |
| ... | ... | @@ -867,7 +871,7 @@ pub const openC = @compileError("deprecated: renamed to openZ"); |
| 867 | 871 | |
| 868 | 872 | /// Open and possibly create a file. Keeps trying if it gets interrupted. |
| 869 | 873 | /// See also `open`. |
| 870 | pub fn openZ(file_path: [*:0]const u8, flags: u32, perm: usize) OpenError!fd_t { | |
| 874 | pub fn openZ(file_path: [*:0]const u8, flags: u32, perm: mode_t) OpenError!fd_t { | |
| 871 | 875 | if (std.Target.current.os.tag == .windows) { |
| 872 | 876 | const file_path_w = try windows.cStrToPrefixedFileW(file_path); |
| 873 | 877 | return openW(file_path_w.span(), flags, perm); |
lib/std/os/linux.zig+3-3| ... | ... | @@ -492,7 +492,7 @@ pub fn renameat2(oldfd: i32, oldpath: [*:0]const u8, newfd: i32, newpath: [*:0]c |
| 492 | 492 | ); |
| 493 | 493 | } |
| 494 | 494 | |
| 495 | pub fn open(path: [*:0]const u8, flags: u32, perm: usize) usize { | |
| 495 | pub fn open(path: [*:0]const u8, flags: u32, perm: mode_t) usize { | |
| 496 | 496 | if (@hasField(SYS, "open")) { |
| 497 | 497 | return syscall3(.open, @ptrToInt(path), flags, perm); |
| 498 | 498 | } else { |
| ... | ... | @@ -506,11 +506,11 @@ pub fn open(path: [*:0]const u8, flags: u32, perm: usize) usize { |
| 506 | 506 | } |
| 507 | 507 | } |
| 508 | 508 | |
| 509 | pub fn create(path: [*:0]const u8, perm: usize) usize { | |
| 509 | pub fn create(path: [*:0]const u8, perm: mode_t) usize { | |
| 510 | 510 | return syscall2(.creat, @ptrToInt(path), perm); |
| 511 | 511 | } |
| 512 | 512 | |
| 513 | pub fn openat(dirfd: i32, path: [*:0]const u8, flags: u32, mode: usize) usize { | |
| 513 | pub fn openat(dirfd: i32, path: [*:0]const u8, flags: u32, mode: mode_t) usize { | |
| 514 | 514 | // dirfd could be negative, for example AT_FDCWD is -100 |
| 515 | 515 | return syscall4(.openat, @bitCast(usize, @as(isize, dirfd)), @ptrToInt(path), flags, mode); |
| 516 | 516 | } |
src/os.cpp+8| ... | ... | @@ -1462,6 +1462,14 @@ static void init_rand() { |
| 1462 | 1462 | unsigned seed; |
| 1463 | 1463 | memcpy(&seed, ptr_random, sizeof(seed)); |
| 1464 | 1464 | srand(seed); |
| 1465 | #elif defined(ZIG_OS_FREEBSD) || defined(ZIG_OS_NETBSD) | |
| 1466 | unsigned seed; | |
| 1467 | size_t len = sizeof(seed); | |
| 1468 | int mib[2] = { CTL_KERN, KERN_ARND }; | |
| 1469 | if (sysctl(mib, 2, &seed, &len, NULL, 0) != 0) { | |
| 1470 | zig_panic("unable to query random data from sysctl"); | |
| 1471 | } | |
| 1472 | srand(seed); | |
| 1465 | 1473 | #else |
| 1466 | 1474 | int fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC); |
| 1467 | 1475 | if (fd == -1) { |