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: Dir
target_path: []const u8
sym_link_path: []const u8
flags: 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 ".";
var rand_buf: [AtomicFile.random_bytes_len]u8 = undefined;
const temp_path_len = dirname.len + 1 + base64_encoder.calcSize(rand_buf.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) {
crypto.random.bytes(rand_buf[0..]);
_ = base64_encoder.encode(temp_path[dirname.len + 1 ..], rand_buf[0..]);
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,
}
}
}