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