mirror of
https://github.com/ziglang/zig.git
synced 2025-12-17 03:33:06 +00:00
Add SymlinkFlags needed to create symlinks to dirs on Win
This commit is contained in:
parent
4894de2b32
commit
30f1176a54
@ -69,7 +69,7 @@ pub const need_async_thread = std.io.is_async and switch (builtin.os.tag) {
|
|||||||
|
|
||||||
/// TODO remove the allocator requirement from this API
|
/// TODO remove the allocator requirement from this API
|
||||||
pub fn atomicSymLink(allocator: *Allocator, existing_path: []const u8, new_path: []const u8) !void {
|
pub fn atomicSymLink(allocator: *Allocator, existing_path: []const u8, new_path: []const u8) !void {
|
||||||
if (symLink(existing_path, new_path)) {
|
if (symLink(existing_path, new_path, .{})) {
|
||||||
return;
|
return;
|
||||||
} else |err| switch (err) {
|
} else |err| switch (err) {
|
||||||
error.PathAlreadyExists => {},
|
error.PathAlreadyExists => {},
|
||||||
@ -87,7 +87,7 @@ pub fn atomicSymLink(allocator: *Allocator, existing_path: []const u8, new_path:
|
|||||||
try crypto.randomBytes(rand_buf[0..]);
|
try crypto.randomBytes(rand_buf[0..]);
|
||||||
base64_encoder.encode(tmp_path[dirname.len + 1 ..], &rand_buf);
|
base64_encoder.encode(tmp_path[dirname.len + 1 ..], &rand_buf);
|
||||||
|
|
||||||
if (symLink(existing_path, tmp_path)) {
|
if (symLink(existing_path, tmp_path, .{})) {
|
||||||
return rename(tmp_path, new_path);
|
return rename(tmp_path, new_path);
|
||||||
} else |err| switch (err) {
|
} else |err| switch (err) {
|
||||||
error.PathAlreadyExists => continue,
|
error.PathAlreadyExists => continue,
|
||||||
|
|||||||
@ -1520,6 +1520,14 @@ pub fn getcwd(out_buffer: []u8) GetCwdError![]u8 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Use with `symlink` to specify whether the symlink will point to a file
|
||||||
|
/// or a directory. This value is ignored on all hosts except Windows where
|
||||||
|
/// creating symlinks to different resource types, requires different flags.
|
||||||
|
/// By default, symlink is assumed to point to a file.
|
||||||
|
pub const SymlinkFlags = struct{
|
||||||
|
is_directory: bool = false,
|
||||||
|
};
|
||||||
|
|
||||||
pub const SymLinkError = error{
|
pub const SymLinkError = error{
|
||||||
/// In WASI, this error may occur when the file descriptor does
|
/// In WASI, this error may occur when the file descriptor does
|
||||||
/// not hold the required rights to create a new symbolic link relative to it.
|
/// not hold the required rights to create a new symbolic link relative to it.
|
||||||
@ -1541,39 +1549,34 @@ pub const SymLinkError = error{
|
|||||||
/// Creates a symbolic link named `sym_link_path` which contains the string `target_path`.
|
/// Creates a symbolic link named `sym_link_path` which contains the string `target_path`.
|
||||||
/// A symbolic link (also known as a soft link) may point to an existing file or to a nonexistent
|
/// A symbolic link (also known as a soft link) may point to an existing file or to a nonexistent
|
||||||
/// one; the latter case is known as a dangling link.
|
/// one; the latter case is known as a dangling link.
|
||||||
/// On Windows, it is only legal to create a symbolic link to an existing resource. Furthermore,
|
|
||||||
/// this function will by default try creating a symbolic link to a file. If you would like to
|
|
||||||
/// create a symbolic link to a directory instead, see `symlinkW` for more information how to
|
|
||||||
/// do that.
|
|
||||||
/// If `sym_link_path` exists, it will not be overwritten.
|
/// If `sym_link_path` exists, it will not be overwritten.
|
||||||
/// See also `symlinkC` and `symlinkW`.
|
/// See also `symlinkC` and `symlinkW`.
|
||||||
pub fn symlink(target_path: []const u8, sym_link_path: []const u8) SymLinkError!void {
|
pub fn symlink(target_path: []const u8, sym_link_path: []const u8, flags: SymlinkFlags) SymLinkError!void {
|
||||||
if (builtin.os.tag == .wasi) {
|
if (builtin.os.tag == .wasi) {
|
||||||
@compileError("symlink is not supported in WASI; use symlinkat instead");
|
@compileError("symlink is not supported in WASI; use symlinkat instead");
|
||||||
}
|
}
|
||||||
if (builtin.os.tag == .windows) {
|
if (builtin.os.tag == .windows) {
|
||||||
const target_path_w = try windows.sliceToPrefixedFileW(target_path);
|
const target_path_w = try windows.sliceToPrefixedFileW(target_path);
|
||||||
const sym_link_path_w = try windows.sliceToPrefixedFileW(sym_link_path);
|
const sym_link_path_w = try windows.sliceToPrefixedFileW(sym_link_path);
|
||||||
return symlinkW(target_path_w.span().ptr, sym_link_path_w.span().ptr);
|
return symlinkW(target_path_w.span().ptr, sym_link_path_w.span().ptr, flags);
|
||||||
}
|
}
|
||||||
const target_path_c = try toPosixPath(target_path);
|
const target_path_c = try toPosixPath(target_path);
|
||||||
const sym_link_path_c = try toPosixPath(sym_link_path);
|
const sym_link_path_c = try toPosixPath(sym_link_path);
|
||||||
return symlinkZ(&target_path_c, &sym_link_path_c);
|
return symlinkZ(&target_path_c, &sym_link_path_c, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const symlinkC = @compileError("deprecated: renamed to symlinkZ");
|
pub const symlinkC = @compileError("deprecated: renamed to symlinkZ");
|
||||||
|
|
||||||
/// Windows-only. Same as `symlink` except the parameters are null-terminated, WTF16 encoded.
|
/// Windows-only. Same as `symlink` except the parameters are null-terminated, WTF16 encoded.
|
||||||
/// Note that this function will by default try creating a symbolic link to a file. If you would
|
/// Note that this function will by default try creating a symbolic link to a file. If you would
|
||||||
/// like to create a symbolic link to a directory, use `std.os.windows.CreateSymbolicLinkW` directly
|
/// like to create a symbolic link to a directory, specify this with `SymlinkFlags{ .is_directory = true }`.
|
||||||
/// specifying as flags `std.os.windows.CreateSymbolicLinkFlags.Directory`.
|
pub fn symlinkW(target_path: [*:0]const u16, sym_link_path: [*:0]const u16, flags: SymlinkFlags) SymLinkError!void {
|
||||||
pub fn symlinkW(target_path: [*:0]const u16, sym_link_path: [*:0]const u16) SymLinkError!void {
|
return windows.CreateSymbolicLinkW(sym_link_path, target_path, flags.is_directory);
|
||||||
return windows.CreateSymbolicLinkW(sym_link_path, target_path, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is the same as `symlink` except the parameters are null-terminated pointers.
|
/// This is the same as `symlink` except the parameters are null-terminated pointers.
|
||||||
/// See also `symlink`.
|
/// See also `symlink`.
|
||||||
pub fn symlinkZ(target_path: [*:0]const u8, sym_link_path: [*:0]const u8) SymLinkError!void {
|
pub fn symlinkZ(target_path: [*:0]const u8, sym_link_path: [*:0]const u8, flags: SymlinkFlags) SymLinkError!void {
|
||||||
if (builtin.os.tag == .windows) {
|
if (builtin.os.tag == .windows) {
|
||||||
const target_path_w = try windows.cStrToPrefixedFileW(target_path);
|
const target_path_w = try windows.cStrToPrefixedFileW(target_path);
|
||||||
const sym_link_path_w = try windows.cStrToPrefixedFileW(sym_link_path);
|
const sym_link_path_w = try windows.cStrToPrefixedFileW(sym_link_path);
|
||||||
|
|||||||
@ -48,7 +48,7 @@ test "readlink" {
|
|||||||
{
|
{
|
||||||
var cwd = fs.cwd();
|
var cwd = fs.cwd();
|
||||||
try cwd.writeFile("file.txt", "nonsense");
|
try cwd.writeFile("file.txt", "nonsense");
|
||||||
try os.symlink("file.txt", "symlinked");
|
try os.symlink("file.txt", "symlinked", .{});
|
||||||
|
|
||||||
var buffer: [fs.MAX_PATH_BYTES]u8 = undefined;
|
var buffer: [fs.MAX_PATH_BYTES]u8 = undefined;
|
||||||
const given = try os.readlink("symlinked", buffer[0..]);
|
const given = try os.readlink("symlinked", buffer[0..]);
|
||||||
@ -81,7 +81,7 @@ test "readlink" {
|
|||||||
std.debug.warn("symlink_path={}\n", .{symlink_path});
|
std.debug.warn("symlink_path={}\n", .{symlink_path});
|
||||||
|
|
||||||
// create symbolic link by path
|
// create symbolic link by path
|
||||||
try os.symlink(target_path, symlink_path);
|
try os.symlink(target_path, symlink_path, .{});
|
||||||
|
|
||||||
// now, read the link and verify
|
// now, read the link and verify
|
||||||
var buffer: [fs.MAX_PATH_BYTES]u8 = undefined;
|
var buffer: [fs.MAX_PATH_BYTES]u8 = undefined;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user