1*635a8641SAndroid Build Coastguard Worker // Copyright 2011 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 #include "base/process/process.h"
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Worker #include <errno.h>
8*635a8641SAndroid Build Coastguard Worker #include <signal.h>
9*635a8641SAndroid Build Coastguard Worker #include <stdint.h>
10*635a8641SAndroid Build Coastguard Worker #include <sys/resource.h>
11*635a8641SAndroid Build Coastguard Worker #include <sys/wait.h>
12*635a8641SAndroid Build Coastguard Worker
13*635a8641SAndroid Build Coastguard Worker #include "base/debug/activity_tracker.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/files/scoped_file.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/logging.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/posix/eintr_wrapper.h"
17*635a8641SAndroid Build Coastguard Worker #include "base/process/kill.h"
18*635a8641SAndroid Build Coastguard Worker #include "base/threading/thread_restrictions.h"
19*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
20*635a8641SAndroid Build Coastguard Worker
21*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX)
22*635a8641SAndroid Build Coastguard Worker #include <sys/event.h>
23*635a8641SAndroid Build Coastguard Worker #endif
24*635a8641SAndroid Build Coastguard Worker
25*635a8641SAndroid Build Coastguard Worker namespace {
26*635a8641SAndroid Build Coastguard Worker
27*635a8641SAndroid Build Coastguard Worker #if !defined(OS_NACL_NONSFI)
28*635a8641SAndroid Build Coastguard Worker
WaitpidWithTimeout(base::ProcessHandle handle,int * status,base::TimeDelta wait)29*635a8641SAndroid Build Coastguard Worker bool WaitpidWithTimeout(base::ProcessHandle handle,
30*635a8641SAndroid Build Coastguard Worker int* status,
31*635a8641SAndroid Build Coastguard Worker base::TimeDelta wait) {
32*635a8641SAndroid Build Coastguard Worker // This POSIX version of this function only guarantees that we wait no less
33*635a8641SAndroid Build Coastguard Worker // than |wait| for the process to exit. The child process may
34*635a8641SAndroid Build Coastguard Worker // exit sometime before the timeout has ended but we may still block for up
35*635a8641SAndroid Build Coastguard Worker // to 256 milliseconds after the fact.
36*635a8641SAndroid Build Coastguard Worker //
37*635a8641SAndroid Build Coastguard Worker // waitpid() has no direct support on POSIX for specifying a timeout, you can
38*635a8641SAndroid Build Coastguard Worker // either ask it to block indefinitely or return immediately (WNOHANG).
39*635a8641SAndroid Build Coastguard Worker // When a child process terminates a SIGCHLD signal is sent to the parent.
40*635a8641SAndroid Build Coastguard Worker // Catching this signal would involve installing a signal handler which may
41*635a8641SAndroid Build Coastguard Worker // affect other parts of the application and would be difficult to debug.
42*635a8641SAndroid Build Coastguard Worker //
43*635a8641SAndroid Build Coastguard Worker // Our strategy is to call waitpid() once up front to check if the process
44*635a8641SAndroid Build Coastguard Worker // has already exited, otherwise to loop for |wait|, sleeping for
45*635a8641SAndroid Build Coastguard Worker // at most 256 milliseconds each time using usleep() and then calling
46*635a8641SAndroid Build Coastguard Worker // waitpid(). The amount of time we sleep starts out at 1 milliseconds, and
47*635a8641SAndroid Build Coastguard Worker // we double it every 4 sleep cycles.
48*635a8641SAndroid Build Coastguard Worker //
49*635a8641SAndroid Build Coastguard Worker // usleep() is speced to exit if a signal is received for which a handler
50*635a8641SAndroid Build Coastguard Worker // has been installed. This means that when a SIGCHLD is sent, it will exit
51*635a8641SAndroid Build Coastguard Worker // depending on behavior external to this function.
52*635a8641SAndroid Build Coastguard Worker //
53*635a8641SAndroid Build Coastguard Worker // This function is used primarily for unit tests, if we want to use it in
54*635a8641SAndroid Build Coastguard Worker // the application itself it would probably be best to examine other routes.
55*635a8641SAndroid Build Coastguard Worker
56*635a8641SAndroid Build Coastguard Worker if (wait == base::TimeDelta::Max()) {
57*635a8641SAndroid Build Coastguard Worker return HANDLE_EINTR(waitpid(handle, status, 0)) > 0;
58*635a8641SAndroid Build Coastguard Worker }
59*635a8641SAndroid Build Coastguard Worker
60*635a8641SAndroid Build Coastguard Worker pid_t ret_pid = HANDLE_EINTR(waitpid(handle, status, WNOHANG));
61*635a8641SAndroid Build Coastguard Worker static const int64_t kMaxSleepInMicroseconds = 1 << 18; // ~256 milliseconds.
62*635a8641SAndroid Build Coastguard Worker int64_t max_sleep_time_usecs = 1 << 10; // ~1 milliseconds.
63*635a8641SAndroid Build Coastguard Worker int64_t double_sleep_time = 0;
64*635a8641SAndroid Build Coastguard Worker
65*635a8641SAndroid Build Coastguard Worker // If the process hasn't exited yet, then sleep and try again.
66*635a8641SAndroid Build Coastguard Worker base::TimeTicks wakeup_time = base::TimeTicks::Now() + wait;
67*635a8641SAndroid Build Coastguard Worker while (ret_pid == 0) {
68*635a8641SAndroid Build Coastguard Worker base::TimeTicks now = base::TimeTicks::Now();
69*635a8641SAndroid Build Coastguard Worker if (now > wakeup_time)
70*635a8641SAndroid Build Coastguard Worker break;
71*635a8641SAndroid Build Coastguard Worker // Guaranteed to be non-negative!
72*635a8641SAndroid Build Coastguard Worker int64_t sleep_time_usecs = (wakeup_time - now).InMicroseconds();
73*635a8641SAndroid Build Coastguard Worker // Sleep for a bit while we wait for the process to finish.
74*635a8641SAndroid Build Coastguard Worker if (sleep_time_usecs > max_sleep_time_usecs)
75*635a8641SAndroid Build Coastguard Worker sleep_time_usecs = max_sleep_time_usecs;
76*635a8641SAndroid Build Coastguard Worker
77*635a8641SAndroid Build Coastguard Worker // usleep() will return 0 and set errno to EINTR on receipt of a signal
78*635a8641SAndroid Build Coastguard Worker // such as SIGCHLD.
79*635a8641SAndroid Build Coastguard Worker usleep(sleep_time_usecs);
80*635a8641SAndroid Build Coastguard Worker ret_pid = HANDLE_EINTR(waitpid(handle, status, WNOHANG));
81*635a8641SAndroid Build Coastguard Worker
82*635a8641SAndroid Build Coastguard Worker if ((max_sleep_time_usecs < kMaxSleepInMicroseconds) &&
83*635a8641SAndroid Build Coastguard Worker (double_sleep_time++ % 4 == 0)) {
84*635a8641SAndroid Build Coastguard Worker max_sleep_time_usecs *= 2;
85*635a8641SAndroid Build Coastguard Worker }
86*635a8641SAndroid Build Coastguard Worker }
87*635a8641SAndroid Build Coastguard Worker
88*635a8641SAndroid Build Coastguard Worker return ret_pid > 0;
89*635a8641SAndroid Build Coastguard Worker }
90*635a8641SAndroid Build Coastguard Worker
91*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX)
92*635a8641SAndroid Build Coastguard Worker // Using kqueue on Mac so that we can wait on non-child processes.
93*635a8641SAndroid Build Coastguard Worker // We can't use kqueues on child processes because we need to reap
94*635a8641SAndroid Build Coastguard Worker // our own children using wait.
WaitForSingleNonChildProcess(base::ProcessHandle handle,base::TimeDelta wait)95*635a8641SAndroid Build Coastguard Worker bool WaitForSingleNonChildProcess(base::ProcessHandle handle,
96*635a8641SAndroid Build Coastguard Worker base::TimeDelta wait) {
97*635a8641SAndroid Build Coastguard Worker DCHECK_GT(handle, 0);
98*635a8641SAndroid Build Coastguard Worker
99*635a8641SAndroid Build Coastguard Worker base::ScopedFD kq(kqueue());
100*635a8641SAndroid Build Coastguard Worker if (!kq.is_valid()) {
101*635a8641SAndroid Build Coastguard Worker DPLOG(ERROR) << "kqueue";
102*635a8641SAndroid Build Coastguard Worker return false;
103*635a8641SAndroid Build Coastguard Worker }
104*635a8641SAndroid Build Coastguard Worker
105*635a8641SAndroid Build Coastguard Worker struct kevent change = {0};
106*635a8641SAndroid Build Coastguard Worker EV_SET(&change, handle, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, NULL);
107*635a8641SAndroid Build Coastguard Worker int result = HANDLE_EINTR(kevent(kq.get(), &change, 1, NULL, 0, NULL));
108*635a8641SAndroid Build Coastguard Worker if (result == -1) {
109*635a8641SAndroid Build Coastguard Worker if (errno == ESRCH) {
110*635a8641SAndroid Build Coastguard Worker // If the process wasn't found, it must be dead.
111*635a8641SAndroid Build Coastguard Worker return true;
112*635a8641SAndroid Build Coastguard Worker }
113*635a8641SAndroid Build Coastguard Worker
114*635a8641SAndroid Build Coastguard Worker DPLOG(ERROR) << "kevent (setup " << handle << ")";
115*635a8641SAndroid Build Coastguard Worker return false;
116*635a8641SAndroid Build Coastguard Worker }
117*635a8641SAndroid Build Coastguard Worker
118*635a8641SAndroid Build Coastguard Worker // Keep track of the elapsed time to be able to restart kevent if it's
119*635a8641SAndroid Build Coastguard Worker // interrupted.
120*635a8641SAndroid Build Coastguard Worker bool wait_forever = (wait == base::TimeDelta::Max());
121*635a8641SAndroid Build Coastguard Worker base::TimeDelta remaining_delta;
122*635a8641SAndroid Build Coastguard Worker base::TimeTicks deadline;
123*635a8641SAndroid Build Coastguard Worker if (!wait_forever) {
124*635a8641SAndroid Build Coastguard Worker remaining_delta = wait;
125*635a8641SAndroid Build Coastguard Worker deadline = base::TimeTicks::Now() + remaining_delta;
126*635a8641SAndroid Build Coastguard Worker }
127*635a8641SAndroid Build Coastguard Worker
128*635a8641SAndroid Build Coastguard Worker result = -1;
129*635a8641SAndroid Build Coastguard Worker struct kevent event = {0};
130*635a8641SAndroid Build Coastguard Worker
131*635a8641SAndroid Build Coastguard Worker do {
132*635a8641SAndroid Build Coastguard Worker struct timespec remaining_timespec;
133*635a8641SAndroid Build Coastguard Worker struct timespec* remaining_timespec_ptr;
134*635a8641SAndroid Build Coastguard Worker if (wait_forever) {
135*635a8641SAndroid Build Coastguard Worker remaining_timespec_ptr = NULL;
136*635a8641SAndroid Build Coastguard Worker } else {
137*635a8641SAndroid Build Coastguard Worker remaining_timespec = remaining_delta.ToTimeSpec();
138*635a8641SAndroid Build Coastguard Worker remaining_timespec_ptr = &remaining_timespec;
139*635a8641SAndroid Build Coastguard Worker }
140*635a8641SAndroid Build Coastguard Worker
141*635a8641SAndroid Build Coastguard Worker result = kevent(kq.get(), NULL, 0, &event, 1, remaining_timespec_ptr);
142*635a8641SAndroid Build Coastguard Worker
143*635a8641SAndroid Build Coastguard Worker if (result == -1 && errno == EINTR) {
144*635a8641SAndroid Build Coastguard Worker if (!wait_forever) {
145*635a8641SAndroid Build Coastguard Worker remaining_delta = deadline - base::TimeTicks::Now();
146*635a8641SAndroid Build Coastguard Worker }
147*635a8641SAndroid Build Coastguard Worker result = 0;
148*635a8641SAndroid Build Coastguard Worker } else {
149*635a8641SAndroid Build Coastguard Worker break;
150*635a8641SAndroid Build Coastguard Worker }
151*635a8641SAndroid Build Coastguard Worker } while (wait_forever || remaining_delta > base::TimeDelta());
152*635a8641SAndroid Build Coastguard Worker
153*635a8641SAndroid Build Coastguard Worker if (result < 0) {
154*635a8641SAndroid Build Coastguard Worker DPLOG(ERROR) << "kevent (wait " << handle << ")";
155*635a8641SAndroid Build Coastguard Worker return false;
156*635a8641SAndroid Build Coastguard Worker } else if (result > 1) {
157*635a8641SAndroid Build Coastguard Worker DLOG(ERROR) << "kevent (wait " << handle << "): unexpected result "
158*635a8641SAndroid Build Coastguard Worker << result;
159*635a8641SAndroid Build Coastguard Worker return false;
160*635a8641SAndroid Build Coastguard Worker } else if (result == 0) {
161*635a8641SAndroid Build Coastguard Worker // Timed out.
162*635a8641SAndroid Build Coastguard Worker return false;
163*635a8641SAndroid Build Coastguard Worker }
164*635a8641SAndroid Build Coastguard Worker
165*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(result, 1);
166*635a8641SAndroid Build Coastguard Worker
167*635a8641SAndroid Build Coastguard Worker if (event.filter != EVFILT_PROC ||
168*635a8641SAndroid Build Coastguard Worker (event.fflags & NOTE_EXIT) == 0 ||
169*635a8641SAndroid Build Coastguard Worker event.ident != static_cast<uintptr_t>(handle)) {
170*635a8641SAndroid Build Coastguard Worker DLOG(ERROR) << "kevent (wait " << handle
171*635a8641SAndroid Build Coastguard Worker << "): unexpected event: filter=" << event.filter
172*635a8641SAndroid Build Coastguard Worker << ", fflags=" << event.fflags
173*635a8641SAndroid Build Coastguard Worker << ", ident=" << event.ident;
174*635a8641SAndroid Build Coastguard Worker return false;
175*635a8641SAndroid Build Coastguard Worker }
176*635a8641SAndroid Build Coastguard Worker
177*635a8641SAndroid Build Coastguard Worker return true;
178*635a8641SAndroid Build Coastguard Worker }
179*635a8641SAndroid Build Coastguard Worker #endif // OS_MACOSX
180*635a8641SAndroid Build Coastguard Worker
WaitForExitWithTimeoutImpl(base::ProcessHandle handle,int * exit_code,base::TimeDelta timeout)181*635a8641SAndroid Build Coastguard Worker bool WaitForExitWithTimeoutImpl(base::ProcessHandle handle,
182*635a8641SAndroid Build Coastguard Worker int* exit_code,
183*635a8641SAndroid Build Coastguard Worker base::TimeDelta timeout) {
184*635a8641SAndroid Build Coastguard Worker const base::ProcessHandle our_pid = base::GetCurrentProcessHandle();
185*635a8641SAndroid Build Coastguard Worker if (handle == our_pid) {
186*635a8641SAndroid Build Coastguard Worker // We won't be able to wait for ourselves to exit.
187*635a8641SAndroid Build Coastguard Worker return false;
188*635a8641SAndroid Build Coastguard Worker }
189*635a8641SAndroid Build Coastguard Worker
190*635a8641SAndroid Build Coastguard Worker const base::ProcessHandle parent_pid = base::GetParentProcessId(handle);
191*635a8641SAndroid Build Coastguard Worker const bool exited = (parent_pid < 0);
192*635a8641SAndroid Build Coastguard Worker
193*635a8641SAndroid Build Coastguard Worker if (!exited && parent_pid != our_pid) {
194*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX)
195*635a8641SAndroid Build Coastguard Worker // On Mac we can wait on non child processes.
196*635a8641SAndroid Build Coastguard Worker return WaitForSingleNonChildProcess(handle, timeout);
197*635a8641SAndroid Build Coastguard Worker #else
198*635a8641SAndroid Build Coastguard Worker // Currently on Linux we can't handle non child processes.
199*635a8641SAndroid Build Coastguard Worker NOTIMPLEMENTED();
200*635a8641SAndroid Build Coastguard Worker #endif // OS_MACOSX
201*635a8641SAndroid Build Coastguard Worker }
202*635a8641SAndroid Build Coastguard Worker
203*635a8641SAndroid Build Coastguard Worker int status;
204*635a8641SAndroid Build Coastguard Worker if (!WaitpidWithTimeout(handle, &status, timeout))
205*635a8641SAndroid Build Coastguard Worker return exited;
206*635a8641SAndroid Build Coastguard Worker if (WIFSIGNALED(status)) {
207*635a8641SAndroid Build Coastguard Worker if (exit_code)
208*635a8641SAndroid Build Coastguard Worker *exit_code = -1;
209*635a8641SAndroid Build Coastguard Worker return true;
210*635a8641SAndroid Build Coastguard Worker }
211*635a8641SAndroid Build Coastguard Worker if (WIFEXITED(status)) {
212*635a8641SAndroid Build Coastguard Worker if (exit_code)
213*635a8641SAndroid Build Coastguard Worker *exit_code = WEXITSTATUS(status);
214*635a8641SAndroid Build Coastguard Worker return true;
215*635a8641SAndroid Build Coastguard Worker }
216*635a8641SAndroid Build Coastguard Worker return exited;
217*635a8641SAndroid Build Coastguard Worker }
218*635a8641SAndroid Build Coastguard Worker #endif // !defined(OS_NACL_NONSFI)
219*635a8641SAndroid Build Coastguard Worker
220*635a8641SAndroid Build Coastguard Worker } // namespace
221*635a8641SAndroid Build Coastguard Worker
222*635a8641SAndroid Build Coastguard Worker namespace base {
223*635a8641SAndroid Build Coastguard Worker
Process(ProcessHandle handle)224*635a8641SAndroid Build Coastguard Worker Process::Process(ProcessHandle handle) : process_(handle) {
225*635a8641SAndroid Build Coastguard Worker }
226*635a8641SAndroid Build Coastguard Worker
227*635a8641SAndroid Build Coastguard Worker Process::~Process() = default;
228*635a8641SAndroid Build Coastguard Worker
Process(Process && other)229*635a8641SAndroid Build Coastguard Worker Process::Process(Process&& other) : process_(other.process_) {
230*635a8641SAndroid Build Coastguard Worker other.Close();
231*635a8641SAndroid Build Coastguard Worker }
232*635a8641SAndroid Build Coastguard Worker
operator =(Process && other)233*635a8641SAndroid Build Coastguard Worker Process& Process::operator=(Process&& other) {
234*635a8641SAndroid Build Coastguard Worker process_ = other.process_;
235*635a8641SAndroid Build Coastguard Worker other.Close();
236*635a8641SAndroid Build Coastguard Worker return *this;
237*635a8641SAndroid Build Coastguard Worker }
238*635a8641SAndroid Build Coastguard Worker
239*635a8641SAndroid Build Coastguard Worker // static
Current()240*635a8641SAndroid Build Coastguard Worker Process Process::Current() {
241*635a8641SAndroid Build Coastguard Worker return Process(GetCurrentProcessHandle());
242*635a8641SAndroid Build Coastguard Worker }
243*635a8641SAndroid Build Coastguard Worker
244*635a8641SAndroid Build Coastguard Worker // static
Open(ProcessId pid)245*635a8641SAndroid Build Coastguard Worker Process Process::Open(ProcessId pid) {
246*635a8641SAndroid Build Coastguard Worker if (pid == GetCurrentProcId())
247*635a8641SAndroid Build Coastguard Worker return Current();
248*635a8641SAndroid Build Coastguard Worker
249*635a8641SAndroid Build Coastguard Worker // On POSIX process handles are the same as PIDs.
250*635a8641SAndroid Build Coastguard Worker return Process(pid);
251*635a8641SAndroid Build Coastguard Worker }
252*635a8641SAndroid Build Coastguard Worker
253*635a8641SAndroid Build Coastguard Worker // static
OpenWithExtraPrivileges(ProcessId pid)254*635a8641SAndroid Build Coastguard Worker Process Process::OpenWithExtraPrivileges(ProcessId pid) {
255*635a8641SAndroid Build Coastguard Worker // On POSIX there are no privileges to set.
256*635a8641SAndroid Build Coastguard Worker return Open(pid);
257*635a8641SAndroid Build Coastguard Worker }
258*635a8641SAndroid Build Coastguard Worker
259*635a8641SAndroid Build Coastguard Worker // static
DeprecatedGetProcessFromHandle(ProcessHandle handle)260*635a8641SAndroid Build Coastguard Worker Process Process::DeprecatedGetProcessFromHandle(ProcessHandle handle) {
261*635a8641SAndroid Build Coastguard Worker DCHECK_NE(handle, GetCurrentProcessHandle());
262*635a8641SAndroid Build Coastguard Worker return Process(handle);
263*635a8641SAndroid Build Coastguard Worker }
264*635a8641SAndroid Build Coastguard Worker
265*635a8641SAndroid Build Coastguard Worker #if !defined(OS_LINUX) && !defined(OS_MACOSX) && !defined(OS_AIX)
266*635a8641SAndroid Build Coastguard Worker // static
CanBackgroundProcesses()267*635a8641SAndroid Build Coastguard Worker bool Process::CanBackgroundProcesses() {
268*635a8641SAndroid Build Coastguard Worker return false;
269*635a8641SAndroid Build Coastguard Worker }
270*635a8641SAndroid Build Coastguard Worker #endif // !defined(OS_LINUX) && !defined(OS_MACOSX) && !defined(OS_AIX)
271*635a8641SAndroid Build Coastguard Worker
272*635a8641SAndroid Build Coastguard Worker // static
TerminateCurrentProcessImmediately(int exit_code)273*635a8641SAndroid Build Coastguard Worker void Process::TerminateCurrentProcessImmediately(int exit_code) {
274*635a8641SAndroid Build Coastguard Worker _exit(exit_code);
275*635a8641SAndroid Build Coastguard Worker }
276*635a8641SAndroid Build Coastguard Worker
IsValid() const277*635a8641SAndroid Build Coastguard Worker bool Process::IsValid() const {
278*635a8641SAndroid Build Coastguard Worker return process_ != kNullProcessHandle;
279*635a8641SAndroid Build Coastguard Worker }
280*635a8641SAndroid Build Coastguard Worker
Handle() const281*635a8641SAndroid Build Coastguard Worker ProcessHandle Process::Handle() const {
282*635a8641SAndroid Build Coastguard Worker return process_;
283*635a8641SAndroid Build Coastguard Worker }
284*635a8641SAndroid Build Coastguard Worker
Duplicate() const285*635a8641SAndroid Build Coastguard Worker Process Process::Duplicate() const {
286*635a8641SAndroid Build Coastguard Worker if (is_current())
287*635a8641SAndroid Build Coastguard Worker return Current();
288*635a8641SAndroid Build Coastguard Worker
289*635a8641SAndroid Build Coastguard Worker return Process(process_);
290*635a8641SAndroid Build Coastguard Worker }
291*635a8641SAndroid Build Coastguard Worker
Pid() const292*635a8641SAndroid Build Coastguard Worker ProcessId Process::Pid() const {
293*635a8641SAndroid Build Coastguard Worker DCHECK(IsValid());
294*635a8641SAndroid Build Coastguard Worker return GetProcId(process_);
295*635a8641SAndroid Build Coastguard Worker }
296*635a8641SAndroid Build Coastguard Worker
is_current() const297*635a8641SAndroid Build Coastguard Worker bool Process::is_current() const {
298*635a8641SAndroid Build Coastguard Worker return process_ == GetCurrentProcessHandle();
299*635a8641SAndroid Build Coastguard Worker }
300*635a8641SAndroid Build Coastguard Worker
Close()301*635a8641SAndroid Build Coastguard Worker void Process::Close() {
302*635a8641SAndroid Build Coastguard Worker process_ = kNullProcessHandle;
303*635a8641SAndroid Build Coastguard Worker // if the process wasn't terminated (so we waited) or the state
304*635a8641SAndroid Build Coastguard Worker // wasn't already collected w/ a wait from process_utils, we're gonna
305*635a8641SAndroid Build Coastguard Worker // end up w/ a zombie when it does finally exit.
306*635a8641SAndroid Build Coastguard Worker }
307*635a8641SAndroid Build Coastguard Worker
308*635a8641SAndroid Build Coastguard Worker #if !defined(OS_NACL_NONSFI)
Terminate(int exit_code,bool wait) const309*635a8641SAndroid Build Coastguard Worker bool Process::Terminate(int exit_code, bool wait) const {
310*635a8641SAndroid Build Coastguard Worker // exit_code isn't supportable.
311*635a8641SAndroid Build Coastguard Worker DCHECK(IsValid());
312*635a8641SAndroid Build Coastguard Worker CHECK_GT(process_, 0);
313*635a8641SAndroid Build Coastguard Worker
314*635a8641SAndroid Build Coastguard Worker bool did_terminate = kill(process_, SIGTERM) == 0;
315*635a8641SAndroid Build Coastguard Worker
316*635a8641SAndroid Build Coastguard Worker if (wait && did_terminate) {
317*635a8641SAndroid Build Coastguard Worker if (WaitForExitWithTimeout(TimeDelta::FromSeconds(60), nullptr))
318*635a8641SAndroid Build Coastguard Worker return true;
319*635a8641SAndroid Build Coastguard Worker did_terminate = kill(process_, SIGKILL) == 0;
320*635a8641SAndroid Build Coastguard Worker if (did_terminate)
321*635a8641SAndroid Build Coastguard Worker return WaitForExit(nullptr);
322*635a8641SAndroid Build Coastguard Worker }
323*635a8641SAndroid Build Coastguard Worker
324*635a8641SAndroid Build Coastguard Worker if (!did_terminate)
325*635a8641SAndroid Build Coastguard Worker DPLOG(ERROR) << "Unable to terminate process " << process_;
326*635a8641SAndroid Build Coastguard Worker
327*635a8641SAndroid Build Coastguard Worker return did_terminate;
328*635a8641SAndroid Build Coastguard Worker }
329*635a8641SAndroid Build Coastguard Worker #endif // !defined(OS_NACL_NONSFI)
330*635a8641SAndroid Build Coastguard Worker
WaitForExit(int * exit_code) const331*635a8641SAndroid Build Coastguard Worker bool Process::WaitForExit(int* exit_code) const {
332*635a8641SAndroid Build Coastguard Worker return WaitForExitWithTimeout(TimeDelta::Max(), exit_code);
333*635a8641SAndroid Build Coastguard Worker }
334*635a8641SAndroid Build Coastguard Worker
WaitForExitWithTimeout(TimeDelta timeout,int * exit_code) const335*635a8641SAndroid Build Coastguard Worker bool Process::WaitForExitWithTimeout(TimeDelta timeout, int* exit_code) const {
336*635a8641SAndroid Build Coastguard Worker if (!timeout.is_zero())
337*635a8641SAndroid Build Coastguard Worker internal::AssertBaseSyncPrimitivesAllowed();
338*635a8641SAndroid Build Coastguard Worker
339*635a8641SAndroid Build Coastguard Worker // Record the event that this thread is blocking upon (for hang diagnosis).
340*635a8641SAndroid Build Coastguard Worker base::debug::ScopedProcessWaitActivity process_activity(this);
341*635a8641SAndroid Build Coastguard Worker
342*635a8641SAndroid Build Coastguard Worker int local_exit_code = 0;
343*635a8641SAndroid Build Coastguard Worker bool exited = WaitForExitWithTimeoutImpl(Handle(), &local_exit_code, timeout);
344*635a8641SAndroid Build Coastguard Worker if (exited) {
345*635a8641SAndroid Build Coastguard Worker Exited(local_exit_code);
346*635a8641SAndroid Build Coastguard Worker if (exit_code)
347*635a8641SAndroid Build Coastguard Worker *exit_code = local_exit_code;
348*635a8641SAndroid Build Coastguard Worker }
349*635a8641SAndroid Build Coastguard Worker return exited;
350*635a8641SAndroid Build Coastguard Worker }
351*635a8641SAndroid Build Coastguard Worker
Exited(int exit_code) const352*635a8641SAndroid Build Coastguard Worker void Process::Exited(int exit_code) const {}
353*635a8641SAndroid Build Coastguard Worker
354*635a8641SAndroid Build Coastguard Worker #if !defined(OS_LINUX) && !defined(OS_MACOSX) && !defined(OS_AIX)
IsProcessBackgrounded() const355*635a8641SAndroid Build Coastguard Worker bool Process::IsProcessBackgrounded() const {
356*635a8641SAndroid Build Coastguard Worker // See SetProcessBackgrounded().
357*635a8641SAndroid Build Coastguard Worker DCHECK(IsValid());
358*635a8641SAndroid Build Coastguard Worker return false;
359*635a8641SAndroid Build Coastguard Worker }
360*635a8641SAndroid Build Coastguard Worker
SetProcessBackgrounded(bool value)361*635a8641SAndroid Build Coastguard Worker bool Process::SetProcessBackgrounded(bool value) {
362*635a8641SAndroid Build Coastguard Worker // Not implemented for POSIX systems other than Linux and Mac. With POSIX, if
363*635a8641SAndroid Build Coastguard Worker // we were to lower the process priority we wouldn't be able to raise it back
364*635a8641SAndroid Build Coastguard Worker // to its initial priority.
365*635a8641SAndroid Build Coastguard Worker NOTIMPLEMENTED();
366*635a8641SAndroid Build Coastguard Worker return false;
367*635a8641SAndroid Build Coastguard Worker }
368*635a8641SAndroid Build Coastguard Worker #endif // !defined(OS_LINUX) && !defined(OS_MACOSX) && !defined(OS_AIX)
369*635a8641SAndroid Build Coastguard Worker
GetPriority() const370*635a8641SAndroid Build Coastguard Worker int Process::GetPriority() const {
371*635a8641SAndroid Build Coastguard Worker DCHECK(IsValid());
372*635a8641SAndroid Build Coastguard Worker return getpriority(PRIO_PROCESS, process_);
373*635a8641SAndroid Build Coastguard Worker }
374*635a8641SAndroid Build Coastguard Worker
375*635a8641SAndroid Build Coastguard Worker } // namespace base
376