| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include <process.h> | 5 #include <process.h> |
| 6 | 6 |
| 7 #include "bin/builtin.h" | 7 #include "bin/builtin.h" |
| 8 #include "bin/process.h" | 8 #include "bin/process.h" |
| 9 #include "bin/eventhandler.h" | 9 #include "bin/eventhandler.h" |
| 10 #include "bin/log.h" | 10 #include "bin/log.h" |
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 return error_code; | 384 return error_code; |
| 385 } | 385 } |
| 386 if (!CreateProcessPipe(exit_handles, pipe_names[3], kInheritNone)) { | 386 if (!CreateProcessPipe(exit_handles, pipe_names[3], kInheritNone)) { |
| 387 int error_code = SetOsErrorMessage(os_error_message); | 387 int error_code = SetOsErrorMessage(os_error_message); |
| 388 CloseProcessPipes( | 388 CloseProcessPipes( |
| 389 stdin_handles, stdout_handles, stderr_handles, exit_handles); | 389 stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| 390 return error_code; | 390 return error_code; |
| 391 } | 391 } |
| 392 | 392 |
| 393 // Setup info structures. | 393 // Setup info structures. |
| 394 STARTUPINFOEX startup_info; | 394 STARTUPINFOEXW startup_info; |
| 395 ZeroMemory(&startup_info, sizeof(startup_info)); | 395 ZeroMemory(&startup_info, sizeof(startup_info)); |
| 396 startup_info.StartupInfo.cb = sizeof(startup_info); | 396 startup_info.StartupInfo.cb = sizeof(startup_info); |
| 397 startup_info.StartupInfo.hStdInput = stdin_handles[kReadHandle]; | 397 startup_info.StartupInfo.hStdInput = stdin_handles[kReadHandle]; |
| 398 startup_info.StartupInfo.hStdOutput = stdout_handles[kWriteHandle]; | 398 startup_info.StartupInfo.hStdOutput = stdout_handles[kWriteHandle]; |
| 399 startup_info.StartupInfo.hStdError = stderr_handles[kWriteHandle]; | 399 startup_info.StartupInfo.hStdError = stderr_handles[kWriteHandle]; |
| 400 startup_info.StartupInfo.dwFlags = STARTF_USESTDHANDLES; | 400 startup_info.StartupInfo.dwFlags = STARTF_USESTDHANDLES; |
| 401 | 401 |
| 402 // Setup the handles to inherit. We only want to inherit the three handles | 402 // Setup the handles to inherit. We only want to inherit the three handles |
| 403 // for stdin, stdout and stderr. | 403 // for stdin, stdout and stderr. |
| 404 SIZE_T size = 0; | 404 SIZE_T size = 0; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 stdin_handles, stdout_handles, stderr_handles, exit_handles); | 439 stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| 440 free(attribute_list); | 440 free(attribute_list); |
| 441 return error_code; | 441 return error_code; |
| 442 } | 442 } |
| 443 startup_info.lpAttributeList = attribute_list; | 443 startup_info.lpAttributeList = attribute_list; |
| 444 | 444 |
| 445 PROCESS_INFORMATION process_info; | 445 PROCESS_INFORMATION process_info; |
| 446 ZeroMemory(&process_info, sizeof(process_info)); | 446 ZeroMemory(&process_info, sizeof(process_info)); |
| 447 | 447 |
| 448 // Transform input strings to system format. | 448 // Transform input strings to system format. |
| 449 path = StringUtils::Utf8ToConsoleString(path); | 449 const wchar_t* system_path = StringUtils::Utf8ToWide(path); |
| 450 wchar_t** system_arguments = new wchar_t*[arguments_length]; |
| 450 for (int i = 0; i < arguments_length; i++) { | 451 for (int i = 0; i < arguments_length; i++) { |
| 451 arguments[i] = StringUtils::Utf8ToConsoleString(arguments[i]); | 452 system_arguments[i] = StringUtils::Utf8ToWide(arguments[i]); |
| 452 } | 453 } |
| 453 | 454 |
| 454 // Compute command-line length. | 455 // Compute command-line length. |
| 455 int command_line_length = strlen(path); | 456 int command_line_length = wcslen(system_path); |
| 456 for (int i = 0; i < arguments_length; i++) { | 457 for (int i = 0; i < arguments_length; i++) { |
| 457 command_line_length += strlen(arguments[i]); | 458 command_line_length += wcslen(system_arguments[i]); |
| 458 } | 459 } |
| 459 // Account for null termination and one space per argument. | 460 // Account for null termination and one space per argument. |
| 460 command_line_length += arguments_length + 1; | 461 command_line_length += arguments_length + 1; |
| 461 static const int kMaxCommandLineLength = 32768; | 462 static const int kMaxCommandLineLength = 32768; |
| 462 if (command_line_length > kMaxCommandLineLength) { | 463 if (command_line_length > kMaxCommandLineLength) { |
| 463 int error_code = SetOsErrorMessage(os_error_message); | 464 int error_code = SetOsErrorMessage(os_error_message); |
| 464 CloseProcessPipes( | 465 CloseProcessPipes( |
| 465 stdin_handles, stdout_handles, stderr_handles, exit_handles); | 466 stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| 466 free(const_cast<char*>(path)); | 467 free(const_cast<wchar_t*>(system_path)); |
| 467 for (int i = 0; i < arguments_length; i++) free(arguments[i]); | 468 for (int i = 0; i < arguments_length; i++) free(system_arguments[i]); |
| 469 delete[] system_arguments; |
| 468 DeleteProcThreadAttributeList(attribute_list); | 470 DeleteProcThreadAttributeList(attribute_list); |
| 469 free(attribute_list); | 471 free(attribute_list); |
| 470 return error_code; | 472 return error_code; |
| 471 } | 473 } |
| 472 | 474 |
| 473 // Put together command-line string. | 475 // Put together command-line string. |
| 474 char* command_line = new char[command_line_length]; | 476 wchar_t* command_line = new wchar_t[command_line_length]; |
| 475 int len = 0; | 477 int len = 0; |
| 476 int remaining = command_line_length; | 478 int remaining = command_line_length; |
| 477 int written = snprintf(command_line + len, remaining, "%s", path); | 479 int written = _snwprintf(command_line + len, remaining, L"%s", system_path); |
| 478 len += written; | 480 len += written; |
| 479 remaining -= written; | 481 remaining -= written; |
| 480 ASSERT(remaining >= 0); | 482 ASSERT(remaining >= 0); |
| 481 for (int i = 0; i < arguments_length; i++) { | 483 for (int i = 0; i < arguments_length; i++) { |
| 482 written = snprintf(command_line + len, remaining, " %s", arguments[i]); | 484 written = |
| 485 _snwprintf(command_line + len, remaining, L" %s", system_arguments[i]); |
| 483 len += written; | 486 len += written; |
| 484 remaining -= written; | 487 remaining -= written; |
| 485 ASSERT(remaining >= 0); | 488 ASSERT(remaining >= 0); |
| 486 } | 489 } |
| 487 free(const_cast<char*>(path)); | 490 free(const_cast<wchar_t*>(system_path)); |
| 488 for (int i = 0; i < arguments_length; i++) free(arguments[i]); | 491 for (int i = 0; i < arguments_length; i++) free(system_arguments[i]); |
| 492 delete[] system_arguments; |
| 489 | 493 |
| 490 // Create environment block if an environment is supplied. | 494 // Create environment block if an environment is supplied. |
| 491 char* environment_block = NULL; | 495 wchar_t* environment_block = NULL; |
| 492 if (environment != NULL) { | 496 if (environment != NULL) { |
| 497 wchar_t** system_environment = new wchar_t*[environment_length]; |
| 493 // Convert environment strings to system strings. | 498 // Convert environment strings to system strings. |
| 494 for (intptr_t i = 0; i < environment_length; i++) { | 499 for (intptr_t i = 0; i < environment_length; i++) { |
| 495 environment[i] = StringUtils::Utf8ToConsoleString(environment[i]); | 500 system_environment[i] = StringUtils::Utf8ToWide(environment[i]); |
| 496 } | 501 } |
| 497 | 502 |
| 498 // An environment block is a sequence of zero-terminated strings | 503 // An environment block is a sequence of zero-terminated strings |
| 499 // followed by a block-terminating zero char. | 504 // followed by a block-terminating zero char. |
| 500 intptr_t block_size = 1; | 505 intptr_t block_size = 1; |
| 501 for (intptr_t i = 0; i < environment_length; i++) { | 506 for (intptr_t i = 0; i < environment_length; i++) { |
| 502 block_size += strlen(environment[i]) + 1; | 507 block_size += wcslen(system_environment[i]) + 1; |
| 503 } | 508 } |
| 504 environment_block = new char[block_size]; | 509 environment_block = new wchar_t[block_size]; |
| 505 intptr_t block_index = 0; | 510 intptr_t block_index = 0; |
| 506 for (intptr_t i = 0; i < environment_length; i++) { | 511 for (intptr_t i = 0; i < environment_length; i++) { |
| 507 intptr_t len = strlen(environment[i]); | 512 intptr_t len = wcslen(system_environment[i]); |
| 508 intptr_t result = snprintf(environment_block + block_index, | 513 intptr_t result = _snwprintf(environment_block + block_index, |
| 509 len, | 514 len, |
| 510 "%s", | 515 L"%s", |
| 511 environment[i]); | 516 system_environment[i]); |
| 512 ASSERT(result == len); | 517 ASSERT(result == len); |
| 513 block_index += len; | 518 block_index += len; |
| 514 environment_block[block_index++] = '\0'; | 519 environment_block[block_index++] = '\0'; |
| 515 } | 520 } |
| 516 // Block-terminating zero char. | 521 // Block-terminating zero char. |
| 517 environment_block[block_index++] = '\0'; | 522 environment_block[block_index++] = '\0'; |
| 518 ASSERT(block_index == block_size); | 523 ASSERT(block_index == block_size); |
| 519 for (intptr_t i = 0; i < environment_length; i++) free(environment[i]); | 524 for (intptr_t i = 0; i < environment_length; i++) { |
| 525 free(system_environment[i]); |
| 526 } |
| 527 delete[] system_environment; |
| 520 } | 528 } |
| 521 | 529 |
| 530 const wchar_t* system_working_directory = NULL; |
| 522 if (working_directory != NULL) { | 531 if (working_directory != NULL) { |
| 523 working_directory = StringUtils::Utf8ToConsoleString(working_directory); | 532 system_working_directory = StringUtils::Utf8ToWide(working_directory); |
| 524 } | 533 } |
| 525 | 534 |
| 526 // Create process. | 535 // Create process. |
| 527 BOOL result = CreateProcess(NULL, // ApplicationName | 536 DWORD creation_flags = |
| 528 command_line, | 537 EXTENDED_STARTUPINFO_PRESENT | CREATE_UNICODE_ENVIRONMENT; |
| 529 NULL, // ProcessAttributes | 538 BOOL result = CreateProcessW(NULL, // ApplicationName |
| 530 NULL, // ThreadAttributes | 539 command_line, |
| 531 TRUE, // InheritHandles | 540 NULL, // ProcessAttributes |
| 532 EXTENDED_STARTUPINFO_PRESENT, | 541 NULL, // ThreadAttributes |
| 533 environment_block, | 542 TRUE, // InheritHandles |
| 534 working_directory, | 543 creation_flags, |
| 535 reinterpret_cast<STARTUPINFO*>(&startup_info), | 544 environment_block, |
| 536 &process_info); | 545 system_working_directory, |
| 546 reinterpret_cast<STARTUPINFOW*>(&startup_info), |
| 547 &process_info); |
| 537 | 548 |
| 538 // Deallocate command-line and environment block strings. | 549 // Deallocate command-line and environment block strings. |
| 539 delete[] command_line; | 550 delete[] command_line; |
| 540 delete[] environment_block; | 551 delete[] environment_block; |
| 541 if (working_directory != NULL) { | 552 if (system_working_directory != NULL) { |
| 542 free(const_cast<char*>(working_directory)); | 553 free(const_cast<wchar_t*>(system_working_directory)); |
| 543 } | 554 } |
| 544 | 555 |
| 545 DeleteProcThreadAttributeList(attribute_list); | 556 DeleteProcThreadAttributeList(attribute_list); |
| 546 free(attribute_list); | 557 free(attribute_list); |
| 547 | 558 |
| 548 if (result == 0) { | 559 if (result == 0) { |
| 549 int error_code = SetOsErrorMessage(os_error_message); | 560 int error_code = SetOsErrorMessage(os_error_message); |
| 550 CloseProcessPipes( | 561 CloseProcessPipes( |
| 551 stdin_handles, stdout_handles, stderr_handles, exit_handles); | 562 stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| 552 return error_code; | 563 return error_code; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 | 605 |
| 595 | 606 |
| 596 void Process::TerminateExitCodeHandler() { | 607 void Process::TerminateExitCodeHandler() { |
| 597 // Nothing needs to be done on Windows. | 608 // Nothing needs to be done on Windows. |
| 598 } | 609 } |
| 599 | 610 |
| 600 | 611 |
| 601 intptr_t Process::CurrentProcessId() { | 612 intptr_t Process::CurrentProcessId() { |
| 602 return static_cast<intptr_t>(GetCurrentProcessId()); | 613 return static_cast<intptr_t>(GetCurrentProcessId()); |
| 603 } | 614 } |
| OLD | NEW |