authorgravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2023-08-19 12:48:51-07:00
committergravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2023-08-19 17:48:18-07:00
log2c2ecd624ad6d85d005f4728f834c0e3377f8f99
treeff17bff644b5eac7243df227c51fb78547b60d35
parent7ef1eb1c27754cb0349fdc10db1f02ff2dddd99b

fs.selfExePath: Make the Windows implementation follow symlinks

Before, selfExePath would be the path of the symlink on Windows instead of the path of what the symlink points to. This deprecates fs.selfExePathW since it does not provide a separate use-case over selfExePath (before, the W version could return [:0]u16 directly) Fixes #16670

1 files changed, 16 insertions(+), 12 deletions(-)

lib/std/fs.zig+16-12
...@@ -2949,8 +2949,12 @@ pub fn openSelfExe(flags: File.OpenFlags) OpenSelfExeError!File {...@@ -2949,8 +2949,12 @@ pub fn openSelfExe(flags: File.OpenFlags) OpenSelfExeError!File {
2949 return openFileAbsoluteZ("/proc/self/exe", flags);2949 return openFileAbsoluteZ("/proc/self/exe", flags);
2950 }2950 }
2951 if (builtin.os.tag == .windows) {2951 if (builtin.os.tag == .windows) {
2952 const wide_slice = selfExePathW();2952 // If ImagePathName is a symlink, then it will contain the path of the symlink,
2953 const prefixed_path_w = try os.windows.wToPrefixedFileW(null, wide_slice);2953 // not the path that the symlink points to. However, because we are opening
2954 // the file, we can let the openFileW call follow the symlink for us.
2955 const image_path_unicode_string = &os.windows.peb().ProcessParameters.ImagePathName;
2956 const image_path_name = image_path_unicode_string.Buffer[0 .. image_path_unicode_string.Length / 2 :0];
2957 const prefixed_path_w = try os.windows.wToPrefixedFileW(null, image_path_name);
2954 return cwd().openFileW(prefixed_path_w.span(), flags);2958 return cwd().openFileW(prefixed_path_w.span(), flags);
2955 }2959 }
2956 // Use of MAX_PATH_BYTES here is valid as the resulting path is immediately2960 // Use of MAX_PATH_BYTES here is valid as the resulting path is immediately
...@@ -2977,7 +2981,7 @@ pub fn selfExePathAlloc(allocator: Allocator) ![]u8 {...@@ -2977,7 +2981,7 @@ pub fn selfExePathAlloc(allocator: Allocator) ![]u8 {
2977 return allocator.dupe(u8, try selfExePath(&buf));2981 return allocator.dupe(u8, try selfExePath(&buf));
2978}2982}
29792983
2980/// Get the path to the current executable.2984/// Get the path to the current executable. Follows symlinks.
2981/// If you only need the directory, use selfExeDirPath.2985/// If you only need the directory, use selfExeDirPath.
2982/// If you only want an open file handle, use openSelfExe.2986/// If you only want an open file handle, use openSelfExe.
2983/// This function may return an error if the current executable2987/// This function may return an error if the current executable
...@@ -3060,21 +3064,21 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {...@@ -3060,21 +3064,21 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
3060 return error.FileNotFound;3064 return error.FileNotFound;
3061 },3065 },
3062 .windows => {3066 .windows => {
3063 const utf16le_slice = selfExePathW();3067 const image_path_unicode_string = &os.windows.peb().ProcessParameters.ImagePathName;
3064 // Trust that Windows gives us valid UTF-16LE.3068 const image_path_name = image_path_unicode_string.Buffer[0 .. image_path_unicode_string.Length / 2 :0];
3065 const end_index = std.unicode.utf16leToUtf8(out_buffer, utf16le_slice) catch unreachable;3069
3066 return out_buffer[0..end_index];3070 // If ImagePathName is a symlink, then it will contain the path of the
3071 // symlink, not the path that the symlink points to. We want the path
3072 // that the symlink points to, though, so we need to get the realpath.
3073 const pathname_w = try os.windows.wToPrefixedFileW(null, image_path_name);
3074 return std.fs.cwd().realpathW(pathname_w.span(), out_buffer);
3067 },3075 },
3068 .wasi => @compileError("std.fs.selfExePath not supported for WASI. Use std.fs.selfExePathAlloc instead."),3076 .wasi => @compileError("std.fs.selfExePath not supported for WASI. Use std.fs.selfExePathAlloc instead."),
3069 else => @compileError("std.fs.selfExePath not supported for this target"),3077 else => @compileError("std.fs.selfExePath not supported for this target"),
3070 }3078 }
3071}3079}
30723080
3073/// The result is UTF16LE-encoded.3081pub const selfExePathW = @compileError("deprecated; use selfExePath instead");
3074pub fn selfExePathW() [:0]const u16 {
3075 const image_path_name = &os.windows.peb().ProcessParameters.ImagePathName;
3076 return image_path_name.Buffer[0 .. image_path_name.Length / 2 :0];
3077}
30783082
3079/// `selfExeDirPath` except allocates the result on the heap.3083/// `selfExeDirPath` except allocates the result on the heap.
3080/// Caller owns returned memory.3084/// Caller owns returned memory.