| ... | @@ -531,17 +531,17 @@ test "memfd_create" { | ... | @@ -531,17 +531,17 @@ test "memfd_create" { |
| 531 | else => return error.SkipZigTest, | 531 | else => return error.SkipZigTest, |
| 532 | } | 532 | } |
| 533 | | 533 | |
| 534 | const fd = std.os.memfd_create("test", 0) catch |err| switch (err) { | 534 | const fd = os.memfd_create("test", 0) catch |err| switch (err) { |
| 535 | // Related: https://github.com/ziglang/zig/issues/4019 | 535 | // Related: https://github.com/ziglang/zig/issues/4019 |
| 536 | error.SystemOutdated => return error.SkipZigTest, | 536 | error.SystemOutdated => return error.SkipZigTest, |
| 537 | else => |e| return e, | 537 | else => |e| return e, |
| 538 | }; | 538 | }; |
| 539 | defer std.os.close(fd); | 539 | defer os.close(fd); |
| 540 | try expect((try std.os.write(fd, "test")) == 4); | 540 | try expect((try os.write(fd, "test")) == 4); |
| 541 | try std.os.lseek_SET(fd, 0); | 541 | try os.lseek_SET(fd, 0); |
| 542 | | 542 | |
| 543 | var buf: [10]u8 = undefined; | 543 | var buf: [10]u8 = undefined; |
| 544 | const bytes_read = try std.os.read(fd, &buf); | 544 | const bytes_read = try os.read(fd, &buf); |
| 545 | try expect(bytes_read == 4); | 545 | try expect(bytes_read == 4); |
| 546 | try expect(mem.eql(u8, buf[0..4], "test")); | 546 | try expect(mem.eql(u8, buf[0..4], "test")); |
| 547 | } | 547 | } |
| ... | @@ -688,7 +688,7 @@ test "signalfd" { | ... | @@ -688,7 +688,7 @@ test "signalfd" { |
| 688 | .linux, .solaris => {}, | 688 | .linux, .solaris => {}, |
| 689 | else => return error.SkipZigTest, | 689 | else => return error.SkipZigTest, |
| 690 | } | 690 | } |
| 691 | _ = std.os.signalfd; | 691 | _ = os.signalfd; |
| 692 | } | 692 | } |
| 693 | | 693 | |
| 694 | test "sync" { | 694 | test "sync" { |
| ... | @@ -757,11 +757,11 @@ test "shutdown socket" { | ... | @@ -757,11 +757,11 @@ test "shutdown socket" { |
| 757 | if (native_os == .wasi) | 757 | if (native_os == .wasi) |
| 758 | return error.SkipZigTest; | 758 | return error.SkipZigTest; |
| 759 | if (native_os == .windows) { | 759 | if (native_os == .windows) { |
| 760 | _ = try std.os.windows.WSAStartup(2, 2); | 760 | _ = try os.windows.WSAStartup(2, 2); |
| 761 | } | 761 | } |
| 762 | defer { | 762 | defer { |
| 763 | if (native_os == .windows) { | 763 | if (native_os == .windows) { |
| 764 | std.os.windows.WSACleanup() catch unreachable; | 764 | os.windows.WSACleanup() catch unreachable; |
| 765 | } | 765 | } |
| 766 | } | 766 | } |
| 767 | const sock = try os.socket(os.AF.INET, os.SOCK.STREAM, 0); | 767 | const sock = try os.socket(os.AF.INET, os.SOCK.STREAM, 0); |
| ... | @@ -855,13 +855,13 @@ test "dup & dup2" { | ... | @@ -855,13 +855,13 @@ test "dup & dup2" { |
| 855 | var file = try tmp.dir.createFile("os_dup_test", .{}); | 855 | var file = try tmp.dir.createFile("os_dup_test", .{}); |
| 856 | defer file.close(); | 856 | defer file.close(); |
| 857 | | 857 | |
| 858 | var duped = std.fs.File{ .handle = try std.os.dup(file.handle) }; | 858 | var duped = std.fs.File{ .handle = try os.dup(file.handle) }; |
| 859 | defer duped.close(); | 859 | defer duped.close(); |
| 860 | try duped.writeAll("dup"); | 860 | try duped.writeAll("dup"); |
| 861 | | 861 | |
| 862 | // Tests aren't run in parallel so using the next fd shouldn't be an issue. | 862 | // Tests aren't run in parallel so using the next fd shouldn't be an issue. |
| 863 | const new_fd = duped.handle + 1; | 863 | const new_fd = duped.handle + 1; |
| 864 | try std.os.dup2(file.handle, new_fd); | 864 | try os.dup2(file.handle, new_fd); |
| 865 | var dup2ed = std.fs.File{ .handle = new_fd }; | 865 | var dup2ed = std.fs.File{ .handle = new_fd }; |
| 866 | defer dup2ed.close(); | 866 | defer dup2ed.close(); |
| 867 | try dup2ed.writeAll("dup2"); | 867 | try dup2ed.writeAll("dup2"); |
| ... | @@ -909,46 +909,46 @@ test "POSIX file locking with fcntl" { | ... | @@ -909,46 +909,46 @@ test "POSIX file locking with fcntl" { |
| 909 | const fd = file.handle; | 909 | const fd = file.handle; |
| 910 | | 910 | |
| 911 | // Place an exclusive lock on the first byte, and a shared lock on the second byte: | 911 | // Place an exclusive lock on the first byte, and a shared lock on the second byte: |
| 912 | var struct_flock = std.mem.zeroInit(std.os.Flock, .{ .type = std.os.F.WRLCK }); | 912 | var struct_flock = std.mem.zeroInit(os.Flock, .{ .type = os.F.WRLCK }); |
| 913 | _ = try std.os.fcntl(fd, std.os.F.SETLK, @ptrToInt(&struct_flock)); | 913 | _ = try os.fcntl(fd, os.F.SETLK, @ptrToInt(&struct_flock)); |
| 914 | struct_flock.start = 1; | 914 | struct_flock.start = 1; |
| 915 | struct_flock.type = std.os.F.RDLCK; | 915 | struct_flock.type = os.F.RDLCK; |
| 916 | _ = try std.os.fcntl(fd, std.os.F.SETLK, @ptrToInt(&struct_flock)); | 916 | _ = try os.fcntl(fd, os.F.SETLK, @ptrToInt(&struct_flock)); |
| 917 | | 917 | |
| 918 | // Check the locks in a child process: | 918 | // Check the locks in a child process: |
| 919 | const pid = try std.os.fork(); | 919 | const pid = try os.fork(); |
| 920 | if (pid == 0) { | 920 | if (pid == 0) { |
| 921 | // child expects be denied the exclusive lock: | 921 | // child expects be denied the exclusive lock: |
| 922 | struct_flock.start = 0; | 922 | struct_flock.start = 0; |
| 923 | struct_flock.type = std.os.F.WRLCK; | 923 | struct_flock.type = os.F.WRLCK; |
| 924 | try expectError(error.Locked, std.os.fcntl(fd, std.os.F.SETLK, @ptrToInt(&struct_flock))); | 924 | try expectError(error.Locked, os.fcntl(fd, os.F.SETLK, @ptrToInt(&struct_flock))); |
| 925 | // child expects to get the shared lock: | 925 | // child expects to get the shared lock: |
| 926 | struct_flock.start = 1; | 926 | struct_flock.start = 1; |
| 927 | struct_flock.type = std.os.F.RDLCK; | 927 | struct_flock.type = os.F.RDLCK; |
| 928 | _ = try std.os.fcntl(fd, std.os.F.SETLK, @ptrToInt(&struct_flock)); | 928 | _ = try os.fcntl(fd, os.F.SETLK, @ptrToInt(&struct_flock)); |
| 929 | // child waits for the exclusive lock in order to test deadlock: | 929 | // child waits for the exclusive lock in order to test deadlock: |
| 930 | struct_flock.start = 0; | 930 | struct_flock.start = 0; |
| 931 | struct_flock.type = std.os.F.WRLCK; | 931 | struct_flock.type = os.F.WRLCK; |
| 932 | _ = try std.os.fcntl(fd, std.os.F.SETLKW, @ptrToInt(&struct_flock)); | 932 | _ = try os.fcntl(fd, os.F.SETLKW, @ptrToInt(&struct_flock)); |
| 933 | // child exits without continuing: | 933 | // child exits without continuing: |
| 934 | std.os.exit(0); | 934 | os.exit(0); |
| 935 | } else { | 935 | } else { |
| 936 | // parent waits for child to get shared lock: | 936 | // parent waits for child to get shared lock: |
| 937 | std.time.sleep(1 * std.time.ns_per_ms); | 937 | std.time.sleep(1 * std.time.ns_per_ms); |
| 938 | // parent expects deadlock when attempting to upgrade the shared lock to exclusive: | 938 | // parent expects deadlock when attempting to upgrade the shared lock to exclusive: |
| 939 | struct_flock.start = 1; | 939 | struct_flock.start = 1; |
| 940 | struct_flock.type = std.os.F.WRLCK; | 940 | struct_flock.type = os.F.WRLCK; |
| 941 | try expectError(error.DeadLock, std.os.fcntl(fd, std.os.F.SETLKW, @ptrToInt(&struct_flock))); | 941 | try expectError(error.DeadLock, os.fcntl(fd, os.F.SETLKW, @ptrToInt(&struct_flock))); |
| 942 | // parent releases exclusive lock: | 942 | // parent releases exclusive lock: |
| 943 | struct_flock.start = 0; | 943 | struct_flock.start = 0; |
| 944 | struct_flock.type = std.os.F.UNLCK; | 944 | struct_flock.type = os.F.UNLCK; |
| 945 | _ = try std.os.fcntl(fd, std.os.F.SETLK, @ptrToInt(&struct_flock)); | 945 | _ = try os.fcntl(fd, os.F.SETLK, @ptrToInt(&struct_flock)); |
| 946 | // parent releases shared lock: | 946 | // parent releases shared lock: |
| 947 | struct_flock.start = 1; | 947 | struct_flock.start = 1; |
| 948 | struct_flock.type = std.os.F.UNLCK; | 948 | struct_flock.type = os.F.UNLCK; |
| 949 | _ = try std.os.fcntl(fd, std.os.F.SETLK, @ptrToInt(&struct_flock)); | 949 | _ = try os.fcntl(fd, os.F.SETLK, @ptrToInt(&struct_flock)); |
| 950 | // parent waits for child: | 950 | // parent waits for child: |
| 951 | const result = std.os.waitpid(pid, 0); | 951 | const result = os.waitpid(pid, 0); |
| 952 | try expect(result.status == 0 * 256); | 952 | try expect(result.status == 0 * 256); |
| 953 | } | 953 | } |
| 954 | } | 954 | } |
| ... | @@ -1182,3 +1182,17 @@ test "pwrite with empty buffer" { | ... | @@ -1182,3 +1182,17 @@ test "pwrite with empty buffer" { |
| 1182 | | 1182 | |
| 1183 | _ = try os.pwrite(file.handle, bytes, 0); | 1183 | _ = try os.pwrite(file.handle, bytes, 0); |
| 1184 | } | 1184 | } |
| | 1185 | |
| | 1186 | test "fchmodat smoke test" { |
| | 1187 | if (!std.fs.has_executable_bit) return error.SkipZigTest; |
| | 1188 | |
| | 1189 | var tmp = tmpDir(.{}); |
| | 1190 | defer tmp.cleanup(); |
| | 1191 | |
| | 1192 | try expectError(error.FileNotFound, os.fchmodat(tmp.dir.fd, "foo.txt", 0o666, 0)); |
| | 1193 | const fd = try os.openat(tmp.dir.fd, "foo.txt", os.O.RDWR | os.O.CREAT | os.O.EXCL, 0o666); |
| | 1194 | os.close(fd); |
| | 1195 | try os.fchmodat(tmp.dir.fd, "foo.txt", 0o755, 0); |
| | 1196 | const st = try os.fstatat(tmp.dir.fd, "foo.txt", 0); |
| | 1197 | try expectEqual(@as(os.mode_t, 0o755), st.mode & 0b111_111_111); |
| | 1198 | } |