summaryrefslogtreecommitdiffstats
path: root/base/process_util_posix.cc
diff options
context:
space:
mode:
authorphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-17 09:57:52 +0000
committerphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-17 09:57:52 +0000
commitc0b210ee445f489f34a6565f51adb62f10988562 (patch)
tree0f9fd1d1061927fcd4865d0e951858473ceab398 /base/process_util_posix.cc
parent3b3cc646c182ca1578e745c110ba47af34468b15 (diff)
downloadchromium_src-c0b210ee445f489f34a6565f51adb62f10988562.zip
chromium_src-c0b210ee445f489f34a6565f51adb62f10988562.tar.gz
chromium_src-c0b210ee445f489f34a6565f51adb62f10988562.tar.bz2
Add GetAppOutput function, a better replacement for popen.
It will replace popen call in chrome_process_util_linux. I don't see much benefit in having a Windows implementation (not many useful programs you can launch and get output), so POSIX-only. Review URL: http://codereview.chromium.org/67226 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@13920 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/process_util_posix.cc')
-rw-r--r--base/process_util_posix.cc68
1 files changed, 68 insertions, 0 deletions
diff --git a/base/process_util_posix.cc b/base/process_util_posix.cc
index d55f65d..75c9b96 100644
--- a/base/process_util_posix.cc
+++ b/base/process_util_posix.cc
@@ -312,6 +312,74 @@ int ProcessMetrics::GetCPUUsage() {
return cpu;
}
+bool GetAppOutput(const CommandLine& cl, std::string* output) {
+ int pipe_fd[2];
+ pid_t pid;
+
+ if (pipe(pipe_fd) < 0)
+ return false;
+
+ switch (pid = fork()) {
+ case -1: // error
+ close(pipe_fd[0]);
+ close(pipe_fd[1]);
+ return false;
+ case 0: // child
+ {
+ int rv;
+ do {
+ rv = dup2(pipe_fd[1], STDOUT_FILENO);
+ } while (rv == -1 && errno == EINTR);
+ do {
+ rv = dup2(pipe_fd[1], STDERR_FILENO);
+ } while (rv == -1 && errno == EINTR);
+ if (pipe_fd[0] != STDOUT_FILENO && pipe_fd[0] != STDERR_FILENO)
+ close(pipe_fd[0]);
+ if (pipe_fd[1] != STDOUT_FILENO && pipe_fd[1] != STDERR_FILENO)
+ close(pipe_fd[1]);
+
+ const std::vector<std::string> argv = cl.argv();
+ char* argv_cstr[argv.size() + 1];
+ for (size_t i = 0; i < argv.size(); i++)
+ argv_cstr[i] = const_cast<char*>(argv[i].c_str());
+ argv_cstr[argv.size()] = NULL;
+ execvp(argv_cstr[0], argv_cstr);
+ exit(127);
+ }
+ default: // parent
+ {
+ // Close our writing end of pipe now. Otherwise later read would not
+ // be able to detect end of child's output (in theory we could still
+ // write to the pipe).
+ close(pipe_fd[1]);
+
+ int exit_code = EXIT_FAILURE;
+ bool success = WaitForExitCode(pid, &exit_code);
+ if (!success || exit_code != EXIT_SUCCESS) {
+ close(pipe_fd[0]);
+ return false;
+ }
+
+ char buffer[256];
+ std::string buf_output;
+ ssize_t bytes_read = 0;
+
+ while (true) {
+ bytes_read = read(pipe_fd[0], buffer, sizeof(buffer));
+ if (bytes_read == 0)
+ break;
+ if (bytes_read == -1 && errno != EINTR)
+ break;
+ if (bytes_read > 0)
+ buf_output.append(buffer, bytes_read);
+ }
+ output->assign(buf_output);
+ close(pipe_fd[0]);
+ return true;
+ }
+ }
+}
+
int GetProcessCount(const std::wstring& executable_name,
const ProcessFilter* filter) {
int count = 0;