46 #define E_V(str) { L##str, L##str L"=", sizeof(str) }
83 SECURITY_ATTRIBUTES
attr;
84 JOBOBJECT_EXTENDED_LIMIT_INFORMATION info;
89 memset(&info, 0,
sizeof info);
90 info.BasicLimitInformation.LimitFlags =
101 JobObjectExtendedLimitInformation,
112 ws_len = MultiByteToWideChar(CP_UTF8,
119 return GetLastError();
122 ws = (WCHAR*)
uv__malloc(ws_len *
sizeof(WCHAR));
124 return ERROR_OUTOFMEMORY;
127 r = MultiByteToWideChar(CP_UTF8,
147 handle->child_stdio_buffer = NULL;
148 handle->exit_cb_pending = 0;
170 WCHAR *
result, *result_pos;
172 if (dir_len > 2 && dir[0] ==
L'\\' && dir[1] ==
L'\\') {
175 }
else if (dir_len >= 1 && (dir[0] ==
L'/' || dir[0] ==
L'\\')) {
178 }
else if (dir_len >= 2 && dir[1] ==
L':' &&
179 (dir_len < 3 || (dir[2] !=
L'/' && dir[2] !=
L'\\'))) {
184 if (cwd_len < 2 || _wcsnicmp(
cwd, dir, 2) != 0) {
190 }
else if (dir_len > 2 && dir[1] ==
L':') {
199 (cwd_len + 1 + dir_len + 1 + name_len + 1 + ext_len + 1));
202 wcsncpy(result_pos,
cwd, cwd_len);
203 result_pos += cwd_len;
206 if (cwd_len && wcsrchr(
L"\\/:", result_pos[-1]) == NULL) {
207 result_pos[0] =
L'\\';
212 wcsncpy(result_pos, dir, dir_len);
213 result_pos += dir_len;
216 if (dir_len && wcsrchr(
L"\\/:", result_pos[-1]) == NULL) {
217 result_pos[0] =
L'\\';
222 wcsncpy(result_pos,
name, name_len);
223 result_pos += name_len;
227 if (name_len && result_pos[-1] !=
'.') {
228 result_pos[0] =
L'.';
233 wcsncpy(result_pos,
ext, ext_len);
234 result_pos += ext_len;
238 result_pos[0] =
L'\0';
242 if (
attrs != INVALID_FILE_ATTRIBUTES &&
243 !(
attrs & FILE_ATTRIBUTE_DIRECTORY)) {
345 WCHAR *file_name_start;
347 const WCHAR *dir_start, *dir_end, *dir_path;
351 size_t file_len = wcslen(
file);
352 size_t cwd_len = wcslen(
cwd);
358 || (file_len == 1 &&
file[0] ==
L'.')) {
364 for (file_name_start = (WCHAR*)
file + file_len;
365 file_name_start >
file
366 && file_name_start[-1] !=
L'\\'
367 && file_name_start[-1] !=
L'/'
368 && file_name_start[-1] !=
L':';
371 file_has_dir = file_name_start !=
file;
374 dot = wcschr(file_name_start,
L'.');
375 name_has_ext = (dot != NULL && dot[1] !=
L'\0');
381 file_name_start, file_len - (file_name_start -
file),
395 if (*dir_end ==
L'\0') {
408 if (*dir_start ==
L'"' || *dir_start ==
L'\'') {
409 dir_end = wcschr(dir_start + 1, *dir_start);
410 if (dir_end == NULL) {
411 dir_end = wcschr(dir_start,
L'\0');
415 dir_end = wcschr(dir_end,
L';');
416 if (dir_end == NULL) {
417 dir_end = wcschr(dir_start,
L'\0');
421 if (dir_end - dir_start == 0) {
425 dir_path = dir_start;
426 dir_len = dir_end - dir_start;
429 if (dir_path[0] ==
'"' || dir_path[0] ==
'\'') {
434 if (dir_path[dir_len - 1] ==
'"' || dir_path[dir_len - 1] ==
'\'') {
454 size_t len = wcslen(source);
466 if (NULL == wcspbrk(source,
L" \t\"")) {
473 if (NULL == wcspbrk(source,
L"\"\\")) {
507 for (
i =
len;
i > 0; --
i) {
510 if (quote_hit && source[
i - 1] ==
L'\\') {
512 }
else if(source[
i - 1] ==
L'"') {
529 WCHAR* temp_buffer = NULL;
531 size_t temp_buffer_len = 0;
540 arg_len = MultiByteToWideChar(CP_UTF8,
547 return GetLastError();
552 if (arg_len > temp_buffer_len)
553 temp_buffer_len = arg_len;
560 dst_len = dst_len * 2 + arg_count * 2;
565 err = ERROR_OUTOFMEMORY;
570 temp_buffer = (WCHAR*)
uv__malloc(temp_buffer_len *
sizeof(WCHAR));
571 if (temp_buffer == NULL) {
572 err = ERROR_OUTOFMEMORY;
581 arg_len = MultiByteToWideChar(CP_UTF8,
586 (
int) (
dst + dst_len -
pos));
588 err = GetLastError();
592 if (verbatim_arguments) {
594 wcscpy(
pos, temp_buffer);
625 a_eq = wcschr(
a,
L'=');
627 na = (
int)(
long)(a_eq -
a);
631 b_eq = wcschr(
b,
L'=');
635 A = alloca((na+1) *
sizeof(
wchar_t));
636 B = alloca((nb+1) *
sizeof(
wchar_t));
650 }
else if (AA > BB) {
652 }
else if (!AA && !BB) {
660 wchar_t* astr = *(
wchar_t*
const*)
a;
661 wchar_t* bstr = *(
wchar_t*
const*)
b;
690 size_t env_block_count = 1;
699 if (strchr(*
env,
'=')) {
700 len = MultiByteToWideChar(CP_UTF8,
707 return GetLastError();
715 dst_copy = (WCHAR*)
uv__malloc(env_len *
sizeof(WCHAR));
716 if (dst_copy == NULL && env_len > 0) {
717 return ERROR_OUTOFMEMORY;
719 env_copy = alloca(env_block_count *
sizeof(WCHAR*));
724 if (strchr(*
env,
'=')) {
725 len = MultiByteToWideChar(CP_UTF8,
730 (
int) (env_len - (
ptr - dst_copy)));
732 DWORD
err = GetLastError();
741 assert(env_len == 0 || env_len == (
size_t) (
ptr - dst_copy));
758 var_size = GetEnvironmentVariableW(
required_vars[
i].wide, NULL, 0);
759 required_vars_value_len[
i] = var_size;
776 return ERROR_OUTOFMEMORY;
779 for (
ptr =
dst, ptr_copy = env_copy,
i = 0;
785 }
else if (!*ptr_copy) {
794 len = required_vars_value_len[
i];
800 (
int) (env_len - (
ptr -
dst)));
801 if (var_size != (DWORD) (
len - 1)) {
808 len = wcslen(*ptr_copy) + 1;
809 wmemcpy(
ptr, *ptr_copy,
len);
817 assert(env_len == (
size_t) (
ptr -
dst));
832 for (;
env != NULL && *
env != 0;
env += wcslen(
env) + 1) {
833 if ((
env[0] ==
L'P' ||
env[0] ==
L'p') &&
834 (
env[1] ==
L'A' ||
env[1] ==
L'a') &&
835 (
env[2] ==
L'T' ||
env[2] ==
L't') &&
836 (
env[3] ==
L'H' ||
env[3] ==
L'h') &&
853 assert(didTimeout ==
FALSE);
855 assert(!
process->exit_cb_pending);
869 assert(
handle->exit_cb_pending);
870 handle->exit_cb_pending = 0;
881 UnregisterWait(
handle->wait_handle);
889 if (GetExitCodeProcess(
handle->process_handle, &
status)) {
918 if (!
handle->exit_cb_pending) {
925 assert(!
handle->exit_cb_pending);
930 CloseHandle(
handle->process_handle);
941 WCHAR*
path = NULL, *alloc_path = NULL;
943 WCHAR* application_path = NULL, *application = NULL, *arguments = NULL,
946 PROCESS_INFORMATION info;
997 cwd_len = GetCurrentDirectoryW(0, NULL);
999 err = GetLastError();
1005 err = ERROR_OUTOFMEMORY;
1009 r = GetCurrentDirectoryW(cwd_len,
cwd);
1010 if (
r == 0 ||
r >= cwd_len) {
1011 err = GetLastError();
1021 path_len = GetEnvironmentVariableW(
L"PATH", NULL, 0);
1022 if (path_len == 0) {
1023 err = GetLastError();
1027 alloc_path = (WCHAR*)
uv__malloc(path_len *
sizeof(WCHAR));
1028 if (alloc_path == NULL) {
1029 err = ERROR_OUTOFMEMORY;
1034 r = GetEnvironmentVariableW(
L"PATH",
path, path_len);
1035 if (
r == 0 ||
r >= path_len) {
1036 err = GetLastError();
1048 if (application_path == NULL) {
1050 err = ERROR_FILE_NOT_FOUND;
1058 startup.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
1067 process_flags = CREATE_UNICODE_ENVIRONMENT;
1076 process_flags |= CREATE_NO_WINDOW;
1082 startup.wShowWindow = SW_HIDE;
1084 startup.wShowWindow = SW_SHOWDEFAULT;
1098 process_flags |= DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP;
1101 if (!CreateProcessW(application_path,
1112 err = GetLastError();
1118 process->process_handle = info.hProcess;
1137 DWORD
err = GetLastError();
1138 if (
err != ERROR_ACCESS_DENIED)
1157 WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE);
1162 CloseHandle(info.hThread);
1179 if (
process->child_stdio_buffer != NULL) {
1182 process->child_stdio_buffer = NULL;
1189 static int uv__kill(HANDLE process_handle,
int signum) {
1190 if (signum < 0 || signum >=
NSIG) {
1203 if (TerminateProcess(process_handle, 1))
1208 err = GetLastError();
1209 if (
err == ERROR_ACCESS_DENIED &&
1210 GetExitCodeProcess(process_handle, &
status) &&
1211 status != STILL_ACTIVE) {
1222 if (!GetExitCodeProcess(process_handle, &
status))
1225 if (
status != STILL_ACTIVE)
1250 process->exit_signal = signum;
1258 HANDLE process_handle;
1261 process_handle = GetCurrentProcess();
1263 process_handle = OpenProcess(PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION,
1268 if (process_handle == NULL) {
1269 err = GetLastError();
1270 if (
err == ERROR_INVALID_PARAMETER) {
1278 CloseHandle(process_handle);