| ... | @@ -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 immediately | 2960 | // 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 | } |
| 2979 | | 2983 | |
| 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 executable | 2987 | /// 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 | } |
| 3072 | | 3080 | |
| 3073 | /// The result is UTF16LE-encoded. | 3081 | pub const selfExePathW = @compileError("deprecated; use selfExePath instead"); |
| 3074 | pub 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 | } | | |
| 3078 | | 3082 | |
| 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. |