xref: /aosp_15_r20/external/libchrome/base/process/process_util_unittest.cc (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #define _CRT_SECURE_NO_WARNINGS
6*635a8641SAndroid Build Coastguard Worker 
7*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
8*635a8641SAndroid Build Coastguard Worker #include <stdint.h>
9*635a8641SAndroid Build Coastguard Worker 
10*635a8641SAndroid Build Coastguard Worker #include <limits>
11*635a8641SAndroid Build Coastguard Worker 
12*635a8641SAndroid Build Coastguard Worker #include "base/command_line.h"
13*635a8641SAndroid Build Coastguard Worker #include "base/debug/alias.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/debug/stack_trace.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/files/file_enumerator.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/files/file_path.h"
17*635a8641SAndroid Build Coastguard Worker #include "base/files/file_util.h"
18*635a8641SAndroid Build Coastguard Worker #include "base/files/scoped_file.h"
19*635a8641SAndroid Build Coastguard Worker #include "base/logging.h"
20*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
21*635a8641SAndroid Build Coastguard Worker #include "base/path_service.h"
22*635a8641SAndroid Build Coastguard Worker #include "base/posix/eintr_wrapper.h"
23*635a8641SAndroid Build Coastguard Worker #include "base/process/kill.h"
24*635a8641SAndroid Build Coastguard Worker #include "base/process/launch.h"
25*635a8641SAndroid Build Coastguard Worker #include "base/process/memory.h"
26*635a8641SAndroid Build Coastguard Worker #include "base/process/process.h"
27*635a8641SAndroid Build Coastguard Worker #include "base/process/process_metrics.h"
28*635a8641SAndroid Build Coastguard Worker #include "base/strings/string_number_conversions.h"
29*635a8641SAndroid Build Coastguard Worker #include "base/strings/utf_string_conversions.h"
30*635a8641SAndroid Build Coastguard Worker #include "base/synchronization/waitable_event.h"
31*635a8641SAndroid Build Coastguard Worker #include "base/test/multiprocess_test.h"
32*635a8641SAndroid Build Coastguard Worker #include "base/test/scoped_task_environment.h"
33*635a8641SAndroid Build Coastguard Worker #include "base/test/test_timeouts.h"
34*635a8641SAndroid Build Coastguard Worker #include "base/threading/platform_thread.h"
35*635a8641SAndroid Build Coastguard Worker #include "base/threading/thread.h"
36*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
37*635a8641SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
38*635a8641SAndroid Build Coastguard Worker #include "testing/multiprocess_func_list.h"
39*635a8641SAndroid Build Coastguard Worker 
40*635a8641SAndroid Build Coastguard Worker #if defined(OS_LINUX)
41*635a8641SAndroid Build Coastguard Worker #include <malloc.h>
42*635a8641SAndroid Build Coastguard Worker #include <sched.h>
43*635a8641SAndroid Build Coastguard Worker #include <sys/syscall.h>
44*635a8641SAndroid Build Coastguard Worker #endif
45*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX)
46*635a8641SAndroid Build Coastguard Worker #include <sys/resource.h>
47*635a8641SAndroid Build Coastguard Worker #endif
48*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX)
49*635a8641SAndroid Build Coastguard Worker #include <dlfcn.h>
50*635a8641SAndroid Build Coastguard Worker #include <errno.h>
51*635a8641SAndroid Build Coastguard Worker #include <sched.h>
52*635a8641SAndroid Build Coastguard Worker #include <signal.h>
53*635a8641SAndroid Build Coastguard Worker #include <sys/wait.h>
54*635a8641SAndroid Build Coastguard Worker #include <unistd.h>
55*635a8641SAndroid Build Coastguard Worker #endif
56*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX) || defined(OS_FUCHSIA)
57*635a8641SAndroid Build Coastguard Worker #include <fcntl.h>
58*635a8641SAndroid Build Coastguard Worker #include <sys/socket.h>
59*635a8641SAndroid Build Coastguard Worker #include <sys/types.h>
60*635a8641SAndroid Build Coastguard Worker #endif
61*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
62*635a8641SAndroid Build Coastguard Worker #include <windows.h>
63*635a8641SAndroid Build Coastguard Worker #endif
64*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX)
65*635a8641SAndroid Build Coastguard Worker #include <mach/vm_param.h>
66*635a8641SAndroid Build Coastguard Worker #include <malloc/malloc.h>
67*635a8641SAndroid Build Coastguard Worker #endif
68*635a8641SAndroid Build Coastguard Worker #if defined(OS_ANDROID)
69*635a8641SAndroid Build Coastguard Worker #include "third_party/lss/linux_syscall_support.h"
70*635a8641SAndroid Build Coastguard Worker #endif
71*635a8641SAndroid Build Coastguard Worker #if defined(OS_FUCHSIA)
72*635a8641SAndroid Build Coastguard Worker #include <lib/fdio/limits.h>
73*635a8641SAndroid Build Coastguard Worker #include <zircon/process.h>
74*635a8641SAndroid Build Coastguard Worker #include <zircon/processargs.h>
75*635a8641SAndroid Build Coastguard Worker #include <zircon/syscalls.h>
76*635a8641SAndroid Build Coastguard Worker #include "base/base_paths_fuchsia.h"
77*635a8641SAndroid Build Coastguard Worker #include "base/files/scoped_temp_dir.h"
78*635a8641SAndroid Build Coastguard Worker #include "base/fuchsia/file_utils.h"
79*635a8641SAndroid Build Coastguard Worker #include "base/fuchsia/fuchsia_logging.h"
80*635a8641SAndroid Build Coastguard Worker #endif
81*635a8641SAndroid Build Coastguard Worker 
82*635a8641SAndroid Build Coastguard Worker namespace base {
83*635a8641SAndroid Build Coastguard Worker 
84*635a8641SAndroid Build Coastguard Worker namespace {
85*635a8641SAndroid Build Coastguard Worker 
86*635a8641SAndroid Build Coastguard Worker const char kSignalFileSlow[] = "SlowChildProcess.die";
87*635a8641SAndroid Build Coastguard Worker const char kSignalFileKill[] = "KilledChildProcess.die";
88*635a8641SAndroid Build Coastguard Worker const char kTestHelper[] = "test_child_process";
89*635a8641SAndroid Build Coastguard Worker 
90*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX)
91*635a8641SAndroid Build Coastguard Worker const char kSignalFileTerm[] = "TerminatedChildProcess.die";
92*635a8641SAndroid Build Coastguard Worker #endif
93*635a8641SAndroid Build Coastguard Worker 
94*635a8641SAndroid Build Coastguard Worker #if defined(OS_FUCHSIA)
95*635a8641SAndroid Build Coastguard Worker const char kSignalFileClone[] = "ClonedTmpDir.die";
96*635a8641SAndroid Build Coastguard Worker const char kDataDirHasStaged[] = "DataDirHasStaged.die";
97*635a8641SAndroid Build Coastguard Worker const char kFooDirHasStaged[] = "FooDirHasStaged.die";
98*635a8641SAndroid Build Coastguard Worker const char kFooDirDoesNotHaveStaged[] = "FooDirDoesNotHaveStaged.die";
99*635a8641SAndroid Build Coastguard Worker #endif
100*635a8641SAndroid Build Coastguard Worker 
101*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
102*635a8641SAndroid Build Coastguard Worker const int kExpectedStillRunningExitCode = 0x102;
103*635a8641SAndroid Build Coastguard Worker const int kExpectedKilledExitCode = 1;
104*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
105*635a8641SAndroid Build Coastguard Worker const int kExpectedStillRunningExitCode = 0;
106*635a8641SAndroid Build Coastguard Worker #endif
107*635a8641SAndroid Build Coastguard Worker 
108*635a8641SAndroid Build Coastguard Worker // Sleeps until file filename is created.
WaitToDie(const char * filename)109*635a8641SAndroid Build Coastguard Worker void WaitToDie(const char* filename) {
110*635a8641SAndroid Build Coastguard Worker   FILE* fp;
111*635a8641SAndroid Build Coastguard Worker   do {
112*635a8641SAndroid Build Coastguard Worker     PlatformThread::Sleep(TimeDelta::FromMilliseconds(10));
113*635a8641SAndroid Build Coastguard Worker     fp = fopen(filename, "r");
114*635a8641SAndroid Build Coastguard Worker   } while (!fp);
115*635a8641SAndroid Build Coastguard Worker   fclose(fp);
116*635a8641SAndroid Build Coastguard Worker }
117*635a8641SAndroid Build Coastguard Worker 
118*635a8641SAndroid Build Coastguard Worker // Signals children they should die now.
SignalChildren(const char * filename)119*635a8641SAndroid Build Coastguard Worker void SignalChildren(const char* filename) {
120*635a8641SAndroid Build Coastguard Worker   FILE* fp = fopen(filename, "w");
121*635a8641SAndroid Build Coastguard Worker   fclose(fp);
122*635a8641SAndroid Build Coastguard Worker }
123*635a8641SAndroid Build Coastguard Worker 
124*635a8641SAndroid Build Coastguard Worker // Using a pipe to the child to wait for an event was considered, but
125*635a8641SAndroid Build Coastguard Worker // there were cases in the past where pipes caused problems (other
126*635a8641SAndroid Build Coastguard Worker // libraries closing the fds, child deadlocking). This is a simple
127*635a8641SAndroid Build Coastguard Worker // case, so it's not worth the risk.  Using wait loops is discouraged
128*635a8641SAndroid Build Coastguard Worker // in most instances.
WaitForChildTermination(ProcessHandle handle,int * exit_code)129*635a8641SAndroid Build Coastguard Worker TerminationStatus WaitForChildTermination(ProcessHandle handle,
130*635a8641SAndroid Build Coastguard Worker                                           int* exit_code) {
131*635a8641SAndroid Build Coastguard Worker   // Now we wait until the result is something other than STILL_RUNNING.
132*635a8641SAndroid Build Coastguard Worker   TerminationStatus status = TERMINATION_STATUS_STILL_RUNNING;
133*635a8641SAndroid Build Coastguard Worker   const TimeDelta kInterval = TimeDelta::FromMilliseconds(20);
134*635a8641SAndroid Build Coastguard Worker   TimeDelta waited;
135*635a8641SAndroid Build Coastguard Worker   do {
136*635a8641SAndroid Build Coastguard Worker     status = GetTerminationStatus(handle, exit_code);
137*635a8641SAndroid Build Coastguard Worker     PlatformThread::Sleep(kInterval);
138*635a8641SAndroid Build Coastguard Worker     waited += kInterval;
139*635a8641SAndroid Build Coastguard Worker   } while (status == TERMINATION_STATUS_STILL_RUNNING &&
140*635a8641SAndroid Build Coastguard Worker            waited < TestTimeouts::action_max_timeout());
141*635a8641SAndroid Build Coastguard Worker 
142*635a8641SAndroid Build Coastguard Worker   return status;
143*635a8641SAndroid Build Coastguard Worker }
144*635a8641SAndroid Build Coastguard Worker 
145*635a8641SAndroid Build Coastguard Worker }  // namespace
146*635a8641SAndroid Build Coastguard Worker 
147*635a8641SAndroid Build Coastguard Worker const int kSuccess = 0;
148*635a8641SAndroid Build Coastguard Worker 
149*635a8641SAndroid Build Coastguard Worker class ProcessUtilTest : public MultiProcessTest {
150*635a8641SAndroid Build Coastguard Worker  public:
SetUp()151*635a8641SAndroid Build Coastguard Worker   void SetUp() override {
152*635a8641SAndroid Build Coastguard Worker     ASSERT_TRUE(PathService::Get(DIR_ASSETS, &test_helper_path_));
153*635a8641SAndroid Build Coastguard Worker     test_helper_path_ = test_helper_path_.AppendASCII(kTestHelper);
154*635a8641SAndroid Build Coastguard Worker   }
155*635a8641SAndroid Build Coastguard Worker 
156*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX) || defined(OS_FUCHSIA)
157*635a8641SAndroid Build Coastguard Worker   // Spawn a child process that counts how many file descriptors are open.
158*635a8641SAndroid Build Coastguard Worker   int CountOpenFDsInChild();
159*635a8641SAndroid Build Coastguard Worker #endif
160*635a8641SAndroid Build Coastguard Worker   // Converts the filename to a platform specific filepath.
161*635a8641SAndroid Build Coastguard Worker   // On Android files can not be created in arbitrary directories.
162*635a8641SAndroid Build Coastguard Worker   static std::string GetSignalFilePath(const char* filename);
163*635a8641SAndroid Build Coastguard Worker 
164*635a8641SAndroid Build Coastguard Worker  protected:
165*635a8641SAndroid Build Coastguard Worker   base::FilePath test_helper_path_;
166*635a8641SAndroid Build Coastguard Worker };
167*635a8641SAndroid Build Coastguard Worker 
GetSignalFilePath(const char * filename)168*635a8641SAndroid Build Coastguard Worker std::string ProcessUtilTest::GetSignalFilePath(const char* filename) {
169*635a8641SAndroid Build Coastguard Worker #if defined(OS_ANDROID) || defined(OS_FUCHSIA)
170*635a8641SAndroid Build Coastguard Worker   FilePath tmp_dir;
171*635a8641SAndroid Build Coastguard Worker   PathService::Get(DIR_TEMP, &tmp_dir);
172*635a8641SAndroid Build Coastguard Worker   tmp_dir = tmp_dir.Append(filename);
173*635a8641SAndroid Build Coastguard Worker   return tmp_dir.value();
174*635a8641SAndroid Build Coastguard Worker #else
175*635a8641SAndroid Build Coastguard Worker   return filename;
176*635a8641SAndroid Build Coastguard Worker #endif
177*635a8641SAndroid Build Coastguard Worker }
178*635a8641SAndroid Build Coastguard Worker 
MULTIPROCESS_TEST_MAIN(SimpleChildProcess)179*635a8641SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN(SimpleChildProcess) {
180*635a8641SAndroid Build Coastguard Worker   return kSuccess;
181*635a8641SAndroid Build Coastguard Worker }
182*635a8641SAndroid Build Coastguard Worker 
183*635a8641SAndroid Build Coastguard Worker // TODO(viettrungluu): This should be in a "MultiProcessTestTest".
TEST_F(ProcessUtilTest,SpawnChild)184*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, SpawnChild) {
185*635a8641SAndroid Build Coastguard Worker   Process process = SpawnChild("SimpleChildProcess");
186*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(process.IsValid());
187*635a8641SAndroid Build Coastguard Worker   int exit_code;
188*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(process.WaitForExitWithTimeout(TestTimeouts::action_max_timeout(),
189*635a8641SAndroid Build Coastguard Worker                                              &exit_code));
190*635a8641SAndroid Build Coastguard Worker }
191*635a8641SAndroid Build Coastguard Worker 
MULTIPROCESS_TEST_MAIN(SlowChildProcess)192*635a8641SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN(SlowChildProcess) {
193*635a8641SAndroid Build Coastguard Worker   WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileSlow).c_str());
194*635a8641SAndroid Build Coastguard Worker   return kSuccess;
195*635a8641SAndroid Build Coastguard Worker }
196*635a8641SAndroid Build Coastguard Worker 
TEST_F(ProcessUtilTest,KillSlowChild)197*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, KillSlowChild) {
198*635a8641SAndroid Build Coastguard Worker   const std::string signal_file =
199*635a8641SAndroid Build Coastguard Worker       ProcessUtilTest::GetSignalFilePath(kSignalFileSlow);
200*635a8641SAndroid Build Coastguard Worker   remove(signal_file.c_str());
201*635a8641SAndroid Build Coastguard Worker   Process process = SpawnChild("SlowChildProcess");
202*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(process.IsValid());
203*635a8641SAndroid Build Coastguard Worker   SignalChildren(signal_file.c_str());
204*635a8641SAndroid Build Coastguard Worker   int exit_code;
205*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(process.WaitForExitWithTimeout(TestTimeouts::action_max_timeout(),
206*635a8641SAndroid Build Coastguard Worker                                              &exit_code));
207*635a8641SAndroid Build Coastguard Worker   remove(signal_file.c_str());
208*635a8641SAndroid Build Coastguard Worker }
209*635a8641SAndroid Build Coastguard Worker 
210*635a8641SAndroid Build Coastguard Worker // Times out on Linux and Win, flakes on other platforms, http://crbug.com/95058
TEST_F(ProcessUtilTest,DISABLED_GetTerminationStatusExit)211*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, DISABLED_GetTerminationStatusExit) {
212*635a8641SAndroid Build Coastguard Worker   const std::string signal_file =
213*635a8641SAndroid Build Coastguard Worker       ProcessUtilTest::GetSignalFilePath(kSignalFileSlow);
214*635a8641SAndroid Build Coastguard Worker   remove(signal_file.c_str());
215*635a8641SAndroid Build Coastguard Worker   Process process = SpawnChild("SlowChildProcess");
216*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(process.IsValid());
217*635a8641SAndroid Build Coastguard Worker 
218*635a8641SAndroid Build Coastguard Worker   int exit_code = 42;
219*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(TERMINATION_STATUS_STILL_RUNNING,
220*635a8641SAndroid Build Coastguard Worker             GetTerminationStatus(process.Handle(), &exit_code));
221*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kExpectedStillRunningExitCode, exit_code);
222*635a8641SAndroid Build Coastguard Worker 
223*635a8641SAndroid Build Coastguard Worker   SignalChildren(signal_file.c_str());
224*635a8641SAndroid Build Coastguard Worker   exit_code = 42;
225*635a8641SAndroid Build Coastguard Worker   TerminationStatus status =
226*635a8641SAndroid Build Coastguard Worker       WaitForChildTermination(process.Handle(), &exit_code);
227*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(TERMINATION_STATUS_NORMAL_TERMINATION, status);
228*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kSuccess, exit_code);
229*635a8641SAndroid Build Coastguard Worker   remove(signal_file.c_str());
230*635a8641SAndroid Build Coastguard Worker }
231*635a8641SAndroid Build Coastguard Worker 
232*635a8641SAndroid Build Coastguard Worker #if defined(OS_FUCHSIA)
233*635a8641SAndroid Build Coastguard Worker 
MULTIPROCESS_TEST_MAIN(CheckDataDirHasStaged)234*635a8641SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN(CheckDataDirHasStaged) {
235*635a8641SAndroid Build Coastguard Worker   if (!PathExists(base::FilePath("/data/staged"))) {
236*635a8641SAndroid Build Coastguard Worker     return 1;
237*635a8641SAndroid Build Coastguard Worker   }
238*635a8641SAndroid Build Coastguard Worker   WaitToDie(ProcessUtilTest::GetSignalFilePath(kDataDirHasStaged).c_str());
239*635a8641SAndroid Build Coastguard Worker   return kSuccess;
240*635a8641SAndroid Build Coastguard Worker }
241*635a8641SAndroid Build Coastguard Worker 
242*635a8641SAndroid Build Coastguard Worker // Test transferred paths override cloned paths.
TEST_F(ProcessUtilTest,HandleTransfersOverrideClones)243*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, HandleTransfersOverrideClones) {
244*635a8641SAndroid Build Coastguard Worker   const std::string signal_file =
245*635a8641SAndroid Build Coastguard Worker       ProcessUtilTest::GetSignalFilePath(kDataDirHasStaged);
246*635a8641SAndroid Build Coastguard Worker   remove(signal_file.c_str());
247*635a8641SAndroid Build Coastguard Worker 
248*635a8641SAndroid Build Coastguard Worker   // Create a tempdir with "staged" as its contents.
249*635a8641SAndroid Build Coastguard Worker   ScopedTempDir tmpdir_with_staged;
250*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(tmpdir_with_staged.CreateUniqueTempDir());
251*635a8641SAndroid Build Coastguard Worker   {
252*635a8641SAndroid Build Coastguard Worker     base::FilePath staged_file_path =
253*635a8641SAndroid Build Coastguard Worker         tmpdir_with_staged.GetPath().Append("staged");
254*635a8641SAndroid Build Coastguard Worker     base::File staged_file(staged_file_path,
255*635a8641SAndroid Build Coastguard Worker                            base::File::FLAG_CREATE | base::File::FLAG_WRITE);
256*635a8641SAndroid Build Coastguard Worker     ASSERT_TRUE(staged_file.created());
257*635a8641SAndroid Build Coastguard Worker     staged_file.Close();
258*635a8641SAndroid Build Coastguard Worker   }
259*635a8641SAndroid Build Coastguard Worker 
260*635a8641SAndroid Build Coastguard Worker   base::LaunchOptions options;
261*635a8641SAndroid Build Coastguard Worker   options.spawn_flags = FDIO_SPAWN_CLONE_STDIO;
262*635a8641SAndroid Build Coastguard Worker 
263*635a8641SAndroid Build Coastguard Worker   // Attach the tempdir to "data", but also try to duplicate the existing "data"
264*635a8641SAndroid Build Coastguard Worker   // directory.
265*635a8641SAndroid Build Coastguard Worker   options.paths_to_clone.push_back(base::FilePath("/data"));
266*635a8641SAndroid Build Coastguard Worker   options.paths_to_clone.push_back(base::FilePath("/tmp"));
267*635a8641SAndroid Build Coastguard Worker   options.paths_to_transfer.push_back(
268*635a8641SAndroid Build Coastguard Worker       {FilePath("/data"),
269*635a8641SAndroid Build Coastguard Worker        fuchsia::GetHandleFromFile(
270*635a8641SAndroid Build Coastguard Worker            base::File(base::FilePath(tmpdir_with_staged.GetPath()),
271*635a8641SAndroid Build Coastguard Worker                       base::File::FLAG_OPEN | base::File::FLAG_READ))
272*635a8641SAndroid Build Coastguard Worker            .release()});
273*635a8641SAndroid Build Coastguard Worker 
274*635a8641SAndroid Build Coastguard Worker   // Verify from that "/data/staged" exists from the child process' perspective.
275*635a8641SAndroid Build Coastguard Worker   Process process(SpawnChildWithOptions("CheckDataDirHasStaged", options));
276*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(process.IsValid());
277*635a8641SAndroid Build Coastguard Worker   SignalChildren(signal_file.c_str());
278*635a8641SAndroid Build Coastguard Worker 
279*635a8641SAndroid Build Coastguard Worker   int exit_code = 42;
280*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(process.WaitForExit(&exit_code));
281*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kSuccess, exit_code);
282*635a8641SAndroid Build Coastguard Worker }
283*635a8641SAndroid Build Coastguard Worker 
MULTIPROCESS_TEST_MAIN(CheckMountedDir)284*635a8641SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN(CheckMountedDir) {
285*635a8641SAndroid Build Coastguard Worker   if (!PathExists(base::FilePath("/foo/staged"))) {
286*635a8641SAndroid Build Coastguard Worker     return 1;
287*635a8641SAndroid Build Coastguard Worker   }
288*635a8641SAndroid Build Coastguard Worker   WaitToDie(ProcessUtilTest::GetSignalFilePath(kFooDirHasStaged).c_str());
289*635a8641SAndroid Build Coastguard Worker   return kSuccess;
290*635a8641SAndroid Build Coastguard Worker }
291*635a8641SAndroid Build Coastguard Worker 
292*635a8641SAndroid Build Coastguard Worker // Test that we can install an opaque handle in the child process' namespace.
TEST_F(ProcessUtilTest,TransferHandleToPath)293*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, TransferHandleToPath) {
294*635a8641SAndroid Build Coastguard Worker   const std::string signal_file =
295*635a8641SAndroid Build Coastguard Worker       ProcessUtilTest::GetSignalFilePath(kFooDirHasStaged);
296*635a8641SAndroid Build Coastguard Worker   remove(signal_file.c_str());
297*635a8641SAndroid Build Coastguard Worker 
298*635a8641SAndroid Build Coastguard Worker   // Create a tempdir with "staged" as its contents.
299*635a8641SAndroid Build Coastguard Worker   ScopedTempDir new_tmpdir;
300*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(new_tmpdir.CreateUniqueTempDir());
301*635a8641SAndroid Build Coastguard Worker   base::FilePath staged_file_path = new_tmpdir.GetPath().Append("staged");
302*635a8641SAndroid Build Coastguard Worker   base::File staged_file(staged_file_path,
303*635a8641SAndroid Build Coastguard Worker                          base::File::FLAG_CREATE | base::File::FLAG_WRITE);
304*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(staged_file.created());
305*635a8641SAndroid Build Coastguard Worker   staged_file.Close();
306*635a8641SAndroid Build Coastguard Worker 
307*635a8641SAndroid Build Coastguard Worker   // Mount the tempdir to "/foo".
308*635a8641SAndroid Build Coastguard Worker   zx::handle tmp_handle = fuchsia::GetHandleFromFile(
309*635a8641SAndroid Build Coastguard Worker       base::File(base::FilePath(new_tmpdir.GetPath()),
310*635a8641SAndroid Build Coastguard Worker                  base::File::FLAG_OPEN | base::File::FLAG_READ));
311*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(tmp_handle.is_valid());
312*635a8641SAndroid Build Coastguard Worker   LaunchOptions options;
313*635a8641SAndroid Build Coastguard Worker   options.paths_to_clone.push_back(base::FilePath("/tmp"));
314*635a8641SAndroid Build Coastguard Worker   options.paths_to_transfer.push_back(
315*635a8641SAndroid Build Coastguard Worker       {base::FilePath("/foo"), tmp_handle.release()});
316*635a8641SAndroid Build Coastguard Worker   options.spawn_flags = FDIO_SPAWN_CLONE_STDIO;
317*635a8641SAndroid Build Coastguard Worker 
318*635a8641SAndroid Build Coastguard Worker   // Verify from that "/foo/staged" exists from the child process' perspective.
319*635a8641SAndroid Build Coastguard Worker   Process process(SpawnChildWithOptions("CheckMountedDir", options));
320*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(process.IsValid());
321*635a8641SAndroid Build Coastguard Worker   SignalChildren(signal_file.c_str());
322*635a8641SAndroid Build Coastguard Worker 
323*635a8641SAndroid Build Coastguard Worker   int exit_code = 42;
324*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(process.WaitForExit(&exit_code));
325*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kSuccess, exit_code);
326*635a8641SAndroid Build Coastguard Worker }
327*635a8641SAndroid Build Coastguard Worker 
MULTIPROCESS_TEST_MAIN(CheckTmpFileExists)328*635a8641SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN(CheckTmpFileExists) {
329*635a8641SAndroid Build Coastguard Worker   // Look through the filesystem to ensure that no other directories
330*635a8641SAndroid Build Coastguard Worker   // besides "tmp" are in the namespace.
331*635a8641SAndroid Build Coastguard Worker   base::FileEnumerator enumerator(
332*635a8641SAndroid Build Coastguard Worker       base::FilePath("/"), false,
333*635a8641SAndroid Build Coastguard Worker       base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES);
334*635a8641SAndroid Build Coastguard Worker   base::FilePath next_path;
335*635a8641SAndroid Build Coastguard Worker   while (!(next_path = enumerator.Next()).empty()) {
336*635a8641SAndroid Build Coastguard Worker     if (next_path != base::FilePath("/tmp")) {
337*635a8641SAndroid Build Coastguard Worker       LOG(ERROR) << "Clone policy violation: found non-tmp directory "
338*635a8641SAndroid Build Coastguard Worker                  << next_path.MaybeAsASCII();
339*635a8641SAndroid Build Coastguard Worker       return 1;
340*635a8641SAndroid Build Coastguard Worker     }
341*635a8641SAndroid Build Coastguard Worker   }
342*635a8641SAndroid Build Coastguard Worker   WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileClone).c_str());
343*635a8641SAndroid Build Coastguard Worker   return kSuccess;
344*635a8641SAndroid Build Coastguard Worker }
345*635a8641SAndroid Build Coastguard Worker 
TEST_F(ProcessUtilTest,CloneTmp)346*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, CloneTmp) {
347*635a8641SAndroid Build Coastguard Worker   const std::string signal_file =
348*635a8641SAndroid Build Coastguard Worker       ProcessUtilTest::GetSignalFilePath(kSignalFileClone);
349*635a8641SAndroid Build Coastguard Worker   remove(signal_file.c_str());
350*635a8641SAndroid Build Coastguard Worker 
351*635a8641SAndroid Build Coastguard Worker   LaunchOptions options;
352*635a8641SAndroid Build Coastguard Worker   options.paths_to_clone.push_back(base::FilePath("/tmp"));
353*635a8641SAndroid Build Coastguard Worker   options.spawn_flags = FDIO_SPAWN_CLONE_STDIO;
354*635a8641SAndroid Build Coastguard Worker 
355*635a8641SAndroid Build Coastguard Worker   Process process(SpawnChildWithOptions("CheckTmpFileExists", options));
356*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(process.IsValid());
357*635a8641SAndroid Build Coastguard Worker 
358*635a8641SAndroid Build Coastguard Worker   SignalChildren(signal_file.c_str());
359*635a8641SAndroid Build Coastguard Worker 
360*635a8641SAndroid Build Coastguard Worker   int exit_code = 42;
361*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(process.WaitForExit(&exit_code));
362*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kSuccess, exit_code);
363*635a8641SAndroid Build Coastguard Worker }
364*635a8641SAndroid Build Coastguard Worker 
MULTIPROCESS_TEST_MAIN(CheckMountedDirDoesNotExist)365*635a8641SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN(CheckMountedDirDoesNotExist) {
366*635a8641SAndroid Build Coastguard Worker   if (PathExists(base::FilePath("/foo"))) {
367*635a8641SAndroid Build Coastguard Worker     return 1;
368*635a8641SAndroid Build Coastguard Worker   }
369*635a8641SAndroid Build Coastguard Worker   WaitToDie(
370*635a8641SAndroid Build Coastguard Worker       ProcessUtilTest::GetSignalFilePath(kFooDirDoesNotHaveStaged).c_str());
371*635a8641SAndroid Build Coastguard Worker   return kSuccess;
372*635a8641SAndroid Build Coastguard Worker }
373*635a8641SAndroid Build Coastguard Worker 
TEST_F(ProcessUtilTest,TransferInvalidHandleFails)374*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, TransferInvalidHandleFails) {
375*635a8641SAndroid Build Coastguard Worker   LaunchOptions options;
376*635a8641SAndroid Build Coastguard Worker   options.paths_to_clone.push_back(base::FilePath("/tmp"));
377*635a8641SAndroid Build Coastguard Worker   options.paths_to_transfer.push_back(
378*635a8641SAndroid Build Coastguard Worker       {base::FilePath("/foo"), ZX_HANDLE_INVALID});
379*635a8641SAndroid Build Coastguard Worker   options.spawn_flags = FDIO_SPAWN_CLONE_STDIO;
380*635a8641SAndroid Build Coastguard Worker 
381*635a8641SAndroid Build Coastguard Worker   // Verify that the process is never constructed.
382*635a8641SAndroid Build Coastguard Worker   const std::string signal_file =
383*635a8641SAndroid Build Coastguard Worker       ProcessUtilTest::GetSignalFilePath(kFooDirDoesNotHaveStaged);
384*635a8641SAndroid Build Coastguard Worker   remove(signal_file.c_str());
385*635a8641SAndroid Build Coastguard Worker   Process process(
386*635a8641SAndroid Build Coastguard Worker       SpawnChildWithOptions("CheckMountedDirDoesNotExist", options));
387*635a8641SAndroid Build Coastguard Worker   ASSERT_FALSE(process.IsValid());
388*635a8641SAndroid Build Coastguard Worker }
389*635a8641SAndroid Build Coastguard Worker 
TEST_F(ProcessUtilTest,CloneInvalidDirFails)390*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, CloneInvalidDirFails) {
391*635a8641SAndroid Build Coastguard Worker   const std::string signal_file =
392*635a8641SAndroid Build Coastguard Worker       ProcessUtilTest::GetSignalFilePath(kSignalFileClone);
393*635a8641SAndroid Build Coastguard Worker   remove(signal_file.c_str());
394*635a8641SAndroid Build Coastguard Worker 
395*635a8641SAndroid Build Coastguard Worker   LaunchOptions options;
396*635a8641SAndroid Build Coastguard Worker   options.paths_to_clone.push_back(base::FilePath("/tmp"));
397*635a8641SAndroid Build Coastguard Worker   options.paths_to_clone.push_back(base::FilePath("/definitely_not_a_dir"));
398*635a8641SAndroid Build Coastguard Worker   options.spawn_flags = FDIO_SPAWN_CLONE_STDIO;
399*635a8641SAndroid Build Coastguard Worker 
400*635a8641SAndroid Build Coastguard Worker   Process process(SpawnChildWithOptions("CheckTmpFileExists", options));
401*635a8641SAndroid Build Coastguard Worker   ASSERT_FALSE(process.IsValid());
402*635a8641SAndroid Build Coastguard Worker }
403*635a8641SAndroid Build Coastguard Worker 
404*635a8641SAndroid Build Coastguard Worker // Test that we can clone other directories. CheckTmpFileExists will return an
405*635a8641SAndroid Build Coastguard Worker // error code if it detects a directory other than "/tmp", so we can use that as
406*635a8641SAndroid Build Coastguard Worker // a signal that it successfully detected another entry in the root namespace.
TEST_F(ProcessUtilTest,CloneAlternateDir)407*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, CloneAlternateDir) {
408*635a8641SAndroid Build Coastguard Worker   const std::string signal_file =
409*635a8641SAndroid Build Coastguard Worker       ProcessUtilTest::GetSignalFilePath(kSignalFileClone);
410*635a8641SAndroid Build Coastguard Worker   remove(signal_file.c_str());
411*635a8641SAndroid Build Coastguard Worker 
412*635a8641SAndroid Build Coastguard Worker   LaunchOptions options;
413*635a8641SAndroid Build Coastguard Worker   options.paths_to_clone.push_back(base::FilePath("/tmp"));
414*635a8641SAndroid Build Coastguard Worker   options.paths_to_clone.push_back(base::FilePath("/data"));
415*635a8641SAndroid Build Coastguard Worker   options.spawn_flags = FDIO_SPAWN_CLONE_STDIO;
416*635a8641SAndroid Build Coastguard Worker 
417*635a8641SAndroid Build Coastguard Worker   Process process(SpawnChildWithOptions("CheckTmpFileExists", options));
418*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(process.IsValid());
419*635a8641SAndroid Build Coastguard Worker 
420*635a8641SAndroid Build Coastguard Worker   SignalChildren(signal_file.c_str());
421*635a8641SAndroid Build Coastguard Worker 
422*635a8641SAndroid Build Coastguard Worker   int exit_code = 42;
423*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(process.WaitForExit(&exit_code));
424*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(1, exit_code);
425*635a8641SAndroid Build Coastguard Worker }
426*635a8641SAndroid Build Coastguard Worker 
TEST_F(ProcessUtilTest,HandlesToTransferClosedOnSpawnFailure)427*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, HandlesToTransferClosedOnSpawnFailure) {
428*635a8641SAndroid Build Coastguard Worker   zx::handle handles[2];
429*635a8641SAndroid Build Coastguard Worker   zx_status_t result = zx_channel_create(0, handles[0].reset_and_get_address(),
430*635a8641SAndroid Build Coastguard Worker                                          handles[1].reset_and_get_address());
431*635a8641SAndroid Build Coastguard Worker   ZX_CHECK(ZX_OK == result, result) << "zx_channel_create";
432*635a8641SAndroid Build Coastguard Worker 
433*635a8641SAndroid Build Coastguard Worker   LaunchOptions options;
434*635a8641SAndroid Build Coastguard Worker   options.handles_to_transfer.push_back({0, handles[0].get()});
435*635a8641SAndroid Build Coastguard Worker 
436*635a8641SAndroid Build Coastguard Worker   // Launch a non-existent binary, causing fdio_spawn() to fail.
437*635a8641SAndroid Build Coastguard Worker   CommandLine command_line(FilePath(
438*635a8641SAndroid Build Coastguard Worker       FILE_PATH_LITERAL("��magical_filename_that_will_never_exist_ever")));
439*635a8641SAndroid Build Coastguard Worker   Process process(LaunchProcess(command_line, options));
440*635a8641SAndroid Build Coastguard Worker   ASSERT_FALSE(process.IsValid());
441*635a8641SAndroid Build Coastguard Worker 
442*635a8641SAndroid Build Coastguard Worker   // If LaunchProcess did its job then handles[0] is no longer valid, and
443*635a8641SAndroid Build Coastguard Worker   // handles[1] should observe a channel-closed signal.
444*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(
445*635a8641SAndroid Build Coastguard Worker       zx_object_wait_one(handles[1].get(), ZX_CHANNEL_PEER_CLOSED, 0, nullptr),
446*635a8641SAndroid Build Coastguard Worker       ZX_OK);
447*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(ZX_ERR_BAD_HANDLE, zx_handle_close(handles[0].get()));
448*635a8641SAndroid Build Coastguard Worker   ignore_result(handles[0].release());
449*635a8641SAndroid Build Coastguard Worker }
450*635a8641SAndroid Build Coastguard Worker 
TEST_F(ProcessUtilTest,HandlesToTransferClosedOnBadPathToMapFailure)451*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, HandlesToTransferClosedOnBadPathToMapFailure) {
452*635a8641SAndroid Build Coastguard Worker   zx::handle handles[2];
453*635a8641SAndroid Build Coastguard Worker   zx_status_t result = zx_channel_create(0, handles[0].reset_and_get_address(),
454*635a8641SAndroid Build Coastguard Worker                                          handles[1].reset_and_get_address());
455*635a8641SAndroid Build Coastguard Worker   ZX_CHECK(ZX_OK == result, result) << "zx_channel_create";
456*635a8641SAndroid Build Coastguard Worker 
457*635a8641SAndroid Build Coastguard Worker   LaunchOptions options;
458*635a8641SAndroid Build Coastguard Worker   options.handles_to_transfer.push_back({0, handles[0].get()});
459*635a8641SAndroid Build Coastguard Worker   options.spawn_flags = options.spawn_flags & ~FDIO_SPAWN_CLONE_NAMESPACE;
460*635a8641SAndroid Build Coastguard Worker   options.paths_to_clone.emplace_back(
461*635a8641SAndroid Build Coastguard Worker       "��magical_path_that_will_never_exist_ever");
462*635a8641SAndroid Build Coastguard Worker 
463*635a8641SAndroid Build Coastguard Worker   // LaunchProces should fail to open() the path_to_map, and fail before
464*635a8641SAndroid Build Coastguard Worker   // fdio_spawn().
465*635a8641SAndroid Build Coastguard Worker   Process process(LaunchProcess(CommandLine(FilePath()), options));
466*635a8641SAndroid Build Coastguard Worker   ASSERT_FALSE(process.IsValid());
467*635a8641SAndroid Build Coastguard Worker 
468*635a8641SAndroid Build Coastguard Worker   // If LaunchProcess did its job then handles[0] is no longer valid, and
469*635a8641SAndroid Build Coastguard Worker   // handles[1] should observe a channel-closed signal.
470*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(
471*635a8641SAndroid Build Coastguard Worker       zx_object_wait_one(handles[1].get(), ZX_CHANNEL_PEER_CLOSED, 0, nullptr),
472*635a8641SAndroid Build Coastguard Worker       ZX_OK);
473*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(ZX_ERR_BAD_HANDLE, zx_handle_close(handles[0].get()));
474*635a8641SAndroid Build Coastguard Worker   ignore_result(handles[0].release());
475*635a8641SAndroid Build Coastguard Worker }
476*635a8641SAndroid Build Coastguard Worker #endif  // defined(OS_FUCHSIA)
477*635a8641SAndroid Build Coastguard Worker 
478*635a8641SAndroid Build Coastguard Worker // On Android SpawnProcess() doesn't use LaunchProcess() and doesn't support
479*635a8641SAndroid Build Coastguard Worker // LaunchOptions::current_directory.
480*635a8641SAndroid Build Coastguard Worker #if !defined(OS_ANDROID)
MULTIPROCESS_TEST_MAIN(CheckCwdProcess)481*635a8641SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN(CheckCwdProcess) {
482*635a8641SAndroid Build Coastguard Worker   FilePath expected;
483*635a8641SAndroid Build Coastguard Worker   CHECK(GetTempDir(&expected));
484*635a8641SAndroid Build Coastguard Worker   expected = MakeAbsoluteFilePath(expected);
485*635a8641SAndroid Build Coastguard Worker   CHECK(!expected.empty());
486*635a8641SAndroid Build Coastguard Worker 
487*635a8641SAndroid Build Coastguard Worker   FilePath actual;
488*635a8641SAndroid Build Coastguard Worker   CHECK(GetCurrentDirectory(&actual));
489*635a8641SAndroid Build Coastguard Worker   actual = MakeAbsoluteFilePath(actual);
490*635a8641SAndroid Build Coastguard Worker   CHECK(!actual.empty());
491*635a8641SAndroid Build Coastguard Worker 
492*635a8641SAndroid Build Coastguard Worker   CHECK(expected == actual) << "Expected: " << expected.value()
493*635a8641SAndroid Build Coastguard Worker                             << "  Actual: " << actual.value();
494*635a8641SAndroid Build Coastguard Worker   return kSuccess;
495*635a8641SAndroid Build Coastguard Worker }
496*635a8641SAndroid Build Coastguard Worker 
TEST_F(ProcessUtilTest,CurrentDirectory)497*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, CurrentDirectory) {
498*635a8641SAndroid Build Coastguard Worker   // TODO(rickyz): Add support for passing arguments to multiprocess children,
499*635a8641SAndroid Build Coastguard Worker   // then create a special directory for this test.
500*635a8641SAndroid Build Coastguard Worker   FilePath tmp_dir;
501*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(GetTempDir(&tmp_dir));
502*635a8641SAndroid Build Coastguard Worker 
503*635a8641SAndroid Build Coastguard Worker   LaunchOptions options;
504*635a8641SAndroid Build Coastguard Worker   options.current_directory = tmp_dir;
505*635a8641SAndroid Build Coastguard Worker 
506*635a8641SAndroid Build Coastguard Worker   Process process(SpawnChildWithOptions("CheckCwdProcess", options));
507*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(process.IsValid());
508*635a8641SAndroid Build Coastguard Worker 
509*635a8641SAndroid Build Coastguard Worker   int exit_code = 42;
510*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(process.WaitForExit(&exit_code));
511*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kSuccess, exit_code);
512*635a8641SAndroid Build Coastguard Worker }
513*635a8641SAndroid Build Coastguard Worker #endif  // !defined(OS_ANDROID)
514*635a8641SAndroid Build Coastguard Worker 
515*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
516*635a8641SAndroid Build Coastguard Worker // TODO(cpu): figure out how to test this in other platforms.
TEST_F(ProcessUtilTest,GetProcId)517*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, GetProcId) {
518*635a8641SAndroid Build Coastguard Worker   ProcessId id1 = GetProcId(GetCurrentProcess());
519*635a8641SAndroid Build Coastguard Worker   EXPECT_NE(0ul, id1);
520*635a8641SAndroid Build Coastguard Worker   Process process = SpawnChild("SimpleChildProcess");
521*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(process.IsValid());
522*635a8641SAndroid Build Coastguard Worker   ProcessId id2 = process.Pid();
523*635a8641SAndroid Build Coastguard Worker   EXPECT_NE(0ul, id2);
524*635a8641SAndroid Build Coastguard Worker   EXPECT_NE(id1, id2);
525*635a8641SAndroid Build Coastguard Worker }
526*635a8641SAndroid Build Coastguard Worker #endif  // defined(OS_WIN)
527*635a8641SAndroid Build Coastguard Worker 
528*635a8641SAndroid Build Coastguard Worker #if !defined(OS_MACOSX) && !defined(OS_ANDROID)
529*635a8641SAndroid Build Coastguard Worker // This test is disabled on Mac, since it's flaky due to ReportCrash
530*635a8641SAndroid Build Coastguard Worker // taking a variable amount of time to parse and load the debug and
531*635a8641SAndroid Build Coastguard Worker // symbol data for this unit test's executable before firing the
532*635a8641SAndroid Build Coastguard Worker // signal handler.
533*635a8641SAndroid Build Coastguard Worker //
534*635a8641SAndroid Build Coastguard Worker // TODO(gspencer): turn this test process into a very small program
535*635a8641SAndroid Build Coastguard Worker // with no symbols (instead of using the multiprocess testing
536*635a8641SAndroid Build Coastguard Worker // framework) to reduce the ReportCrash overhead.
537*635a8641SAndroid Build Coastguard Worker //
538*635a8641SAndroid Build Coastguard Worker // It is disabled on Android as MultiprocessTests are started as services that
539*635a8641SAndroid Build Coastguard Worker // the framework restarts on crashes.
540*635a8641SAndroid Build Coastguard Worker const char kSignalFileCrash[] = "CrashingChildProcess.die";
541*635a8641SAndroid Build Coastguard Worker 
MULTIPROCESS_TEST_MAIN(CrashingChildProcess)542*635a8641SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN(CrashingChildProcess) {
543*635a8641SAndroid Build Coastguard Worker   WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileCrash).c_str());
544*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX)
545*635a8641SAndroid Build Coastguard Worker   // Have to disable to signal handler for segv so we can get a crash
546*635a8641SAndroid Build Coastguard Worker   // instead of an abnormal termination through the crash dump handler.
547*635a8641SAndroid Build Coastguard Worker   ::signal(SIGSEGV, SIG_DFL);
548*635a8641SAndroid Build Coastguard Worker #endif
549*635a8641SAndroid Build Coastguard Worker   // Make this process have a segmentation fault.
550*635a8641SAndroid Build Coastguard Worker   volatile int* oops = nullptr;
551*635a8641SAndroid Build Coastguard Worker   *oops = 0xDEAD;
552*635a8641SAndroid Build Coastguard Worker   return 1;
553*635a8641SAndroid Build Coastguard Worker }
554*635a8641SAndroid Build Coastguard Worker 
555*635a8641SAndroid Build Coastguard Worker // This test intentionally crashes, so we don't need to run it under
556*635a8641SAndroid Build Coastguard Worker // AddressSanitizer.
557*635a8641SAndroid Build Coastguard Worker #if defined(ADDRESS_SANITIZER) || defined(OS_FUCHSIA)
558*635a8641SAndroid Build Coastguard Worker // TODO(crbug.com/753490): Access to the process termination reason is not
559*635a8641SAndroid Build Coastguard Worker // implemented in Fuchsia.
560*635a8641SAndroid Build Coastguard Worker #define MAYBE_GetTerminationStatusCrash DISABLED_GetTerminationStatusCrash
561*635a8641SAndroid Build Coastguard Worker #else
562*635a8641SAndroid Build Coastguard Worker #define MAYBE_GetTerminationStatusCrash GetTerminationStatusCrash
563*635a8641SAndroid Build Coastguard Worker #endif
TEST_F(ProcessUtilTest,MAYBE_GetTerminationStatusCrash)564*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, MAYBE_GetTerminationStatusCrash) {
565*635a8641SAndroid Build Coastguard Worker   const std::string signal_file =
566*635a8641SAndroid Build Coastguard Worker     ProcessUtilTest::GetSignalFilePath(kSignalFileCrash);
567*635a8641SAndroid Build Coastguard Worker   remove(signal_file.c_str());
568*635a8641SAndroid Build Coastguard Worker   Process process = SpawnChild("CrashingChildProcess");
569*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(process.IsValid());
570*635a8641SAndroid Build Coastguard Worker 
571*635a8641SAndroid Build Coastguard Worker   int exit_code = 42;
572*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(TERMINATION_STATUS_STILL_RUNNING,
573*635a8641SAndroid Build Coastguard Worker             GetTerminationStatus(process.Handle(), &exit_code));
574*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kExpectedStillRunningExitCode, exit_code);
575*635a8641SAndroid Build Coastguard Worker 
576*635a8641SAndroid Build Coastguard Worker   SignalChildren(signal_file.c_str());
577*635a8641SAndroid Build Coastguard Worker   exit_code = 42;
578*635a8641SAndroid Build Coastguard Worker   TerminationStatus status =
579*635a8641SAndroid Build Coastguard Worker       WaitForChildTermination(process.Handle(), &exit_code);
580*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(TERMINATION_STATUS_PROCESS_CRASHED, status);
581*635a8641SAndroid Build Coastguard Worker 
582*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
583*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(static_cast<int>(0xc0000005), exit_code);
584*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX)
585*635a8641SAndroid Build Coastguard Worker   int signaled = WIFSIGNALED(exit_code);
586*635a8641SAndroid Build Coastguard Worker   EXPECT_NE(0, signaled);
587*635a8641SAndroid Build Coastguard Worker   int signal = WTERMSIG(exit_code);
588*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(SIGSEGV, signal);
589*635a8641SAndroid Build Coastguard Worker #endif
590*635a8641SAndroid Build Coastguard Worker 
591*635a8641SAndroid Build Coastguard Worker   // Reset signal handlers back to "normal".
592*635a8641SAndroid Build Coastguard Worker   debug::EnableInProcessStackDumping();
593*635a8641SAndroid Build Coastguard Worker   remove(signal_file.c_str());
594*635a8641SAndroid Build Coastguard Worker }
595*635a8641SAndroid Build Coastguard Worker #endif  // !defined(OS_MACOSX) && !defined(OS_ANDROID)
596*635a8641SAndroid Build Coastguard Worker 
MULTIPROCESS_TEST_MAIN(KilledChildProcess)597*635a8641SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN(KilledChildProcess) {
598*635a8641SAndroid Build Coastguard Worker   WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileKill).c_str());
599*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
600*635a8641SAndroid Build Coastguard Worker   // Kill ourselves.
601*635a8641SAndroid Build Coastguard Worker   HANDLE handle = ::OpenProcess(PROCESS_ALL_ACCESS, 0, ::GetCurrentProcessId());
602*635a8641SAndroid Build Coastguard Worker   ::TerminateProcess(handle, kExpectedKilledExitCode);
603*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX)
604*635a8641SAndroid Build Coastguard Worker   // Send a SIGKILL to this process, just like the OOM killer would.
605*635a8641SAndroid Build Coastguard Worker   ::kill(getpid(), SIGKILL);
606*635a8641SAndroid Build Coastguard Worker #elif defined(OS_FUCHSIA)
607*635a8641SAndroid Build Coastguard Worker   zx_task_kill(zx_process_self());
608*635a8641SAndroid Build Coastguard Worker #endif
609*635a8641SAndroid Build Coastguard Worker   return 1;
610*635a8641SAndroid Build Coastguard Worker }
611*635a8641SAndroid Build Coastguard Worker 
612*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX)
MULTIPROCESS_TEST_MAIN(TerminatedChildProcess)613*635a8641SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN(TerminatedChildProcess) {
614*635a8641SAndroid Build Coastguard Worker   WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileTerm).c_str());
615*635a8641SAndroid Build Coastguard Worker   // Send a SIGTERM to this process.
616*635a8641SAndroid Build Coastguard Worker   ::kill(getpid(), SIGTERM);
617*635a8641SAndroid Build Coastguard Worker   return 1;
618*635a8641SAndroid Build Coastguard Worker }
619*635a8641SAndroid Build Coastguard Worker #endif  // defined(OS_POSIX) || defined(OS_FUCHSIA)
620*635a8641SAndroid Build Coastguard Worker 
621*635a8641SAndroid Build Coastguard Worker #if defined(OS_FUCHSIA)
622*635a8641SAndroid Build Coastguard Worker // TODO(crbug.com/753490): Access to the process termination reason is not
623*635a8641SAndroid Build Coastguard Worker // implemented in Fuchsia.
624*635a8641SAndroid Build Coastguard Worker #define MAYBE_GetTerminationStatusSigKill DISABLED_GetTerminationStatusSigKill
625*635a8641SAndroid Build Coastguard Worker #else
626*635a8641SAndroid Build Coastguard Worker #define MAYBE_GetTerminationStatusSigKill GetTerminationStatusSigKill
627*635a8641SAndroid Build Coastguard Worker #endif
TEST_F(ProcessUtilTest,MAYBE_GetTerminationStatusSigKill)628*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, MAYBE_GetTerminationStatusSigKill) {
629*635a8641SAndroid Build Coastguard Worker   const std::string signal_file =
630*635a8641SAndroid Build Coastguard Worker     ProcessUtilTest::GetSignalFilePath(kSignalFileKill);
631*635a8641SAndroid Build Coastguard Worker   remove(signal_file.c_str());
632*635a8641SAndroid Build Coastguard Worker   Process process = SpawnChild("KilledChildProcess");
633*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(process.IsValid());
634*635a8641SAndroid Build Coastguard Worker 
635*635a8641SAndroid Build Coastguard Worker   int exit_code = 42;
636*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(TERMINATION_STATUS_STILL_RUNNING,
637*635a8641SAndroid Build Coastguard Worker             GetTerminationStatus(process.Handle(), &exit_code));
638*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kExpectedStillRunningExitCode, exit_code);
639*635a8641SAndroid Build Coastguard Worker 
640*635a8641SAndroid Build Coastguard Worker   SignalChildren(signal_file.c_str());
641*635a8641SAndroid Build Coastguard Worker   exit_code = 42;
642*635a8641SAndroid Build Coastguard Worker   TerminationStatus status =
643*635a8641SAndroid Build Coastguard Worker       WaitForChildTermination(process.Handle(), &exit_code);
644*635a8641SAndroid Build Coastguard Worker #if defined(OS_CHROMEOS)
645*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM, status);
646*635a8641SAndroid Build Coastguard Worker #else
647*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(TERMINATION_STATUS_PROCESS_WAS_KILLED, status);
648*635a8641SAndroid Build Coastguard Worker #endif
649*635a8641SAndroid Build Coastguard Worker 
650*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
651*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kExpectedKilledExitCode, exit_code);
652*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX)
653*635a8641SAndroid Build Coastguard Worker   int signaled = WIFSIGNALED(exit_code);
654*635a8641SAndroid Build Coastguard Worker   EXPECT_NE(0, signaled);
655*635a8641SAndroid Build Coastguard Worker   int signal = WTERMSIG(exit_code);
656*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(SIGKILL, signal);
657*635a8641SAndroid Build Coastguard Worker #endif
658*635a8641SAndroid Build Coastguard Worker   remove(signal_file.c_str());
659*635a8641SAndroid Build Coastguard Worker }
660*635a8641SAndroid Build Coastguard Worker 
661*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX)
662*635a8641SAndroid Build Coastguard Worker // TODO(crbug.com/753490): Access to the process termination reason is not
663*635a8641SAndroid Build Coastguard Worker // implemented in Fuchsia. Unix signals are not implemented in Fuchsia so this
664*635a8641SAndroid Build Coastguard Worker // test might not be relevant anyway.
TEST_F(ProcessUtilTest,GetTerminationStatusSigTerm)665*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, GetTerminationStatusSigTerm) {
666*635a8641SAndroid Build Coastguard Worker   const std::string signal_file =
667*635a8641SAndroid Build Coastguard Worker     ProcessUtilTest::GetSignalFilePath(kSignalFileTerm);
668*635a8641SAndroid Build Coastguard Worker   remove(signal_file.c_str());
669*635a8641SAndroid Build Coastguard Worker   Process process = SpawnChild("TerminatedChildProcess");
670*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(process.IsValid());
671*635a8641SAndroid Build Coastguard Worker 
672*635a8641SAndroid Build Coastguard Worker   int exit_code = 42;
673*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(TERMINATION_STATUS_STILL_RUNNING,
674*635a8641SAndroid Build Coastguard Worker             GetTerminationStatus(process.Handle(), &exit_code));
675*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kExpectedStillRunningExitCode, exit_code);
676*635a8641SAndroid Build Coastguard Worker 
677*635a8641SAndroid Build Coastguard Worker   SignalChildren(signal_file.c_str());
678*635a8641SAndroid Build Coastguard Worker   exit_code = 42;
679*635a8641SAndroid Build Coastguard Worker   TerminationStatus status =
680*635a8641SAndroid Build Coastguard Worker       WaitForChildTermination(process.Handle(), &exit_code);
681*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(TERMINATION_STATUS_PROCESS_WAS_KILLED, status);
682*635a8641SAndroid Build Coastguard Worker 
683*635a8641SAndroid Build Coastguard Worker   int signaled = WIFSIGNALED(exit_code);
684*635a8641SAndroid Build Coastguard Worker   EXPECT_NE(0, signaled);
685*635a8641SAndroid Build Coastguard Worker   int signal = WTERMSIG(exit_code);
686*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(SIGTERM, signal);
687*635a8641SAndroid Build Coastguard Worker   remove(signal_file.c_str());
688*635a8641SAndroid Build Coastguard Worker }
689*635a8641SAndroid Build Coastguard Worker #endif  // defined(OS_POSIX)
690*635a8641SAndroid Build Coastguard Worker 
TEST_F(ProcessUtilTest,EnsureTerminationUndying)691*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, EnsureTerminationUndying) {
692*635a8641SAndroid Build Coastguard Worker   test::ScopedTaskEnvironment task_environment;
693*635a8641SAndroid Build Coastguard Worker 
694*635a8641SAndroid Build Coastguard Worker   Process child_process = SpawnChild("process_util_test_never_die");
695*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(child_process.IsValid());
696*635a8641SAndroid Build Coastguard Worker 
697*635a8641SAndroid Build Coastguard Worker   EnsureProcessTerminated(child_process.Duplicate());
698*635a8641SAndroid Build Coastguard Worker 
699*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX)
700*635a8641SAndroid Build Coastguard Worker   errno = 0;
701*635a8641SAndroid Build Coastguard Worker #endif  // defined(OS_POSIX)
702*635a8641SAndroid Build Coastguard Worker 
703*635a8641SAndroid Build Coastguard Worker   // Allow a generous timeout, to cope with slow/loaded test bots.
704*635a8641SAndroid Build Coastguard Worker   bool did_exit = child_process.WaitForExitWithTimeout(
705*635a8641SAndroid Build Coastguard Worker       TestTimeouts::action_max_timeout(), nullptr);
706*635a8641SAndroid Build Coastguard Worker 
707*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX)
708*635a8641SAndroid Build Coastguard Worker   // Both EnsureProcessTerminated() and WaitForExitWithTimeout() will call
709*635a8641SAndroid Build Coastguard Worker   // waitpid(). One will succeed, and the other will fail with ECHILD. If our
710*635a8641SAndroid Build Coastguard Worker   // wait failed then check for ECHILD, and assumed |did_exit| in that case.
711*635a8641SAndroid Build Coastguard Worker   did_exit = did_exit || (errno == ECHILD);
712*635a8641SAndroid Build Coastguard Worker #endif  // defined(OS_POSIX)
713*635a8641SAndroid Build Coastguard Worker 
714*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(did_exit);
715*635a8641SAndroid Build Coastguard Worker }
716*635a8641SAndroid Build Coastguard Worker 
MULTIPROCESS_TEST_MAIN(process_util_test_never_die)717*635a8641SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN(process_util_test_never_die) {
718*635a8641SAndroid Build Coastguard Worker   while (1) {
719*635a8641SAndroid Build Coastguard Worker     PlatformThread::Sleep(TimeDelta::FromSeconds(500));
720*635a8641SAndroid Build Coastguard Worker   }
721*635a8641SAndroid Build Coastguard Worker   return kSuccess;
722*635a8641SAndroid Build Coastguard Worker }
723*635a8641SAndroid Build Coastguard Worker 
TEST_F(ProcessUtilTest,EnsureTerminationGracefulExit)724*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, EnsureTerminationGracefulExit) {
725*635a8641SAndroid Build Coastguard Worker   test::ScopedTaskEnvironment task_environment;
726*635a8641SAndroid Build Coastguard Worker 
727*635a8641SAndroid Build Coastguard Worker   Process child_process = SpawnChild("process_util_test_die_immediately");
728*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(child_process.IsValid());
729*635a8641SAndroid Build Coastguard Worker 
730*635a8641SAndroid Build Coastguard Worker   // Wait for the child process to actually exit.
731*635a8641SAndroid Build Coastguard Worker   child_process.Duplicate().WaitForExitWithTimeout(
732*635a8641SAndroid Build Coastguard Worker       TestTimeouts::action_max_timeout(), nullptr);
733*635a8641SAndroid Build Coastguard Worker 
734*635a8641SAndroid Build Coastguard Worker   EnsureProcessTerminated(child_process.Duplicate());
735*635a8641SAndroid Build Coastguard Worker 
736*635a8641SAndroid Build Coastguard Worker   // Verify that the process is really, truly gone.
737*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(child_process.WaitForExitWithTimeout(
738*635a8641SAndroid Build Coastguard Worker       TestTimeouts::action_max_timeout(), nullptr));
739*635a8641SAndroid Build Coastguard Worker }
740*635a8641SAndroid Build Coastguard Worker 
MULTIPROCESS_TEST_MAIN(process_util_test_die_immediately)741*635a8641SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN(process_util_test_die_immediately) {
742*635a8641SAndroid Build Coastguard Worker   return kSuccess;
743*635a8641SAndroid Build Coastguard Worker }
744*635a8641SAndroid Build Coastguard Worker 
745*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
746*635a8641SAndroid Build Coastguard Worker // TODO(estade): if possible, port this test.
TEST_F(ProcessUtilTest,LaunchAsUser)747*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, LaunchAsUser) {
748*635a8641SAndroid Build Coastguard Worker   UserTokenHandle token;
749*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &token));
750*635a8641SAndroid Build Coastguard Worker   LaunchOptions options;
751*635a8641SAndroid Build Coastguard Worker   options.as_user = token;
752*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(
753*635a8641SAndroid Build Coastguard Worker       LaunchProcess(MakeCmdLine("SimpleChildProcess"), options).IsValid());
754*635a8641SAndroid Build Coastguard Worker }
755*635a8641SAndroid Build Coastguard Worker 
756*635a8641SAndroid Build Coastguard Worker static const char kEventToTriggerHandleSwitch[] = "event-to-trigger-handle";
757*635a8641SAndroid Build Coastguard Worker 
MULTIPROCESS_TEST_MAIN(TriggerEventChildProcess)758*635a8641SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN(TriggerEventChildProcess) {
759*635a8641SAndroid Build Coastguard Worker   std::string handle_value_string =
760*635a8641SAndroid Build Coastguard Worker       CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
761*635a8641SAndroid Build Coastguard Worker           kEventToTriggerHandleSwitch);
762*635a8641SAndroid Build Coastguard Worker   CHECK(!handle_value_string.empty());
763*635a8641SAndroid Build Coastguard Worker 
764*635a8641SAndroid Build Coastguard Worker   uint64_t handle_value_uint64;
765*635a8641SAndroid Build Coastguard Worker   CHECK(StringToUint64(handle_value_string, &handle_value_uint64));
766*635a8641SAndroid Build Coastguard Worker   // Give ownership of the handle to |event|.
767*635a8641SAndroid Build Coastguard Worker   WaitableEvent event(
768*635a8641SAndroid Build Coastguard Worker       win::ScopedHandle(reinterpret_cast<HANDLE>(handle_value_uint64)));
769*635a8641SAndroid Build Coastguard Worker 
770*635a8641SAndroid Build Coastguard Worker   event.Signal();
771*635a8641SAndroid Build Coastguard Worker 
772*635a8641SAndroid Build Coastguard Worker   return 0;
773*635a8641SAndroid Build Coastguard Worker }
774*635a8641SAndroid Build Coastguard Worker 
TEST_F(ProcessUtilTest,InheritSpecifiedHandles)775*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, InheritSpecifiedHandles) {
776*635a8641SAndroid Build Coastguard Worker   // Manually create the event, so that it can be inheritable.
777*635a8641SAndroid Build Coastguard Worker   SECURITY_ATTRIBUTES security_attributes = {};
778*635a8641SAndroid Build Coastguard Worker   security_attributes.nLength = static_cast<DWORD>(sizeof(security_attributes));
779*635a8641SAndroid Build Coastguard Worker   security_attributes.lpSecurityDescriptor = NULL;
780*635a8641SAndroid Build Coastguard Worker   security_attributes.bInheritHandle = true;
781*635a8641SAndroid Build Coastguard Worker 
782*635a8641SAndroid Build Coastguard Worker   // Takes ownership of the event handle.
783*635a8641SAndroid Build Coastguard Worker   WaitableEvent event(
784*635a8641SAndroid Build Coastguard Worker       win::ScopedHandle(CreateEvent(&security_attributes, true, false, NULL)));
785*635a8641SAndroid Build Coastguard Worker   LaunchOptions options;
786*635a8641SAndroid Build Coastguard Worker   options.handles_to_inherit.emplace_back(event.handle());
787*635a8641SAndroid Build Coastguard Worker 
788*635a8641SAndroid Build Coastguard Worker   CommandLine cmd_line = MakeCmdLine("TriggerEventChildProcess");
789*635a8641SAndroid Build Coastguard Worker   cmd_line.AppendSwitchASCII(
790*635a8641SAndroid Build Coastguard Worker       kEventToTriggerHandleSwitch,
791*635a8641SAndroid Build Coastguard Worker       NumberToString(reinterpret_cast<uint64_t>(event.handle())));
792*635a8641SAndroid Build Coastguard Worker 
793*635a8641SAndroid Build Coastguard Worker   // Launch the process and wait for it to trigger the event.
794*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(LaunchProcess(cmd_line, options).IsValid());
795*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(event.TimedWait(TestTimeouts::action_max_timeout()));
796*635a8641SAndroid Build Coastguard Worker }
797*635a8641SAndroid Build Coastguard Worker #endif  // defined(OS_WIN)
798*635a8641SAndroid Build Coastguard Worker 
TEST_F(ProcessUtilTest,GetAppOutput)799*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, GetAppOutput) {
800*635a8641SAndroid Build Coastguard Worker   base::CommandLine command(test_helper_path_);
801*635a8641SAndroid Build Coastguard Worker   command.AppendArg("hello");
802*635a8641SAndroid Build Coastguard Worker   command.AppendArg("there");
803*635a8641SAndroid Build Coastguard Worker   command.AppendArg("good");
804*635a8641SAndroid Build Coastguard Worker   command.AppendArg("people");
805*635a8641SAndroid Build Coastguard Worker   std::string output;
806*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(GetAppOutput(command, &output));
807*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("hello there good people", output);
808*635a8641SAndroid Build Coastguard Worker   output.clear();
809*635a8641SAndroid Build Coastguard Worker 
810*635a8641SAndroid Build Coastguard Worker   const char* kEchoMessage = "blah";
811*635a8641SAndroid Build Coastguard Worker   command = base::CommandLine(test_helper_path_);
812*635a8641SAndroid Build Coastguard Worker   command.AppendArg("-x");
813*635a8641SAndroid Build Coastguard Worker   command.AppendArg("28");
814*635a8641SAndroid Build Coastguard Worker   command.AppendArg(kEchoMessage);
815*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(GetAppOutput(command, &output));
816*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kEchoMessage, output);
817*635a8641SAndroid Build Coastguard Worker }
818*635a8641SAndroid Build Coastguard Worker 
TEST_F(ProcessUtilTest,GetAppOutputWithExitCode)819*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, GetAppOutputWithExitCode) {
820*635a8641SAndroid Build Coastguard Worker   const char* kEchoMessage1 = "doge";
821*635a8641SAndroid Build Coastguard Worker   int exit_code = -1;
822*635a8641SAndroid Build Coastguard Worker   base::CommandLine command(test_helper_path_);
823*635a8641SAndroid Build Coastguard Worker   command.AppendArg(kEchoMessage1);
824*635a8641SAndroid Build Coastguard Worker   std::string output;
825*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(GetAppOutputWithExitCode(command, &output, &exit_code));
826*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kEchoMessage1, output);
827*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0, exit_code);
828*635a8641SAndroid Build Coastguard Worker   output.clear();
829*635a8641SAndroid Build Coastguard Worker 
830*635a8641SAndroid Build Coastguard Worker   const char* kEchoMessage2 = "pupper";
831*635a8641SAndroid Build Coastguard Worker   const int kExpectedExitCode = 42;
832*635a8641SAndroid Build Coastguard Worker   command = base::CommandLine(test_helper_path_);
833*635a8641SAndroid Build Coastguard Worker   command.AppendArg("-x");
834*635a8641SAndroid Build Coastguard Worker   command.AppendArg(base::IntToString(kExpectedExitCode));
835*635a8641SAndroid Build Coastguard Worker   command.AppendArg(kEchoMessage2);
836*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
837*635a8641SAndroid Build Coastguard Worker   // On Windows, anything that quits with a nonzero status code is handled as a
838*635a8641SAndroid Build Coastguard Worker   // "crash", so just ignore GetAppOutputWithExitCode's return value.
839*635a8641SAndroid Build Coastguard Worker   GetAppOutputWithExitCode(command, &output, &exit_code);
840*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
841*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(GetAppOutputWithExitCode(command, &output, &exit_code));
842*635a8641SAndroid Build Coastguard Worker #endif
843*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kEchoMessage2, output);
844*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kExpectedExitCode, exit_code);
845*635a8641SAndroid Build Coastguard Worker }
846*635a8641SAndroid Build Coastguard Worker 
847*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX) || defined(OS_FUCHSIA)
848*635a8641SAndroid Build Coastguard Worker 
849*635a8641SAndroid Build Coastguard Worker namespace {
850*635a8641SAndroid Build Coastguard Worker 
851*635a8641SAndroid Build Coastguard Worker // Returns the maximum number of files that a process can have open.
852*635a8641SAndroid Build Coastguard Worker // Returns 0 on error.
GetMaxFilesOpenInProcess()853*635a8641SAndroid Build Coastguard Worker int GetMaxFilesOpenInProcess() {
854*635a8641SAndroid Build Coastguard Worker #if defined(OS_FUCHSIA)
855*635a8641SAndroid Build Coastguard Worker   return FDIO_MAX_FD;
856*635a8641SAndroid Build Coastguard Worker #else
857*635a8641SAndroid Build Coastguard Worker   struct rlimit rlim;
858*635a8641SAndroid Build Coastguard Worker   if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) {
859*635a8641SAndroid Build Coastguard Worker     return 0;
860*635a8641SAndroid Build Coastguard Worker   }
861*635a8641SAndroid Build Coastguard Worker 
862*635a8641SAndroid Build Coastguard Worker   // rlim_t is a uint64_t - clip to maxint. We do this since FD #s are ints
863*635a8641SAndroid Build Coastguard Worker   // which are all 32 bits on the supported platforms.
864*635a8641SAndroid Build Coastguard Worker   rlim_t max_int = static_cast<rlim_t>(std::numeric_limits<int32_t>::max());
865*635a8641SAndroid Build Coastguard Worker   if (rlim.rlim_cur > max_int) {
866*635a8641SAndroid Build Coastguard Worker     return max_int;
867*635a8641SAndroid Build Coastguard Worker   }
868*635a8641SAndroid Build Coastguard Worker 
869*635a8641SAndroid Build Coastguard Worker   return rlim.rlim_cur;
870*635a8641SAndroid Build Coastguard Worker #endif  // defined(OS_FUCHSIA)
871*635a8641SAndroid Build Coastguard Worker }
872*635a8641SAndroid Build Coastguard Worker 
873*635a8641SAndroid Build Coastguard Worker const int kChildPipe = 20;  // FD # for write end of pipe in child process.
874*635a8641SAndroid Build Coastguard Worker 
875*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX)
876*635a8641SAndroid Build Coastguard Worker 
877*635a8641SAndroid Build Coastguard Worker // <http://opensource.apple.com/source/xnu/xnu-2422.1.72/bsd/sys/guarded.h>
878*635a8641SAndroid Build Coastguard Worker #if !defined(_GUARDID_T)
879*635a8641SAndroid Build Coastguard Worker #define _GUARDID_T
880*635a8641SAndroid Build Coastguard Worker typedef __uint64_t guardid_t;
881*635a8641SAndroid Build Coastguard Worker #endif  // _GUARDID_T
882*635a8641SAndroid Build Coastguard Worker 
883*635a8641SAndroid Build Coastguard Worker // From .../MacOSX10.9.sdk/usr/include/sys/syscall.h
884*635a8641SAndroid Build Coastguard Worker #if !defined(SYS_change_fdguard_np)
885*635a8641SAndroid Build Coastguard Worker #define SYS_change_fdguard_np 444
886*635a8641SAndroid Build Coastguard Worker #endif
887*635a8641SAndroid Build Coastguard Worker 
888*635a8641SAndroid Build Coastguard Worker // <http://opensource.apple.com/source/xnu/xnu-2422.1.72/bsd/sys/guarded.h>
889*635a8641SAndroid Build Coastguard Worker #if !defined(GUARD_DUP)
890*635a8641SAndroid Build Coastguard Worker #define GUARD_DUP (1u << 1)
891*635a8641SAndroid Build Coastguard Worker #endif
892*635a8641SAndroid Build Coastguard Worker 
893*635a8641SAndroid Build Coastguard Worker // <http://opensource.apple.com/source/xnu/xnu-2422.1.72/bsd/kern/kern_guarded.c?txt>
894*635a8641SAndroid Build Coastguard Worker //
895*635a8641SAndroid Build Coastguard Worker // Atomically replaces |guard|/|guardflags| with |nguard|/|nguardflags| on |fd|.
change_fdguard_np(int fd,const guardid_t * guard,u_int guardflags,const guardid_t * nguard,u_int nguardflags,int * fdflagsp)896*635a8641SAndroid Build Coastguard Worker int change_fdguard_np(int fd,
897*635a8641SAndroid Build Coastguard Worker                       const guardid_t *guard, u_int guardflags,
898*635a8641SAndroid Build Coastguard Worker                       const guardid_t *nguard, u_int nguardflags,
899*635a8641SAndroid Build Coastguard Worker                       int *fdflagsp) {
900*635a8641SAndroid Build Coastguard Worker   return syscall(SYS_change_fdguard_np, fd, guard, guardflags,
901*635a8641SAndroid Build Coastguard Worker                  nguard, nguardflags, fdflagsp);
902*635a8641SAndroid Build Coastguard Worker }
903*635a8641SAndroid Build Coastguard Worker 
904*635a8641SAndroid Build Coastguard Worker // Attempt to set a file-descriptor guard on |fd|.  In case of success, remove
905*635a8641SAndroid Build Coastguard Worker // it and return |true| to indicate that it can be guarded.  Returning |false|
906*635a8641SAndroid Build Coastguard Worker // means either that |fd| is guarded by some other code, or more likely EBADF.
907*635a8641SAndroid Build Coastguard Worker //
908*635a8641SAndroid Build Coastguard Worker // Starting with 10.9, libdispatch began setting GUARD_DUP on a file descriptor.
909*635a8641SAndroid Build Coastguard Worker // Unfortunately, it is spun up as part of +[NSApplication initialize], which is
910*635a8641SAndroid Build Coastguard Worker // not really something that Chromium can avoid using on OSX.  See
911*635a8641SAndroid Build Coastguard Worker // <http://crbug.com/338157>.  This function allows querying whether the file
912*635a8641SAndroid Build Coastguard Worker // descriptor is guarded before attempting to close it.
CanGuardFd(int fd)913*635a8641SAndroid Build Coastguard Worker bool CanGuardFd(int fd) {
914*635a8641SAndroid Build Coastguard Worker   // Saves the original flags to reset later.
915*635a8641SAndroid Build Coastguard Worker   int original_fdflags = 0;
916*635a8641SAndroid Build Coastguard Worker 
917*635a8641SAndroid Build Coastguard Worker   // This can be any value at all, it just has to match up between the two
918*635a8641SAndroid Build Coastguard Worker   // calls.
919*635a8641SAndroid Build Coastguard Worker   const guardid_t kGuard = 15;
920*635a8641SAndroid Build Coastguard Worker 
921*635a8641SAndroid Build Coastguard Worker   // Attempt to change the guard.  This can fail with EBADF if the file
922*635a8641SAndroid Build Coastguard Worker   // descriptor is bad, or EINVAL if the fd already has a guard set.
923*635a8641SAndroid Build Coastguard Worker   int ret =
924*635a8641SAndroid Build Coastguard Worker       change_fdguard_np(fd, NULL, 0, &kGuard, GUARD_DUP, &original_fdflags);
925*635a8641SAndroid Build Coastguard Worker   if (ret == -1)
926*635a8641SAndroid Build Coastguard Worker     return false;
927*635a8641SAndroid Build Coastguard Worker 
928*635a8641SAndroid Build Coastguard Worker   // Remove the guard.  It should not be possible to fail in removing the guard
929*635a8641SAndroid Build Coastguard Worker   // just added.
930*635a8641SAndroid Build Coastguard Worker   ret = change_fdguard_np(fd, &kGuard, GUARD_DUP, NULL, 0, &original_fdflags);
931*635a8641SAndroid Build Coastguard Worker   DPCHECK(ret == 0);
932*635a8641SAndroid Build Coastguard Worker 
933*635a8641SAndroid Build Coastguard Worker   return true;
934*635a8641SAndroid Build Coastguard Worker }
935*635a8641SAndroid Build Coastguard Worker #endif  // defined(OS_MACOSX)
936*635a8641SAndroid Build Coastguard Worker 
937*635a8641SAndroid Build Coastguard Worker }  // namespace
938*635a8641SAndroid Build Coastguard Worker 
MULTIPROCESS_TEST_MAIN(ProcessUtilsLeakFDChildProcess)939*635a8641SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN(ProcessUtilsLeakFDChildProcess) {
940*635a8641SAndroid Build Coastguard Worker   // This child process counts the number of open FDs, it then writes that
941*635a8641SAndroid Build Coastguard Worker   // number out to a pipe connected to the parent.
942*635a8641SAndroid Build Coastguard Worker   int num_open_files = 0;
943*635a8641SAndroid Build Coastguard Worker   int write_pipe = kChildPipe;
944*635a8641SAndroid Build Coastguard Worker   int max_files = GetMaxFilesOpenInProcess();
945*635a8641SAndroid Build Coastguard Worker   for (int i = STDERR_FILENO + 1; i < max_files; i++) {
946*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX)
947*635a8641SAndroid Build Coastguard Worker     // Ignore guarded or invalid file descriptors.
948*635a8641SAndroid Build Coastguard Worker     if (!CanGuardFd(i))
949*635a8641SAndroid Build Coastguard Worker       continue;
950*635a8641SAndroid Build Coastguard Worker #endif
951*635a8641SAndroid Build Coastguard Worker 
952*635a8641SAndroid Build Coastguard Worker     if (i != kChildPipe) {
953*635a8641SAndroid Build Coastguard Worker       int fd;
954*635a8641SAndroid Build Coastguard Worker       if ((fd = HANDLE_EINTR(dup(i))) != -1) {
955*635a8641SAndroid Build Coastguard Worker         close(fd);
956*635a8641SAndroid Build Coastguard Worker         num_open_files += 1;
957*635a8641SAndroid Build Coastguard Worker       }
958*635a8641SAndroid Build Coastguard Worker     }
959*635a8641SAndroid Build Coastguard Worker   }
960*635a8641SAndroid Build Coastguard Worker 
961*635a8641SAndroid Build Coastguard Worker   int written = HANDLE_EINTR(write(write_pipe, &num_open_files,
962*635a8641SAndroid Build Coastguard Worker                                    sizeof(num_open_files)));
963*635a8641SAndroid Build Coastguard Worker   DCHECK_EQ(static_cast<size_t>(written), sizeof(num_open_files));
964*635a8641SAndroid Build Coastguard Worker   int ret = IGNORE_EINTR(close(write_pipe));
965*635a8641SAndroid Build Coastguard Worker   DPCHECK(ret == 0);
966*635a8641SAndroid Build Coastguard Worker 
967*635a8641SAndroid Build Coastguard Worker   return 0;
968*635a8641SAndroid Build Coastguard Worker }
969*635a8641SAndroid Build Coastguard Worker 
CountOpenFDsInChild()970*635a8641SAndroid Build Coastguard Worker int ProcessUtilTest::CountOpenFDsInChild() {
971*635a8641SAndroid Build Coastguard Worker   int fds[2];
972*635a8641SAndroid Build Coastguard Worker   if (pipe(fds) < 0)
973*635a8641SAndroid Build Coastguard Worker     NOTREACHED();
974*635a8641SAndroid Build Coastguard Worker 
975*635a8641SAndroid Build Coastguard Worker   LaunchOptions options;
976*635a8641SAndroid Build Coastguard Worker   options.fds_to_remap.emplace_back(fds[1], kChildPipe);
977*635a8641SAndroid Build Coastguard Worker   Process process =
978*635a8641SAndroid Build Coastguard Worker       SpawnChildWithOptions("ProcessUtilsLeakFDChildProcess", options);
979*635a8641SAndroid Build Coastguard Worker   CHECK(process.IsValid());
980*635a8641SAndroid Build Coastguard Worker   int ret = IGNORE_EINTR(close(fds[1]));
981*635a8641SAndroid Build Coastguard Worker   DPCHECK(ret == 0);
982*635a8641SAndroid Build Coastguard Worker 
983*635a8641SAndroid Build Coastguard Worker   // Read number of open files in client process from pipe;
984*635a8641SAndroid Build Coastguard Worker   int num_open_files = -1;
985*635a8641SAndroid Build Coastguard Worker   ssize_t bytes_read =
986*635a8641SAndroid Build Coastguard Worker       HANDLE_EINTR(read(fds[0], &num_open_files, sizeof(num_open_files)));
987*635a8641SAndroid Build Coastguard Worker   CHECK_EQ(bytes_read, static_cast<ssize_t>(sizeof(num_open_files)));
988*635a8641SAndroid Build Coastguard Worker 
989*635a8641SAndroid Build Coastguard Worker #if defined(THREAD_SANITIZER)
990*635a8641SAndroid Build Coastguard Worker   // Compiler-based ThreadSanitizer makes this test slow.
991*635a8641SAndroid Build Coastguard Worker   TimeDelta timeout = TimeDelta::FromSeconds(3);
992*635a8641SAndroid Build Coastguard Worker #else
993*635a8641SAndroid Build Coastguard Worker   TimeDelta timeout = TimeDelta::FromSeconds(1);
994*635a8641SAndroid Build Coastguard Worker #endif
995*635a8641SAndroid Build Coastguard Worker   int exit_code;
996*635a8641SAndroid Build Coastguard Worker   CHECK(process.WaitForExitWithTimeout(timeout, &exit_code));
997*635a8641SAndroid Build Coastguard Worker   ret = IGNORE_EINTR(close(fds[0]));
998*635a8641SAndroid Build Coastguard Worker   DPCHECK(ret == 0);
999*635a8641SAndroid Build Coastguard Worker 
1000*635a8641SAndroid Build Coastguard Worker   return num_open_files;
1001*635a8641SAndroid Build Coastguard Worker }
1002*635a8641SAndroid Build Coastguard Worker 
1003*635a8641SAndroid Build Coastguard Worker #if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER)
1004*635a8641SAndroid Build Coastguard Worker // ProcessUtilTest.FDRemapping is flaky when ran under xvfb-run on Precise.
1005*635a8641SAndroid Build Coastguard Worker // The problem is 100% reproducible with both ASan and TSan.
1006*635a8641SAndroid Build Coastguard Worker // See http://crbug.com/136720.
1007*635a8641SAndroid Build Coastguard Worker #define MAYBE_FDRemapping DISABLED_FDRemapping
1008*635a8641SAndroid Build Coastguard Worker #else
1009*635a8641SAndroid Build Coastguard Worker #define MAYBE_FDRemapping FDRemapping
1010*635a8641SAndroid Build Coastguard Worker #endif  // defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER)
TEST_F(ProcessUtilTest,MAYBE_FDRemapping)1011*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, MAYBE_FDRemapping) {
1012*635a8641SAndroid Build Coastguard Worker   int fds_before = CountOpenFDsInChild();
1013*635a8641SAndroid Build Coastguard Worker 
1014*635a8641SAndroid Build Coastguard Worker   // open some dummy fds to make sure they don't propagate over to the
1015*635a8641SAndroid Build Coastguard Worker   // child process.
1016*635a8641SAndroid Build Coastguard Worker   int dev_null = open("/dev/null", O_RDONLY);
1017*635a8641SAndroid Build Coastguard Worker   DPCHECK(dev_null != -1);
1018*635a8641SAndroid Build Coastguard Worker   int sockets[2];
1019*635a8641SAndroid Build Coastguard Worker   int ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sockets);
1020*635a8641SAndroid Build Coastguard Worker   DPCHECK(ret == 0);
1021*635a8641SAndroid Build Coastguard Worker 
1022*635a8641SAndroid Build Coastguard Worker   int fds_after = CountOpenFDsInChild();
1023*635a8641SAndroid Build Coastguard Worker 
1024*635a8641SAndroid Build Coastguard Worker   ASSERT_EQ(fds_after, fds_before);
1025*635a8641SAndroid Build Coastguard Worker 
1026*635a8641SAndroid Build Coastguard Worker   ret = IGNORE_EINTR(close(sockets[0]));
1027*635a8641SAndroid Build Coastguard Worker   DPCHECK(ret == 0);
1028*635a8641SAndroid Build Coastguard Worker   ret = IGNORE_EINTR(close(sockets[1]));
1029*635a8641SAndroid Build Coastguard Worker   DPCHECK(ret == 0);
1030*635a8641SAndroid Build Coastguard Worker   ret = IGNORE_EINTR(close(dev_null));
1031*635a8641SAndroid Build Coastguard Worker   DPCHECK(ret == 0);
1032*635a8641SAndroid Build Coastguard Worker }
1033*635a8641SAndroid Build Coastguard Worker 
1034*635a8641SAndroid Build Coastguard Worker const char kPipeValue = '\xcc';
MULTIPROCESS_TEST_MAIN(ProcessUtilsVerifyStdio)1035*635a8641SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN(ProcessUtilsVerifyStdio) {
1036*635a8641SAndroid Build Coastguard Worker   // Write to stdio so the parent process can observe output.
1037*635a8641SAndroid Build Coastguard Worker   CHECK_EQ(1, HANDLE_EINTR(write(STDOUT_FILENO, &kPipeValue, 1)));
1038*635a8641SAndroid Build Coastguard Worker 
1039*635a8641SAndroid Build Coastguard Worker   // Close all of the handles, to verify they are valid.
1040*635a8641SAndroid Build Coastguard Worker   CHECK_EQ(0, IGNORE_EINTR(close(STDIN_FILENO)));
1041*635a8641SAndroid Build Coastguard Worker   CHECK_EQ(0, IGNORE_EINTR(close(STDOUT_FILENO)));
1042*635a8641SAndroid Build Coastguard Worker   CHECK_EQ(0, IGNORE_EINTR(close(STDERR_FILENO)));
1043*635a8641SAndroid Build Coastguard Worker   return 0;
1044*635a8641SAndroid Build Coastguard Worker }
1045*635a8641SAndroid Build Coastguard Worker 
TEST_F(ProcessUtilTest,FDRemappingIncludesStdio)1046*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, FDRemappingIncludesStdio) {
1047*635a8641SAndroid Build Coastguard Worker   int dev_null = open("/dev/null", O_RDONLY);
1048*635a8641SAndroid Build Coastguard Worker   ASSERT_LT(2, dev_null);
1049*635a8641SAndroid Build Coastguard Worker 
1050*635a8641SAndroid Build Coastguard Worker   // Backup stdio and replace it with the write end of a pipe, for our
1051*635a8641SAndroid Build Coastguard Worker   // child process to inherit.
1052*635a8641SAndroid Build Coastguard Worker   int pipe_fds[2];
1053*635a8641SAndroid Build Coastguard Worker   int result = pipe(pipe_fds);
1054*635a8641SAndroid Build Coastguard Worker   ASSERT_EQ(0, result);
1055*635a8641SAndroid Build Coastguard Worker   int backup_stdio = HANDLE_EINTR(dup(STDOUT_FILENO));
1056*635a8641SAndroid Build Coastguard Worker   ASSERT_LE(0, backup_stdio);
1057*635a8641SAndroid Build Coastguard Worker   result = dup2(pipe_fds[1], STDOUT_FILENO);
1058*635a8641SAndroid Build Coastguard Worker   ASSERT_EQ(STDOUT_FILENO, result);
1059*635a8641SAndroid Build Coastguard Worker 
1060*635a8641SAndroid Build Coastguard Worker   // Launch the test process, which should inherit our pipe stdio.
1061*635a8641SAndroid Build Coastguard Worker   LaunchOptions options;
1062*635a8641SAndroid Build Coastguard Worker   options.fds_to_remap.emplace_back(dev_null, dev_null);
1063*635a8641SAndroid Build Coastguard Worker   Process process = SpawnChildWithOptions("ProcessUtilsVerifyStdio", options);
1064*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(process.IsValid());
1065*635a8641SAndroid Build Coastguard Worker 
1066*635a8641SAndroid Build Coastguard Worker   // Restore stdio, so we can output stuff.
1067*635a8641SAndroid Build Coastguard Worker   result = dup2(backup_stdio, STDOUT_FILENO);
1068*635a8641SAndroid Build Coastguard Worker   ASSERT_EQ(STDOUT_FILENO, result);
1069*635a8641SAndroid Build Coastguard Worker 
1070*635a8641SAndroid Build Coastguard Worker   // Close our copy of the write end of the pipe, so that the read()
1071*635a8641SAndroid Build Coastguard Worker   // from the other end will see EOF if it wasn't copied to the child.
1072*635a8641SAndroid Build Coastguard Worker   result = IGNORE_EINTR(close(pipe_fds[1]));
1073*635a8641SAndroid Build Coastguard Worker   ASSERT_EQ(0, result);
1074*635a8641SAndroid Build Coastguard Worker 
1075*635a8641SAndroid Build Coastguard Worker   result = IGNORE_EINTR(close(backup_stdio));
1076*635a8641SAndroid Build Coastguard Worker   ASSERT_EQ(0, result);
1077*635a8641SAndroid Build Coastguard Worker   result = IGNORE_EINTR(close(dev_null));
1078*635a8641SAndroid Build Coastguard Worker   ASSERT_EQ(0, result);
1079*635a8641SAndroid Build Coastguard Worker 
1080*635a8641SAndroid Build Coastguard Worker   // Read from the pipe to verify that it is connected to the child
1081*635a8641SAndroid Build Coastguard Worker   // process' stdio.
1082*635a8641SAndroid Build Coastguard Worker   char buf[16] = {};
1083*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(1, HANDLE_EINTR(read(pipe_fds[0], buf, sizeof(buf))));
1084*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kPipeValue, buf[0]);
1085*635a8641SAndroid Build Coastguard Worker 
1086*635a8641SAndroid Build Coastguard Worker   result = IGNORE_EINTR(close(pipe_fds[0]));
1087*635a8641SAndroid Build Coastguard Worker   ASSERT_EQ(0, result);
1088*635a8641SAndroid Build Coastguard Worker 
1089*635a8641SAndroid Build Coastguard Worker   int exit_code;
1090*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(
1091*635a8641SAndroid Build Coastguard Worker       process.WaitForExitWithTimeout(TimeDelta::FromSeconds(5), &exit_code));
1092*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0, exit_code);
1093*635a8641SAndroid Build Coastguard Worker }
1094*635a8641SAndroid Build Coastguard Worker 
1095*635a8641SAndroid Build Coastguard Worker #if defined(OS_FUCHSIA)
1096*635a8641SAndroid Build Coastguard Worker 
1097*635a8641SAndroid Build Coastguard Worker const uint16_t kStartupHandleId = 43;
MULTIPROCESS_TEST_MAIN(ProcessUtilsVerifyHandle)1098*635a8641SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN(ProcessUtilsVerifyHandle) {
1099*635a8641SAndroid Build Coastguard Worker   zx_handle_t handle =
1100*635a8641SAndroid Build Coastguard Worker       zx_take_startup_handle(PA_HND(PA_USER0, kStartupHandleId));
1101*635a8641SAndroid Build Coastguard Worker   CHECK_NE(ZX_HANDLE_INVALID, handle);
1102*635a8641SAndroid Build Coastguard Worker 
1103*635a8641SAndroid Build Coastguard Worker   // Write to the pipe so the parent process can observe output.
1104*635a8641SAndroid Build Coastguard Worker   size_t bytes_written = 0;
1105*635a8641SAndroid Build Coastguard Worker   zx_status_t result = zx_socket_write(handle, 0, &kPipeValue,
1106*635a8641SAndroid Build Coastguard Worker                                        sizeof(kPipeValue), &bytes_written);
1107*635a8641SAndroid Build Coastguard Worker   CHECK_EQ(ZX_OK, result);
1108*635a8641SAndroid Build Coastguard Worker   CHECK_EQ(1u, bytes_written);
1109*635a8641SAndroid Build Coastguard Worker 
1110*635a8641SAndroid Build Coastguard Worker   CHECK_EQ(ZX_OK, zx_handle_close(handle));
1111*635a8641SAndroid Build Coastguard Worker   return 0;
1112*635a8641SAndroid Build Coastguard Worker }
1113*635a8641SAndroid Build Coastguard Worker 
TEST_F(ProcessUtilTest,LaunchWithHandleTransfer)1114*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, LaunchWithHandleTransfer) {
1115*635a8641SAndroid Build Coastguard Worker   // Create a pipe to pass to the child process.
1116*635a8641SAndroid Build Coastguard Worker   zx_handle_t handles[2];
1117*635a8641SAndroid Build Coastguard Worker   zx_status_t result =
1118*635a8641SAndroid Build Coastguard Worker       zx_socket_create(ZX_SOCKET_STREAM, &handles[0], &handles[1]);
1119*635a8641SAndroid Build Coastguard Worker   ASSERT_EQ(ZX_OK, result);
1120*635a8641SAndroid Build Coastguard Worker 
1121*635a8641SAndroid Build Coastguard Worker   // Launch the test process, and pass it one end of the pipe.
1122*635a8641SAndroid Build Coastguard Worker   LaunchOptions options;
1123*635a8641SAndroid Build Coastguard Worker   options.handles_to_transfer.push_back(
1124*635a8641SAndroid Build Coastguard Worker       {PA_HND(PA_USER0, kStartupHandleId), handles[0]});
1125*635a8641SAndroid Build Coastguard Worker   Process process = SpawnChildWithOptions("ProcessUtilsVerifyHandle", options);
1126*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(process.IsValid());
1127*635a8641SAndroid Build Coastguard Worker 
1128*635a8641SAndroid Build Coastguard Worker   // Read from the pipe to verify that the child received it.
1129*635a8641SAndroid Build Coastguard Worker   zx_signals_t signals = 0;
1130*635a8641SAndroid Build Coastguard Worker   result = zx_object_wait_one(
1131*635a8641SAndroid Build Coastguard Worker       handles[1], ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED,
1132*635a8641SAndroid Build Coastguard Worker       (base::TimeTicks::Now() + TestTimeouts::action_timeout()).ToZxTime(),
1133*635a8641SAndroid Build Coastguard Worker       &signals);
1134*635a8641SAndroid Build Coastguard Worker   ASSERT_EQ(ZX_OK, result);
1135*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(signals & ZX_SOCKET_READABLE);
1136*635a8641SAndroid Build Coastguard Worker 
1137*635a8641SAndroid Build Coastguard Worker   size_t bytes_read = 0;
1138*635a8641SAndroid Build Coastguard Worker   char buf[16] = {0};
1139*635a8641SAndroid Build Coastguard Worker   result = zx_socket_read(handles[1], 0, buf, sizeof(buf), &bytes_read);
1140*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(ZX_OK, result);
1141*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(1u, bytes_read);
1142*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kPipeValue, buf[0]);
1143*635a8641SAndroid Build Coastguard Worker 
1144*635a8641SAndroid Build Coastguard Worker   CHECK_EQ(ZX_OK, zx_handle_close(handles[1]));
1145*635a8641SAndroid Build Coastguard Worker 
1146*635a8641SAndroid Build Coastguard Worker   int exit_code;
1147*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(process.WaitForExitWithTimeout(TestTimeouts::action_timeout(),
1148*635a8641SAndroid Build Coastguard Worker                                              &exit_code));
1149*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0, exit_code);
1150*635a8641SAndroid Build Coastguard Worker }
1151*635a8641SAndroid Build Coastguard Worker 
1152*635a8641SAndroid Build Coastguard Worker #endif  // defined(OS_FUCHSIA)
1153*635a8641SAndroid Build Coastguard Worker 
1154*635a8641SAndroid Build Coastguard Worker namespace {
1155*635a8641SAndroid Build Coastguard Worker 
TestLaunchProcess(const std::vector<std::string> & args,const EnvironmentMap & env_changes,const bool clear_environ,const int clone_flags)1156*635a8641SAndroid Build Coastguard Worker std::string TestLaunchProcess(const std::vector<std::string>& args,
1157*635a8641SAndroid Build Coastguard Worker                               const EnvironmentMap& env_changes,
1158*635a8641SAndroid Build Coastguard Worker                               const bool clear_environ,
1159*635a8641SAndroid Build Coastguard Worker                               const int clone_flags) {
1160*635a8641SAndroid Build Coastguard Worker   int fds[2];
1161*635a8641SAndroid Build Coastguard Worker   PCHECK(pipe(fds) == 0);
1162*635a8641SAndroid Build Coastguard Worker 
1163*635a8641SAndroid Build Coastguard Worker   LaunchOptions options;
1164*635a8641SAndroid Build Coastguard Worker   options.wait = true;
1165*635a8641SAndroid Build Coastguard Worker   options.environ = env_changes;
1166*635a8641SAndroid Build Coastguard Worker   options.clear_environ = clear_environ;
1167*635a8641SAndroid Build Coastguard Worker   options.fds_to_remap.emplace_back(fds[1], 1);
1168*635a8641SAndroid Build Coastguard Worker #if defined(OS_LINUX)
1169*635a8641SAndroid Build Coastguard Worker   options.clone_flags = clone_flags;
1170*635a8641SAndroid Build Coastguard Worker #else
1171*635a8641SAndroid Build Coastguard Worker   CHECK_EQ(0, clone_flags);
1172*635a8641SAndroid Build Coastguard Worker #endif  // defined(OS_LINUX)
1173*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(LaunchProcess(args, options).IsValid());
1174*635a8641SAndroid Build Coastguard Worker   PCHECK(IGNORE_EINTR(close(fds[1])) == 0);
1175*635a8641SAndroid Build Coastguard Worker 
1176*635a8641SAndroid Build Coastguard Worker   char buf[512];
1177*635a8641SAndroid Build Coastguard Worker   const ssize_t n = HANDLE_EINTR(read(fds[0], buf, sizeof(buf)));
1178*635a8641SAndroid Build Coastguard Worker 
1179*635a8641SAndroid Build Coastguard Worker   PCHECK(IGNORE_EINTR(close(fds[0])) == 0);
1180*635a8641SAndroid Build Coastguard Worker 
1181*635a8641SAndroid Build Coastguard Worker   return std::string(buf, n);
1182*635a8641SAndroid Build Coastguard Worker }
1183*635a8641SAndroid Build Coastguard Worker 
1184*635a8641SAndroid Build Coastguard Worker const char kLargeString[] =
1185*635a8641SAndroid Build Coastguard Worker     "0123456789012345678901234567890123456789012345678901234567890123456789"
1186*635a8641SAndroid Build Coastguard Worker     "0123456789012345678901234567890123456789012345678901234567890123456789"
1187*635a8641SAndroid Build Coastguard Worker     "0123456789012345678901234567890123456789012345678901234567890123456789"
1188*635a8641SAndroid Build Coastguard Worker     "0123456789012345678901234567890123456789012345678901234567890123456789"
1189*635a8641SAndroid Build Coastguard Worker     "0123456789012345678901234567890123456789012345678901234567890123456789"
1190*635a8641SAndroid Build Coastguard Worker     "0123456789012345678901234567890123456789012345678901234567890123456789"
1191*635a8641SAndroid Build Coastguard Worker     "0123456789012345678901234567890123456789012345678901234567890123456789";
1192*635a8641SAndroid Build Coastguard Worker 
1193*635a8641SAndroid Build Coastguard Worker }  // namespace
1194*635a8641SAndroid Build Coastguard Worker 
TEST_F(ProcessUtilTest,LaunchProcess)1195*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, LaunchProcess) {
1196*635a8641SAndroid Build Coastguard Worker   const int no_clone_flags = 0;
1197*635a8641SAndroid Build Coastguard Worker   const bool no_clear_environ = false;
1198*635a8641SAndroid Build Coastguard Worker   const char kBaseTest[] = "BASE_TEST";
1199*635a8641SAndroid Build Coastguard Worker   const std::vector<std::string> kPrintEnvCommand = {test_helper_path_.value(),
1200*635a8641SAndroid Build Coastguard Worker                                                      "-e", kBaseTest};
1201*635a8641SAndroid Build Coastguard Worker 
1202*635a8641SAndroid Build Coastguard Worker   EnvironmentMap env_changes;
1203*635a8641SAndroid Build Coastguard Worker   env_changes[kBaseTest] = "bar";
1204*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("bar", TestLaunchProcess(kPrintEnvCommand, env_changes,
1205*635a8641SAndroid Build Coastguard Worker                                      no_clear_environ, no_clone_flags));
1206*635a8641SAndroid Build Coastguard Worker   env_changes.clear();
1207*635a8641SAndroid Build Coastguard Worker 
1208*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0, setenv(kBaseTest, "testing", 1 /* override */));
1209*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("testing", TestLaunchProcess(kPrintEnvCommand, env_changes,
1210*635a8641SAndroid Build Coastguard Worker                                          no_clear_environ, no_clone_flags));
1211*635a8641SAndroid Build Coastguard Worker 
1212*635a8641SAndroid Build Coastguard Worker   env_changes[kBaseTest] = std::string();
1213*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("", TestLaunchProcess(kPrintEnvCommand, env_changes,
1214*635a8641SAndroid Build Coastguard Worker                                   no_clear_environ, no_clone_flags));
1215*635a8641SAndroid Build Coastguard Worker 
1216*635a8641SAndroid Build Coastguard Worker   env_changes[kBaseTest] = "foo";
1217*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("foo", TestLaunchProcess(kPrintEnvCommand, env_changes,
1218*635a8641SAndroid Build Coastguard Worker                                      no_clear_environ, no_clone_flags));
1219*635a8641SAndroid Build Coastguard Worker 
1220*635a8641SAndroid Build Coastguard Worker   env_changes.clear();
1221*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0, setenv(kBaseTest, kLargeString, 1 /* override */));
1222*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(std::string(kLargeString),
1223*635a8641SAndroid Build Coastguard Worker             TestLaunchProcess(kPrintEnvCommand, env_changes, no_clear_environ,
1224*635a8641SAndroid Build Coastguard Worker                               no_clone_flags));
1225*635a8641SAndroid Build Coastguard Worker 
1226*635a8641SAndroid Build Coastguard Worker   env_changes[kBaseTest] = "wibble";
1227*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("wibble", TestLaunchProcess(kPrintEnvCommand, env_changes,
1228*635a8641SAndroid Build Coastguard Worker                                         no_clear_environ, no_clone_flags));
1229*635a8641SAndroid Build Coastguard Worker 
1230*635a8641SAndroid Build Coastguard Worker #if defined(OS_LINUX)
1231*635a8641SAndroid Build Coastguard Worker   // Test a non-trival value for clone_flags.
1232*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("wibble", TestLaunchProcess(kPrintEnvCommand, env_changes,
1233*635a8641SAndroid Build Coastguard Worker                                         no_clear_environ, CLONE_FS));
1234*635a8641SAndroid Build Coastguard Worker 
1235*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("wibble",
1236*635a8641SAndroid Build Coastguard Worker             TestLaunchProcess(kPrintEnvCommand, env_changes,
1237*635a8641SAndroid Build Coastguard Worker                               true /* clear_environ */, no_clone_flags));
1238*635a8641SAndroid Build Coastguard Worker   env_changes.clear();
1239*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("", TestLaunchProcess(kPrintEnvCommand, env_changes,
1240*635a8641SAndroid Build Coastguard Worker                                   true /* clear_environ */, no_clone_flags));
1241*635a8641SAndroid Build Coastguard Worker #endif  // defined(OS_LINUX)
1242*635a8641SAndroid Build Coastguard Worker }
1243*635a8641SAndroid Build Coastguard Worker 
1244*635a8641SAndroid Build Coastguard Worker // There's no such thing as a parent process id on Fuchsia.
1245*635a8641SAndroid Build Coastguard Worker #if !defined(OS_FUCHSIA)
TEST_F(ProcessUtilTest,GetParentProcessId)1246*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, GetParentProcessId) {
1247*635a8641SAndroid Build Coastguard Worker   ProcessId ppid = GetParentProcessId(GetCurrentProcessHandle());
1248*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(ppid, static_cast<ProcessId>(getppid()));
1249*635a8641SAndroid Build Coastguard Worker }
1250*635a8641SAndroid Build Coastguard Worker #endif  // !defined(OS_FUCHSIA)
1251*635a8641SAndroid Build Coastguard Worker 
1252*635a8641SAndroid Build Coastguard Worker #if !defined(OS_ANDROID) && !defined(OS_FUCHSIA)
1253*635a8641SAndroid Build Coastguard Worker class WriteToPipeDelegate : public LaunchOptions::PreExecDelegate {
1254*635a8641SAndroid Build Coastguard Worker  public:
WriteToPipeDelegate(int fd)1255*635a8641SAndroid Build Coastguard Worker   explicit WriteToPipeDelegate(int fd) : fd_(fd) {}
1256*635a8641SAndroid Build Coastguard Worker   ~WriteToPipeDelegate() override = default;
RunAsyncSafe()1257*635a8641SAndroid Build Coastguard Worker   void RunAsyncSafe() override {
1258*635a8641SAndroid Build Coastguard Worker     RAW_CHECK(HANDLE_EINTR(write(fd_, &kPipeValue, 1)) == 1);
1259*635a8641SAndroid Build Coastguard Worker     RAW_CHECK(IGNORE_EINTR(close(fd_)) == 0);
1260*635a8641SAndroid Build Coastguard Worker   }
1261*635a8641SAndroid Build Coastguard Worker 
1262*635a8641SAndroid Build Coastguard Worker  private:
1263*635a8641SAndroid Build Coastguard Worker   int fd_;
1264*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(WriteToPipeDelegate);
1265*635a8641SAndroid Build Coastguard Worker };
1266*635a8641SAndroid Build Coastguard Worker 
TEST_F(ProcessUtilTest,PreExecHook)1267*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, PreExecHook) {
1268*635a8641SAndroid Build Coastguard Worker   int pipe_fds[2];
1269*635a8641SAndroid Build Coastguard Worker   ASSERT_EQ(0, pipe(pipe_fds));
1270*635a8641SAndroid Build Coastguard Worker 
1271*635a8641SAndroid Build Coastguard Worker   ScopedFD read_fd(pipe_fds[0]);
1272*635a8641SAndroid Build Coastguard Worker   ScopedFD write_fd(pipe_fds[1]);
1273*635a8641SAndroid Build Coastguard Worker 
1274*635a8641SAndroid Build Coastguard Worker   WriteToPipeDelegate write_to_pipe_delegate(write_fd.get());
1275*635a8641SAndroid Build Coastguard Worker   LaunchOptions options;
1276*635a8641SAndroid Build Coastguard Worker   options.fds_to_remap.emplace_back(write_fd.get(), write_fd.get());
1277*635a8641SAndroid Build Coastguard Worker   options.pre_exec_delegate = &write_to_pipe_delegate;
1278*635a8641SAndroid Build Coastguard Worker   Process process(SpawnChildWithOptions("SimpleChildProcess", options));
1279*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(process.IsValid());
1280*635a8641SAndroid Build Coastguard Worker 
1281*635a8641SAndroid Build Coastguard Worker   write_fd.reset();
1282*635a8641SAndroid Build Coastguard Worker   char c;
1283*635a8641SAndroid Build Coastguard Worker   ASSERT_EQ(1, HANDLE_EINTR(read(read_fd.get(), &c, 1)));
1284*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(c, kPipeValue);
1285*635a8641SAndroid Build Coastguard Worker 
1286*635a8641SAndroid Build Coastguard Worker   int exit_code = 42;
1287*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(process.WaitForExit(&exit_code));
1288*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0, exit_code);
1289*635a8641SAndroid Build Coastguard Worker }
1290*635a8641SAndroid Build Coastguard Worker #endif  // !defined(OS_ANDROID) && !defined(OS_FUCHSIA)
1291*635a8641SAndroid Build Coastguard Worker 
1292*635a8641SAndroid Build Coastguard Worker #endif  // !defined(OS_MACOSX) && !defined(OS_ANDROID)
1293*635a8641SAndroid Build Coastguard Worker 
1294*635a8641SAndroid Build Coastguard Worker #if defined(OS_LINUX)
MULTIPROCESS_TEST_MAIN(CheckPidProcess)1295*635a8641SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN(CheckPidProcess) {
1296*635a8641SAndroid Build Coastguard Worker   const pid_t kInitPid = 1;
1297*635a8641SAndroid Build Coastguard Worker   const pid_t pid = syscall(__NR_getpid);
1298*635a8641SAndroid Build Coastguard Worker   CHECK(pid == kInitPid);
1299*635a8641SAndroid Build Coastguard Worker   CHECK(getpid() == pid);
1300*635a8641SAndroid Build Coastguard Worker   return kSuccess;
1301*635a8641SAndroid Build Coastguard Worker }
1302*635a8641SAndroid Build Coastguard Worker 
1303*635a8641SAndroid Build Coastguard Worker #if defined(CLONE_NEWUSER) && defined(CLONE_NEWPID)
TEST_F(ProcessUtilTest,CloneFlags)1304*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, CloneFlags) {
1305*635a8641SAndroid Build Coastguard Worker   if (!PathExists(FilePath("/proc/self/ns/user")) ||
1306*635a8641SAndroid Build Coastguard Worker       !PathExists(FilePath("/proc/self/ns/pid"))) {
1307*635a8641SAndroid Build Coastguard Worker     // User or PID namespaces are not supported.
1308*635a8641SAndroid Build Coastguard Worker     return;
1309*635a8641SAndroid Build Coastguard Worker   }
1310*635a8641SAndroid Build Coastguard Worker 
1311*635a8641SAndroid Build Coastguard Worker   LaunchOptions options;
1312*635a8641SAndroid Build Coastguard Worker   options.clone_flags = CLONE_NEWUSER | CLONE_NEWPID;
1313*635a8641SAndroid Build Coastguard Worker 
1314*635a8641SAndroid Build Coastguard Worker   Process process(SpawnChildWithOptions("CheckPidProcess", options));
1315*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(process.IsValid());
1316*635a8641SAndroid Build Coastguard Worker 
1317*635a8641SAndroid Build Coastguard Worker   int exit_code = 42;
1318*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(process.WaitForExit(&exit_code));
1319*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kSuccess, exit_code);
1320*635a8641SAndroid Build Coastguard Worker }
1321*635a8641SAndroid Build Coastguard Worker #endif  // defined(CLONE_NEWUSER) && defined(CLONE_NEWPID)
1322*635a8641SAndroid Build Coastguard Worker 
TEST(ForkWithFlagsTest,UpdatesPidCache)1323*635a8641SAndroid Build Coastguard Worker TEST(ForkWithFlagsTest, UpdatesPidCache) {
1324*635a8641SAndroid Build Coastguard Worker   // Warm up the libc pid cache, if there is one.
1325*635a8641SAndroid Build Coastguard Worker   ASSERT_EQ(syscall(__NR_getpid), getpid());
1326*635a8641SAndroid Build Coastguard Worker 
1327*635a8641SAndroid Build Coastguard Worker   pid_t ctid = 0;
1328*635a8641SAndroid Build Coastguard Worker   const pid_t pid = ForkWithFlags(SIGCHLD | CLONE_CHILD_SETTID, nullptr, &ctid);
1329*635a8641SAndroid Build Coastguard Worker   if (pid == 0) {
1330*635a8641SAndroid Build Coastguard Worker     // In child.  Check both the raw getpid syscall and the libc getpid wrapper
1331*635a8641SAndroid Build Coastguard Worker     // (which may rely on a pid cache).
1332*635a8641SAndroid Build Coastguard Worker     RAW_CHECK(syscall(__NR_getpid) == ctid);
1333*635a8641SAndroid Build Coastguard Worker     RAW_CHECK(getpid() == ctid);
1334*635a8641SAndroid Build Coastguard Worker     _exit(kSuccess);
1335*635a8641SAndroid Build Coastguard Worker   }
1336*635a8641SAndroid Build Coastguard Worker 
1337*635a8641SAndroid Build Coastguard Worker   ASSERT_NE(-1, pid);
1338*635a8641SAndroid Build Coastguard Worker   int status = 42;
1339*635a8641SAndroid Build Coastguard Worker   ASSERT_EQ(pid, HANDLE_EINTR(waitpid(pid, &status, 0)));
1340*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(WIFEXITED(status));
1341*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kSuccess, WEXITSTATUS(status));
1342*635a8641SAndroid Build Coastguard Worker }
1343*635a8641SAndroid Build Coastguard Worker 
TEST_F(ProcessUtilTest,InvalidCurrentDirectory)1344*635a8641SAndroid Build Coastguard Worker TEST_F(ProcessUtilTest, InvalidCurrentDirectory) {
1345*635a8641SAndroid Build Coastguard Worker   LaunchOptions options;
1346*635a8641SAndroid Build Coastguard Worker   options.current_directory = FilePath("/dev/null");
1347*635a8641SAndroid Build Coastguard Worker 
1348*635a8641SAndroid Build Coastguard Worker   Process process(SpawnChildWithOptions("SimpleChildProcess", options));
1349*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(process.IsValid());
1350*635a8641SAndroid Build Coastguard Worker 
1351*635a8641SAndroid Build Coastguard Worker   int exit_code = kSuccess;
1352*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(process.WaitForExit(&exit_code));
1353*635a8641SAndroid Build Coastguard Worker   EXPECT_NE(kSuccess, exit_code);
1354*635a8641SAndroid Build Coastguard Worker }
1355*635a8641SAndroid Build Coastguard Worker #endif  // defined(OS_LINUX)
1356*635a8641SAndroid Build Coastguard Worker 
1357*635a8641SAndroid Build Coastguard Worker }  // namespace base
1358