Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1263)

Side by Side Diff: runtime/bin/process_win.cc

Issue 11637014: Fix Windows XP process handling. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698