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 m : namespace kasko {
27 m : namespace testing {
28 m : namespace {
29 :
30 m : HANDLE DuplicateStdHandleForInheritance(DWORD std_handle) {
31 m : HANDLE original = ::GetStdHandle(std_handle);
32 m : HANDLE duplicate = nullptr;
33 :
34 m : if (original && original != INVALID_HANDLE_VALUE) {
35 m : BOOL result = ::DuplicateHandle(base::GetCurrentProcessHandle(), original,
36 m : base::GetCurrentProcessHandle(), &duplicate,
37 m : 0, TRUE, DUPLICATE_SAME_ACCESS);
38 m : CHECK(result);
39 m : }
40 :
41 m : return duplicate;
42 m : }
43 :
44 m : } // namespace
45 :
46 m : base::Process LaunchPythonProcess(
47 m : const base::FilePath& src_relative_path,
48 m : const base::CommandLine& args) {
49 m : base::CommandLine python_command(args);
50 m : python_command.SetProgram(
51 m : ::testing::GetSrcRelativePath(src_relative_path.value().c_str()));
52 m : python_command.PrependWrapper(
53 m : ::testing::GetSrcRelativePath(L"third_party/python_26/python.exe")
54 m : .value());
55 :
56 m : HANDLE stdout_dup = DuplicateStdHandleForInheritance(STD_OUTPUT_HANDLE);
57 m : HANDLE stderr_dup = DuplicateStdHandleForInheritance(STD_ERROR_HANDLE);
58 m : HANDLE stdin_dup = DuplicateStdHandleForInheritance(STD_INPUT_HANDLE);
59 :
60 m : base::LaunchOptions launch_options;
61 m : launch_options.inherit_handles = true;
62 m : launch_options.stdin_handle = stdin_dup ? stdin_dup : INVALID_HANDLE_VALUE;
63 m : launch_options.stdout_handle = stdout_dup ? stdout_dup : INVALID_HANDLE_VALUE;
64 m : launch_options.stderr_handle = stderr_dup ? stderr_dup : INVALID_HANDLE_VALUE;
65 :
66 m : base::Process process = base::LaunchProcess(python_command, launch_options);
67 :
68 m : if (stdin_dup)
69 m : ::CloseHandle(stdin_dup);
70 m : if (stdout_dup)
71 m : ::CloseHandle(stdout_dup);
72 m : if (stderr_dup)
73 m : ::CloseHandle(stderr_dup);
74 :
75 m : return std::move(process);
76 m : }
77 :
78 m : } // namespace testing
79 m : } // namespace kasko
|