| author | |
| committer | |
| log | c22d99a3b27ecbb82c8ea59ad7645a0c10483d61 |
| tree | 2c394f4781e4312931bcd1872360edb25629484a |
| parent | 32534ecae6e87ba3ea22698d06843e6d4f353208 |
| parent | cdd6e545cc7e4c6cb32d1a87695f215ce9d5f753 |
Reviewed-on: https://codeberg.org/ziglang/zig/pulls/372102 files changed, 18 insertions(+), 4 deletions(-)
lib/std/Io/Dir.zig+7-2| ... | @@ -1122,8 +1122,7 @@ pub const RenamePreserveError = error{ | ... | @@ -1122,8 +1122,7 @@ pub const RenamePreserveError = error{ |
| 1122 | /// policy of the current thread or process disallows dataless directory materialization. | 1122 | /// policy of the current thread or process disallows dataless directory materialization. |
| 1123 | AccessDenied, | 1123 | AccessDenied, |
| 1124 | PathAlreadyExists, | 1124 | PathAlreadyExists, |
| 1125 | /// Operating system or file system does not support atomic nonreplacing | 1125 | /// Operating system or file system does not support atomic nonreplacing rename. |
| 1126 | /// rename. | ||
| 1127 | OperationUnsupported, | 1126 | OperationUnsupported, |
| 1128 | } || RenameError; | 1127 | } || RenameError; |
| 1129 | 1128 | ||
| ... | @@ -1131,6 +1130,12 @@ pub const RenamePreserveError = error{ | ... | @@ -1131,6 +1130,12 @@ pub const RenamePreserveError = error{ |
| 1131 | /// | 1130 | /// |
| 1132 | /// If `new_sub_path` already exists, `error.PathAlreadyExists` will be returned. | 1131 | /// If `new_sub_path` already exists, `error.PathAlreadyExists` will be returned. |
| 1133 | /// | 1132 | /// |
| 1133 | /// If the operating system supports it, the entire operation will be done atomically. If unsupported, will | ||
| 1134 | /// fall back to hard link followed by unlink, which is atomic with respect to `new_sub_path` but leaves a | ||
| 1135 | /// window where the cleanup of `old_sub_path may fail. Although the operation is fairly portable, technically | ||
| 1136 | /// this fallback, too, may be unsupported in some environments, in which case `error.OperationUnsupported` is | ||
| 1137 | /// returned. | ||
| 1138 | /// | ||
| 1134 | /// * On Windows, both paths should be encoded as [WTF-8](https://wtf-8.codeberg.page/). | 1139 | /// * On Windows, both paths should be encoded as [WTF-8](https://wtf-8.codeberg.page/). |
| 1135 | /// * On WASI, both paths should be encoded as valid UTF-8. | 1140 | /// * On WASI, both paths should be encoded as valid UTF-8. |
| 1136 | /// * On other platforms, both paths are an opaque sequence of bytes with no particular encoding. | 1141 | /// * On other platforms, both paths are an opaque sequence of bytes with no particular encoding. |
lib/std/Io/Threaded.zig+11-2| ... | @@ -7756,7 +7756,14 @@ fn dirRenamePreserve( | ... | @@ -7756,7 +7756,14 @@ fn dirRenamePreserve( |
| 7756 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 7756 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 7757 | if (is_windows) return dirRenameWindowsInner(old_dir, old_sub_path, new_dir, new_sub_path, false); | 7757 | if (is_windows) return dirRenameWindowsInner(old_dir, old_sub_path, new_dir, new_sub_path, false); |
| 7758 | if (is_darwin) return dirRenamePreserveDarwin(old_dir, old_sub_path, new_dir, new_sub_path); | 7758 | if (is_darwin) return dirRenamePreserveDarwin(old_dir, old_sub_path, new_dir, new_sub_path); |
| 7759 | if (native_os == .linux) return dirRenamePreserveLinux(old_dir, old_sub_path, new_dir, new_sub_path); | 7759 | if (native_os == .linux) { |
| 7760 | if (dirRenamePreserveLinux(old_dir, old_sub_path, new_dir, new_sub_path)) |_| { | ||
| 7761 | return; | ||
| 7762 | } else |err| switch (err) { | ||
| 7763 | else => |e| return e, | ||
| 7764 | error.OperationUnsupported => {}, // Fall back to link/unlink below. | ||
| 7765 | } | ||
| 7766 | } | ||
| 7760 | // Make a hard link then delete the original. | 7767 | // Make a hard link then delete the original. |
| 7761 | try dirHardLink(t, old_dir, old_sub_path, new_dir, new_sub_path, .{ .follow_symlinks = false }); | 7768 | try dirHardLink(t, old_dir, old_sub_path, new_dir, new_sub_path, .{ .follow_symlinks = false }); |
| 7762 | const prev = swapCancelProtection(t, .blocked); | 7769 | const prev = swapCancelProtection(t, .blocked); |
| ... | @@ -8084,8 +8091,10 @@ fn dirRenamePreserveLinux( | ... | @@ -8084,8 +8091,10 @@ fn dirRenamePreserveLinux( |
| 8084 | .ROFS => return syscall.fail(error.ReadOnlyFileSystem), | 8091 | .ROFS => return syscall.fail(error.ReadOnlyFileSystem), |
| 8085 | .XDEV => return syscall.fail(error.CrossDevice), | 8092 | .XDEV => return syscall.fail(error.CrossDevice), |
| 8086 | .ILSEQ => return syscall.fail(error.BadPathName), | 8093 | .ILSEQ => return syscall.fail(error.BadPathName), |
| 8094 | // EINVAL when passing NOREPLACE=true observed on ext4, 7.0.0-38-generic #38~24.04.4-Ubuntu. | ||
| 8095 | // OPNOTSUPP handled defensively. | ||
| 8096 | .INVAL, .OPNOTSUPP => return syscall.fail(error.OperationUnsupported), | ||
| 8087 | .FAULT => |err| return syscall.errnoBug(err), | 8097 | .FAULT => |err| return syscall.errnoBug(err), |
| 8088 | .INVAL => |err| return syscall.errnoBug(err), | ||
| 8089 | else => |err| return syscall.unexpectedErrno(err), | 8098 | else => |err| return syscall.unexpectedErrno(err), |
| 8090 | }; | 8099 | }; |
| 8091 | } | 8100 | } |