From 58a271e60b53f6d2393f84bc3f56f087b3d7f5af Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 8 Feb 2024 16:35:54 -0500 Subject: cmUVProcessChain: Implement no-extension-on-Windows support with libuv 1.48 Use the new `UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME` option when building against libuv 1.48 or higher. --- Source/cmUVProcessChain.cxx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Source/cmUVProcessChain.cxx b/Source/cmUVProcessChain.cxx index cd452cb..8b8ace6 100644 --- a/Source/cmUVProcessChain.cxx +++ b/Source/cmUVProcessChain.cxx @@ -311,6 +311,9 @@ void cmUVProcessChain::InternalData::SpawnProcess( arguments.push_back(nullptr); options.args = const_cast(arguments.data()); options.flags = UV_PROCESS_WINDOWS_HIDE; +#if UV_VERSION_MAJOR > 1 || (UV_VERSION_MAJOR == 1 && UV_VERSION_MINOR >= 48) + options.flags |= UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME; +#endif if (!this->Builder->WorkingDirectory.empty()) { options.cwd = this->Builder->WorkingDirectory.c_str(); } -- cgit v0.12 From 077a1d57695c6c052fee47ddb977a3d95144dabd Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 8 Feb 2024 16:49:18 -0500 Subject: libuv: win/spawn: optionally run executable paths with no file extension Backport libuv commit `3f7191e5` (win/spawn: optionally run executable paths with no file extension, 2024-02-05, v1.48.0~8) to add the `UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME` option we now use. Issue: #25450 --- Source/cmUVProcessChain.cxx | 4 +++- Utilities/cmlibuv/include/uv.h | 9 ++++++++- Utilities/cmlibuv/src/unix/process.c | 1 + Utilities/cmlibuv/src/win/process.c | 14 +++++++++----- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/Source/cmUVProcessChain.cxx b/Source/cmUVProcessChain.cxx index 8b8ace6..b0f1cf1 100644 --- a/Source/cmUVProcessChain.cxx +++ b/Source/cmUVProcessChain.cxx @@ -311,7 +311,9 @@ void cmUVProcessChain::InternalData::SpawnProcess( arguments.push_back(nullptr); options.args = const_cast(arguments.data()); options.flags = UV_PROCESS_WINDOWS_HIDE; -#if UV_VERSION_MAJOR > 1 || (UV_VERSION_MAJOR == 1 && UV_VERSION_MINOR >= 48) +#if UV_VERSION_MAJOR > 1 || \ + (UV_VERSION_MAJOR == 1 && UV_VERSION_MINOR >= 48) || \ + !defined(CMAKE_USE_SYSTEM_LIBUV) options.flags |= UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME; #endif if (!this->Builder->WorkingDirectory.empty()) { diff --git a/Utilities/cmlibuv/include/uv.h b/Utilities/cmlibuv/include/uv.h index ffe34ec..42e3446 100644 --- a/Utilities/cmlibuv/include/uv.h +++ b/Utilities/cmlibuv/include/uv.h @@ -1080,7 +1080,14 @@ enum uv_process_flags { * option is only meaningful on Windows systems. On Unix it is silently * ignored. */ - UV_PROCESS_WINDOWS_HIDE_GUI = (1 << 6) + UV_PROCESS_WINDOWS_HIDE_GUI = (1 << 6), + /* + * On Windows, if the path to the program to execute, specified in + * uv_process_options_t's file field, has a directory component, + * search for the exact file name before trying variants with + * extensions like '.exe' or '.cmd'. + */ + UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME = (1 << 7) }; /* diff --git a/Utilities/cmlibuv/src/unix/process.c b/Utilities/cmlibuv/src/unix/process.c index 30872cf..39ec451 100644 --- a/Utilities/cmlibuv/src/unix/process.c +++ b/Utilities/cmlibuv/src/unix/process.c @@ -1008,6 +1008,7 @@ int uv_spawn(uv_loop_t* loop, assert(!(options->flags & ~(UV_PROCESS_DETACHED | UV_PROCESS_SETGID | UV_PROCESS_SETUID | + UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME | UV_PROCESS_WINDOWS_HIDE | UV_PROCESS_WINDOWS_HIDE_CONSOLE | UV_PROCESS_WINDOWS_HIDE_GUI | diff --git a/Utilities/cmlibuv/src/win/process.c b/Utilities/cmlibuv/src/win/process.c index 9d0ceba..11cf5b2 100644 --- a/Utilities/cmlibuv/src/win/process.c +++ b/Utilities/cmlibuv/src/win/process.c @@ -329,8 +329,9 @@ static WCHAR* path_search_walk_ext(const WCHAR *dir, * - If there's really only a filename, check the current directory for file, * then search all path directories. * - * - If filename specified has *any* extension, search for the file with the - * specified extension first. + * - If filename specified has *any* extension, or already contains a path + * and the UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME flag is specified, + * search for the file with the exact specified filename first. * * - If the literal filename is not found in a directory, try *appending* * (not replacing) .com first and then .exe. @@ -356,7 +357,8 @@ static WCHAR* path_search_walk_ext(const WCHAR *dir, */ static WCHAR* search_path(const WCHAR *file, WCHAR *cwd, - const WCHAR *path) { + const WCHAR *path, + unsigned int flags) { int file_has_dir; WCHAR* result = NULL; WCHAR *file_name_start; @@ -397,7 +399,7 @@ static WCHAR* search_path(const WCHAR *file, file, file_name_start - file, file_name_start, file_len - (file_name_start - file), cwd, cwd_len, - name_has_ext); + name_has_ext || (flags & UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME)); } else { dir_end = path; @@ -987,6 +989,7 @@ int uv_spawn(uv_loop_t* loop, assert(!(options->flags & ~(UV_PROCESS_DETACHED | UV_PROCESS_SETGID | UV_PROCESS_SETUID | + UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME | UV_PROCESS_WINDOWS_HIDE | UV_PROCESS_WINDOWS_HIDE_CONSOLE | UV_PROCESS_WINDOWS_HIDE_GUI | @@ -1066,7 +1069,8 @@ int uv_spawn(uv_loop_t* loop, application_path = search_path(application, cwd, - path); + path, + options->flags); if (application_path == NULL) { /* Not found. */ err = ERROR_FILE_NOT_FOUND; -- cgit v0.12