1 : // Copyright 2015 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #include "syzygy/kasko/testing/launch_python_process.h"
16 :
17 : #include <windows.h>
18 :
19 : #include "base/command_line.h"
20 : #include "base/logging.h"
21 : #include "base/files/file_path.h"
22 : #include "base/process/launch.h"
23 : #include "base/process/process_handle.h"
24 : #include "syzygy/core/unittest_util.h"
25 :
26 : namespace kasko {
27 : namespace testing {
28 : namespace {
29 :
30 E : HANDLE DuplicateStdHandleForInheritance(DWORD std_handle) {
31 E : HANDLE original = ::GetStdHandle(std_handle);
32 E : HANDLE duplicate = nullptr;
33 :
34 E : if (original && original != INVALID_HANDLE_VALUE) {
35 : BOOL result = ::DuplicateHandle(base::GetCurrentProcessHandle(), original,
36 : base::GetCurrentProcessHandle(), &duplicate,
37 E : 0, TRUE, DUPLICATE_SAME_ACCESS);
38 E : CHECK(result);
39 : }
40 :
41 E : return duplicate;
42 E : }
43 :
44 : } // namespace
45 :
46 : base::Process LaunchPythonProcess(
47 : const base::FilePath& src_relative_path,
48 E : const base::CommandLine& args) {
49 E : base::CommandLine python_command(args);
50 : python_command.SetProgram(
51 E : ::testing::GetSrcRelativePath(src_relative_path.value().c_str()));
52 : python_command.PrependWrapper(
53 : ::testing::GetSrcRelativePath(L"third_party/python_26/python.exe")
54 E : .value());
55 :
56 E : HANDLE stdout_dup = DuplicateStdHandleForInheritance(STD_OUTPUT_HANDLE);
57 E : HANDLE stderr_dup = DuplicateStdHandleForInheritance(STD_ERROR_HANDLE);
58 E : HANDLE stdin_dup = DuplicateStdHandleForInheritance(STD_INPUT_HANDLE);
59 :
60 E : base::LaunchOptions launch_options;
61 E : launch_options.inherit_handles = true;
62 E : launch_options.stdin_handle = stdin_dup ? stdin_dup : INVALID_HANDLE_VALUE;
63 E : launch_options.stdout_handle = stdout_dup ? stdout_dup : INVALID_HANDLE_VALUE;
64 E : launch_options.stderr_handle = stderr_dup ? stderr_dup : INVALID_HANDLE_VALUE;
65 :
66 E : base::Process process = base::LaunchProcess(python_command, launch_options);
67 :
68 E : if (stdin_dup)
69 E : ::CloseHandle(stdin_dup);
70 E : if (stdout_dup)
71 E : ::CloseHandle(stdout_dup);
72 E : if (stderr_dup)
73 E : ::CloseHandle(stderr_dup);
74 :
75 E : return process.Pass();
76 E : }
77 :
78 : } // namespace testing
79 : } // namespace kasko
|