Enterprise policy: Ignore the deprecated ForceSafeSearch if ForceGoogleSafeSearch...
[chromium-blink-merge.git] / base / process / process_posix.cc
blob389bf76b39a7397828e04b49abc3731c2c469507
1 // Copyright (c) 2011 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.
5 #include "base/process/process.h"
7 #include <sys/resource.h>
8 #include <sys/wait.h>
10 #include "base/files/scoped_file.h"
11 #include "base/logging.h"
12 #include "base/posix/eintr_wrapper.h"
13 #include "base/process/kill.h"
14 #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
16 #if defined(OS_MACOSX)
17 #include <sys/event.h>
18 #endif
20 namespace {
22 #if !defined(OS_NACL_NONSFI)
24 bool WaitpidWithTimeout(base::ProcessHandle handle,
25 int* status,
26 base::TimeDelta wait) {
27 // This POSIX version of this function only guarantees that we wait no less
28 // than |wait| for the process to exit. The child process may
29 // exit sometime before the timeout has ended but we may still block for up
30 // to 256 milliseconds after the fact.
32 // waitpid() has no direct support on POSIX for specifying a timeout, you can
33 // either ask it to block indefinitely or return immediately (WNOHANG).
34 // When a child process terminates a SIGCHLD signal is sent to the parent.
35 // Catching this signal would involve installing a signal handler which may
36 // affect other parts of the application and would be difficult to debug.
38 // Our strategy is to call waitpid() once up front to check if the process
39 // has already exited, otherwise to loop for |wait|, sleeping for
40 // at most 256 milliseconds each time using usleep() and then calling
41 // waitpid(). The amount of time we sleep starts out at 1 milliseconds, and
42 // we double it every 4 sleep cycles.
44 // usleep() is speced to exit if a signal is received for which a handler
45 // has been installed. This means that when a SIGCHLD is sent, it will exit
46 // depending on behavior external to this function.
48 // This function is used primarily for unit tests, if we want to use it in
49 // the application itself it would probably be best to examine other routes.
51 if (wait == base::TimeDelta::Max()) {
52 return HANDLE_EINTR(waitpid(handle, status, 0)) > 0;
55 pid_t ret_pid = HANDLE_EINTR(waitpid(handle, status, WNOHANG));
56 static const int64 kMaxSleepInMicroseconds = 1 << 18; // ~256 milliseconds.
57 int64 max_sleep_time_usecs = 1 << 10; // ~1 milliseconds.
58 int64 double_sleep_time = 0;
60 // If the process hasn't exited yet, then sleep and try again.
61 base::TimeTicks wakeup_time = base::TimeTicks::Now() + wait;
62 while (ret_pid == 0) {
63 base::TimeTicks now = base::TimeTicks::Now();
64 if (now > wakeup_time)
65 break;
66 // Guaranteed to be non-negative!
67 int64 sleep_time_usecs = (wakeup_time - now).InMicroseconds();
68 // Sleep for a bit while we wait for the process to finish.
69 if (sleep_time_usecs > max_sleep_time_usecs)
70 sleep_time_usecs = max_sleep_time_usecs;
72 // usleep() will return 0 and set errno to EINTR on receipt of a signal
73 // such as SIGCHLD.
74 usleep(sleep_time_usecs);
75 ret_pid = HANDLE_EINTR(waitpid(handle, status, WNOHANG));
77 if ((max_sleep_time_usecs < kMaxSleepInMicroseconds) &&
78 (double_sleep_time++ % 4 == 0)) {
79 max_sleep_time_usecs *= 2;
83 return ret_pid > 0;
86 #if defined(OS_MACOSX)
87 // Using kqueue on Mac so that we can wait on non-child processes.
88 // We can't use kqueues on child processes because we need to reap
89 // our own children using wait.
90 static bool WaitForSingleNonChildProcess(base::ProcessHandle handle,
91 base::TimeDelta wait) {
92 DCHECK_GT(handle, 0);
93 DCHECK_GT(wait, base::TimeDelta());
95 base::ScopedFD kq(kqueue());
96 if (!kq.is_valid()) {
97 DPLOG(ERROR) << "kqueue";
98 return false;
101 struct kevent change = {0};
102 EV_SET(&change, handle, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, NULL);
103 int result = HANDLE_EINTR(kevent(kq.get(), &change, 1, NULL, 0, NULL));
104 if (result == -1) {
105 if (errno == ESRCH) {
106 // If the process wasn't found, it must be dead.
107 return true;
110 DPLOG(ERROR) << "kevent (setup " << handle << ")";
111 return false;
114 // Keep track of the elapsed time to be able to restart kevent if it's
115 // interrupted.
116 bool wait_forever = (wait == base::TimeDelta::Max());
117 base::TimeDelta remaining_delta;
118 base::TimeTicks deadline;
119 if (!wait_forever) {
120 remaining_delta = wait;
121 deadline = base::TimeTicks::Now() + remaining_delta;
124 result = -1;
125 struct kevent event = {0};
127 while (wait_forever || remaining_delta > base::TimeDelta()) {
128 struct timespec remaining_timespec;
129 struct timespec* remaining_timespec_ptr;
130 if (wait_forever) {
131 remaining_timespec_ptr = NULL;
132 } else {
133 remaining_timespec = remaining_delta.ToTimeSpec();
134 remaining_timespec_ptr = &remaining_timespec;
137 result = kevent(kq.get(), NULL, 0, &event, 1, remaining_timespec_ptr);
139 if (result == -1 && errno == EINTR) {
140 if (!wait_forever) {
141 remaining_delta = deadline - base::TimeTicks::Now();
143 result = 0;
144 } else {
145 break;
149 if (result < 0) {
150 DPLOG(ERROR) << "kevent (wait " << handle << ")";
151 return false;
152 } else if (result > 1) {
153 DLOG(ERROR) << "kevent (wait " << handle << "): unexpected result "
154 << result;
155 return false;
156 } else if (result == 0) {
157 // Timed out.
158 return false;
161 DCHECK_EQ(result, 1);
163 if (event.filter != EVFILT_PROC ||
164 (event.fflags & NOTE_EXIT) == 0 ||
165 event.ident != static_cast<uintptr_t>(handle)) {
166 DLOG(ERROR) << "kevent (wait " << handle
167 << "): unexpected event: filter=" << event.filter
168 << ", fflags=" << event.fflags
169 << ", ident=" << event.ident;
170 return false;
173 return true;
175 #endif // OS_MACOSX
177 bool WaitForExitWithTimeoutImpl(base::ProcessHandle handle,
178 int* exit_code,
179 base::TimeDelta timeout) {
180 base::ProcessHandle parent_pid = base::GetParentProcessId(handle);
181 base::ProcessHandle our_pid = base::GetCurrentProcessHandle();
182 if (parent_pid != our_pid) {
183 #if defined(OS_MACOSX)
184 // On Mac we can wait on non child processes.
185 return WaitForSingleNonChildProcess(handle, timeout);
186 #else
187 // Currently on Linux we can't handle non child processes.
188 NOTIMPLEMENTED();
189 #endif // OS_MACOSX
192 int status;
193 if (!WaitpidWithTimeout(handle, &status, timeout))
194 return false;
195 if (WIFSIGNALED(status)) {
196 *exit_code = -1;
197 return true;
199 if (WIFEXITED(status)) {
200 *exit_code = WEXITSTATUS(status);
201 return true;
203 return false;
205 #endif // !defined(OS_NACL_NONSFI)
207 } // namespace
209 namespace base {
211 Process::Process(ProcessHandle handle) : process_(handle) {
214 Process::Process(RValue other)
215 : process_(other.object->process_) {
216 other.object->Close();
219 Process& Process::operator=(RValue other) {
220 if (this != other.object) {
221 process_ = other.object->process_;
222 other.object->Close();
224 return *this;
227 // static
228 Process Process::Current() {
229 return Process(GetCurrentProcessHandle());
232 // static
233 Process Process::Open(ProcessId pid) {
234 if (pid == GetCurrentProcId())
235 return Current();
237 // On POSIX process handles are the same as PIDs.
238 return Process(pid);
241 // static
242 Process Process::OpenWithExtraPrivileges(ProcessId pid) {
243 // On POSIX there are no privileges to set.
244 return Open(pid);
247 // static
248 Process Process::DeprecatedGetProcessFromHandle(ProcessHandle handle) {
249 DCHECK_NE(handle, GetCurrentProcessHandle());
250 return Process(handle);
253 #if !defined(OS_LINUX)
254 // static
255 bool Process::CanBackgroundProcesses() {
256 return false;
258 #endif // !defined(OS_LINUX)
260 bool Process::IsValid() const {
261 return process_ != kNullProcessHandle;
264 ProcessHandle Process::Handle() const {
265 return process_;
268 Process Process::Duplicate() const {
269 if (is_current())
270 return Current();
272 return Process(process_);
275 ProcessId Process::Pid() const {
276 DCHECK(IsValid());
277 return GetProcId(process_);
280 bool Process::is_current() const {
281 return process_ == GetCurrentProcessHandle();
284 void Process::Close() {
285 process_ = kNullProcessHandle;
286 // if the process wasn't terminated (so we waited) or the state
287 // wasn't already collected w/ a wait from process_utils, we're gonna
288 // end up w/ a zombie when it does finally exit.
291 #if !defined(OS_NACL_NONSFI)
292 bool Process::Terminate(int exit_code, bool wait) const {
293 // result_code isn't supportable.
294 DCHECK(IsValid());
295 DCHECK_GT(process_, 1);
296 bool result = kill(process_, SIGTERM) == 0;
297 if (result && wait) {
298 int tries = 60;
300 if (RunningOnValgrind()) {
301 // Wait for some extra time when running under Valgrind since the child
302 // processes may take some time doing leak checking.
303 tries *= 2;
306 unsigned sleep_ms = 4;
308 // The process may not end immediately due to pending I/O
309 bool exited = false;
310 while (tries-- > 0) {
311 pid_t pid = HANDLE_EINTR(waitpid(process_, NULL, WNOHANG));
312 if (pid == process_) {
313 exited = true;
314 break;
316 if (pid == -1) {
317 if (errno == ECHILD) {
318 // The wait may fail with ECHILD if another process also waited for
319 // the same pid, causing the process state to get cleaned up.
320 exited = true;
321 break;
323 DPLOG(ERROR) << "Error waiting for process " << process_;
326 usleep(sleep_ms * 1000);
327 const unsigned kMaxSleepMs = 1000;
328 if (sleep_ms < kMaxSleepMs)
329 sleep_ms *= 2;
332 // If we're waiting and the child hasn't died by now, force it
333 // with a SIGKILL.
334 if (!exited)
335 result = kill(process_, SIGKILL) == 0;
338 if (!result)
339 DPLOG(ERROR) << "Unable to terminate process " << process_;
341 return result;
343 #endif // !defined(OS_NACL_NONSFI)
345 bool Process::WaitForExit(int* exit_code) {
346 return WaitForExitWithTimeout(TimeDelta::Max(), exit_code);
349 bool Process::WaitForExitWithTimeout(TimeDelta timeout, int* exit_code) {
350 return WaitForExitWithTimeoutImpl(Handle(), exit_code, timeout);
353 #if !defined(OS_LINUX)
354 bool Process::IsProcessBackgrounded() const {
355 // See SetProcessBackgrounded().
356 DCHECK(IsValid());
357 return false;
360 bool Process::SetProcessBackgrounded(bool value) {
361 // POSIX only allows lowering the priority of a process, so if we
362 // were to lower it we wouldn't be able to raise it back to its initial
363 // priority.
364 DCHECK(IsValid());
365 return false;
367 #endif // !defined(OS_LINUX)
369 int Process::GetPriority() const {
370 DCHECK(IsValid());
371 return getpriority(PRIO_PROCESS, process_);
374 } // namespace base