Chromium Code Reviews| 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 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 312 Log::PrintErr("FormatMessage failed %d\n", GetLastError()); | 312 Log::PrintErr("FormatMessage failed %d\n", GetLastError()); |
| 313 } | 313 } |
| 314 _snwprintf(message, kMaxMessageLength, L"OS Error %d", error_code); | 314 _snwprintf(message, kMaxMessageLength, L"OS Error %d", error_code); |
| 315 } | 315 } |
| 316 message[kMaxMessageLength - 1] = '\0'; | 316 message[kMaxMessageLength - 1] = '\0'; |
| 317 *os_error_message = StringUtils::WideToUtf8(message); | 317 *os_error_message = StringUtils::WideToUtf8(message); |
| 318 return error_code; | 318 return error_code; |
| 319 } | 319 } |
| 320 | 320 |
| 321 | 321 |
| 322 typedef BOOL (WINAPI *InitProcThreadAttrListFn)( | |
| 323 LPPROC_THREAD_ATTRIBUTE_LIST, DWORD, DWORD, PSIZE_T); | |
| 324 | |
| 325 typedef BOOL (WINAPI *UpdateProcThreadAttrFn)( | |
| 326 LPPROC_THREAD_ATTRIBUTE_LIST, DWORD, DWORD_PTR, | |
| 327 PVOID, SIZE_T, PVOID, PSIZE_T); | |
| 328 | |
| 329 typedef VOID (WINAPI *DeleteProcThreadAttrListFn)( | |
| 330 LPPROC_THREAD_ATTRIBUTE_LIST); | |
| 331 | |
| 332 | |
| 333 static InitProcThreadAttrListFn init_proc_thread_attr_list = NULL; | |
| 334 static UpdateProcThreadAttrFn update_proc_thread_attr = NULL; | |
| 335 static DeleteProcThreadAttrListFn delete_proc_thread_attr_list = NULL; | |
| 336 | |
| 337 | |
| 338 static bool EnsureInitialized() { | |
| 339 HMODULE kernel32_module = GetModuleHandle(L"kernel32.dll"); | |
| 340 if (init_proc_thread_attr_list == NULL) { | |
|
Søren Gjesse
2012/12/19 09:51:51
On XP this will try to load InitializeProcThreadAt
Mads Ager (google)
2012/12/19 10:00:54
Fixed as part of the below.
| |
| 341 init_proc_thread_attr_list = reinterpret_cast<InitProcThreadAttrListFn>( | |
|
Søren Gjesse
2012/12/19 09:51:51
As this could be called by several threads at the
Mads Ager (google)
2012/12/19 10:00:54
Thanks. I put in locking.
| |
| 342 GetProcAddress(kernel32_module, "InitializeProcThreadAttributeList")); | |
| 343 if (init_proc_thread_attr_list == NULL) return false; | |
| 344 update_proc_thread_attr = | |
| 345 reinterpret_cast<UpdateProcThreadAttrFn>( | |
| 346 GetProcAddress(kernel32_module, "UpdateProcThreadAttribute")); | |
| 347 if (update_proc_thread_attr == NULL) return false; | |
| 348 delete_proc_thread_attr_list = reinterpret_cast<DeleteProcThreadAttrListFn>( | |
| 349 reinterpret_cast<DeleteProcThreadAttrListFn>( | |
| 350 GetProcAddress(kernel32_module, "DeleteProcThreadAttributeList"))); | |
| 351 return delete_proc_thread_attr_list != NULL; | |
| 352 } | |
| 353 return true; | |
| 354 } | |
| 355 | |
| 356 | |
| 322 int Process::Start(const char* path, | 357 int Process::Start(const char* path, |
| 323 char* arguments[], | 358 char* arguments[], |
| 324 intptr_t arguments_length, | 359 intptr_t arguments_length, |
| 325 const char* working_directory, | 360 const char* working_directory, |
| 326 char* environment[], | 361 char* environment[], |
| 327 intptr_t environment_length, | 362 intptr_t environment_length, |
| 328 intptr_t* in, | 363 intptr_t* in, |
| 329 intptr_t* out, | 364 intptr_t* out, |
| 330 intptr_t* err, | 365 intptr_t* err, |
| 331 intptr_t* id, | 366 intptr_t* id, |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 393 | 428 |
| 394 // Setup info structures. | 429 // Setup info structures. |
| 395 STARTUPINFOEXW startup_info; | 430 STARTUPINFOEXW startup_info; |
| 396 ZeroMemory(&startup_info, sizeof(startup_info)); | 431 ZeroMemory(&startup_info, sizeof(startup_info)); |
| 397 startup_info.StartupInfo.cb = sizeof(startup_info); | 432 startup_info.StartupInfo.cb = sizeof(startup_info); |
| 398 startup_info.StartupInfo.hStdInput = stdin_handles[kReadHandle]; | 433 startup_info.StartupInfo.hStdInput = stdin_handles[kReadHandle]; |
| 399 startup_info.StartupInfo.hStdOutput = stdout_handles[kWriteHandle]; | 434 startup_info.StartupInfo.hStdOutput = stdout_handles[kWriteHandle]; |
| 400 startup_info.StartupInfo.hStdError = stderr_handles[kWriteHandle]; | 435 startup_info.StartupInfo.hStdError = stderr_handles[kWriteHandle]; |
| 401 startup_info.StartupInfo.dwFlags = STARTF_USESTDHANDLES; | 436 startup_info.StartupInfo.dwFlags = STARTF_USESTDHANDLES; |
| 402 | 437 |
| 403 // Setup the handles to inherit. We only want to inherit the three handles | 438 LPPROC_THREAD_ATTRIBUTE_LIST attribute_list = NULL; |
| 404 // for stdin, stdout and stderr. | 439 |
| 405 SIZE_T size = 0; | 440 bool supports_proc_thread_attr_lists = EnsureInitialized(); |
| 406 // The call to determine the size of an attribute list always fails with | 441 if (supports_proc_thread_attr_lists) { |
| 407 // ERROR_INSUFFICIENT_BUFFER and that error should be ignored. | 442 // Setup the handles to inherit. We only want to inherit the three handles |
| 408 if (!InitializeProcThreadAttributeList(NULL, 1, 0, &size) && | 443 // for stdin, stdout and stderr. |
| 409 GetLastError() != ERROR_INSUFFICIENT_BUFFER) { | 444 SIZE_T size = 0; |
| 410 int error_code = SetOsErrorMessage(os_error_message); | 445 // The call to determine the size of an attribute list always fails with |
| 411 CloseProcessPipes( | 446 // ERROR_INSUFFICIENT_BUFFER and that error should be ignored. |
| 412 stdin_handles, stdout_handles, stderr_handles, exit_handles); | 447 if (!init_proc_thread_attr_list(NULL, 1, 0, &size) && |
| 413 return error_code; | 448 GetLastError() != ERROR_INSUFFICIENT_BUFFER) { |
| 414 } | 449 int error_code = SetOsErrorMessage(os_error_message); |
| 415 LPPROC_THREAD_ATTRIBUTE_LIST attribute_list = | 450 CloseProcessPipes( |
| 416 reinterpret_cast<LPPROC_THREAD_ATTRIBUTE_LIST>(malloc(size)); | 451 stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| 417 ZeroMemory(attribute_list, size); | 452 return error_code; |
| 418 if (!InitializeProcThreadAttributeList(attribute_list, 1, 0, &size)) { | 453 } |
| 419 int error_code = SetOsErrorMessage(os_error_message); | 454 attribute_list = |
| 420 CloseProcessPipes( | 455 reinterpret_cast<LPPROC_THREAD_ATTRIBUTE_LIST>(malloc(size)); |
| 421 stdin_handles, stdout_handles, stderr_handles, exit_handles); | 456 ZeroMemory(attribute_list, size); |
| 422 free(attribute_list); | 457 if (!init_proc_thread_attr_list(attribute_list, 1, 0, &size)) { |
| 423 return error_code; | 458 int error_code = SetOsErrorMessage(os_error_message); |
| 424 } | 459 CloseProcessPipes( |
| 425 static const int kNumInheritedHandles = 3; | 460 stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| 426 HANDLE inherited_handles[kNumInheritedHandles] = | 461 free(attribute_list); |
| 427 { stdin_handles[kReadHandle], | 462 return error_code; |
| 428 stdout_handles[kWriteHandle], | 463 } |
| 429 stderr_handles[kWriteHandle] }; | 464 static const int kNumInheritedHandles = 3; |
| 430 if (!UpdateProcThreadAttribute(attribute_list, | 465 HANDLE inherited_handles[kNumInheritedHandles] = |
| 466 { stdin_handles[kReadHandle], | |
| 467 stdout_handles[kWriteHandle], | |
| 468 stderr_handles[kWriteHandle] }; | |
| 469 if (!update_proc_thread_attr(attribute_list, | |
| 431 0, | 470 0, |
| 432 PROC_THREAD_ATTRIBUTE_HANDLE_LIST, | 471 PROC_THREAD_ATTRIBUTE_HANDLE_LIST, |
| 433 inherited_handles, | 472 inherited_handles, |
| 434 kNumInheritedHandles * sizeof(HANDLE), | 473 kNumInheritedHandles * sizeof(HANDLE), |
| 435 NULL, | 474 NULL, |
| 436 NULL)) { | 475 NULL)) { |
| 437 DeleteProcThreadAttributeList(attribute_list); | 476 delete_proc_thread_attr_list(attribute_list); |
| 438 int error_code = SetOsErrorMessage(os_error_message); | 477 int error_code = SetOsErrorMessage(os_error_message); |
| 439 CloseProcessPipes( | 478 CloseProcessPipes( |
| 440 stdin_handles, stdout_handles, stderr_handles, exit_handles); | 479 stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| 441 free(attribute_list); | 480 free(attribute_list); |
| 442 return error_code; | 481 return error_code; |
| 482 } | |
| 483 startup_info.lpAttributeList = attribute_list; | |
| 443 } | 484 } |
| 444 startup_info.lpAttributeList = attribute_list; | |
| 445 | 485 |
| 446 PROCESS_INFORMATION process_info; | 486 PROCESS_INFORMATION process_info; |
| 447 ZeroMemory(&process_info, sizeof(process_info)); | 487 ZeroMemory(&process_info, sizeof(process_info)); |
| 448 | 488 |
| 449 // Transform input strings to system format. | 489 // Transform input strings to system format. |
| 450 const wchar_t* system_path = StringUtils::Utf8ToWide(path); | 490 const wchar_t* system_path = StringUtils::Utf8ToWide(path); |
| 451 wchar_t** system_arguments = new wchar_t*[arguments_length]; | 491 wchar_t** system_arguments = new wchar_t*[arguments_length]; |
| 452 for (int i = 0; i < arguments_length; i++) { | 492 for (int i = 0; i < arguments_length; i++) { |
| 453 system_arguments[i] = StringUtils::Utf8ToWide(arguments[i]); | 493 system_arguments[i] = StringUtils::Utf8ToWide(arguments[i]); |
| 454 } | 494 } |
| 455 | 495 |
| 456 // Compute command-line length. | 496 // Compute command-line length. |
| 457 int command_line_length = wcslen(system_path); | 497 int command_line_length = wcslen(system_path); |
| 458 for (int i = 0; i < arguments_length; i++) { | 498 for (int i = 0; i < arguments_length; i++) { |
| 459 command_line_length += wcslen(system_arguments[i]); | 499 command_line_length += wcslen(system_arguments[i]); |
| 460 } | 500 } |
| 461 // Account for null termination and one space per argument. | 501 // Account for null termination and one space per argument. |
| 462 command_line_length += arguments_length + 1; | 502 command_line_length += arguments_length + 1; |
| 463 static const int kMaxCommandLineLength = 32768; | 503 static const int kMaxCommandLineLength = 32768; |
| 464 if (command_line_length > kMaxCommandLineLength) { | 504 if (command_line_length > kMaxCommandLineLength) { |
| 465 int error_code = SetOsErrorMessage(os_error_message); | 505 int error_code = SetOsErrorMessage(os_error_message); |
| 466 CloseProcessPipes( | 506 CloseProcessPipes( |
| 467 stdin_handles, stdout_handles, stderr_handles, exit_handles); | 507 stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| 468 free(const_cast<wchar_t*>(system_path)); | 508 free(const_cast<wchar_t*>(system_path)); |
| 469 for (int i = 0; i < arguments_length; i++) free(system_arguments[i]); | 509 for (int i = 0; i < arguments_length; i++) free(system_arguments[i]); |
| 470 delete[] system_arguments; | 510 delete[] system_arguments; |
| 471 DeleteProcThreadAttributeList(attribute_list); | 511 if (supports_proc_thread_attr_lists) { |
| 472 free(attribute_list); | 512 delete_proc_thread_attr_list(attribute_list); |
| 513 free(attribute_list); | |
| 514 } | |
| 473 return error_code; | 515 return error_code; |
| 474 } | 516 } |
| 475 | 517 |
| 476 // Put together command-line string. | 518 // Put together command-line string. |
| 477 wchar_t* command_line = new wchar_t[command_line_length]; | 519 wchar_t* command_line = new wchar_t[command_line_length]; |
| 478 int len = 0; | 520 int len = 0; |
| 479 int remaining = command_line_length; | 521 int remaining = command_line_length; |
| 480 int written = _snwprintf(command_line + len, remaining, L"%s", system_path); | 522 int written = _snwprintf(command_line + len, remaining, L"%s", system_path); |
| 481 len += written; | 523 len += written; |
| 482 remaining -= written; | 524 remaining -= written; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 547 reinterpret_cast<STARTUPINFOW*>(&startup_info), | 589 reinterpret_cast<STARTUPINFOW*>(&startup_info), |
| 548 &process_info); | 590 &process_info); |
| 549 | 591 |
| 550 // Deallocate command-line and environment block strings. | 592 // Deallocate command-line and environment block strings. |
| 551 delete[] command_line; | 593 delete[] command_line; |
| 552 delete[] environment_block; | 594 delete[] environment_block; |
| 553 if (system_working_directory != NULL) { | 595 if (system_working_directory != NULL) { |
| 554 free(const_cast<wchar_t*>(system_working_directory)); | 596 free(const_cast<wchar_t*>(system_working_directory)); |
| 555 } | 597 } |
| 556 | 598 |
| 557 DeleteProcThreadAttributeList(attribute_list); | 599 if (supports_proc_thread_attr_lists) { |
| 558 free(attribute_list); | 600 delete_proc_thread_attr_list(attribute_list); |
| 601 free(attribute_list); | |
| 602 } | |
| 559 | 603 |
| 560 if (result == 0) { | 604 if (result == 0) { |
| 561 int error_code = SetOsErrorMessage(os_error_message); | 605 int error_code = SetOsErrorMessage(os_error_message); |
| 562 CloseProcessPipes( | 606 CloseProcessPipes( |
| 563 stdin_handles, stdout_handles, stderr_handles, exit_handles); | 607 stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| 564 return error_code; | 608 return error_code; |
| 565 } | 609 } |
| 566 | 610 |
| 567 ProcessInfoList::AddProcess(process_info.dwProcessId, | 611 ProcessInfoList::AddProcess(process_info.dwProcessId, |
| 568 process_info.hProcess, | 612 process_info.hProcess, |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 606 | 650 |
| 607 | 651 |
| 608 void Process::TerminateExitCodeHandler() { | 652 void Process::TerminateExitCodeHandler() { |
| 609 // Nothing needs to be done on Windows. | 653 // Nothing needs to be done on Windows. |
| 610 } | 654 } |
| 611 | 655 |
| 612 | 656 |
| 613 intptr_t Process::CurrentProcessId() { | 657 intptr_t Process::CurrentProcessId() { |
| 614 return static_cast<intptr_t>(GetCurrentProcessId()); | 658 return static_cast<intptr_t>(GetCurrentProcessId()); |
| 615 } | 659 } |
| OLD | NEW |