1 : //* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
3 : // Use of this source code is governed by a BSD-style license that can be
4 : // found in the LICENSE file.
5 :
6 : #include <dirent.h>
7 : #include <errno.h>
8 : #include <fcntl.h>
9 : #include <signal.h>
10 : #include <stdlib.h>
11 : #include <sys/resource.h>
12 : #include <sys/time.h>
13 : #include <sys/types.h>
14 : #include <sys/wait.h>
15 : #include <unistd.h>
16 :
17 : #include <limits>
18 : #include <set>
19 :
20 : #include "base/basictypes.h"
21 : #include "base/eintr_wrapper.h"
22 : #include "base/logging.h"
23 : #include "base/platform_thread.h"
24 : #include "base/process_util.h"
25 : #include "base/scoped_ptr.h"
26 : #include "base/sys_info.h"
27 : #include "base/time.h"
28 : #include "base/waitable_event.h"
29 : #include "base/dir_reader_posix.h"
30 :
31 : const int kMicrosecondsPerSecond = 1000000;
32 :
33 : namespace base {
34 :
35 1 : ProcessId GetCurrentProcId() {
36 1 : return getpid();
37 : }
38 :
39 0 : ProcessHandle GetCurrentProcessHandle() {
40 0 : return GetCurrentProcId();
41 : }
42 :
43 1 : bool OpenProcessHandle(ProcessId pid, ProcessHandle* handle) {
44 : // On Posix platforms, process handles are the same as PIDs, so we
45 : // don't need to do anything.
46 1 : *handle = pid;
47 1 : return true;
48 : }
49 :
50 0 : bool OpenPrivilegedProcessHandle(ProcessId pid, ProcessHandle* handle) {
51 : // On POSIX permissions are checked for each operation on process,
52 : // not when opening a "handle".
53 0 : return OpenProcessHandle(pid, handle);
54 : }
55 :
56 0 : void CloseProcessHandle(ProcessHandle process) {
57 : // See OpenProcessHandle, nothing to do.
58 : return;
59 : }
60 :
61 0 : ProcessId GetProcId(ProcessHandle process) {
62 0 : return process;
63 : }
64 :
65 : // Attempts to kill the process identified by the given process
66 : // entry structure. Ignores specified exit_code; posix can't force that.
67 : // Returns true if this is successful, false otherwise.
68 0 : bool KillProcess(ProcessHandle process_id, int exit_code, bool wait) {
69 0 : bool result = kill(process_id, SIGTERM) == 0;
70 :
71 0 : if (result && wait) {
72 0 : int tries = 60;
73 : // The process may not end immediately due to pending I/O
74 0 : while (tries-- > 0) {
75 0 : int pid = HANDLE_EINTR(waitpid(process_id, NULL, WNOHANG));
76 0 : if (pid == process_id)
77 0 : break;
78 :
79 0 : sleep(1);
80 : }
81 :
82 0 : result = kill(process_id, SIGKILL) == 0;
83 : }
84 :
85 0 : if (!result)
86 0 : DLOG(ERROR) << "Unable to terminate process.";
87 :
88 0 : return result;
89 : }
90 :
91 : #ifdef ANDROID
92 : typedef unsigned long int rlim_t;
93 : #endif
94 :
95 : // A class to handle auto-closing of DIR*'s.
96 : class ScopedDIRClose {
97 : public:
98 0 : inline void operator()(DIR* x) const {
99 0 : if (x) {
100 0 : closedir(x);
101 : }
102 0 : }
103 : };
104 : typedef scoped_ptr_malloc<DIR, ScopedDIRClose> ScopedDIR;
105 :
106 :
107 0 : void CloseSuperfluousFds(const base::InjectiveMultimap& saved_mapping) {
108 : // DANGER: no calls to malloc are allowed from now on:
109 : // http://crbug.com/36678
110 : #if defined(ANDROID)
111 : static const rlim_t kSystemDefaultMaxFds = 1024;
112 : static const char kFDDir[] = "/proc/self/fd";
113 : #elif defined(OS_LINUX)
114 : static const rlim_t kSystemDefaultMaxFds = 8192;
115 : static const char kFDDir[] = "/proc/self/fd";
116 : #elif defined(OS_MACOSX)
117 : static const rlim_t kSystemDefaultMaxFds = 256;
118 : static const char kFDDir[] = "/dev/fd";
119 : #endif
120 :
121 : // Get the maximum number of FDs possible.
122 : struct rlimit nofile;
123 : rlim_t max_fds;
124 0 : if (getrlimit(RLIMIT_NOFILE, &nofile)) {
125 : // getrlimit failed. Take a best guess.
126 0 : max_fds = kSystemDefaultMaxFds;
127 0 : DLOG(ERROR) << "getrlimit(RLIMIT_NOFILE) failed: " << errno;
128 : } else {
129 0 : max_fds = nofile.rlim_cur;
130 : }
131 :
132 0 : if (max_fds > INT_MAX)
133 0 : max_fds = INT_MAX;
134 :
135 0 : DirReaderPosix fd_dir(kFDDir);
136 :
137 0 : if (!fd_dir.IsValid()) {
138 : // Fallback case: Try every possible fd.
139 0 : for (rlim_t i = 0; i < max_fds; ++i) {
140 0 : const int fd = static_cast<int>(i);
141 0 : if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO)
142 0 : continue;
143 0 : InjectiveMultimap::const_iterator j;
144 0 : for (j = saved_mapping.begin(); j != saved_mapping.end(); j++) {
145 0 : if (fd == j->dest)
146 0 : break;
147 : }
148 0 : if (j != saved_mapping.end())
149 0 : continue;
150 :
151 : // Since we're just trying to close anything we can find,
152 : // ignore any error return values of close().
153 0 : HANDLE_EINTR(close(fd));
154 : }
155 : return;
156 : }
157 :
158 0 : const int dir_fd = fd_dir.fd();
159 :
160 0 : for ( ; fd_dir.Next(); ) {
161 : // Skip . and .. entries.
162 0 : if (fd_dir.name()[0] == '.')
163 0 : continue;
164 :
165 : char *endptr;
166 0 : errno = 0;
167 0 : const long int fd = strtol(fd_dir.name(), &endptr, 10);
168 0 : if (fd_dir.name()[0] == 0 || *endptr || fd < 0 || errno)
169 0 : continue;
170 0 : if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO)
171 0 : continue;
172 0 : InjectiveMultimap::const_iterator i;
173 0 : for (i = saved_mapping.begin(); i != saved_mapping.end(); i++) {
174 0 : if (fd == i->dest)
175 0 : break;
176 : }
177 0 : if (i != saved_mapping.end())
178 0 : continue;
179 0 : if (fd == dir_fd)
180 0 : continue;
181 :
182 : // When running under Valgrind, Valgrind opens several FDs for its
183 : // own use and will complain if we try to close them. All of
184 : // these FDs are >= |max_fds|, so we can check against that here
185 : // before closing. See https://bugs.kde.org/show_bug.cgi?id=191758
186 0 : if (fd < static_cast<int>(max_fds)) {
187 0 : int ret = HANDLE_EINTR(close(fd));
188 0 : if (ret != 0) {
189 0 : DLOG(ERROR) << "Problem closing fd";
190 : }
191 : }
192 : }
193 : }
194 :
195 : // Sets all file descriptors to close on exec except for stdin, stdout
196 : // and stderr.
197 : // TODO(agl): Remove this function. It's fundamentally broken for multithreaded
198 : // apps.
199 0 : void SetAllFDsToCloseOnExec() {
200 : #if defined(OS_LINUX)
201 0 : const char fd_dir[] = "/proc/self/fd";
202 : #elif defined(OS_MACOSX)
203 : const char fd_dir[] = "/dev/fd";
204 : #endif
205 0 : ScopedDIR dir_closer(opendir(fd_dir));
206 0 : DIR *dir = dir_closer.get();
207 0 : if (NULL == dir) {
208 0 : DLOG(ERROR) << "Unable to open " << fd_dir;
209 : return;
210 : }
211 :
212 : struct dirent *ent;
213 0 : while ((ent = readdir(dir))) {
214 : // Skip . and .. entries.
215 0 : if (ent->d_name[0] == '.')
216 0 : continue;
217 0 : int i = atoi(ent->d_name);
218 : // We don't close stdin, stdout or stderr.
219 0 : if (i <= STDERR_FILENO)
220 0 : continue;
221 :
222 0 : int flags = fcntl(i, F_GETFD);
223 0 : if ((flags == -1) || (fcntl(i, F_SETFD, flags | FD_CLOEXEC) == -1)) {
224 0 : DLOG(ERROR) << "fcntl failure.";
225 : }
226 : }
227 : }
228 :
229 0 : ProcessMetrics::ProcessMetrics(ProcessHandle process) : process_(process),
230 : last_time_(0),
231 0 : last_system_time_(0) {
232 0 : processor_count_ = base::SysInfo::NumberOfProcessors();
233 0 : }
234 :
235 : // static
236 0 : ProcessMetrics* ProcessMetrics::CreateProcessMetrics(ProcessHandle process) {
237 0 : return new ProcessMetrics(process);
238 : }
239 :
240 0 : ProcessMetrics::~ProcessMetrics() { }
241 :
242 0 : void EnableTerminationOnHeapCorruption() {
243 : // On POSIX, there nothing to do AFAIK.
244 0 : }
245 :
246 0 : void RaiseProcessToHighPriority() {
247 : // On POSIX, we don't actually do anything here. We could try to nice() or
248 : // setpriority() or sched_getscheduler, but these all require extra rights.
249 0 : }
250 :
251 0 : bool DidProcessCrash(bool* child_exited, ProcessHandle handle) {
252 : int status;
253 0 : const int result = HANDLE_EINTR(waitpid(handle, &status, WNOHANG));
254 0 : if (result == -1) {
255 0 : LOG(ERROR) << "waitpid failed pid:" << handle << " errno:" << errno;
256 0 : if (child_exited)
257 0 : *child_exited = false;
258 0 : return false;
259 0 : } else if (result == 0) {
260 : // the child hasn't exited yet.
261 0 : if (child_exited)
262 0 : *child_exited = false;
263 0 : return false;
264 : }
265 :
266 0 : if (child_exited)
267 0 : *child_exited = true;
268 :
269 0 : if (WIFSIGNALED(status)) {
270 0 : switch(WTERMSIG(status)) {
271 : case SIGSEGV:
272 : case SIGILL:
273 : case SIGABRT:
274 : case SIGFPE:
275 0 : return true;
276 : default:
277 0 : return false;
278 : }
279 : }
280 :
281 0 : if (WIFEXITED(status))
282 0 : return WEXITSTATUS(status) != 0;
283 :
284 0 : return false;
285 : }
286 :
287 0 : bool WaitForExitCode(ProcessHandle handle, int* exit_code) {
288 : int status;
289 0 : if (HANDLE_EINTR(waitpid(handle, &status, 0)) == -1) {
290 0 : NOTREACHED();
291 0 : return false;
292 : }
293 :
294 0 : if (WIFEXITED(status)) {
295 0 : *exit_code = WEXITSTATUS(status);
296 0 : return true;
297 : }
298 :
299 : // If it didn't exit cleanly, it must have been signaled.
300 0 : DCHECK(WIFSIGNALED(status));
301 0 : return false;
302 : }
303 :
304 : namespace {
305 :
306 0 : int WaitpidWithTimeout(ProcessHandle handle, int wait_milliseconds,
307 : bool* success) {
308 : // This POSIX version of this function only guarantees that we wait no less
309 : // than |wait_milliseconds| for the proces to exit. The child process may
310 : // exit sometime before the timeout has ended but we may still block for
311 : // up to 0.25 seconds after the fact.
312 : //
313 : // waitpid() has no direct support on POSIX for specifying a timeout, you can
314 : // either ask it to block indefinitely or return immediately (WNOHANG).
315 : // When a child process terminates a SIGCHLD signal is sent to the parent.
316 : // Catching this signal would involve installing a signal handler which may
317 : // affect other parts of the application and would be difficult to debug.
318 : //
319 : // Our strategy is to call waitpid() once up front to check if the process
320 : // has already exited, otherwise to loop for wait_milliseconds, sleeping for
321 : // at most 0.25 secs each time using usleep() and then calling waitpid().
322 : //
323 : // usleep() is speced to exit if a signal is received for which a handler
324 : // has been installed. This means that when a SIGCHLD is sent, it will exit
325 : // depending on behavior external to this function.
326 : //
327 : // This function is used primarily for unit tests, if we want to use it in
328 : // the application itself it would probably be best to examine other routes.
329 0 : int status = -1;
330 0 : pid_t ret_pid = HANDLE_EINTR(waitpid(handle, &status, WNOHANG));
331 : static const int64 kQuarterSecondInMicroseconds = kMicrosecondsPerSecond/4;
332 :
333 : // If the process hasn't exited yet, then sleep and try again.
334 : Time wakeup_time = Time::Now() + TimeDelta::FromMilliseconds(
335 0 : wait_milliseconds);
336 0 : while (ret_pid == 0) {
337 0 : Time now = Time::Now();
338 0 : if (now > wakeup_time)
339 0 : break;
340 : // Guaranteed to be non-negative!
341 0 : int64 sleep_time_usecs = (wakeup_time - now).InMicroseconds();
342 : // Don't sleep for more than 0.25 secs at a time.
343 0 : if (sleep_time_usecs > kQuarterSecondInMicroseconds) {
344 0 : sleep_time_usecs = kQuarterSecondInMicroseconds;
345 : }
346 :
347 : // usleep() will return 0 and set errno to EINTR on receipt of a signal
348 : // such as SIGCHLD.
349 0 : usleep(sleep_time_usecs);
350 0 : ret_pid = HANDLE_EINTR(waitpid(handle, &status, WNOHANG));
351 : }
352 :
353 0 : if (success)
354 0 : *success = (ret_pid != -1);
355 :
356 0 : return status;
357 : }
358 :
359 : } // namespace
360 :
361 0 : bool WaitForSingleProcess(ProcessHandle handle, int wait_milliseconds) {
362 : bool waitpid_success;
363 : int status;
364 0 : if (wait_milliseconds == base::kNoTimeout)
365 0 : waitpid_success = (HANDLE_EINTR(waitpid(handle, &status, 0)) != -1);
366 : else
367 0 : status = WaitpidWithTimeout(handle, wait_milliseconds, &waitpid_success);
368 0 : if (status != -1) {
369 0 : DCHECK(waitpid_success);
370 0 : return WIFEXITED(status);
371 : } else {
372 0 : return false;
373 : }
374 : }
375 :
376 0 : bool CrashAwareSleep(ProcessHandle handle, int wait_milliseconds) {
377 : bool waitpid_success;
378 0 : int status = WaitpidWithTimeout(handle, wait_milliseconds, &waitpid_success);
379 0 : if (status != -1) {
380 0 : DCHECK(waitpid_success);
381 0 : return !(WIFEXITED(status) || WIFSIGNALED(status));
382 : } else {
383 : // If waitpid returned with an error, then the process doesn't exist
384 : // (which most probably means it didn't exist before our call).
385 0 : return waitpid_success;
386 : }
387 : }
388 :
389 : namespace {
390 :
391 0 : int64 TimeValToMicroseconds(const struct timeval& tv) {
392 0 : return tv.tv_sec * kMicrosecondsPerSecond + tv.tv_usec;
393 : }
394 :
395 : }
396 :
397 0 : int ProcessMetrics::GetCPUUsage() {
398 : struct timeval now;
399 : struct rusage usage;
400 :
401 0 : int retval = gettimeofday(&now, NULL);
402 0 : if (retval)
403 0 : return 0;
404 0 : retval = getrusage(RUSAGE_SELF, &usage);
405 0 : if (retval)
406 0 : return 0;
407 :
408 0 : int64 system_time = (TimeValToMicroseconds(usage.ru_stime) +
409 0 : TimeValToMicroseconds(usage.ru_utime)) /
410 0 : processor_count_;
411 0 : int64 time = TimeValToMicroseconds(now);
412 :
413 0 : if ((last_system_time_ == 0) || (last_time_ == 0)) {
414 : // First call, just set the last values.
415 0 : last_system_time_ = system_time;
416 0 : last_time_ = time;
417 0 : return 0;
418 : }
419 :
420 0 : int64 system_time_delta = system_time - last_system_time_;
421 0 : int64 time_delta = time - last_time_;
422 0 : DCHECK(time_delta != 0);
423 0 : if (time_delta == 0)
424 0 : return 0;
425 :
426 : // We add time_delta / 2 so the result is rounded.
427 : int cpu = static_cast<int>((system_time_delta * 100 + time_delta / 2) /
428 0 : time_delta);
429 :
430 0 : last_system_time_ = system_time;
431 0 : last_time_ = time;
432 :
433 0 : return cpu;
434 : }
435 :
436 0 : bool GetAppOutput(const CommandLine& cl, std::string* output) {
437 : int pipe_fd[2];
438 : pid_t pid;
439 :
440 : // Illegal to allocate memory after fork and before execvp
441 0 : InjectiveMultimap fd_shuffle1, fd_shuffle2;
442 0 : fd_shuffle1.reserve(3);
443 0 : fd_shuffle2.reserve(3);
444 0 : const std::vector<std::string>& argv = cl.argv();
445 0 : scoped_array<char*> argv_cstr(new char*[argv.size() + 1]);
446 :
447 0 : if (pipe(pipe_fd) < 0)
448 0 : return false;
449 :
450 0 : switch (pid = fork()) {
451 : case -1: // error
452 0 : close(pipe_fd[0]);
453 0 : close(pipe_fd[1]);
454 0 : return false;
455 : case 0: // child
456 : {
457 : // Obscure fork() rule: in the child, if you don't end up doing exec*(),
458 : // you call _exit() instead of exit(). This is because _exit() does not
459 : // call any previously-registered (in the parent) exit handlers, which
460 : // might do things like block waiting for threads that don't even exist
461 : // in the child.
462 0 : int dev_null = open("/dev/null", O_WRONLY);
463 0 : if (dev_null < 0)
464 0 : _exit(127);
465 :
466 0 : fd_shuffle1.push_back(InjectionArc(pipe_fd[1], STDOUT_FILENO, true));
467 0 : fd_shuffle1.push_back(InjectionArc(dev_null, STDERR_FILENO, true));
468 0 : fd_shuffle1.push_back(InjectionArc(dev_null, STDIN_FILENO, true));
469 : // Adding another element here? Remeber to increase the argument to
470 : // reserve(), above.
471 :
472 : std::copy(fd_shuffle1.begin(), fd_shuffle1.end(),
473 0 : std::back_inserter(fd_shuffle2));
474 :
475 : // fd_shuffle1 is mutated by this call because it cannot malloc.
476 0 : if (!ShuffleFileDescriptors(&fd_shuffle1))
477 0 : _exit(127);
478 :
479 0 : CloseSuperfluousFds(fd_shuffle2);
480 :
481 0 : for (size_t i = 0; i < argv.size(); i++)
482 0 : argv_cstr[i] = const_cast<char*>(argv[i].c_str());
483 0 : argv_cstr[argv.size()] = NULL;
484 0 : execvp(argv_cstr[0], argv_cstr.get());
485 0 : _exit(127);
486 : }
487 : default: // parent
488 : {
489 : // Close our writing end of pipe now. Otherwise later read would not
490 : // be able to detect end of child's output (in theory we could still
491 : // write to the pipe).
492 0 : close(pipe_fd[1]);
493 :
494 0 : int exit_code = EXIT_FAILURE;
495 0 : bool success = WaitForExitCode(pid, &exit_code);
496 0 : if (!success || exit_code != EXIT_SUCCESS) {
497 0 : close(pipe_fd[0]);
498 0 : return false;
499 : }
500 :
501 : char buffer[256];
502 0 : std::string buf_output;
503 :
504 0 : while (true) {
505 : ssize_t bytes_read =
506 0 : HANDLE_EINTR(read(pipe_fd[0], buffer, sizeof(buffer)));
507 0 : if (bytes_read <= 0)
508 : break;
509 0 : buf_output.append(buffer, bytes_read);
510 : }
511 0 : output->swap(buf_output);
512 0 : close(pipe_fd[0]);
513 0 : return true;
514 : }
515 : }
516 : }
517 :
518 0 : int GetProcessCount(const std::wstring& executable_name,
519 : const ProcessFilter* filter) {
520 0 : int count = 0;
521 :
522 0 : NamedProcessIterator iter(executable_name, filter);
523 0 : while (iter.NextProcessEntry())
524 0 : ++count;
525 0 : return count;
526 : }
527 :
528 0 : bool KillProcesses(const std::wstring& executable_name, int exit_code,
529 : const ProcessFilter* filter) {
530 0 : bool result = true;
531 : const ProcessEntry* entry;
532 :
533 0 : NamedProcessIterator iter(executable_name, filter);
534 0 : while ((entry = iter.NextProcessEntry()) != NULL)
535 0 : result = KillProcess((*entry).pid, exit_code, true) && result;
536 :
537 0 : return result;
538 : }
539 :
540 0 : bool WaitForProcessesToExit(const std::wstring& executable_name,
541 : int wait_milliseconds,
542 : const ProcessFilter* filter) {
543 0 : bool result = false;
544 :
545 : // TODO(port): This is inefficient, but works if there are multiple procs.
546 : // TODO(port): use waitpid to avoid leaving zombies around
547 :
548 : base::Time end_time = base::Time::Now() +
549 0 : base::TimeDelta::FromMilliseconds(wait_milliseconds);
550 0 : do {
551 0 : NamedProcessIterator iter(executable_name, filter);
552 0 : if (!iter.NextProcessEntry()) {
553 0 : result = true;
554 : break;
555 : }
556 0 : PlatformThread::Sleep(100);
557 0 : } while ((base::Time::Now() - end_time) > base::TimeDelta());
558 :
559 0 : return result;
560 : }
561 :
562 0 : bool CleanupProcesses(const std::wstring& executable_name,
563 : int wait_milliseconds,
564 : int exit_code,
565 : const ProcessFilter* filter) {
566 : bool exited_cleanly =
567 : WaitForProcessesToExit(executable_name, wait_milliseconds,
568 0 : filter);
569 0 : if (!exited_cleanly)
570 0 : KillProcesses(executable_name, exit_code, filter);
571 0 : return exited_cleanly;
572 : }
573 :
574 4392 : } // namespace base
|