Merge 69eda08da4 into 44125af62a
This commit is contained in:
commit
d740da7960
@ -94,6 +94,9 @@ modifies the child process behaviour:
|
|||||||
Changing the UID/GID is only supported on Unix, ``uv_spawn`` will fail on
|
Changing the UID/GID is only supported on Unix, ``uv_spawn`` will fail on
|
||||||
Windows with ``UV_ENOTSUP``.
|
Windows with ``UV_ENOTSUP``.
|
||||||
|
|
||||||
|
* ``UV_PROCESS_WINDOWS_RESOLVE_BATCH`` - Considers .cmd and .bat files
|
||||||
|
when resolving an executable without an explicit extension on Windows.
|
||||||
|
Ignored on Unix.
|
||||||
* ``UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS`` - No quoting or escaping of
|
* ``UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS`` - No quoting or escaping of
|
||||||
``uv_process_options_t.args`` is done on Windows. Ignored on Unix.
|
``uv_process_options_t.args`` is done on Windows. Ignored on Unix.
|
||||||
* ``UV_PROCESS_DETACHED`` - Starts the child process in a new session, which
|
* ``UV_PROCESS_DETACHED`` - Starts the child process in a new session, which
|
||||||
|
|||||||
@ -92,7 +92,13 @@ Data types
|
|||||||
* search for the exact file name before trying variants with
|
* search for the exact file name before trying variants with
|
||||||
* extensions like '.exe' or '.cmd'.
|
* extensions like '.exe' or '.cmd'.
|
||||||
*/
|
*/
|
||||||
UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME = (1 << 7)
|
UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME = (1 << 7),
|
||||||
|
/*
|
||||||
|
* Consider '.cmd' and '.bat' files when resolving an executable
|
||||||
|
* without an explicit extension. This option is only meaningful
|
||||||
|
* on Windows systems. On Unix it is silently ignored.
|
||||||
|
*/
|
||||||
|
UV_PROCESS_WINDOWS_RESOLVE_BATCH = (1 << 8)
|
||||||
};
|
};
|
||||||
|
|
||||||
.. c:type:: uv_stdio_container_t
|
.. c:type:: uv_stdio_container_t
|
||||||
|
|||||||
@ -1161,7 +1161,13 @@ enum uv_process_flags {
|
|||||||
* search for the exact file name before trying variants with
|
* search for the exact file name before trying variants with
|
||||||
* extensions like '.exe' or '.cmd'.
|
* extensions like '.exe' or '.cmd'.
|
||||||
*/
|
*/
|
||||||
UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME = (1 << 7)
|
UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME = (1 << 7),
|
||||||
|
/*
|
||||||
|
* Consider '.cmd' and '.bat' files when resolving an executable
|
||||||
|
* without an explicit extension. This option is only meaningful
|
||||||
|
* on Windows systems. On Unix it is silently ignored.
|
||||||
|
*/
|
||||||
|
UV_PROCESS_WINDOWS_RESOLVE_BATCH = (1 << 8)
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -1028,6 +1028,7 @@ int uv_spawn(uv_loop_t* loop,
|
|||||||
UV_PROCESS_WINDOWS_HIDE |
|
UV_PROCESS_WINDOWS_HIDE |
|
||||||
UV_PROCESS_WINDOWS_HIDE_CONSOLE |
|
UV_PROCESS_WINDOWS_HIDE_CONSOLE |
|
||||||
UV_PROCESS_WINDOWS_HIDE_GUI |
|
UV_PROCESS_WINDOWS_HIDE_GUI |
|
||||||
|
UV_PROCESS_WINDOWS_RESOLVE_BATCH |
|
||||||
UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS)));
|
UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS)));
|
||||||
|
|
||||||
uv__handle_init(loop, (uv_handle_t*)process, UV_PROCESS);
|
uv__handle_init(loop, (uv_handle_t*)process, UV_PROCESS);
|
||||||
|
|||||||
@ -249,7 +249,8 @@ static WCHAR* path_search_walk_ext(const WCHAR *dir,
|
|||||||
size_t name_len,
|
size_t name_len,
|
||||||
WCHAR *cwd,
|
WCHAR *cwd,
|
||||||
size_t cwd_len,
|
size_t cwd_len,
|
||||||
int name_has_ext) {
|
int name_has_ext,
|
||||||
|
int resolve_batch) {
|
||||||
WCHAR* result;
|
WCHAR* result;
|
||||||
|
|
||||||
/* If the name itself has a nonempty extension, try this extension first */
|
/* If the name itself has a nonempty extension, try this extension first */
|
||||||
@ -281,6 +282,28 @@ static WCHAR* path_search_walk_ext(const WCHAR *dir,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!resolve_batch) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try .cmd extension */
|
||||||
|
result = search_path_join_test(dir, dir_len,
|
||||||
|
name, name_len,
|
||||||
|
L"cmd", 3,
|
||||||
|
cwd, cwd_len);
|
||||||
|
if (result != NULL) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try .bat extension */
|
||||||
|
result = search_path_join_test(dir, dir_len,
|
||||||
|
name, name_len,
|
||||||
|
L"bat", 3,
|
||||||
|
cwd, cwd_len);
|
||||||
|
if (result != NULL) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,6 +363,7 @@ static WCHAR* search_path(const WCHAR *file,
|
|||||||
const WCHAR *dir_start, *dir_end, *dir_path;
|
const WCHAR *dir_start, *dir_end, *dir_path;
|
||||||
size_t dir_len;
|
size_t dir_len;
|
||||||
int name_has_ext;
|
int name_has_ext;
|
||||||
|
int resolve_batch = flags & UV_PROCESS_WINDOWS_RESOLVE_BATCH;
|
||||||
|
|
||||||
size_t file_len = wcslen(file);
|
size_t file_len = wcslen(file);
|
||||||
size_t cwd_len = wcslen(cwd);
|
size_t cwd_len = wcslen(cwd);
|
||||||
@ -373,7 +397,8 @@ static WCHAR* search_path(const WCHAR *file,
|
|||||||
file, file_name_start - file,
|
file, file_name_start - file,
|
||||||
file_name_start, file_len - (file_name_start - file),
|
file_name_start, file_len - (file_name_start - file),
|
||||||
cwd, cwd_len,
|
cwd, cwd_len,
|
||||||
name_has_ext || (flags & UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME));
|
name_has_ext || (flags & UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME),
|
||||||
|
resolve_batch);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
dir_end = path;
|
dir_end = path;
|
||||||
@ -383,7 +408,7 @@ static WCHAR* search_path(const WCHAR *file,
|
|||||||
result = path_search_walk_ext(L"", 0,
|
result = path_search_walk_ext(L"", 0,
|
||||||
file, file_len,
|
file, file_len,
|
||||||
cwd, cwd_len,
|
cwd, cwd_len,
|
||||||
name_has_ext);
|
name_has_ext, resolve_batch);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (result == NULL) {
|
while (result == NULL) {
|
||||||
@ -433,7 +458,7 @@ static WCHAR* search_path(const WCHAR *file,
|
|||||||
result = path_search_walk_ext(dir_path, dir_len,
|
result = path_search_walk_ext(dir_path, dir_len,
|
||||||
file, file_len,
|
file, file_len,
|
||||||
cwd, cwd_len,
|
cwd, cwd_len,
|
||||||
name_has_ext);
|
name_has_ext, resolve_batch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -928,6 +953,7 @@ int uv_spawn(uv_loop_t* loop,
|
|||||||
UV_PROCESS_WINDOWS_HIDE |
|
UV_PROCESS_WINDOWS_HIDE |
|
||||||
UV_PROCESS_WINDOWS_HIDE_CONSOLE |
|
UV_PROCESS_WINDOWS_HIDE_CONSOLE |
|
||||||
UV_PROCESS_WINDOWS_HIDE_GUI |
|
UV_PROCESS_WINDOWS_HIDE_GUI |
|
||||||
|
UV_PROCESS_WINDOWS_RESOLVE_BATCH |
|
||||||
UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS)));
|
UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS)));
|
||||||
|
|
||||||
err = uv__utf8_to_utf16_alloc(options->file, &application);
|
err = uv__utf8_to_utf16_alloc(options->file, &application);
|
||||||
|
|||||||
@ -352,6 +352,7 @@ TEST_DECLARE (spawn_quoted_path)
|
|||||||
TEST_DECLARE (spawn_tcp_server)
|
TEST_DECLARE (spawn_tcp_server)
|
||||||
TEST_DECLARE (spawn_exercise_sigchld_issue)
|
TEST_DECLARE (spawn_exercise_sigchld_issue)
|
||||||
TEST_DECLARE (spawn_relative_path)
|
TEST_DECLARE (spawn_relative_path)
|
||||||
|
TEST_DECLARE (spawn_batch_file)
|
||||||
TEST_DECLARE (fs_poll)
|
TEST_DECLARE (fs_poll)
|
||||||
TEST_DECLARE (fs_poll_getpath)
|
TEST_DECLARE (fs_poll_getpath)
|
||||||
TEST_DECLARE (fs_poll_close_request)
|
TEST_DECLARE (fs_poll_close_request)
|
||||||
@ -1049,6 +1050,7 @@ TASK_LIST_START
|
|||||||
TEST_ENTRY (spawn_tcp_server)
|
TEST_ENTRY (spawn_tcp_server)
|
||||||
TEST_ENTRY (spawn_exercise_sigchld_issue)
|
TEST_ENTRY (spawn_exercise_sigchld_issue)
|
||||||
TEST_ENTRY (spawn_relative_path)
|
TEST_ENTRY (spawn_relative_path)
|
||||||
|
TEST_ENTRY (spawn_batch_file)
|
||||||
TEST_ENTRY (fs_poll)
|
TEST_ENTRY (fs_poll)
|
||||||
TEST_ENTRY (fs_poll_getpath)
|
TEST_ENTRY (fs_poll_getpath)
|
||||||
TEST_ENTRY (fs_poll_close_request)
|
TEST_ENTRY (fs_poll_close_request)
|
||||||
|
|||||||
@ -1532,6 +1532,7 @@ TEST_IMPL(spawn_setuid_fails) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* These flags should be ignored on Unices. */
|
/* These flags should be ignored on Unices. */
|
||||||
|
options.flags |= UV_PROCESS_WINDOWS_RESOLVE_BATCH;
|
||||||
options.flags |= UV_PROCESS_WINDOWS_HIDE;
|
options.flags |= UV_PROCESS_WINDOWS_HIDE;
|
||||||
options.flags |= UV_PROCESS_WINDOWS_HIDE_CONSOLE;
|
options.flags |= UV_PROCESS_WINDOWS_HIDE_CONSOLE;
|
||||||
options.flags |= UV_PROCESS_WINDOWS_HIDE_GUI;
|
options.flags |= UV_PROCESS_WINDOWS_HIDE_GUI;
|
||||||
@ -2111,3 +2112,36 @@ TEST_IMPL(spawn_relative_path) {
|
|||||||
MAKE_VALGRIND_HAPPY(uv_default_loop());
|
MAKE_VALGRIND_HAPPY(uv_default_loop());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_IMPL(spawn_batch_file) {
|
||||||
|
#ifndef _WIN32
|
||||||
|
RETURN_SKIP("Test for Windows");
|
||||||
|
#else
|
||||||
|
char filename[1024];
|
||||||
|
FILE* file;
|
||||||
|
uv_process_t process2;
|
||||||
|
|
||||||
|
snprintf(exepath, sizeof(exepath), "test_file_foo");
|
||||||
|
snprintf(filename, sizeof(filename), "%s.bat", exepath);
|
||||||
|
file = fopen(filename, "w");
|
||||||
|
fprintf(file, "exit /B 1\r\n");
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
args[0] = exepath;
|
||||||
|
args[1] = NULL;
|
||||||
|
options.file = args[0];
|
||||||
|
options.args = args;
|
||||||
|
options.exit_cb = exit_cb;
|
||||||
|
options.flags = 0;
|
||||||
|
|
||||||
|
ASSERT_EQ(uv_spawn(uv_default_loop(), &process, &options), UV_ENOENT);
|
||||||
|
|
||||||
|
options.flags |= UV_PROCESS_WINDOWS_RESOLVE_BATCH;
|
||||||
|
ASSERT_OK(uv_spawn(uv_default_loop(), &process2, &options));
|
||||||
|
ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
|
||||||
|
|
||||||
|
MAKE_VALGRIND_HAPPY(uv_default_loop());
|
||||||
|
remove(filename);
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user