blob: c5f92081fcdce25a0180d87b960846bb8822b04a [file] [log] [blame]
Elly Jonesa44d22d2012-01-05 18:05:56 -05001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Elly Jones1c4c3a12011-12-20 15:01:59 -05002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Alex Vakulenko262be3f2014-07-30 15:25:50 -07005#include "debugd/src/process_with_output.h"
Elly Jones1c4c3a12011-12-20 15:01:59 -05006
7#include <base/basictypes.h>
Elly Jones1c4c3a12011-12-20 15:01:59 -05008#include <base/file_util.h>
Ben Chan5facf4a2014-07-23 16:36:54 -07009#include <base/files/file_path.h>
Ben Chan9953a592014-02-05 23:32:00 -080010#include <base/strings/string_split.h>
Elly Jones1c4c3a12011-12-20 15:01:59 -050011
12namespace debugd {
13
Ben Chan78f89532014-08-29 09:35:09 -070014ProcessWithOutput::ProcessWithOutput() : outfile_(NULL) {}
15
Elly Jones1c4c3a12011-12-20 15:01:59 -050016ProcessWithOutput::~ProcessWithOutput() {
17 if (outfile_)
18 fclose(outfile_);
Ben Chan78f89532014-08-29 09:35:09 -070019
Elly Jones1c4c3a12011-12-20 15:01:59 -050020 if (!outfile_path_.empty())
Ben Chan9953a592014-02-05 23:32:00 -080021 base::DeleteFile(outfile_path_, false); // not recursive
Elly Jones1c4c3a12011-12-20 15:01:59 -050022}
23
24bool ProcessWithOutput::Init() {
Elly Fong-Jonesd9a16cd2012-11-12 16:09:49 -050025 if (!SandboxedProcess::Init())
26 return false;
Ben Chan78f89532014-08-29 09:35:09 -070027
Ben Chan9953a592014-02-05 23:32:00 -080028 outfile_ = base::CreateAndOpenTemporaryFile(&outfile_path_);
Elly Jones1c4c3a12011-12-20 15:01:59 -050029 if (!outfile_)
30 return false;
Ben Chan78f89532014-08-29 09:35:09 -070031
Elly Jones1c4c3a12011-12-20 15:01:59 -050032 // We can't just RedirectOutput to the file we just created, since
33 // RedirectOutput uses O_CREAT | O_EXCL to open the target file (i.e., it'll
34 // fail if the file already exists). We can't CreateTemporaryFile() and then
35 // use that filename, since we'd have to remove it before using
36 // RedirectOutput, which exposes us to a /tmp race. Instead, bind outfile_'s
37 // fd to the subprocess's stdout and stderr.
38 BindFd(fileno(outfile_), STDOUT_FILENO);
39 BindFd(fileno(outfile_), STDERR_FILENO);
40 return true;
41}
42
43bool ProcessWithOutput::GetOutputLines(std::vector<std::string>* output) {
44 std::string contents;
Ben Chan9953a592014-02-05 23:32:00 -080045 if (!base::ReadFileToString(outfile_path_, &contents))
Elly Jones1c4c3a12011-12-20 15:01:59 -050046 return false;
Ben Chan78f89532014-08-29 09:35:09 -070047
Elly Jones1c4c3a12011-12-20 15:01:59 -050048 base::SplitString(contents, '\n', output);
49 return true;
50}
51
52bool ProcessWithOutput::GetOutput(std::string* output) {
Ben Chan9953a592014-02-05 23:32:00 -080053 return base::ReadFileToString(outfile_path_, output);
Elly Jones1c4c3a12011-12-20 15:01:59 -050054}
55
Ben Chana0011d82014-05-13 00:19:29 -070056} // namespace debugd