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/thread.h" | 10 #include "bin/thread.h" |
| 11 #include "bin/utils.h" |
11 #include "platform/globals.h" | 12 #include "platform/globals.h" |
12 | 13 |
13 static const int kReadHandle = 0; | 14 static const int kReadHandle = 0; |
14 static const int kWriteHandle = 1; | 15 static const int kWriteHandle = 1; |
15 | 16 |
16 | 17 |
17 // ProcessInfo is used to map a process id to the process handle, | 18 // ProcessInfo is used to map a process id to the process handle, |
18 // wait handle for registered exit code event and the pipe used to | 19 // wait handle for registered exit code event and the pipe used to |
19 // communicate the exit code of the process to Dart. | 20 // communicate the exit code of the process to Dart. |
20 // ProcessInfo objects are kept in the static singly-linked | 21 // ProcessInfo objects are kept in the static singly-linked |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 ZeroMemory(&startup_info, sizeof(startup_info)); | 392 ZeroMemory(&startup_info, sizeof(startup_info)); |
392 startup_info.cb = sizeof(startup_info); | 393 startup_info.cb = sizeof(startup_info); |
393 startup_info.hStdInput = stdin_handles[kReadHandle]; | 394 startup_info.hStdInput = stdin_handles[kReadHandle]; |
394 startup_info.hStdOutput = stdout_handles[kWriteHandle]; | 395 startup_info.hStdOutput = stdout_handles[kWriteHandle]; |
395 startup_info.hStdError = stderr_handles[kWriteHandle]; | 396 startup_info.hStdError = stderr_handles[kWriteHandle]; |
396 startup_info.dwFlags = STARTF_USESTDHANDLES; | 397 startup_info.dwFlags = STARTF_USESTDHANDLES; |
397 | 398 |
398 PROCESS_INFORMATION process_info; | 399 PROCESS_INFORMATION process_info; |
399 ZeroMemory(&process_info, sizeof(process_info)); | 400 ZeroMemory(&process_info, sizeof(process_info)); |
400 | 401 |
| 402 // Transform input strings to system format. |
| 403 path = StringUtils::Utf8ToSystemString(path); |
| 404 for (int i = 0; i < arguments_length; i++) { |
| 405 arguments[i] = StringUtils::Utf8ToSystemString(arguments[i]); |
| 406 } |
| 407 |
401 // Compute command-line length. | 408 // Compute command-line length. |
402 int command_line_length = strlen(path); | 409 int command_line_length = strlen(path); |
403 for (int i = 0; i < arguments_length; i++) { | 410 for (int i = 0; i < arguments_length; i++) { |
404 command_line_length += strlen(arguments[i]); | 411 command_line_length += strlen(arguments[i]); |
405 } | 412 } |
406 // Account for null termination and one space per argument. | 413 // Account for null termination and one space per argument. |
407 command_line_length += arguments_length + 1; | 414 command_line_length += arguments_length + 1; |
408 static const int kMaxCommandLineLength = 32768; | 415 static const int kMaxCommandLineLength = 32768; |
409 if (command_line_length > kMaxCommandLineLength) { | 416 if (command_line_length > kMaxCommandLineLength) { |
410 int error_code = SetOsErrorMessage(os_error_message, os_error_message_len); | 417 int error_code = SetOsErrorMessage(os_error_message, os_error_message_len); |
411 CloseProcessPipes( | 418 CloseProcessPipes( |
412 stdin_handles, stdout_handles, stderr_handles, exit_handles); | 419 stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| 420 free(const_cast<char*>(path)); |
| 421 for (int i = 0; i < arguments_length; i++) free(arguments[i]); |
413 return error_code; | 422 return error_code; |
414 } | 423 } |
415 | 424 |
416 // Put together command-line string. | 425 // Put together command-line string. |
417 char* command_line = new char[command_line_length]; | 426 char* command_line = new char[command_line_length]; |
418 int len = 0; | 427 int len = 0; |
419 int remaining = command_line_length; | 428 int remaining = command_line_length; |
420 int written = snprintf(command_line + len, remaining, "%s", path); | 429 int written = snprintf(command_line + len, remaining, "%s", path); |
421 len += written; | 430 len += written; |
422 remaining -= written; | 431 remaining -= written; |
423 ASSERT(remaining >= 0); | 432 ASSERT(remaining >= 0); |
424 for (int i = 0; i < arguments_length; i++) { | 433 for (int i = 0; i < arguments_length; i++) { |
425 written = snprintf(command_line + len, remaining, " %s", arguments[i]); | 434 written = snprintf(command_line + len, remaining, " %s", arguments[i]); |
426 len += written; | 435 len += written; |
427 remaining -= written; | 436 remaining -= written; |
428 ASSERT(remaining >= 0); | 437 ASSERT(remaining >= 0); |
429 } | 438 } |
| 439 free(const_cast<char*>(path)); |
| 440 for (int i = 0; i < arguments_length; i++) free(arguments[i]); |
430 | 441 |
431 // Create environment block if an environment is supplied. | 442 // Create environment block if an environment is supplied. |
432 char* environment_block = NULL; | 443 char* environment_block = NULL; |
433 if (environment != NULL) { | 444 if (environment != NULL) { |
| 445 // Convert environment strings to system strings. |
| 446 for (intptr_t i = 0; i < environment_length; i++) { |
| 447 environment[i] = StringUtils::Utf8ToSystemString(environment[i]); |
| 448 } |
| 449 |
434 // An environment block is a sequence of zero-terminated strings | 450 // An environment block is a sequence of zero-terminated strings |
435 // followed by a block-terminating zero char. | 451 // followed by a block-terminating zero char. |
436 intptr_t block_size = 1; | 452 intptr_t block_size = 1; |
437 for (intptr_t i = 0; i < environment_length; i++) { | 453 for (intptr_t i = 0; i < environment_length; i++) { |
438 block_size += strlen(environment[i]) + 1; | 454 block_size += strlen(environment[i]) + 1; |
439 } | 455 } |
440 environment_block = new char[block_size]; | 456 environment_block = new char[block_size]; |
441 intptr_t block_index = 0; | 457 intptr_t block_index = 0; |
442 for (intptr_t i = 0; i < environment_length; i++) { | 458 for (intptr_t i = 0; i < environment_length; i++) { |
443 intptr_t len = strlen(environment[i]); | 459 intptr_t len = strlen(environment[i]); |
444 intptr_t result = snprintf(environment_block + block_index, | 460 intptr_t result = snprintf(environment_block + block_index, |
445 len, | 461 len, |
446 "%s", | 462 "%s", |
447 environment[i]); | 463 environment[i]); |
448 ASSERT(result == len); | 464 ASSERT(result == len); |
449 block_index += len; | 465 block_index += len; |
450 environment_block[block_index++] = '\0'; | 466 environment_block[block_index++] = '\0'; |
451 } | 467 } |
452 // Block-terminating zero char. | 468 // Block-terminating zero char. |
453 environment_block[block_index++] = '\0'; | 469 environment_block[block_index++] = '\0'; |
454 ASSERT(block_index == block_size); | 470 ASSERT(block_index == block_size); |
| 471 for (intptr_t i = 0; i < environment_length; i++) free(environment[i]); |
| 472 } |
| 473 |
| 474 if (working_directory != NULL) { |
| 475 working_directory = StringUtils::Utf8ToSystemString(working_directory); |
455 } | 476 } |
456 | 477 |
457 // Create process. | 478 // Create process. |
458 BOOL result = CreateProcess(NULL, // ApplicationName | 479 BOOL result = CreateProcess(NULL, // ApplicationName |
459 command_line, | 480 command_line, |
460 NULL, // ProcessAttributes | 481 NULL, // ProcessAttributes |
461 NULL, // ThreadAttributes | 482 NULL, // ThreadAttributes |
462 TRUE, // InheritHandles | 483 TRUE, // InheritHandles |
463 0, // CreationFlags | 484 0, // CreationFlags |
464 environment_block, | 485 environment_block, |
465 working_directory, | 486 working_directory, |
466 &startup_info, | 487 &startup_info, |
467 &process_info); | 488 &process_info); |
468 | 489 |
469 // Deallocate command-line and environment block strings. | 490 // Deallocate command-line and environment block strings. |
470 delete[] command_line; | 491 delete[] command_line; |
471 delete[] environment_block; | 492 delete[] environment_block; |
| 493 if (working_directory != NULL) { |
| 494 free(const_cast<char*>(working_directory)); |
| 495 } |
472 | 496 |
473 if (result == 0) { | 497 if (result == 0) { |
474 int error_code = SetOsErrorMessage(os_error_message, os_error_message_len); | 498 int error_code = SetOsErrorMessage(os_error_message, os_error_message_len); |
475 CloseProcessPipes( | 499 CloseProcessPipes( |
476 stdin_handles, stdout_handles, stderr_handles, exit_handles); | 500 stdin_handles, stdout_handles, stderr_handles, exit_handles); |
477 return error_code; | 501 return error_code; |
478 } | 502 } |
479 | 503 |
480 ProcessInfoList::AddProcess(process_info.dwProcessId, | 504 ProcessInfoList::AddProcess(process_info.dwProcessId, |
481 process_info.hProcess, | 505 process_info.hProcess, |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 | 543 |
520 | 544 |
521 void Process::TerminateExitCodeHandler() { | 545 void Process::TerminateExitCodeHandler() { |
522 // Nothing needs to be done on Windows. | 546 // Nothing needs to be done on Windows. |
523 } | 547 } |
524 | 548 |
525 | 549 |
526 intptr_t Process::CurrentProcessId() { | 550 intptr_t Process::CurrentProcessId() { |
527 return static_cast<intptr_t>(GetCurrentProcessId()); | 551 return static_cast<intptr_t>(GetCurrentProcessId()); |
528 } | 552 } |
OLD | NEW |