From daa90345834318f0e3a8d7352c0849756dc9175e Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Tue, 14 Mar 2023 00:51:52 +0200 Subject: [PATCH] os: return the long path for os.temp_dir() on windows, even for folders like `c:\someth~1` (#17623) --- vlib/os/os.v | 1 + vlib/os/os_js.js.v | 6 ++++++ vlib/os/os_nix.c.v | 6 ++++++ vlib/os/os_windows.c.v | 21 +++++++++++++++++++++ vlib/os/signal.js.v | 2 +- 5 files changed, 35 insertions(+), 1 deletion(-) diff --git a/vlib/os/os.v b/vlib/os/os.v index f3497e0fb5..18c7790810 100644 --- a/vlib/os/os.v +++ b/vlib/os/os.v @@ -716,6 +716,7 @@ pub fn temp_dir() string { path = 'C:/tmp' } } + path = get_long_path(path) or { path } } $if macos { // avoid /var/folders/6j/cmsk8gd90pd.... on macs diff --git a/vlib/os/os_js.js.v b/vlib/os/os_js.js.v index d6fbb79cc3..b711c3fa3d 100644 --- a/vlib/os/os_js.js.v +++ b/vlib/os/os_js.js.v @@ -183,3 +183,9 @@ pub fn is_readable(path string) bool { return false } } + +// get_long_path has no meaning for *nix, but has for windows, where `c:\folder\some~1` for example +// can be the equivalent of `c:\folder\some spa ces`. On *nix, it just returns a copy of the input path. +fn get_long_path(path string) !string { + return path +} diff --git a/vlib/os/os_nix.c.v b/vlib/os/os_nix.c.v index 80ab6e4116..fe09e2b2ad 100644 --- a/vlib/os/os_nix.c.v +++ b/vlib/os/os_nix.c.v @@ -500,3 +500,9 @@ pub fn posix_set_permission_bit(path_s string, mode u32, enable bool) { } C.chmod(path, int(new_mode)) } + +// get_long_path has no meaning for *nix, but has for windows, where `c:\folder\some~1` for example +// can be the equivalent of `c:\folder\some spa ces`. On *nix, it just returns a copy of the input path. +fn get_long_path(path string) !string { + return path +} diff --git a/vlib/os/os_windows.c.v b/vlib/os/os_windows.c.v index 4863a86184..a8534524d9 100644 --- a/vlib/os/os_windows.c.v +++ b/vlib/os/os_windows.c.v @@ -558,3 +558,24 @@ pub fn (mut c Command) read_line() string { pub fn (mut c Command) close() ! { panic('not implemented') } + +fn C.GetLongPathName(short_path &u16, long_path &u16, long_path_bufsize u32) u32 + +// get_long_path has no meaning for *nix, but has for windows, where `c:\folder\some~1` for example +// can be the equivalent of `c:\folder\some spa ces`. On *nix, it just returns a copy of the input path. +fn get_long_path(path string) !string { + if !path.contains('~') { + return path + } + input_short_path := path.to_wide() + defer { + unsafe { free(input_short_path) } + } + long_path_buf := [4096]u16{} + res := C.GetLongPathName(input_short_path, &long_path_buf[0], sizeof(long_path_buf)) + if res == 0 { + return error(get_error_msg(int(C.GetLastError()))) + } + long_path := unsafe { string_from_wide(&long_path_buf[0]) } + return long_path +} diff --git a/vlib/os/signal.js.v b/vlib/os/signal.js.v index 85fe8a18c2..bb801757c3 100644 --- a/vlib/os/signal.js.v +++ b/vlib/os/signal.js.v @@ -115,7 +115,7 @@ fn signal_from_str(str JS.String) Signal { // - Browser: Will use `window.addEventListener` for handling signal // // TODO: Add signal events implementation for browser backend -pub fn signal_opt(signum Signal, handler SignalHandler) ?SignalHandler { +pub fn signal_opt(signum Signal, handler SignalHandler) !SignalHandler { signame := signal_str(signum) _ := signame $if js_node {