Function atomicSymLink [src]
Same as symLink, except tries to create the symbolic link until it
succeeds or encounters an error other than error.PathAlreadyExists.
On Windows, both paths should be encoded as WTF-8.
On WASI, both paths should be encoded as valid UTF-8.
On other platforms, both paths are an opaque sequence of bytes with no particular encoding.
Prototype
pub fn atomicSymLink( dir: Dir, target_path: []const u8, sym_link_path: []const u8, flags: SymLinkFlags, ) !void Parameters
dir: Dirtarget_path: []const u8sym_link_path: []const u8flags: SymLinkFlags Source
pub fn atomicSymLink(
dir: Dir,
target_path: []const u8,
sym_link_path: []const u8,
flags: SymLinkFlags,
) !void {
if (dir.symLink(target_path, sym_link_path, flags)) {
return;
} else |err| switch (err) {
error.PathAlreadyExists => {},
else => |e| return e,
}
const dirname = path.dirname(sym_link_path) orelse ".";
const rand_len = @sizeOf(u64) * 2;
const temp_path_len = dirname.len + 1 + rand_len;
var temp_path_buf: [fs.max_path_bytes]u8 = undefined;
if (temp_path_len > temp_path_buf.len) return error.NameTooLong;
@memcpy(temp_path_buf[0..dirname.len], dirname);
temp_path_buf[dirname.len] = path.sep;
const temp_path = temp_path_buf[0..temp_path_len];
while (true) {
const random_integer = std.crypto.random.int(u64);
temp_path[dirname.len + 1 ..][0..rand_len].* = std.fmt.hex(random_integer);
if (dir.symLink(target_path, temp_path, flags)) {
return dir.rename(temp_path, sym_link_path);
} else |err| switch (err) {
error.PathAlreadyExists => continue,
else => |e| return e,
}
}
}