| 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 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 static void CloseProcessPipes(HANDLE handles1[2], | 287 static void CloseProcessPipes(HANDLE handles1[2], |
| 288 HANDLE handles2[2], | 288 HANDLE handles2[2], |
| 289 HANDLE handles3[2], | 289 HANDLE handles3[2], |
| 290 HANDLE handles4[2]) { | 290 HANDLE handles4[2]) { |
| 291 CloseProcessPipe(handles1); | 291 CloseProcessPipe(handles1); |
| 292 CloseProcessPipe(handles2); | 292 CloseProcessPipe(handles2); |
| 293 CloseProcessPipe(handles3); | 293 CloseProcessPipe(handles3); |
| 294 CloseProcessPipe(handles4); | 294 CloseProcessPipe(handles4); |
| 295 } | 295 } |
| 296 | 296 |
| 297 static int SetOsErrorMessage(char* os_error_message, | 297 |
| 298 int os_error_message_len) { | 298 static int SetOsErrorMessage(char** os_error_message) { |
| 299 int error_code = GetLastError(); | 299 int error_code = GetLastError(); |
| 300 static const int kMaxMessageLength = 256; |
| 301 wchar_t message[kMaxMessageLength]; |
| 300 DWORD message_size = | 302 DWORD message_size = |
| 301 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, | 303 FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, |
| 302 NULL, | 304 NULL, |
| 303 error_code, | 305 error_code, |
| 304 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | 306 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), |
| 305 os_error_message, | 307 message, |
| 306 os_error_message_len, | 308 kMaxMessageLength, |
| 307 NULL); | 309 NULL); |
| 308 if (message_size == 0) { | 310 if (message_size == 0) { |
| 309 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { | 311 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { |
| 310 Log::PrintErr("FormatMessage failed %d\n", GetLastError()); | 312 Log::PrintErr("FormatMessage failed %d\n", GetLastError()); |
| 311 } | 313 } |
| 312 snprintf(os_error_message, os_error_message_len, "OS Error %d", error_code); | 314 _snwprintf(message, kMaxMessageLength, L"OS Error %d", error_code); |
| 313 } | 315 } |
| 314 os_error_message[os_error_message_len - 1] = '\0'; | 316 message[kMaxMessageLength - 1] = '\0'; |
| 317 *os_error_message = StringUtils::WideToUtf8(message); |
| 315 return error_code; | 318 return error_code; |
| 316 } | 319 } |
| 317 | 320 |
| 318 | 321 |
| 319 int Process::Start(const char* path, | 322 int Process::Start(const char* path, |
| 320 char* arguments[], | 323 char* arguments[], |
| 321 intptr_t arguments_length, | 324 intptr_t arguments_length, |
| 322 const char* working_directory, | 325 const char* working_directory, |
| 323 char* environment[], | 326 char* environment[], |
| 324 intptr_t environment_length, | 327 intptr_t environment_length, |
| 325 intptr_t* in, | 328 intptr_t* in, |
| 326 intptr_t* out, | 329 intptr_t* out, |
| 327 intptr_t* err, | 330 intptr_t* err, |
| 328 intptr_t* id, | 331 intptr_t* id, |
| 329 intptr_t* exit_handler, | 332 intptr_t* exit_handler, |
| 330 char* os_error_message, | 333 char** os_error_message) { |
| 331 int os_error_message_len) { | |
| 332 HANDLE stdin_handles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; | 334 HANDLE stdin_handles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; |
| 333 HANDLE stdout_handles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; | 335 HANDLE stdout_handles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; |
| 334 HANDLE stderr_handles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; | 336 HANDLE stderr_handles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; |
| 335 HANDLE exit_handles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; | 337 HANDLE exit_handles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; |
| 336 | 338 |
| 337 // Generate unique pipe names for the four named pipes needed. | 339 // Generate unique pipe names for the four named pipes needed. |
| 338 char pipe_names[4][80]; | 340 char pipe_names[4][80]; |
| 339 UUID uuid; | 341 UUID uuid; |
| 340 RPC_STATUS status = UuidCreateSequential(&uuid); | 342 RPC_STATUS status = UuidCreateSequential(&uuid); |
| 341 if (status != RPC_S_OK && status != RPC_S_UUID_LOCAL_ONLY) { | 343 if (status != RPC_S_OK && status != RPC_S_UUID_LOCAL_ONLY) { |
| 344 SetOsErrorMessage(os_error_message); |
| 342 Log::PrintErr("UuidCreateSequential failed %d\n", status); | 345 Log::PrintErr("UuidCreateSequential failed %d\n", status); |
| 343 SetOsErrorMessage(os_error_message, os_error_message_len); | |
| 344 return status; | 346 return status; |
| 345 } | 347 } |
| 346 RPC_CSTR uuid_string; | 348 RPC_CSTR uuid_string; |
| 347 status = UuidToString(&uuid, &uuid_string); | 349 status = UuidToString(&uuid, &uuid_string); |
| 348 if (status != RPC_S_OK) { | 350 if (status != RPC_S_OK) { |
| 351 SetOsErrorMessage(os_error_message); |
| 349 Log::PrintErr("UuidToString failed %d\n", status); | 352 Log::PrintErr("UuidToString failed %d\n", status); |
| 350 SetOsErrorMessage(os_error_message, os_error_message_len); | |
| 351 return status; | 353 return status; |
| 352 } | 354 } |
| 353 for (int i = 0; i < 4; i++) { | 355 for (int i = 0; i < 4; i++) { |
| 354 static const char* prefix = "\\\\.\\Pipe\\dart"; | 356 static const char* prefix = "\\\\.\\Pipe\\dart"; |
| 355 snprintf(pipe_names[i], | 357 snprintf(pipe_names[i], |
| 356 sizeof(pipe_names[i]), | 358 sizeof(pipe_names[i]), |
| 357 "%s_%s_%d", prefix, uuid_string, i + 1); | 359 "%s_%s_%d", prefix, uuid_string, i + 1); |
| 358 } | 360 } |
| 359 status = RpcStringFree(&uuid_string); | 361 status = RpcStringFree(&uuid_string); |
| 360 if (status != RPC_S_OK) { | 362 if (status != RPC_S_OK) { |
| 363 SetOsErrorMessage(os_error_message); |
| 361 Log::PrintErr("RpcStringFree failed %d\n", status); | 364 Log::PrintErr("RpcStringFree failed %d\n", status); |
| 362 SetOsErrorMessage(os_error_message, os_error_message_len); | |
| 363 return status; | 365 return status; |
| 364 } | 366 } |
| 365 | 367 |
| 366 if (!CreateProcessPipe(stdin_handles, pipe_names[0], kInheritRead)) { | 368 if (!CreateProcessPipe(stdin_handles, pipe_names[0], kInheritRead)) { |
| 367 int error_code = SetOsErrorMessage(os_error_message, os_error_message_len); | 369 int error_code = SetOsErrorMessage(os_error_message); |
| 368 CloseProcessPipes( | 370 CloseProcessPipes( |
| 369 stdin_handles, stdout_handles, stderr_handles, exit_handles); | 371 stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| 370 return error_code; | 372 return error_code; |
| 371 } | 373 } |
| 372 if (!CreateProcessPipe(stdout_handles, pipe_names[1], kInheritWrite)) { | 374 if (!CreateProcessPipe(stdout_handles, pipe_names[1], kInheritWrite)) { |
| 373 int error_code = SetOsErrorMessage(os_error_message, os_error_message_len); | 375 int error_code = SetOsErrorMessage(os_error_message); |
| 374 CloseProcessPipes( | 376 CloseProcessPipes( |
| 375 stdin_handles, stdout_handles, stderr_handles, exit_handles); | 377 stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| 376 return error_code; | 378 return error_code; |
| 377 } | 379 } |
| 378 if (!CreateProcessPipe(stderr_handles, pipe_names[2], kInheritWrite)) { | 380 if (!CreateProcessPipe(stderr_handles, pipe_names[2], kInheritWrite)) { |
| 379 int error_code = SetOsErrorMessage(os_error_message, os_error_message_len); | 381 int error_code = SetOsErrorMessage(os_error_message); |
| 380 CloseProcessPipes( | 382 CloseProcessPipes( |
| 381 stdin_handles, stdout_handles, stderr_handles, exit_handles); | 383 stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| 382 return error_code; | 384 return error_code; |
| 383 } | 385 } |
| 384 if (!CreateProcessPipe(exit_handles, pipe_names[3], kInheritNone)) { | 386 if (!CreateProcessPipe(exit_handles, pipe_names[3], kInheritNone)) { |
| 385 int error_code = SetOsErrorMessage(os_error_message, os_error_message_len); | 387 int error_code = SetOsErrorMessage(os_error_message); |
| 386 CloseProcessPipes( | 388 CloseProcessPipes( |
| 387 stdin_handles, stdout_handles, stderr_handles, exit_handles); | 389 stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| 388 return error_code; | 390 return error_code; |
| 389 } | 391 } |
| 390 | 392 |
| 391 // Setup info structures. | 393 // Setup info structures. |
| 392 STARTUPINFOEX startup_info; | 394 STARTUPINFOEX startup_info; |
| 393 ZeroMemory(&startup_info, sizeof(startup_info)); | 395 ZeroMemory(&startup_info, sizeof(startup_info)); |
| 394 startup_info.StartupInfo.cb = sizeof(startup_info); | 396 startup_info.StartupInfo.cb = sizeof(startup_info); |
| 395 startup_info.StartupInfo.hStdInput = stdin_handles[kReadHandle]; | 397 startup_info.StartupInfo.hStdInput = stdin_handles[kReadHandle]; |
| 396 startup_info.StartupInfo.hStdOutput = stdout_handles[kWriteHandle]; | 398 startup_info.StartupInfo.hStdOutput = stdout_handles[kWriteHandle]; |
| 397 startup_info.StartupInfo.hStdError = stderr_handles[kWriteHandle]; | 399 startup_info.StartupInfo.hStdError = stderr_handles[kWriteHandle]; |
| 398 startup_info.StartupInfo.dwFlags = STARTF_USESTDHANDLES; | 400 startup_info.StartupInfo.dwFlags = STARTF_USESTDHANDLES; |
| 399 | 401 |
| 400 // 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 |
| 401 // for stdin, stdout and stderr. | 403 // for stdin, stdout and stderr. |
| 402 SIZE_T size = 0; | 404 SIZE_T size = 0; |
| 403 // The call to determine the size of an attribute list always fails with | 405 // The call to determine the size of an attribute list always fails with |
| 404 // ERROR_INSUFFICIENT_BUFFER and that error should be ignored. | 406 // ERROR_INSUFFICIENT_BUFFER and that error should be ignored. |
| 405 if (!InitializeProcThreadAttributeList(NULL, 1, 0, &size) && | 407 if (!InitializeProcThreadAttributeList(NULL, 1, 0, &size) && |
| 406 GetLastError() != ERROR_INSUFFICIENT_BUFFER) { | 408 GetLastError() != ERROR_INSUFFICIENT_BUFFER) { |
| 407 int error_code = SetOsErrorMessage(os_error_message, os_error_message_len); | 409 int error_code = SetOsErrorMessage(os_error_message); |
| 408 CloseProcessPipes( | 410 CloseProcessPipes( |
| 409 stdin_handles, stdout_handles, stderr_handles, exit_handles); | 411 stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| 410 return error_code; | 412 return error_code; |
| 411 } | 413 } |
| 412 LPPROC_THREAD_ATTRIBUTE_LIST attribute_list = | 414 LPPROC_THREAD_ATTRIBUTE_LIST attribute_list = |
| 413 reinterpret_cast<LPPROC_THREAD_ATTRIBUTE_LIST>(malloc(size)); | 415 reinterpret_cast<LPPROC_THREAD_ATTRIBUTE_LIST>(malloc(size)); |
| 414 ZeroMemory(attribute_list, size); | 416 ZeroMemory(attribute_list, size); |
| 415 if (!InitializeProcThreadAttributeList(attribute_list, 1, 0, &size)) { | 417 if (!InitializeProcThreadAttributeList(attribute_list, 1, 0, &size)) { |
| 416 int error_code = SetOsErrorMessage(os_error_message, os_error_message_len); | 418 int error_code = SetOsErrorMessage(os_error_message); |
| 417 CloseProcessPipes( | 419 CloseProcessPipes( |
| 418 stdin_handles, stdout_handles, stderr_handles, exit_handles); | 420 stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| 419 free(attribute_list); | 421 free(attribute_list); |
| 420 return error_code; | 422 return error_code; |
| 421 } | 423 } |
| 422 static const int kNumInheritedHandles = 3; | 424 static const int kNumInheritedHandles = 3; |
| 423 HANDLE inherited_handles[kNumInheritedHandles] = | 425 HANDLE inherited_handles[kNumInheritedHandles] = |
| 424 { stdin_handles[kReadHandle], | 426 { stdin_handles[kReadHandle], |
| 425 stdout_handles[kWriteHandle], | 427 stdout_handles[kWriteHandle], |
| 426 stderr_handles[kWriteHandle] }; | 428 stderr_handles[kWriteHandle] }; |
| 427 if (!UpdateProcThreadAttribute(attribute_list, | 429 if (!UpdateProcThreadAttribute(attribute_list, |
| 428 0, | 430 0, |
| 429 PROC_THREAD_ATTRIBUTE_HANDLE_LIST, | 431 PROC_THREAD_ATTRIBUTE_HANDLE_LIST, |
| 430 inherited_handles, | 432 inherited_handles, |
| 431 kNumInheritedHandles * sizeof(HANDLE), | 433 kNumInheritedHandles * sizeof(HANDLE), |
| 432 NULL, | 434 NULL, |
| 433 NULL)) { | 435 NULL)) { |
| 434 DeleteProcThreadAttributeList(attribute_list); | 436 DeleteProcThreadAttributeList(attribute_list); |
| 435 int error_code = SetOsErrorMessage(os_error_message, os_error_message_len); | 437 int error_code = SetOsErrorMessage(os_error_message); |
| 436 CloseProcessPipes( | 438 CloseProcessPipes( |
| 437 stdin_handles, stdout_handles, stderr_handles, exit_handles); | 439 stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| 438 free(attribute_list); | 440 free(attribute_list); |
| 439 return error_code; | 441 return error_code; |
| 440 } | 442 } |
| 441 startup_info.lpAttributeList = attribute_list; | 443 startup_info.lpAttributeList = attribute_list; |
| 442 | 444 |
| 443 PROCESS_INFORMATION process_info; | 445 PROCESS_INFORMATION process_info; |
| 444 ZeroMemory(&process_info, sizeof(process_info)); | 446 ZeroMemory(&process_info, sizeof(process_info)); |
| 445 | 447 |
| 446 // Transform input strings to system format. | 448 // Transform input strings to system format. |
| 447 path = StringUtils::Utf8ToSystemString(path); | 449 path = StringUtils::Utf8ToConsoleString(path); |
| 448 for (int i = 0; i < arguments_length; i++) { | 450 for (int i = 0; i < arguments_length; i++) { |
| 449 arguments[i] = StringUtils::Utf8ToSystemString(arguments[i]); | 451 arguments[i] = StringUtils::Utf8ToConsoleString(arguments[i]); |
| 450 } | 452 } |
| 451 | 453 |
| 452 // Compute command-line length. | 454 // Compute command-line length. |
| 453 int command_line_length = strlen(path); | 455 int command_line_length = strlen(path); |
| 454 for (int i = 0; i < arguments_length; i++) { | 456 for (int i = 0; i < arguments_length; i++) { |
| 455 command_line_length += strlen(arguments[i]); | 457 command_line_length += strlen(arguments[i]); |
| 456 } | 458 } |
| 457 // Account for null termination and one space per argument. | 459 // Account for null termination and one space per argument. |
| 458 command_line_length += arguments_length + 1; | 460 command_line_length += arguments_length + 1; |
| 459 static const int kMaxCommandLineLength = 32768; | 461 static const int kMaxCommandLineLength = 32768; |
| 460 if (command_line_length > kMaxCommandLineLength) { | 462 if (command_line_length > kMaxCommandLineLength) { |
| 461 int error_code = SetOsErrorMessage(os_error_message, os_error_message_len); | 463 int error_code = SetOsErrorMessage(os_error_message); |
| 462 CloseProcessPipes( | 464 CloseProcessPipes( |
| 463 stdin_handles, stdout_handles, stderr_handles, exit_handles); | 465 stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| 464 free(const_cast<char*>(path)); | 466 free(const_cast<char*>(path)); |
| 465 for (int i = 0; i < arguments_length; i++) free(arguments[i]); | 467 for (int i = 0; i < arguments_length; i++) free(arguments[i]); |
| 466 DeleteProcThreadAttributeList(attribute_list); | 468 DeleteProcThreadAttributeList(attribute_list); |
| 467 free(attribute_list); | 469 free(attribute_list); |
| 468 return error_code; | 470 return error_code; |
| 469 } | 471 } |
| 470 | 472 |
| 471 // Put together command-line string. | 473 // Put together command-line string. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 483 ASSERT(remaining >= 0); | 485 ASSERT(remaining >= 0); |
| 484 } | 486 } |
| 485 free(const_cast<char*>(path)); | 487 free(const_cast<char*>(path)); |
| 486 for (int i = 0; i < arguments_length; i++) free(arguments[i]); | 488 for (int i = 0; i < arguments_length; i++) free(arguments[i]); |
| 487 | 489 |
| 488 // Create environment block if an environment is supplied. | 490 // Create environment block if an environment is supplied. |
| 489 char* environment_block = NULL; | 491 char* environment_block = NULL; |
| 490 if (environment != NULL) { | 492 if (environment != NULL) { |
| 491 // Convert environment strings to system strings. | 493 // Convert environment strings to system strings. |
| 492 for (intptr_t i = 0; i < environment_length; i++) { | 494 for (intptr_t i = 0; i < environment_length; i++) { |
| 493 environment[i] = StringUtils::Utf8ToSystemString(environment[i]); | 495 environment[i] = StringUtils::Utf8ToConsoleString(environment[i]); |
| 494 } | 496 } |
| 495 | 497 |
| 496 // An environment block is a sequence of zero-terminated strings | 498 // An environment block is a sequence of zero-terminated strings |
| 497 // followed by a block-terminating zero char. | 499 // followed by a block-terminating zero char. |
| 498 intptr_t block_size = 1; | 500 intptr_t block_size = 1; |
| 499 for (intptr_t i = 0; i < environment_length; i++) { | 501 for (intptr_t i = 0; i < environment_length; i++) { |
| 500 block_size += strlen(environment[i]) + 1; | 502 block_size += strlen(environment[i]) + 1; |
| 501 } | 503 } |
| 502 environment_block = new char[block_size]; | 504 environment_block = new char[block_size]; |
| 503 intptr_t block_index = 0; | 505 intptr_t block_index = 0; |
| 504 for (intptr_t i = 0; i < environment_length; i++) { | 506 for (intptr_t i = 0; i < environment_length; i++) { |
| 505 intptr_t len = strlen(environment[i]); | 507 intptr_t len = strlen(environment[i]); |
| 506 intptr_t result = snprintf(environment_block + block_index, | 508 intptr_t result = snprintf(environment_block + block_index, |
| 507 len, | 509 len, |
| 508 "%s", | 510 "%s", |
| 509 environment[i]); | 511 environment[i]); |
| 510 ASSERT(result == len); | 512 ASSERT(result == len); |
| 511 block_index += len; | 513 block_index += len; |
| 512 environment_block[block_index++] = '\0'; | 514 environment_block[block_index++] = '\0'; |
| 513 } | 515 } |
| 514 // Block-terminating zero char. | 516 // Block-terminating zero char. |
| 515 environment_block[block_index++] = '\0'; | 517 environment_block[block_index++] = '\0'; |
| 516 ASSERT(block_index == block_size); | 518 ASSERT(block_index == block_size); |
| 517 for (intptr_t i = 0; i < environment_length; i++) free(environment[i]); | 519 for (intptr_t i = 0; i < environment_length; i++) free(environment[i]); |
| 518 } | 520 } |
| 519 | 521 |
| 520 if (working_directory != NULL) { | 522 if (working_directory != NULL) { |
| 521 working_directory = StringUtils::Utf8ToSystemString(working_directory); | 523 working_directory = StringUtils::Utf8ToConsoleString(working_directory); |
| 522 } | 524 } |
| 523 | 525 |
| 524 // Create process. | 526 // Create process. |
| 525 BOOL result = CreateProcess(NULL, // ApplicationName | 527 BOOL result = CreateProcess(NULL, // ApplicationName |
| 526 command_line, | 528 command_line, |
| 527 NULL, // ProcessAttributes | 529 NULL, // ProcessAttributes |
| 528 NULL, // ThreadAttributes | 530 NULL, // ThreadAttributes |
| 529 TRUE, // InheritHandles | 531 TRUE, // InheritHandles |
| 530 EXTENDED_STARTUPINFO_PRESENT, | 532 EXTENDED_STARTUPINFO_PRESENT, |
| 531 environment_block, | 533 environment_block, |
| 532 working_directory, | 534 working_directory, |
| 533 reinterpret_cast<STARTUPINFO*>(&startup_info), | 535 reinterpret_cast<STARTUPINFO*>(&startup_info), |
| 534 &process_info); | 536 &process_info); |
| 535 | 537 |
| 536 // Deallocate command-line and environment block strings. | 538 // Deallocate command-line and environment block strings. |
| 537 delete[] command_line; | 539 delete[] command_line; |
| 538 delete[] environment_block; | 540 delete[] environment_block; |
| 539 if (working_directory != NULL) { | 541 if (working_directory != NULL) { |
| 540 free(const_cast<char*>(working_directory)); | 542 free(const_cast<char*>(working_directory)); |
| 541 } | 543 } |
| 542 | 544 |
| 543 DeleteProcThreadAttributeList(attribute_list); | 545 DeleteProcThreadAttributeList(attribute_list); |
| 544 free(attribute_list); | 546 free(attribute_list); |
| 545 | 547 |
| 546 if (result == 0) { | 548 if (result == 0) { |
| 547 int error_code = SetOsErrorMessage(os_error_message, os_error_message_len); | 549 int error_code = SetOsErrorMessage(os_error_message); |
| 548 CloseProcessPipes( | 550 CloseProcessPipes( |
| 549 stdin_handles, stdout_handles, stderr_handles, exit_handles); | 551 stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| 550 return error_code; | 552 return error_code; |
| 551 } | 553 } |
| 552 | 554 |
| 553 ProcessInfoList::AddProcess(process_info.dwProcessId, | 555 ProcessInfoList::AddProcess(process_info.dwProcessId, |
| 554 process_info.hProcess, | 556 process_info.hProcess, |
| 555 exit_handles[kWriteHandle]); | 557 exit_handles[kWriteHandle]); |
| 556 | 558 |
| 557 // Connect the three std streams. | 559 // Connect the three std streams. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 | 594 |
| 593 | 595 |
| 594 void Process::TerminateExitCodeHandler() { | 596 void Process::TerminateExitCodeHandler() { |
| 595 // Nothing needs to be done on Windows. | 597 // Nothing needs to be done on Windows. |
| 596 } | 598 } |
| 597 | 599 |
| 598 | 600 |
| 599 intptr_t Process::CurrentProcessId() { | 601 intptr_t Process::CurrentProcessId() { |
| 600 return static_cast<intptr_t>(GetCurrentProcessId()); | 602 return static_cast<intptr_t>(GetCurrentProcessId()); |
| 601 } | 603 } |
| OLD | NEW |