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 |