| ... | ... | @@ -1728,10 +1728,12 @@ test "writev/fsync/readv" { |
| 1728 | 1728 | }; |
| 1729 | 1729 | defer ring.deinit(); |
| 1730 | 1730 | |
| 1731 | var tmp = std.testing.tmpDir(.{}); |
| 1732 | defer tmp.cleanup(); |
| 1733 | |
| 1731 | 1734 | const path = "test_io_uring_writev_fsync_readv"; |
| 1732 | | const file = try std.fs.cwd().createFile(path, .{ .read = true, .truncate = true }); |
| 1735 | const file = try tmp.dir.createFile(path, .{ .read = true, .truncate = true }); |
| 1733 | 1736 | defer file.close(); |
| 1734 | | defer std.fs.cwd().deleteFile(path) catch {}; |
| 1735 | 1737 | const fd = file.handle; |
| 1736 | 1738 | |
| 1737 | 1739 | const buffer_write = [_]u8{42} ** 128; |
| ... | ... | @@ -1796,10 +1798,11 @@ test "write/read" { |
| 1796 | 1798 | }; |
| 1797 | 1799 | defer ring.deinit(); |
| 1798 | 1800 | |
| 1801 | var tmp = std.testing.tmpDir(.{}); |
| 1802 | defer tmp.cleanup(); |
| 1799 | 1803 | const path = "test_io_uring_write_read"; |
| 1800 | | const file = try std.fs.cwd().createFile(path, .{ .read = true, .truncate = true }); |
| 1804 | const file = try tmp.dir.createFile(path, .{ .read = true, .truncate = true }); |
| 1801 | 1805 | defer file.close(); |
| 1802 | | defer std.fs.cwd().deleteFile(path) catch {}; |
| 1803 | 1806 | const fd = file.handle; |
| 1804 | 1807 | |
| 1805 | 1808 | const buffer_write = [_]u8{97} ** 20; |
| ... | ... | @@ -1842,10 +1845,12 @@ test "write_fixed/read_fixed" { |
| 1842 | 1845 | }; |
| 1843 | 1846 | defer ring.deinit(); |
| 1844 | 1847 | |
| 1848 | var tmp = std.testing.tmpDir(.{}); |
| 1849 | defer tmp.cleanup(); |
| 1850 | |
| 1845 | 1851 | const path = "test_io_uring_write_read_fixed"; |
| 1846 | | const file = try std.fs.cwd().createFile(path, .{ .read = true, .truncate = true }); |
| 1852 | const file = try tmp.dir.createFile(path, .{ .read = true, .truncate = true }); |
| 1847 | 1853 | defer file.close(); |
| 1848 | | defer std.fs.cwd().deleteFile(path) catch {}; |
| 1849 | 1854 | const fd = file.handle; |
| 1850 | 1855 | |
| 1851 | 1856 | var raw_buffers: [2][11]u8 = undefined; |
| ... | ... | @@ -1899,8 +1904,10 @@ test "openat" { |
| 1899 | 1904 | }; |
| 1900 | 1905 | defer ring.deinit(); |
| 1901 | 1906 | |
| 1907 | var tmp = std.testing.tmpDir(.{}); |
| 1908 | defer tmp.cleanup(); |
| 1909 | |
| 1902 | 1910 | const path = "test_io_uring_openat"; |
| 1903 | | defer std.fs.cwd().deleteFile(path) catch {}; |
| 1904 | 1911 | |
| 1905 | 1912 | // Workaround for LLVM bug: https://github.com/ziglang/zig/issues/12014 |
| 1906 | 1913 | const path_addr = if (builtin.zig_backend == .stage2_llvm) p: { |
| ... | ... | @@ -1910,12 +1917,12 @@ test "openat" { |
| 1910 | 1917 | |
| 1911 | 1918 | const flags: u32 = os.O.CLOEXEC | os.O.RDWR | os.O.CREAT; |
| 1912 | 1919 | const mode: os.mode_t = 0o666; |
| 1913 | | const sqe_openat = try ring.openat(0x33333333, linux.AT.FDCWD, path, flags, mode); |
| 1920 | const sqe_openat = try ring.openat(0x33333333, tmp.dir.fd, path, flags, mode); |
| 1914 | 1921 | try testing.expectEqual(linux.io_uring_sqe{ |
| 1915 | 1922 | .opcode = .OPENAT, |
| 1916 | 1923 | .flags = 0, |
| 1917 | 1924 | .ioprio = 0, |
| 1918 | | .fd = linux.AT.FDCWD, |
| 1925 | .fd = tmp.dir.fd, |
| 1919 | 1926 | .off = 0, |
| 1920 | 1927 | .addr = path_addr, |
| 1921 | 1928 | .len = mode, |
| ... | ... | @@ -1931,12 +1938,6 @@ test "openat" { |
| 1931 | 1938 | const cqe_openat = try ring.copy_cqe(); |
| 1932 | 1939 | try testing.expectEqual(@as(u64, 0x33333333), cqe_openat.user_data); |
| 1933 | 1940 | if (cqe_openat.err() == .INVAL) return error.SkipZigTest; |
| 1934 | | // AT.FDCWD is not fully supported before kernel 5.6: |
| 1935 | | // See https://lore.kernel.org/io-uring/20200207155039.12819-1-axboe@kernel.dk/T/ |
| 1936 | | // We use IORING_FEAT_RW_CUR_POS to know if we are pre-5.6 since that feature was added in 5.6. |
| 1937 | | if (cqe_openat.err() == .BADF and (ring.features & linux.IORING_FEAT_RW_CUR_POS) == 0) { |
| 1938 | | return error.SkipZigTest; |
| 1939 | | } |
| 1940 | 1941 | if (cqe_openat.res <= 0) std.debug.print("\ncqe_openat.res={}\n", .{cqe_openat.res}); |
| 1941 | 1942 | try testing.expect(cqe_openat.res > 0); |
| 1942 | 1943 | try testing.expectEqual(@as(u32, 0), cqe_openat.flags); |
| ... | ... | @@ -1954,10 +1955,12 @@ test "close" { |
| 1954 | 1955 | }; |
| 1955 | 1956 | defer ring.deinit(); |
| 1956 | 1957 | |
| 1958 | var tmp = std.testing.tmpDir(.{}); |
| 1959 | defer tmp.cleanup(); |
| 1960 | |
| 1957 | 1961 | const path = "test_io_uring_close"; |
| 1958 | | const file = try std.fs.cwd().createFile(path, .{}); |
| 1962 | const file = try tmp.dir.createFile(path, .{}); |
| 1959 | 1963 | errdefer file.close(); |
| 1960 | | defer std.fs.cwd().deleteFile(path) catch {}; |
| 1961 | 1964 | |
| 1962 | 1965 | const sqe_close = try ring.close(0x44444444, file.handle); |
| 1963 | 1966 | try testing.expectEqual(linux.IORING_OP.CLOSE, sqe_close.opcode); |
| ... | ... | @@ -2295,10 +2298,12 @@ test "fallocate" { |
| 2295 | 2298 | }; |
| 2296 | 2299 | defer ring.deinit(); |
| 2297 | 2300 | |
| 2301 | var tmp = std.testing.tmpDir(.{}); |
| 2302 | defer tmp.cleanup(); |
| 2303 | |
| 2298 | 2304 | const path = "test_io_uring_fallocate"; |
| 2299 | | const file = try std.fs.cwd().createFile(path, .{ .truncate = true, .mode = 0o666 }); |
| 2305 | const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 }); |
| 2300 | 2306 | defer file.close(); |
| 2301 | | defer std.fs.cwd().deleteFile(path) catch {}; |
| 2302 | 2307 | |
| 2303 | 2308 | try testing.expectEqual(@as(u64, 0), (try file.stat()).size); |
| 2304 | 2309 | |
| ... | ... | @@ -2339,10 +2344,11 @@ test "statx" { |
| 2339 | 2344 | }; |
| 2340 | 2345 | defer ring.deinit(); |
| 2341 | 2346 | |
| 2347 | var tmp = std.testing.tmpDir(.{}); |
| 2348 | defer tmp.cleanup(); |
| 2342 | 2349 | const path = "test_io_uring_statx"; |
| 2343 | | const file = try std.fs.cwd().createFile(path, .{ .truncate = true, .mode = 0o666 }); |
| 2350 | const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 }); |
| 2344 | 2351 | defer file.close(); |
| 2345 | | defer std.fs.cwd().deleteFile(path) catch {}; |
| 2346 | 2352 | |
| 2347 | 2353 | try testing.expectEqual(@as(u64, 0), (try file.stat()).size); |
| 2348 | 2354 | |
| ... | ... | @@ -2351,14 +2357,14 @@ test "statx" { |
| 2351 | 2357 | var buf: linux.Statx = undefined; |
| 2352 | 2358 | const sqe = try ring.statx( |
| 2353 | 2359 | 0xaaaaaaaa, |
| 2354 | | linux.AT.FDCWD, |
| 2360 | tmp.dir.fd, |
| 2355 | 2361 | path, |
| 2356 | 2362 | 0, |
| 2357 | 2363 | linux.STATX_SIZE, |
| 2358 | 2364 | &buf, |
| 2359 | 2365 | ); |
| 2360 | 2366 | try testing.expectEqual(linux.IORING_OP.STATX, sqe.opcode); |
| 2361 | | try testing.expectEqual(@as(i32, linux.AT.FDCWD), sqe.fd); |
| 2367 | try testing.expectEqual(@as(i32, tmp.dir.fd), sqe.fd); |
| 2362 | 2368 | try testing.expectEqual(@as(u32, 1), try ring.submit()); |
| 2363 | 2369 | |
| 2364 | 2370 | const cqe = try ring.copy_cqe(); |
| ... | ... | @@ -2371,8 +2377,6 @@ test "statx" { |
| 2371 | 2377 | // The filesystem containing the file referred to by fd does not support this operation; |
| 2372 | 2378 | // or the mode is not supported by the filesystem containing the file referred to by fd: |
| 2373 | 2379 | .OPNOTSUPP => return error.SkipZigTest, |
| 2374 | | // The kernel is too old to support FDCWD for dir_fd |
| 2375 | | .BADF => return error.SkipZigTest, |
| 2376 | 2380 | else => |errno| std.debug.panic("unhandled errno: {}", .{errno}), |
| 2377 | 2381 | } |
| 2378 | 2382 | try testing.expectEqual(linux.io_uring_cqe{ |
| ... | ... | @@ -2606,28 +2610,28 @@ test "renameat" { |
| 2606 | 2610 | const old_path = "test_io_uring_renameat_old"; |
| 2607 | 2611 | const new_path = "test_io_uring_renameat_new"; |
| 2608 | 2612 | |
| 2613 | var tmp = std.testing.tmpDir(.{}); |
| 2614 | defer tmp.cleanup(); |
| 2615 | |
| 2609 | 2616 | // Write old file with data |
| 2610 | 2617 | |
| 2611 | | const old_file = try std.fs.cwd().createFile(old_path, .{ .truncate = true, .mode = 0o666 }); |
| 2612 | | defer { |
| 2613 | | old_file.close(); |
| 2614 | | std.fs.cwd().deleteFile(new_path) catch {}; |
| 2615 | | } |
| 2618 | const old_file = try tmp.dir.createFile(old_path, .{ .truncate = true, .mode = 0o666 }); |
| 2619 | defer old_file.close(); |
| 2616 | 2620 | try old_file.writeAll("hello"); |
| 2617 | 2621 | |
| 2618 | 2622 | // Submit renameat |
| 2619 | 2623 | |
| 2620 | 2624 | var sqe = try ring.renameat( |
| 2621 | 2625 | 0x12121212, |
| 2622 | | linux.AT.FDCWD, |
| 2626 | tmp.dir.fd, |
| 2623 | 2627 | old_path, |
| 2624 | | linux.AT.FDCWD, |
| 2628 | tmp.dir.fd, |
| 2625 | 2629 | new_path, |
| 2626 | 2630 | 0, |
| 2627 | 2631 | ); |
| 2628 | 2632 | try testing.expectEqual(linux.IORING_OP.RENAMEAT, sqe.opcode); |
| 2629 | | try testing.expectEqual(@as(i32, linux.AT.FDCWD), sqe.fd); |
| 2630 | | try testing.expectEqual(@as(i32, linux.AT.FDCWD), @bitCast(i32, sqe.len)); |
| 2633 | try testing.expectEqual(@as(i32, tmp.dir.fd), sqe.fd); |
| 2634 | try testing.expectEqual(@as(i32, tmp.dir.fd), @bitCast(i32, sqe.len)); |
| 2631 | 2635 | try testing.expectEqual(@as(u32, 1), try ring.submit()); |
| 2632 | 2636 | |
| 2633 | 2637 | const cqe = try ring.copy_cqe(); |
| ... | ... | @@ -2645,7 +2649,7 @@ test "renameat" { |
| 2645 | 2649 | |
| 2646 | 2650 | // Validate that the old file doesn't exist anymore |
| 2647 | 2651 | { |
| 2648 | | _ = std.fs.cwd().openFile(old_path, .{}) catch |err| switch (err) { |
| 2652 | _ = tmp.dir.openFile(old_path, .{}) catch |err| switch (err) { |
| 2649 | 2653 | error.FileNotFound => {}, |
| 2650 | 2654 | else => std.debug.panic("unexpected error: {}", .{err}), |
| 2651 | 2655 | }; |
| ... | ... | @@ -2653,7 +2657,7 @@ test "renameat" { |
| 2653 | 2657 | |
| 2654 | 2658 | // Validate that the new file exists with the proper content |
| 2655 | 2659 | { |
| 2656 | | const new_file = try std.fs.cwd().openFile(new_path, .{}); |
| 2660 | const new_file = try tmp.dir.openFile(new_path, .{}); |
| 2657 | 2661 | defer new_file.close(); |
| 2658 | 2662 | |
| 2659 | 2663 | var new_file_data: [16]u8 = undefined; |
| ... | ... | @@ -2674,22 +2678,24 @@ test "unlinkat" { |
| 2674 | 2678 | |
| 2675 | 2679 | const path = "test_io_uring_unlinkat"; |
| 2676 | 2680 | |
| 2681 | var tmp = std.testing.tmpDir(.{}); |
| 2682 | defer tmp.cleanup(); |
| 2683 | |
| 2677 | 2684 | // Write old file with data |
| 2678 | 2685 | |
| 2679 | | const file = try std.fs.cwd().createFile(path, .{ .truncate = true, .mode = 0o666 }); |
| 2686 | const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 }); |
| 2680 | 2687 | defer file.close(); |
| 2681 | | defer std.fs.cwd().deleteFile(path) catch {}; |
| 2682 | 2688 | |
| 2683 | 2689 | // Submit unlinkat |
| 2684 | 2690 | |
| 2685 | 2691 | var sqe = try ring.unlinkat( |
| 2686 | 2692 | 0x12121212, |
| 2687 | | linux.AT.FDCWD, |
| 2693 | tmp.dir.fd, |
| 2688 | 2694 | path, |
| 2689 | 2695 | 0, |
| 2690 | 2696 | ); |
| 2691 | 2697 | try testing.expectEqual(linux.IORING_OP.UNLINKAT, sqe.opcode); |
| 2692 | | try testing.expectEqual(@as(i32, linux.AT.FDCWD), sqe.fd); |
| 2698 | try testing.expectEqual(@as(i32, tmp.dir.fd), sqe.fd); |
| 2693 | 2699 | try testing.expectEqual(@as(u32, 1), try ring.submit()); |
| 2694 | 2700 | |
| 2695 | 2701 | const cqe = try ring.copy_cqe(); |
| ... | ... | @@ -2706,7 +2712,7 @@ test "unlinkat" { |
| 2706 | 2712 | }, cqe); |
| 2707 | 2713 | |
| 2708 | 2714 | // Validate that the file doesn't exist anymore |
| 2709 | | _ = std.fs.cwd().openFile(path, .{}) catch |err| switch (err) { |
| 2715 | _ = tmp.dir.openFile(path, .{}) catch |err| switch (err) { |
| 2710 | 2716 | error.FileNotFound => {}, |
| 2711 | 2717 | else => std.debug.panic("unexpected error: {}", .{err}), |
| 2712 | 2718 | }; |
| ... | ... | @@ -2722,20 +2728,21 @@ test "mkdirat" { |
| 2722 | 2728 | }; |
| 2723 | 2729 | defer ring.deinit(); |
| 2724 | 2730 | |
| 2725 | | const path = "test_io_uring_mkdirat"; |
| 2731 | var tmp = std.testing.tmpDir(.{}); |
| 2732 | defer tmp.cleanup(); |
| 2726 | 2733 | |
| 2727 | | defer std.fs.cwd().deleteDir(path) catch {}; |
| 2734 | const path = "test_io_uring_mkdirat"; |
| 2728 | 2735 | |
| 2729 | 2736 | // Submit mkdirat |
| 2730 | 2737 | |
| 2731 | 2738 | var sqe = try ring.mkdirat( |
| 2732 | 2739 | 0x12121212, |
| 2733 | | linux.AT.FDCWD, |
| 2740 | tmp.dir.fd, |
| 2734 | 2741 | path, |
| 2735 | 2742 | 0o0755, |
| 2736 | 2743 | ); |
| 2737 | 2744 | try testing.expectEqual(linux.IORING_OP.MKDIRAT, sqe.opcode); |
| 2738 | | try testing.expectEqual(@as(i32, linux.AT.FDCWD), sqe.fd); |
| 2745 | try testing.expectEqual(@as(i32, tmp.dir.fd), sqe.fd); |
| 2739 | 2746 | try testing.expectEqual(@as(u32, 1), try ring.submit()); |
| 2740 | 2747 | |
| 2741 | 2748 | const cqe = try ring.copy_cqe(); |
| ... | ... | @@ -2752,7 +2759,7 @@ test "mkdirat" { |
| 2752 | 2759 | }, cqe); |
| 2753 | 2760 | |
| 2754 | 2761 | // Validate that the directory exist |
| 2755 | | _ = try std.fs.cwd().openDir(path, .{}); |
| 2762 | _ = try tmp.dir.openDir(path, .{}); |
| 2756 | 2763 | } |
| 2757 | 2764 | |
| 2758 | 2765 | test "symlinkat" { |
| ... | ... | @@ -2765,26 +2772,25 @@ test "symlinkat" { |
| 2765 | 2772 | }; |
| 2766 | 2773 | defer ring.deinit(); |
| 2767 | 2774 | |
| 2775 | var tmp = std.testing.tmpDir(.{}); |
| 2776 | defer tmp.cleanup(); |
| 2777 | |
| 2768 | 2778 | const path = "test_io_uring_symlinkat"; |
| 2769 | 2779 | const link_path = "test_io_uring_symlinkat_link"; |
| 2770 | 2780 | |
| 2771 | | const file = try std.fs.cwd().createFile(path, .{ .truncate = true, .mode = 0o666 }); |
| 2772 | | defer { |
| 2773 | | file.close(); |
| 2774 | | std.fs.cwd().deleteFile(path) catch {}; |
| 2775 | | std.fs.cwd().deleteFile(link_path) catch {}; |
| 2776 | | } |
| 2781 | const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 }); |
| 2782 | defer file.close(); |
| 2777 | 2783 | |
| 2778 | 2784 | // Submit symlinkat |
| 2779 | 2785 | |
| 2780 | 2786 | var sqe = try ring.symlinkat( |
| 2781 | 2787 | 0x12121212, |
| 2782 | 2788 | path, |
| 2783 | | linux.AT.FDCWD, |
| 2789 | tmp.dir.fd, |
| 2784 | 2790 | link_path, |
| 2785 | 2791 | ); |
| 2786 | 2792 | try testing.expectEqual(linux.IORING_OP.SYMLINKAT, sqe.opcode); |
| 2787 | | try testing.expectEqual(@as(i32, linux.AT.FDCWD), sqe.fd); |
| 2793 | try testing.expectEqual(@as(i32, tmp.dir.fd), sqe.fd); |
| 2788 | 2794 | try testing.expectEqual(@as(u32, 1), try ring.submit()); |
| 2789 | 2795 | |
| 2790 | 2796 | const cqe = try ring.copy_cqe(); |
| ... | ... | @@ -2801,7 +2807,7 @@ test "symlinkat" { |
| 2801 | 2807 | }, cqe); |
| 2802 | 2808 | |
| 2803 | 2809 | // Validate that the symlink exist |
| 2804 | | _ = try std.fs.cwd().openFile(link_path, .{}); |
| 2810 | _ = try tmp.dir.openFile(link_path, .{}); |
| 2805 | 2811 | } |
| 2806 | 2812 | |
| 2807 | 2813 | test "linkat" { |
| ... | ... | @@ -2814,32 +2820,31 @@ test "linkat" { |
| 2814 | 2820 | }; |
| 2815 | 2821 | defer ring.deinit(); |
| 2816 | 2822 | |
| 2823 | var tmp = std.testing.tmpDir(.{}); |
| 2824 | defer tmp.cleanup(); |
| 2825 | |
| 2817 | 2826 | const first_path = "test_io_uring_linkat_first"; |
| 2818 | 2827 | const second_path = "test_io_uring_linkat_second"; |
| 2819 | 2828 | |
| 2820 | 2829 | // Write file with data |
| 2821 | 2830 | |
| 2822 | | const first_file = try std.fs.cwd().createFile(first_path, .{ .truncate = true, .mode = 0o666 }); |
| 2823 | | defer { |
| 2824 | | first_file.close(); |
| 2825 | | std.fs.cwd().deleteFile(first_path) catch {}; |
| 2826 | | std.fs.cwd().deleteFile(second_path) catch {}; |
| 2827 | | } |
| 2831 | const first_file = try tmp.dir.createFile(first_path, .{ .truncate = true, .mode = 0o666 }); |
| 2832 | defer first_file.close(); |
| 2828 | 2833 | try first_file.writeAll("hello"); |
| 2829 | 2834 | |
| 2830 | 2835 | // Submit linkat |
| 2831 | 2836 | |
| 2832 | 2837 | var sqe = try ring.linkat( |
| 2833 | 2838 | 0x12121212, |
| 2834 | | linux.AT.FDCWD, |
| 2839 | tmp.dir.fd, |
| 2835 | 2840 | first_path, |
| 2836 | | linux.AT.FDCWD, |
| 2841 | tmp.dir.fd, |
| 2837 | 2842 | second_path, |
| 2838 | 2843 | 0, |
| 2839 | 2844 | ); |
| 2840 | 2845 | try testing.expectEqual(linux.IORING_OP.LINKAT, sqe.opcode); |
| 2841 | | try testing.expectEqual(@as(i32, linux.AT.FDCWD), sqe.fd); |
| 2842 | | try testing.expectEqual(@as(i32, linux.AT.FDCWD), @bitCast(i32, sqe.len)); |
| 2846 | try testing.expectEqual(@as(i32, tmp.dir.fd), sqe.fd); |
| 2847 | try testing.expectEqual(@as(i32, tmp.dir.fd), @bitCast(i32, sqe.len)); |
| 2843 | 2848 | try testing.expectEqual(@as(u32, 1), try ring.submit()); |
| 2844 | 2849 | |
| 2845 | 2850 | const cqe = try ring.copy_cqe(); |
| ... | ... | @@ -2856,7 +2861,7 @@ test "linkat" { |
| 2856 | 2861 | }, cqe); |
| 2857 | 2862 | |
| 2858 | 2863 | // Validate the second file |
| 2859 | | const second_file = try std.fs.cwd().openFile(second_path, .{}); |
| 2864 | const second_file = try tmp.dir.openFile(second_path, .{}); |
| 2860 | 2865 | defer second_file.close(); |
| 2861 | 2866 | |
| 2862 | 2867 | var second_file_data: [16]u8 = undefined; |