Home | History | Annotate | Download | only in process
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #define _CRT_SECURE_NO_WARNINGS
      6 
      7 #include <limits>
      8 
      9 #include "base/command_line.h"
     10 #include "base/debug/alias.h"
     11 #include "base/debug/stack_trace.h"
     12 #include "base/files/file_path.h"
     13 #include "base/logging.h"
     14 #include "base/memory/scoped_ptr.h"
     15 #include "base/path_service.h"
     16 #include "base/posix/eintr_wrapper.h"
     17 #include "base/process/kill.h"
     18 #include "base/process/launch.h"
     19 #include "base/process/memory.h"
     20 #include "base/process/process.h"
     21 #include "base/process/process_metrics.h"
     22 #include "base/strings/string_number_conversions.h"
     23 #include "base/strings/utf_string_conversions.h"
     24 #include "base/synchronization/waitable_event.h"
     25 #include "base/test/multiprocess_test.h"
     26 #include "base/test/test_timeouts.h"
     27 #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
     28 #include "base/threading/platform_thread.h"
     29 #include "base/threading/thread.h"
     30 #include "testing/gtest/include/gtest/gtest.h"
     31 #include "testing/multiprocess_func_list.h"
     32 
     33 #if defined(OS_LINUX)
     34 #include <malloc.h>
     35 #include <sched.h>
     36 #endif
     37 #if defined(OS_POSIX)
     38 #include <dlfcn.h>
     39 #include <errno.h>
     40 #include <fcntl.h>
     41 #include <signal.h>
     42 #include <sys/resource.h>
     43 #include <sys/socket.h>
     44 #include <sys/wait.h>
     45 #endif
     46 #if defined(OS_WIN)
     47 #include <windows.h>
     48 #include "base/win/windows_version.h"
     49 #endif
     50 #if defined(OS_MACOSX)
     51 #include <mach/vm_param.h>
     52 #include <malloc/malloc.h>
     53 #include "base/mac/mac_util.h"
     54 #endif
     55 
     56 using base::FilePath;
     57 
     58 namespace {
     59 
     60 #if defined(OS_ANDROID)
     61 const char kShellPath[] = "/system/bin/sh";
     62 const char kPosixShell[] = "sh";
     63 #else
     64 const char kShellPath[] = "/bin/sh";
     65 const char kPosixShell[] = "bash";
     66 #endif
     67 
     68 const char kSignalFileSlow[] = "SlowChildProcess.die";
     69 const char kSignalFileKill[] = "KilledChildProcess.die";
     70 
     71 #if defined(OS_WIN)
     72 const int kExpectedStillRunningExitCode = 0x102;
     73 const int kExpectedKilledExitCode = 1;
     74 #else
     75 const int kExpectedStillRunningExitCode = 0;
     76 #endif
     77 
     78 // Sleeps until file filename is created.
     79 void WaitToDie(const char* filename) {
     80   FILE* fp;
     81   do {
     82     base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
     83     fp = fopen(filename, "r");
     84   } while (!fp);
     85   fclose(fp);
     86 }
     87 
     88 // Signals children they should die now.
     89 void SignalChildren(const char* filename) {
     90   FILE* fp = fopen(filename, "w");
     91   fclose(fp);
     92 }
     93 
     94 // Using a pipe to the child to wait for an event was considered, but
     95 // there were cases in the past where pipes caused problems (other
     96 // libraries closing the fds, child deadlocking). This is a simple
     97 // case, so it's not worth the risk.  Using wait loops is discouraged
     98 // in most instances.
     99 base::TerminationStatus WaitForChildTermination(base::ProcessHandle handle,
    100                                                 int* exit_code) {
    101   // Now we wait until the result is something other than STILL_RUNNING.
    102   base::TerminationStatus status = base::TERMINATION_STATUS_STILL_RUNNING;
    103   const base::TimeDelta kInterval = base::TimeDelta::FromMilliseconds(20);
    104   base::TimeDelta waited;
    105   do {
    106     status = base::GetTerminationStatus(handle, exit_code);
    107     base::PlatformThread::Sleep(kInterval);
    108     waited += kInterval;
    109   } while (status == base::TERMINATION_STATUS_STILL_RUNNING &&
    110            waited < TestTimeouts::action_max_timeout());
    111 
    112   return status;
    113 }
    114 
    115 }  // namespace
    116 
    117 class ProcessUtilTest : public base::MultiProcessTest {
    118  public:
    119 #if defined(OS_POSIX)
    120   // Spawn a child process that counts how many file descriptors are open.
    121   int CountOpenFDsInChild();
    122 #endif
    123   // Converts the filename to a platform specific filepath.
    124   // On Android files can not be created in arbitrary directories.
    125   static std::string GetSignalFilePath(const char* filename);
    126 };
    127 
    128 std::string ProcessUtilTest::GetSignalFilePath(const char* filename) {
    129 #if !defined(OS_ANDROID)
    130   return filename;
    131 #else
    132   FilePath tmp_dir;
    133   PathService::Get(base::DIR_CACHE, &tmp_dir);
    134   tmp_dir = tmp_dir.Append(filename);
    135   return tmp_dir.value();
    136 #endif
    137 }
    138 
    139 MULTIPROCESS_TEST_MAIN(SimpleChildProcess) {
    140   return 0;
    141 }
    142 
    143 // TODO(viettrungluu): This should be in a "MultiProcessTestTest".
    144 TEST_F(ProcessUtilTest, SpawnChild) {
    145   base::ProcessHandle handle = SpawnChild("SimpleChildProcess");
    146   ASSERT_NE(base::kNullProcessHandle, handle);
    147   EXPECT_TRUE(base::WaitForSingleProcess(
    148                   handle, TestTimeouts::action_max_timeout()));
    149   base::CloseProcessHandle(handle);
    150 }
    151 
    152 MULTIPROCESS_TEST_MAIN(SlowChildProcess) {
    153   WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileSlow).c_str());
    154   return 0;
    155 }
    156 
    157 TEST_F(ProcessUtilTest, KillSlowChild) {
    158   const std::string signal_file =
    159       ProcessUtilTest::GetSignalFilePath(kSignalFileSlow);
    160   remove(signal_file.c_str());
    161   base::ProcessHandle handle = SpawnChild("SlowChildProcess");
    162   ASSERT_NE(base::kNullProcessHandle, handle);
    163   SignalChildren(signal_file.c_str());
    164   EXPECT_TRUE(base::WaitForSingleProcess(
    165                   handle, TestTimeouts::action_max_timeout()));
    166   base::CloseProcessHandle(handle);
    167   remove(signal_file.c_str());
    168 }
    169 
    170 // Times out on Linux and Win, flakes on other platforms, http://crbug.com/95058
    171 TEST_F(ProcessUtilTest, DISABLED_GetTerminationStatusExit) {
    172   const std::string signal_file =
    173       ProcessUtilTest::GetSignalFilePath(kSignalFileSlow);
    174   remove(signal_file.c_str());
    175   base::ProcessHandle handle = SpawnChild("SlowChildProcess");
    176   ASSERT_NE(base::kNullProcessHandle, handle);
    177 
    178   int exit_code = 42;
    179   EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING,
    180             base::GetTerminationStatus(handle, &exit_code));
    181   EXPECT_EQ(kExpectedStillRunningExitCode, exit_code);
    182 
    183   SignalChildren(signal_file.c_str());
    184   exit_code = 42;
    185   base::TerminationStatus status =
    186       WaitForChildTermination(handle, &exit_code);
    187   EXPECT_EQ(base::TERMINATION_STATUS_NORMAL_TERMINATION, status);
    188   EXPECT_EQ(0, exit_code);
    189   base::CloseProcessHandle(handle);
    190   remove(signal_file.c_str());
    191 }
    192 
    193 #if defined(OS_WIN)
    194 // TODO(cpu): figure out how to test this in other platforms.
    195 TEST_F(ProcessUtilTest, GetProcId) {
    196   base::ProcessId id1 = base::GetProcId(GetCurrentProcess());
    197   EXPECT_NE(0ul, id1);
    198   base::ProcessHandle handle = SpawnChild("SimpleChildProcess");
    199   ASSERT_NE(base::kNullProcessHandle, handle);
    200   base::ProcessId id2 = base::GetProcId(handle);
    201   EXPECT_NE(0ul, id2);
    202   EXPECT_NE(id1, id2);
    203   base::CloseProcessHandle(handle);
    204 }
    205 #endif
    206 
    207 #if !defined(OS_MACOSX)
    208 // This test is disabled on Mac, since it's flaky due to ReportCrash
    209 // taking a variable amount of time to parse and load the debug and
    210 // symbol data for this unit test's executable before firing the
    211 // signal handler.
    212 //
    213 // TODO(gspencer): turn this test process into a very small program
    214 // with no symbols (instead of using the multiprocess testing
    215 // framework) to reduce the ReportCrash overhead.
    216 const char kSignalFileCrash[] = "CrashingChildProcess.die";
    217 
    218 MULTIPROCESS_TEST_MAIN(CrashingChildProcess) {
    219   WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileCrash).c_str());
    220 #if defined(OS_POSIX)
    221   // Have to disable to signal handler for segv so we can get a crash
    222   // instead of an abnormal termination through the crash dump handler.
    223   ::signal(SIGSEGV, SIG_DFL);
    224 #endif
    225   // Make this process have a segmentation fault.
    226   volatile int* oops = NULL;
    227   *oops = 0xDEAD;
    228   return 1;
    229 }
    230 
    231 // This test intentionally crashes, so we don't need to run it under
    232 // AddressSanitizer.
    233 #if defined(ADDRESS_SANITIZER) || defined(SYZYASAN)
    234 #define MAYBE_GetTerminationStatusCrash DISABLED_GetTerminationStatusCrash
    235 #else
    236 #define MAYBE_GetTerminationStatusCrash GetTerminationStatusCrash
    237 #endif
    238 TEST_F(ProcessUtilTest, MAYBE_GetTerminationStatusCrash) {
    239   const std::string signal_file =
    240     ProcessUtilTest::GetSignalFilePath(kSignalFileCrash);
    241   remove(signal_file.c_str());
    242   base::ProcessHandle handle = SpawnChild("CrashingChildProcess");
    243   ASSERT_NE(base::kNullProcessHandle, handle);
    244 
    245   int exit_code = 42;
    246   EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING,
    247             base::GetTerminationStatus(handle, &exit_code));
    248   EXPECT_EQ(kExpectedStillRunningExitCode, exit_code);
    249 
    250   SignalChildren(signal_file.c_str());
    251   exit_code = 42;
    252   base::TerminationStatus status =
    253       WaitForChildTermination(handle, &exit_code);
    254   EXPECT_EQ(base::TERMINATION_STATUS_PROCESS_CRASHED, status);
    255 
    256 #if defined(OS_WIN)
    257   EXPECT_EQ(0xc0000005, exit_code);
    258 #elif defined(OS_POSIX)
    259   int signaled = WIFSIGNALED(exit_code);
    260   EXPECT_NE(0, signaled);
    261   int signal = WTERMSIG(exit_code);
    262   EXPECT_EQ(SIGSEGV, signal);
    263 #endif
    264   base::CloseProcessHandle(handle);
    265 
    266   // Reset signal handlers back to "normal".
    267   base::debug::EnableInProcessStackDumping();
    268   remove(signal_file.c_str());
    269 }
    270 #endif  // !defined(OS_MACOSX)
    271 
    272 MULTIPROCESS_TEST_MAIN(KilledChildProcess) {
    273   WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileKill).c_str());
    274 #if defined(OS_WIN)
    275   // Kill ourselves.
    276   HANDLE handle = ::OpenProcess(PROCESS_ALL_ACCESS, 0, ::GetCurrentProcessId());
    277   ::TerminateProcess(handle, kExpectedKilledExitCode);
    278 #elif defined(OS_POSIX)
    279   // Send a SIGKILL to this process, just like the OOM killer would.
    280   ::kill(getpid(), SIGKILL);
    281 #endif
    282   return 1;
    283 }
    284 
    285 TEST_F(ProcessUtilTest, GetTerminationStatusKill) {
    286   const std::string signal_file =
    287     ProcessUtilTest::GetSignalFilePath(kSignalFileKill);
    288   remove(signal_file.c_str());
    289   base::ProcessHandle handle = SpawnChild("KilledChildProcess");
    290   ASSERT_NE(base::kNullProcessHandle, handle);
    291 
    292   int exit_code = 42;
    293   EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING,
    294             base::GetTerminationStatus(handle, &exit_code));
    295   EXPECT_EQ(kExpectedStillRunningExitCode, exit_code);
    296 
    297   SignalChildren(signal_file.c_str());
    298   exit_code = 42;
    299   base::TerminationStatus status =
    300       WaitForChildTermination(handle, &exit_code);
    301   EXPECT_EQ(base::TERMINATION_STATUS_PROCESS_WAS_KILLED, status);
    302 #if defined(OS_WIN)
    303   EXPECT_EQ(kExpectedKilledExitCode, exit_code);
    304 #elif defined(OS_POSIX)
    305   int signaled = WIFSIGNALED(exit_code);
    306   EXPECT_NE(0, signaled);
    307   int signal = WTERMSIG(exit_code);
    308   EXPECT_EQ(SIGKILL, signal);
    309 #endif
    310   base::CloseProcessHandle(handle);
    311   remove(signal_file.c_str());
    312 }
    313 
    314 // Ensure that the priority of a process is restored correctly after
    315 // backgrounding and restoring.
    316 // Note: a platform may not be willing or able to lower the priority of
    317 // a process. The calls to SetProcessBackground should be noops then.
    318 TEST_F(ProcessUtilTest, SetProcessBackgrounded) {
    319   base::ProcessHandle handle = SpawnChild("SimpleChildProcess");
    320   base::Process process(handle);
    321   int old_priority = process.GetPriority();
    322 #if defined(OS_WIN)
    323   EXPECT_TRUE(process.SetProcessBackgrounded(true));
    324   EXPECT_TRUE(process.IsProcessBackgrounded());
    325   EXPECT_TRUE(process.SetProcessBackgrounded(false));
    326   EXPECT_FALSE(process.IsProcessBackgrounded());
    327 #else
    328   process.SetProcessBackgrounded(true);
    329   process.SetProcessBackgrounded(false);
    330 #endif
    331   int new_priority = process.GetPriority();
    332   EXPECT_EQ(old_priority, new_priority);
    333 }
    334 
    335 // Same as SetProcessBackgrounded but to this very process. It uses
    336 // a different code path at least for Windows.
    337 TEST_F(ProcessUtilTest, SetProcessBackgroundedSelf) {
    338   base::Process process(base::Process::Current().handle());
    339   int old_priority = process.GetPriority();
    340 #if defined(OS_WIN)
    341   EXPECT_TRUE(process.SetProcessBackgrounded(true));
    342   EXPECT_TRUE(process.IsProcessBackgrounded());
    343   EXPECT_TRUE(process.SetProcessBackgrounded(false));
    344   EXPECT_FALSE(process.IsProcessBackgrounded());
    345 #else
    346   process.SetProcessBackgrounded(true);
    347   process.SetProcessBackgrounded(false);
    348 #endif
    349   int new_priority = process.GetPriority();
    350   EXPECT_EQ(old_priority, new_priority);
    351 }
    352 
    353 #if defined(OS_WIN)
    354 // TODO(estade): if possible, port this test.
    355 TEST_F(ProcessUtilTest, GetAppOutput) {
    356   // Let's create a decently long message.
    357   std::string message;
    358   for (int i = 0; i < 1025; i++) {  // 1025 so it does not end on a kilo-byte
    359                                     // boundary.
    360     message += "Hello!";
    361   }
    362   // cmd.exe's echo always adds a \r\n to its output.
    363   std::string expected(message);
    364   expected += "\r\n";
    365 
    366   FilePath cmd(L"cmd.exe");
    367   CommandLine cmd_line(cmd);
    368   cmd_line.AppendArg("/c");
    369   cmd_line.AppendArg("echo " + message + "");
    370   std::string output;
    371   ASSERT_TRUE(base::GetAppOutput(cmd_line, &output));
    372   EXPECT_EQ(expected, output);
    373 
    374   // Let's make sure stderr is ignored.
    375   CommandLine other_cmd_line(cmd);
    376   other_cmd_line.AppendArg("/c");
    377   // http://msdn.microsoft.com/library/cc772622.aspx
    378   cmd_line.AppendArg("echo " + message + " >&2");
    379   output.clear();
    380   ASSERT_TRUE(base::GetAppOutput(other_cmd_line, &output));
    381   EXPECT_EQ("", output);
    382 }
    383 
    384 // TODO(estade): if possible, port this test.
    385 TEST_F(ProcessUtilTest, LaunchAsUser) {
    386   base::UserTokenHandle token;
    387   ASSERT_TRUE(OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &token));
    388   base::LaunchOptions options;
    389   options.as_user = token;
    390   EXPECT_TRUE(base::LaunchProcess(MakeCmdLine("SimpleChildProcess"), options,
    391                                   NULL));
    392 }
    393 
    394 static const char kEventToTriggerHandleSwitch[] = "event-to-trigger-handle";
    395 
    396 MULTIPROCESS_TEST_MAIN(TriggerEventChildProcess) {
    397   std::string handle_value_string =
    398       CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
    399           kEventToTriggerHandleSwitch);
    400   CHECK(!handle_value_string.empty());
    401 
    402   uint64 handle_value_uint64;
    403   CHECK(base::StringToUint64(handle_value_string, &handle_value_uint64));
    404   // Give ownership of the handle to |event|.
    405   base::WaitableEvent event(reinterpret_cast<HANDLE>(handle_value_uint64));
    406 
    407   event.Signal();
    408 
    409   return 0;
    410 }
    411 
    412 TEST_F(ProcessUtilTest, InheritSpecifiedHandles) {
    413   // Manually create the event, so that it can be inheritable.
    414   SECURITY_ATTRIBUTES security_attributes = {};
    415   security_attributes.nLength = static_cast<DWORD>(sizeof(security_attributes));
    416   security_attributes.lpSecurityDescriptor = NULL;
    417   security_attributes.bInheritHandle = true;
    418 
    419   // Takes ownership of the event handle.
    420   base::WaitableEvent event(
    421       CreateEvent(&security_attributes, true, false, NULL));
    422   base::HandlesToInheritVector handles_to_inherit;
    423   handles_to_inherit.push_back(event.handle());
    424   base::LaunchOptions options;
    425   options.handles_to_inherit = &handles_to_inherit;
    426 
    427   CommandLine cmd_line = MakeCmdLine("TriggerEventChildProcess");
    428   cmd_line.AppendSwitchASCII(kEventToTriggerHandleSwitch,
    429       base::Uint64ToString(reinterpret_cast<uint64>(event.handle())));
    430 
    431   // This functionality actually requires Vista or later. Make sure that it
    432   // fails properly on XP.
    433   if (base::win::GetVersion() < base::win::VERSION_VISTA) {
    434     EXPECT_FALSE(base::LaunchProcess(cmd_line, options, NULL));
    435     return;
    436   }
    437 
    438   // Launch the process and wait for it to trigger the event.
    439   ASSERT_TRUE(base::LaunchProcess(cmd_line, options, NULL));
    440   EXPECT_TRUE(event.TimedWait(TestTimeouts::action_max_timeout()));
    441 }
    442 #endif  // defined(OS_WIN)
    443 
    444 #if defined(OS_POSIX)
    445 
    446 namespace {
    447 
    448 // Returns the maximum number of files that a process can have open.
    449 // Returns 0 on error.
    450 int GetMaxFilesOpenInProcess() {
    451   struct rlimit rlim;
    452   if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) {
    453     return 0;
    454   }
    455 
    456   // rlim_t is a uint64 - clip to maxint. We do this since FD #s are ints
    457   // which are all 32 bits on the supported platforms.
    458   rlim_t max_int = static_cast<rlim_t>(std::numeric_limits<int32>::max());
    459   if (rlim.rlim_cur > max_int) {
    460     return max_int;
    461   }
    462 
    463   return rlim.rlim_cur;
    464 }
    465 
    466 const int kChildPipe = 20;  // FD # for write end of pipe in child process.
    467 
    468 #if defined(OS_MACOSX)
    469 
    470 // <http://opensource.apple.com/source/xnu/xnu-2422.1.72/bsd/sys/guarded.h>
    471 #if !defined(_GUARDID_T)
    472 #define _GUARDID_T
    473 typedef __uint64_t guardid_t;
    474 #endif  // _GUARDID_T
    475 
    476 // From .../MacOSX10.9.sdk/usr/include/sys/syscall.h
    477 #if !defined(SYS_change_fdguard_np)
    478 #define SYS_change_fdguard_np 444
    479 #endif
    480 
    481 // <http://opensource.apple.com/source/xnu/xnu-2422.1.72/bsd/sys/guarded.h>
    482 #if !defined(GUARD_DUP)
    483 #define GUARD_DUP (1u << 1)
    484 #endif
    485 
    486 // <http://opensource.apple.com/source/xnu/xnu-2422.1.72/bsd/kern/kern_guarded.c?txt>
    487 //
    488 // Atomically replaces |guard|/|guardflags| with |nguard|/|nguardflags| on |fd|.
    489 int change_fdguard_np(int fd,
    490                       const guardid_t *guard, u_int guardflags,
    491                       const guardid_t *nguard, u_int nguardflags,
    492                       int *fdflagsp) {
    493   return syscall(SYS_change_fdguard_np, fd, guard, guardflags,
    494                  nguard, nguardflags, fdflagsp);
    495 }
    496 
    497 // Attempt to set a file-descriptor guard on |fd|.  In case of success, remove
    498 // it and return |true| to indicate that it can be guarded.  Returning |false|
    499 // means either that |fd| is guarded by some other code, or more likely EBADF.
    500 //
    501 // Starting with 10.9, libdispatch began setting GUARD_DUP on a file descriptor.
    502 // Unfortunately, it is spun up as part of +[NSApplication initialize], which is
    503 // not really something that Chromium can avoid using on OSX.  See
    504 // <http://crbug.com/338157>.  This function allows querying whether the file
    505 // descriptor is guarded before attempting to close it.
    506 bool CanGuardFd(int fd) {
    507   // The syscall is first provided in 10.9/Mavericks.
    508   if (!base::mac::IsOSMavericksOrLater())
    509     return true;
    510 
    511   // Saves the original flags to reset later.
    512   int original_fdflags = 0;
    513 
    514   // This can be any value at all, it just has to match up between the two
    515   // calls.
    516   const guardid_t kGuard = 15;
    517 
    518   // Attempt to change the guard.  This can fail with EBADF if the file
    519   // descriptor is bad, or EINVAL if the fd already has a guard set.
    520   int ret =
    521       change_fdguard_np(fd, NULL, 0, &kGuard, GUARD_DUP, &original_fdflags);
    522   if (ret == -1)
    523     return false;
    524 
    525   // Remove the guard.  It should not be possible to fail in removing the guard
    526   // just added.
    527   ret = change_fdguard_np(fd, &kGuard, GUARD_DUP, NULL, 0, &original_fdflags);
    528   DPCHECK(ret == 0);
    529 
    530   return true;
    531 }
    532 #endif  // OS_MACOSX
    533 
    534 }  // namespace
    535 
    536 MULTIPROCESS_TEST_MAIN(ProcessUtilsLeakFDChildProcess) {
    537   // This child process counts the number of open FDs, it then writes that
    538   // number out to a pipe connected to the parent.
    539   int num_open_files = 0;
    540   int write_pipe = kChildPipe;
    541   int max_files = GetMaxFilesOpenInProcess();
    542   for (int i = STDERR_FILENO + 1; i < max_files; i++) {
    543 #if defined(OS_MACOSX)
    544     // Ignore guarded or invalid file descriptors.
    545     if (!CanGuardFd(i))
    546       continue;
    547 #endif
    548 
    549     if (i != kChildPipe) {
    550       int fd;
    551       if ((fd = HANDLE_EINTR(dup(i))) != -1) {
    552         close(fd);
    553         num_open_files += 1;
    554       }
    555     }
    556   }
    557 
    558   int written = HANDLE_EINTR(write(write_pipe, &num_open_files,
    559                                    sizeof(num_open_files)));
    560   DCHECK_EQ(static_cast<size_t>(written), sizeof(num_open_files));
    561   int ret = IGNORE_EINTR(close(write_pipe));
    562   DPCHECK(ret == 0);
    563 
    564   return 0;
    565 }
    566 
    567 int ProcessUtilTest::CountOpenFDsInChild() {
    568   int fds[2];
    569   if (pipe(fds) < 0)
    570     NOTREACHED();
    571 
    572   base::FileHandleMappingVector fd_mapping_vec;
    573   fd_mapping_vec.push_back(std::pair<int, int>(fds[1], kChildPipe));
    574   base::LaunchOptions options;
    575   options.fds_to_remap = &fd_mapping_vec;
    576   base::ProcessHandle handle =
    577       SpawnChildWithOptions("ProcessUtilsLeakFDChildProcess", options);
    578   CHECK(handle);
    579   int ret = IGNORE_EINTR(close(fds[1]));
    580   DPCHECK(ret == 0);
    581 
    582   // Read number of open files in client process from pipe;
    583   int num_open_files = -1;
    584   ssize_t bytes_read =
    585       HANDLE_EINTR(read(fds[0], &num_open_files, sizeof(num_open_files)));
    586   CHECK_EQ(bytes_read, static_cast<ssize_t>(sizeof(num_open_files)));
    587 
    588 #if defined(THREAD_SANITIZER)
    589   // Compiler-based ThreadSanitizer makes this test slow.
    590   CHECK(base::WaitForSingleProcess(handle, base::TimeDelta::FromSeconds(3)));
    591 #else
    592   CHECK(base::WaitForSingleProcess(handle, base::TimeDelta::FromSeconds(1)));
    593 #endif
    594   base::CloseProcessHandle(handle);
    595   ret = IGNORE_EINTR(close(fds[0]));
    596   DPCHECK(ret == 0);
    597 
    598   return num_open_files;
    599 }
    600 
    601 #if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER)
    602 // ProcessUtilTest.FDRemapping is flaky when ran under xvfb-run on Precise.
    603 // The problem is 100% reproducible with both ASan and TSan.
    604 // See http://crbug.com/136720.
    605 #define MAYBE_FDRemapping DISABLED_FDRemapping
    606 #else
    607 #define MAYBE_FDRemapping FDRemapping
    608 #endif
    609 TEST_F(ProcessUtilTest, MAYBE_FDRemapping) {
    610   int fds_before = CountOpenFDsInChild();
    611 
    612   // open some dummy fds to make sure they don't propagate over to the
    613   // child process.
    614   int dev_null = open("/dev/null", O_RDONLY);
    615   int sockets[2];
    616   socketpair(AF_UNIX, SOCK_STREAM, 0, sockets);
    617 
    618   int fds_after = CountOpenFDsInChild();
    619 
    620   ASSERT_EQ(fds_after, fds_before);
    621 
    622   int ret;
    623   ret = IGNORE_EINTR(close(sockets[0]));
    624   DPCHECK(ret == 0);
    625   ret = IGNORE_EINTR(close(sockets[1]));
    626   DPCHECK(ret == 0);
    627   ret = IGNORE_EINTR(close(dev_null));
    628   DPCHECK(ret == 0);
    629 }
    630 
    631 namespace {
    632 
    633 std::string TestLaunchProcess(const std::vector<std::string>& args,
    634                               const base::EnvironmentMap& env_changes,
    635                               const bool clear_environ,
    636                               const int clone_flags) {
    637   base::FileHandleMappingVector fds_to_remap;
    638 
    639   int fds[2];
    640   PCHECK(pipe(fds) == 0);
    641 
    642   fds_to_remap.push_back(std::make_pair(fds[1], 1));
    643   base::LaunchOptions options;
    644   options.wait = true;
    645   options.environ = env_changes;
    646   options.clear_environ = clear_environ;
    647   options.fds_to_remap = &fds_to_remap;
    648 #if defined(OS_LINUX)
    649   options.clone_flags = clone_flags;
    650 #else
    651   CHECK_EQ(0, clone_flags);
    652 #endif  // OS_LINUX
    653   EXPECT_TRUE(base::LaunchProcess(args, options, NULL));
    654   PCHECK(IGNORE_EINTR(close(fds[1])) == 0);
    655 
    656   char buf[512];
    657   const ssize_t n = HANDLE_EINTR(read(fds[0], buf, sizeof(buf)));
    658 
    659   PCHECK(IGNORE_EINTR(close(fds[0])) == 0);
    660 
    661   return std::string(buf, n);
    662 }
    663 
    664 const char kLargeString[] =
    665     "0123456789012345678901234567890123456789012345678901234567890123456789"
    666     "0123456789012345678901234567890123456789012345678901234567890123456789"
    667     "0123456789012345678901234567890123456789012345678901234567890123456789"
    668     "0123456789012345678901234567890123456789012345678901234567890123456789"
    669     "0123456789012345678901234567890123456789012345678901234567890123456789"
    670     "0123456789012345678901234567890123456789012345678901234567890123456789"
    671     "0123456789012345678901234567890123456789012345678901234567890123456789";
    672 
    673 }  // namespace
    674 
    675 TEST_F(ProcessUtilTest, LaunchProcess) {
    676   base::EnvironmentMap env_changes;
    677   std::vector<std::string> echo_base_test;
    678   echo_base_test.push_back(kPosixShell);
    679   echo_base_test.push_back("-c");
    680   echo_base_test.push_back("echo $BASE_TEST");
    681 
    682   std::vector<std::string> print_env;
    683   print_env.push_back("/usr/bin/env");
    684   const int no_clone_flags = 0;
    685   const bool no_clear_environ = false;
    686 
    687   const char kBaseTest[] = "BASE_TEST";
    688 
    689   env_changes[kBaseTest] = "bar";
    690   EXPECT_EQ("bar\n",
    691             TestLaunchProcess(
    692                 echo_base_test, env_changes, no_clear_environ, no_clone_flags));
    693   env_changes.clear();
    694 
    695   EXPECT_EQ(0, setenv(kBaseTest, "testing", 1 /* override */));
    696   EXPECT_EQ("testing\n",
    697             TestLaunchProcess(
    698                 echo_base_test, env_changes, no_clear_environ, no_clone_flags));
    699 
    700   env_changes[kBaseTest] = std::string();
    701   EXPECT_EQ("\n",
    702             TestLaunchProcess(
    703                 echo_base_test, env_changes, no_clear_environ, no_clone_flags));
    704 
    705   env_changes[kBaseTest] = "foo";
    706   EXPECT_EQ("foo\n",
    707             TestLaunchProcess(
    708                 echo_base_test, env_changes, no_clear_environ, no_clone_flags));
    709 
    710   env_changes.clear();
    711   EXPECT_EQ(0, setenv(kBaseTest, kLargeString, 1 /* override */));
    712   EXPECT_EQ(std::string(kLargeString) + "\n",
    713             TestLaunchProcess(
    714                 echo_base_test, env_changes, no_clear_environ, no_clone_flags));
    715 
    716   env_changes[kBaseTest] = "wibble";
    717   EXPECT_EQ("wibble\n",
    718             TestLaunchProcess(
    719                 echo_base_test, env_changes, no_clear_environ, no_clone_flags));
    720 
    721 #if defined(OS_LINUX)
    722   // Test a non-trival value for clone_flags.
    723   // Don't test on Valgrind as it has limited support for clone().
    724   if (!RunningOnValgrind()) {
    725     EXPECT_EQ(
    726         "wibble\n",
    727         TestLaunchProcess(
    728             echo_base_test, env_changes, no_clear_environ, CLONE_FS | SIGCHLD));
    729   }
    730 
    731   EXPECT_EQ(
    732       "BASE_TEST=wibble\n",
    733       TestLaunchProcess(
    734           print_env, env_changes, true /* clear_environ */, no_clone_flags));
    735   env_changes.clear();
    736   EXPECT_EQ(
    737       "",
    738       TestLaunchProcess(
    739           print_env, env_changes, true /* clear_environ */, no_clone_flags));
    740 #endif
    741 }
    742 
    743 TEST_F(ProcessUtilTest, GetAppOutput) {
    744   std::string output;
    745 
    746 #if defined(OS_ANDROID)
    747   std::vector<std::string> argv;
    748   argv.push_back("sh");  // Instead of /bin/sh, force path search to find it.
    749   argv.push_back("-c");
    750 
    751   argv.push_back("exit 0");
    752   EXPECT_TRUE(base::GetAppOutput(CommandLine(argv), &output));
    753   EXPECT_STREQ("", output.c_str());
    754 
    755   argv[2] = "exit 1";
    756   EXPECT_FALSE(base::GetAppOutput(CommandLine(argv), &output));
    757   EXPECT_STREQ("", output.c_str());
    758 
    759   argv[2] = "echo foobar42";
    760   EXPECT_TRUE(base::GetAppOutput(CommandLine(argv), &output));
    761   EXPECT_STREQ("foobar42\n", output.c_str());
    762 #else
    763   EXPECT_TRUE(base::GetAppOutput(CommandLine(FilePath("true")), &output));
    764   EXPECT_STREQ("", output.c_str());
    765 
    766   EXPECT_FALSE(base::GetAppOutput(CommandLine(FilePath("false")), &output));
    767 
    768   std::vector<std::string> argv;
    769   argv.push_back("/bin/echo");
    770   argv.push_back("-n");
    771   argv.push_back("foobar42");
    772   EXPECT_TRUE(base::GetAppOutput(CommandLine(argv), &output));
    773   EXPECT_STREQ("foobar42", output.c_str());
    774 #endif  // defined(OS_ANDROID)
    775 }
    776 
    777 // Flakes on Android, crbug.com/375840
    778 #if defined(OS_ANDROID)
    779 #define MAYBE_GetAppOutputRestricted DISABLED_GetAppOutputRestricted
    780 #else
    781 #define MAYBE_GetAppOutputRestricted GetAppOutputRestricted
    782 #endif
    783 TEST_F(ProcessUtilTest, MAYBE_GetAppOutputRestricted) {
    784   // Unfortunately, since we can't rely on the path, we need to know where
    785   // everything is. So let's use /bin/sh, which is on every POSIX system, and
    786   // its built-ins.
    787   std::vector<std::string> argv;
    788   argv.push_back(std::string(kShellPath));  // argv[0]
    789   argv.push_back("-c");  // argv[1]
    790 
    791   // On success, should set |output|. We use |/bin/sh -c 'exit 0'| instead of
    792   // |true| since the location of the latter may be |/bin| or |/usr/bin| (and we
    793   // need absolute paths).
    794   argv.push_back("exit 0");   // argv[2]; equivalent to "true"
    795   std::string output = "abc";
    796   EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 100));
    797   EXPECT_STREQ("", output.c_str());
    798 
    799   argv[2] = "exit 1";  // equivalent to "false"
    800   output = "before";
    801   EXPECT_FALSE(base::GetAppOutputRestricted(CommandLine(argv),
    802                                             &output, 100));
    803   EXPECT_STREQ("", output.c_str());
    804 
    805   // Amount of output exactly equal to space allowed.
    806   argv[2] = "echo 123456789";  // (the sh built-in doesn't take "-n")
    807   output.clear();
    808   EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 10));
    809   EXPECT_STREQ("123456789\n", output.c_str());
    810 
    811   // Amount of output greater than space allowed.
    812   output.clear();
    813   EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 5));
    814   EXPECT_STREQ("12345", output.c_str());
    815 
    816   // Amount of output less than space allowed.
    817   output.clear();
    818   EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 15));
    819   EXPECT_STREQ("123456789\n", output.c_str());
    820 
    821   // Zero space allowed.
    822   output = "abc";
    823   EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 0));
    824   EXPECT_STREQ("", output.c_str());
    825 }
    826 
    827 #if !defined(OS_MACOSX) && !defined(OS_OPENBSD)
    828 // TODO(benwells): GetAppOutputRestricted should terminate applications
    829 // with SIGPIPE when we have enough output. http://crbug.com/88502
    830 TEST_F(ProcessUtilTest, GetAppOutputRestrictedSIGPIPE) {
    831   std::vector<std::string> argv;
    832   std::string output;
    833 
    834   argv.push_back(std::string(kShellPath));  // argv[0]
    835   argv.push_back("-c");
    836 #if defined(OS_ANDROID)
    837   argv.push_back("while echo 12345678901234567890; do :; done");
    838   EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 10));
    839   EXPECT_STREQ("1234567890", output.c_str());
    840 #else
    841   argv.push_back("yes");
    842   EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 10));
    843   EXPECT_STREQ("y\ny\ny\ny\ny\n", output.c_str());
    844 #endif
    845 }
    846 #endif
    847 
    848 #if defined(ADDRESS_SANITIZER) && defined(OS_MACOSX) && \
    849     defined(ARCH_CPU_64_BITS)
    850 // Times out under AddressSanitizer on 64-bit OS X, see
    851 // http://crbug.com/298197.
    852 #define MAYBE_GetAppOutputRestrictedNoZombies \
    853     DISABLED_GetAppOutputRestrictedNoZombies
    854 #else
    855 #define MAYBE_GetAppOutputRestrictedNoZombies GetAppOutputRestrictedNoZombies
    856 #endif
    857 TEST_F(ProcessUtilTest, MAYBE_GetAppOutputRestrictedNoZombies) {
    858   std::vector<std::string> argv;
    859 
    860   argv.push_back(std::string(kShellPath));  // argv[0]
    861   argv.push_back("-c");  // argv[1]
    862   argv.push_back("echo 123456789012345678901234567890");  // argv[2]
    863 
    864   // Run |GetAppOutputRestricted()| 300 (> default per-user processes on Mac OS
    865   // 10.5) times with an output buffer big enough to capture all output.
    866   for (int i = 0; i < 300; i++) {
    867     std::string output;
    868     EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 100));
    869     EXPECT_STREQ("123456789012345678901234567890\n", output.c_str());
    870   }
    871 
    872   // Ditto, but with an output buffer too small to capture all output.
    873   for (int i = 0; i < 300; i++) {
    874     std::string output;
    875     EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 10));
    876     EXPECT_STREQ("1234567890", output.c_str());
    877   }
    878 }
    879 
    880 TEST_F(ProcessUtilTest, GetAppOutputWithExitCode) {
    881   // Test getting output from a successful application.
    882   std::vector<std::string> argv;
    883   std::string output;
    884   int exit_code;
    885   argv.push_back(std::string(kShellPath));  // argv[0]
    886   argv.push_back("-c");  // argv[1]
    887   argv.push_back("echo foo");  // argv[2];
    888   EXPECT_TRUE(base::GetAppOutputWithExitCode(CommandLine(argv), &output,
    889                                              &exit_code));
    890   EXPECT_STREQ("foo\n", output.c_str());
    891   EXPECT_EQ(exit_code, 0);
    892 
    893   // Test getting output from an application which fails with a specific exit
    894   // code.
    895   output.clear();
    896   argv[2] = "echo foo; exit 2";
    897   EXPECT_TRUE(base::GetAppOutputWithExitCode(CommandLine(argv), &output,
    898                                              &exit_code));
    899   EXPECT_STREQ("foo\n", output.c_str());
    900   EXPECT_EQ(exit_code, 2);
    901 }
    902 
    903 TEST_F(ProcessUtilTest, GetParentProcessId) {
    904   base::ProcessId ppid = base::GetParentProcessId(base::GetCurrentProcId());
    905   EXPECT_EQ(ppid, getppid());
    906 }
    907 
    908 // TODO(port): port those unit tests.
    909 bool IsProcessDead(base::ProcessHandle child) {
    910   // waitpid() will actually reap the process which is exactly NOT what we
    911   // want to test for.  The good thing is that if it can't find the process
    912   // we'll get a nice value for errno which we can test for.
    913   const pid_t result = HANDLE_EINTR(waitpid(child, NULL, WNOHANG));
    914   return result == -1 && errno == ECHILD;
    915 }
    916 
    917 TEST_F(ProcessUtilTest, DelayedTermination) {
    918   base::ProcessHandle child_process = SpawnChild("process_util_test_never_die");
    919   ASSERT_TRUE(child_process);
    920   base::EnsureProcessTerminated(child_process);
    921   base::WaitForSingleProcess(child_process, base::TimeDelta::FromSeconds(5));
    922 
    923   // Check that process was really killed.
    924   EXPECT_TRUE(IsProcessDead(child_process));
    925   base::CloseProcessHandle(child_process);
    926 }
    927 
    928 MULTIPROCESS_TEST_MAIN(process_util_test_never_die) {
    929   while (1) {
    930     sleep(500);
    931   }
    932   return 0;
    933 }
    934 
    935 TEST_F(ProcessUtilTest, ImmediateTermination) {
    936   base::ProcessHandle child_process =
    937       SpawnChild("process_util_test_die_immediately");
    938   ASSERT_TRUE(child_process);
    939   // Give it time to die.
    940   sleep(2);
    941   base::EnsureProcessTerminated(child_process);
    942 
    943   // Check that process was really killed.
    944   EXPECT_TRUE(IsProcessDead(child_process));
    945   base::CloseProcessHandle(child_process);
    946 }
    947 
    948 MULTIPROCESS_TEST_MAIN(process_util_test_die_immediately) {
    949   return 0;
    950 }
    951 
    952 #endif  // defined(OS_POSIX)
    953