| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/test/launcher/test_launcher.h" | 5 #include "base/test/launcher/test_launcher.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/at_exit.h" | 9 #include "base/at_exit.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 302 #endif | 302 #endif |
| 303 | 303 |
| 304 Process process; | 304 Process process; |
| 305 | 305 |
| 306 { | 306 { |
| 307 // Note how we grab the lock before the process possibly gets created. | 307 // Note how we grab the lock before the process possibly gets created. |
| 308 // This ensures that when the lock is held, ALL the processes are registered | 308 // This ensures that when the lock is held, ALL the processes are registered |
| 309 // in the set. | 309 // in the set. |
| 310 AutoLock lock(g_live_processes_lock.Get()); | 310 AutoLock lock(g_live_processes_lock.Get()); |
| 311 | 311 |
| 312 #if defined(OS_WIN) |
| 313 // Allow the handle used to capture stdio and stdout to be inherited by the |
| 314 // child. Note that this is done under g_live_processes_lock to ensure that |
| 315 // only the desired child receives the handle. |
| 316 if (new_options.stdout_handle) { |
| 317 ::SetHandleInformation(new_options.stdout_handle, HANDLE_FLAG_INHERIT, |
| 318 HANDLE_FLAG_INHERIT); |
| 319 } |
| 320 #endif |
| 321 |
| 312 process = LaunchProcess(command_line, new_options); | 322 process = LaunchProcess(command_line, new_options); |
| 323 |
| 324 #if defined(OS_WIN) |
| 325 // Revoke inheritance so that the handle isn't leaked into other children. |
| 326 // Note that this is done under g_live_processes_lock to ensure that only |
| 327 // the desired child receives the handle. |
| 328 if (new_options.stdout_handle) |
| 329 ::SetHandleInformation(new_options.stdout_handle, HANDLE_FLAG_INHERIT, 0); |
| 330 #endif |
| 331 |
| 313 if (!process.IsValid()) | 332 if (!process.IsValid()) |
| 314 return -1; | 333 return -1; |
| 315 | 334 |
| 316 // TODO(rvargas) crbug.com/417532: Don't store process handles. | 335 // TODO(rvargas) crbug.com/417532: Don't store process handles. |
| 317 g_live_processes.Get().insert(std::make_pair(process.Handle(), | 336 g_live_processes.Get().insert(std::make_pair(process.Handle(), |
| 318 command_line)); | 337 command_line)); |
| 319 } | 338 } |
| 320 | 339 |
| 321 if (!launched_callback.is_null()) | 340 if (!launched_callback.is_null()) |
| 322 launched_callback.Run(process.Handle(), process.Pid()); | 341 launched_callback.Run(process.Handle(), process.Pid()); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 375 | 394 |
| 376 // Redirect child process output to a file. | 395 // Redirect child process output to a file. |
| 377 FilePath output_file; | 396 FilePath output_file; |
| 378 CHECK(CreateTemporaryFile(&output_file)); | 397 CHECK(CreateTemporaryFile(&output_file)); |
| 379 | 398 |
| 380 LaunchOptions options; | 399 LaunchOptions options; |
| 381 #if defined(OS_WIN) | 400 #if defined(OS_WIN) |
| 382 win::ScopedHandle handle; | 401 win::ScopedHandle handle; |
| 383 | 402 |
| 384 if (redirect_stdio) { | 403 if (redirect_stdio) { |
| 385 // Make the file handle inheritable by the child. | 404 handle.Set(CreateFile(output_file.value().c_str(), GENERIC_WRITE, |
| 386 SECURITY_ATTRIBUTES sa_attr; | 405 FILE_SHARE_READ | FILE_SHARE_DELETE, nullptr, |
| 387 sa_attr.nLength = sizeof(SECURITY_ATTRIBUTES); | 406 OPEN_EXISTING, FILE_ATTRIBUTE_TEMPORARY, NULL)); |
| 388 sa_attr.lpSecurityDescriptor = NULL; | |
| 389 sa_attr.bInheritHandle = TRUE; | |
| 390 | |
| 391 handle.Set(CreateFile(output_file.value().c_str(), | |
| 392 GENERIC_WRITE, | |
| 393 FILE_SHARE_READ | FILE_SHARE_DELETE, | |
| 394 &sa_attr, | |
| 395 OPEN_EXISTING, | |
| 396 FILE_ATTRIBUTE_TEMPORARY, | |
| 397 NULL)); | |
| 398 CHECK(handle.IsValid()); | 407 CHECK(handle.IsValid()); |
| 399 options.inherit_handles = true; | 408 options.inherit_handles = true; |
| 400 options.stdin_handle = INVALID_HANDLE_VALUE; | 409 options.stdin_handle = INVALID_HANDLE_VALUE; |
| 401 options.stdout_handle = handle.Get(); | 410 options.stdout_handle = handle.Get(); |
| 402 options.stderr_handle = handle.Get(); | 411 options.stderr_handle = handle.Get(); |
| 403 } | 412 } |
| 404 | 413 |
| 405 if (test_launch_options.inherit_handles) { | 414 if (test_launch_options.inherit_handles) { |
| 406 if (!options.inherit_handles) { | 415 if (!options.inherit_handles) { |
| 407 options.inherit_handles = true; | 416 options.inherit_handles = true; |
| (...skipping 797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1205 } | 1214 } |
| 1206 | 1215 |
| 1207 std::string snippet(full_output.substr(run_pos)); | 1216 std::string snippet(full_output.substr(run_pos)); |
| 1208 if (end_pos != std::string::npos) | 1217 if (end_pos != std::string::npos) |
| 1209 snippet = full_output.substr(run_pos, end_pos - run_pos); | 1218 snippet = full_output.substr(run_pos, end_pos - run_pos); |
| 1210 | 1219 |
| 1211 return snippet; | 1220 return snippet; |
| 1212 } | 1221 } |
| 1213 | 1222 |
| 1214 } // namespace base | 1223 } // namespace base |
| OLD | NEW |