Skip to content

Commit

Permalink
win/spawn: add option for no file extension
Browse files Browse the repository at this point in the history
  • Loading branch information
KyleFromKitware committed Nov 29, 2023
1 parent a5c01d4 commit 10e0442
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 24 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/CI-win.yml
Expand Up @@ -91,7 +91,7 @@ jobs:
cmake --install build --prefix "`pwd`/build/usr"
mkdir -p build/usr/test build/usr/bin
cp -av test/fixtures build/usr/test
cp -av build/uv_run_tests_a.exe build/uv_run_tests.exe \
cp -av build/uv_run_tests_a.exe build/uv_run_tests.exe build/uv_run_tests_a_no_ext build/uv_run_tests_no_ext \
`${{ matrix.config.arch }}-w64-mingw32-gcc -print-file-name=libgcc_s_${{ matrix.config.libgcc }}-1.dll` \
`${{ matrix.config.arch }}-w64-mingw32-gcc -print-file-name=libwinpthread-1.dll` \
`${{ matrix.config.arch }}-w64-mingw32-gcc -print-file-name=libatomic-1.dll` \
Expand Down
12 changes: 12 additions & 0 deletions CMakeLists.txt
Expand Up @@ -703,6 +703,12 @@ if(LIBUV_BUILD_TESTS)
set_tests_properties(uv_test PROPERTIES ENVIRONMENT
"LIBPATH=${CMAKE_BINARY_DIR}:$ENV{LIBPATH}")
endif()
if(WIN32)
add_custom_command(TARGET uv_run_tests POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy
"$<TARGET_FILE:uv_run_tests>"
"$<TARGET_FILE_DIR:uv_run_tests>/uv_run_tests_no_ext")
endif()
add_executable(uv_run_tests_a ${uv_test_sources} uv_win_longpath.manifest)
target_compile_definitions(uv_run_tests_a PRIVATE ${uv_defines})
target_compile_options(uv_run_tests_a PRIVATE ${uv_cflags})
Expand All @@ -719,6 +725,12 @@ if(LIBUV_BUILD_TESTS)
set_target_properties(uv_run_tests PROPERTIES LINKER_LANGUAGE CXX)
set_target_properties(uv_run_tests_a PROPERTIES LINKER_LANGUAGE CXX)
endif()
if(WIN32)
add_custom_command(TARGET uv_run_tests_a POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy
"$<TARGET_FILE:uv_run_tests_a>"
"$<TARGET_FILE_DIR:uv_run_tests_a>/uv_run_tests_a_no_ext")
endif()
endif()

# Now for some gibbering horrors from beyond the stars...
Expand Down
35 changes: 12 additions & 23 deletions src/win/process.c
Expand Up @@ -249,19 +249,16 @@ static WCHAR* path_search_walk_ext(const WCHAR *dir,
const WCHAR *name,
size_t name_len,
WCHAR *cwd,
size_t cwd_len,
int name_has_ext) {
size_t cwd_len) {
WCHAR* result;

/* If the name itself has a nonempty extension, try this extension first */
if (name_has_ext) {
result = search_path_join_test(dir, dir_len,
name, name_len,
L"", 0,
cwd, cwd_len);
if (result != NULL) {
return result;
}
/* Try the name itself first */
result = search_path_join_test(dir, dir_len,
name, name_len,
L"", 0,
cwd, cwd_len);
if (result != NULL) {
return result;
}

/* Try .com extension */
Expand Down Expand Up @@ -304,8 +301,7 @@ 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.
* - Search for the file exactly as specified first.
*
* - If the literal filename is not found in a directory, try *appending*
* (not replacing) .com first and then .exe.
Expand Down Expand Up @@ -362,26 +358,20 @@ static WCHAR* search_path(const WCHAR *file,

file_has_dir = file_name_start != file;

/* Check if the filename includes an extension */
dot = wcschr(file_name_start, L'.');
name_has_ext = (dot != NULL && dot[1] != L'\0');

if (file_has_dir) {
/* The file has a path inside, don't use path */
result = path_search_walk_ext(
file, file_name_start - file,
file_name_start, file_len - (file_name_start - file),
cwd, cwd_len,
name_has_ext);
cwd, cwd_len);

} else {
dir_end = path;

/* The file is really only a name; look in cwd first, then scan path */
result = path_search_walk_ext(L"", 0,
file, file_len,
cwd, cwd_len,
name_has_ext);
cwd, cwd_len);

while (result == NULL) {
if (dir_end == NULL || *dir_end == L'\0') {
Expand Down Expand Up @@ -429,8 +419,7 @@ static WCHAR* search_path(const WCHAR *file,

result = path_search_walk_ext(dir_path, dir_len,
file, file_len,
cwd, cwd_len,
name_has_ext);
cwd, cwd_len);
}
}

Expand Down
4 changes: 4 additions & 0 deletions test/test-list.h
Expand Up @@ -506,6 +506,8 @@ TEST_DECLARE (listen_no_simultaneous_accepts)
TEST_DECLARE (fs_stat_root)
TEST_DECLARE (spawn_with_an_odd_path)
TEST_DECLARE (spawn_no_path)
TEST_DECLARE (spawn_no_ext)
TEST_DECLARE (spawn_path_no_ext)
TEST_DECLARE (ipc_listen_after_bind_twice)
TEST_DECLARE (win32_signum_number)
#else
Expand Down Expand Up @@ -1025,6 +1027,8 @@ TASK_LIST_START
TEST_ENTRY (fs_stat_root)
TEST_ENTRY (spawn_with_an_odd_path)
TEST_ENTRY (spawn_no_path)
TEST_ENTRY (spawn_no_ext)
TEST_ENTRY (spawn_path_no_ext)
TEST_ENTRY (ipc_listen_after_bind_twice)
TEST_ENTRY (win32_signum_number)
#else
Expand Down
61 changes: 61 additions & 0 deletions test/test-spawn.c
Expand Up @@ -1394,6 +1394,67 @@ TEST_IMPL(spawn_no_path) {
MAKE_VALGRIND_HAPPY(uv_default_loop());
return 0;
}


TEST_IMPL(spawn_no_ext) {
char new_exepath[1024];

init_process_options("spawn_helper1", exit_cb);
memcpy(new_exepath, exepath, exepath_size - (sizeof(".exe") - sizeof(char)));
memcpy(new_exepath + exepath_size - (sizeof(".exe") - sizeof(char)), "_no_ext", sizeof("_no_ext"));
options.file = options.args[0] = new_exepath;

ASSERT_OK(uv_spawn(uv_default_loop(), &process, &options));
ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));

ASSERT_EQ(1, exit_cb_called);
ASSERT_EQ(1, close_cb_called);

MAKE_VALGRIND_HAPPY(uv_default_loop());
return 0;
}


TEST_IMPL(spawn_path_no_ext) {
int r;
int len;
int file_len;
char file[64];
char path[1024];
char* env[2];

/* Set up the process, but make sure that the file to run is relative and
* requires a lookup into PATH. */
init_process_options("spawn_helper1", exit_cb);

/* Set up the PATH env variable */
for (len = strlen(exepath), file_len = 0;
exepath[len - 1] != '/' && exepath[len - 1] != '\\';
len--, file_len++);
memcpy(file, exepath + len, file_len - (sizeof(".exe") - sizeof(char)));
memcpy(file + file_len - (sizeof(".exe") - sizeof(char)), "_no_ext", sizeof("_no_ext"));
exepath[len] = 0;
strcpy(path, "PATH=");
strcpy(path + 5, exepath);

env[0] = path;
env[1] = NULL;

options.file = options.args[0] = file;
options.env = env;

r = uv_spawn(uv_default_loop(), &process, &options);
ASSERT_OK(r);

r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT_OK(r);

ASSERT_EQ(1, exit_cb_called);
ASSERT_EQ(1, close_cb_called);

MAKE_VALGRIND_HAPPY(uv_default_loop());
return 0;
}
#endif

#ifndef _WIN32
Expand Down

0 comments on commit 10e0442

Please sign in to comment.