blob: 747eefb9a6d17298cdbdacdcc7199b3195dcdc37 [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#ifndef DEBUGD_SRC_PROCESS_WITH_OUTPUT_H_
6#define DEBUGD_SRC_PROCESS_WITH_OUTPUT_H_
Elly Jones1c4c3a12011-12-20 15:01:59 -05007
8#include <string>
9#include <vector>
10
Ben Chan9953a592014-02-05 23:32:00 -080011#include <base/files/file_path.h>
David Pursell300498a2014-11-03 15:47:36 -080012#include <base/files/scoped_file.h>
Eric Carusocc7106c2017-04-27 14:22:42 -070013#include <brillo/errors/error.h>
Elly Fong-Jonesd9a16cd2012-11-12 16:09:49 -050014
Alex Vakulenko262be3f2014-07-30 15:25:50 -070015#include "debugd/src/sandboxed_process.h"
Elly Jones1c4c3a12011-12-20 15:01:59 -050016
17namespace debugd {
18
David Pursell300498a2014-11-03 15:47:36 -080019// Represents a process whose output can be collected.
Elly Jones1c4c3a12011-12-20 15:01:59 -050020//
21// The process must be Run() to completion before its output can be collected.
David Pursell300498a2014-11-03 15:47:36 -080022// By default both stdout and stderr are included in the output.
Elly Fong-Jonesd9a16cd2012-11-12 16:09:49 -050023class ProcessWithOutput : public SandboxedProcess {
Elly Jones1c4c3a12011-12-20 15:01:59 -050024 public:
Ben Chan81905fb2017-02-08 22:03:11 -080025 using ArgList = std::vector<std::string>;
Ben Chan5399a352017-07-27 23:47:22 -070026
27 static constexpr int kRunError = -1;
David Pursell300498a2014-11-03 15:47:36 -080028
Elly Jones1c4c3a12011-12-20 15:01:59 -050029 ProcessWithOutput();
Ben Chan4b110122014-08-29 08:22:59 -070030 ~ProcessWithOutput() override;
31 bool Init() override;
Paul Moy970e1122020-01-14 16:17:18 -070032 bool Init(const std::vector<std::string>& minijail_extra_args) override;
Wei-Cheng Xiao9076cf52018-10-08 14:33:42 +080033 bool GetOutput(std::string* output) const;
34 bool GetOutputLines(std::vector<std::string>* output) const;
Ben Chana0011d82014-05-13 00:19:29 -070035
David Pursell300498a2014-11-03 15:47:36 -080036 // Reads the stderr output. Must have called set_separate_stderr(true) and
37 // run the process to completion.
38 bool GetError(std::string* error);
39
40 // Separates stderr from stdout. Must be called before Init() to have effect.
41 void set_separate_stderr(bool separate_stderr) {
42 separate_stderr_ = separate_stderr;
43 }
44
45 // Sets whether to use Minijail or not. Disabling Minijail will omit all
46 // sandboxing functionality from the process, and should only be used from
47 // within helper programs that are already sandboxed. The purpose of this is
48 // to allow the process to search PATH for the executable, since Minijail does
49 // not support this.
50 // This must be called before Init() to have any effect. Defaults to true.
51 void set_use_minijail(bool use_minijail) { use_minijail_ = use_minijail; }
52
Wei-Cheng Xiao88aee2412018-10-15 16:03:45 +080053 // Initializes, configures, and runs a ProcessWithOutput. If |disable_sandbox|
54 // is set, |requires_root| will be ignored. The D-Bus error will only be set
55 // if process setup fails, it's up to the caller to check the process exit
56 // code and handle run failures as needed.
David Pursell300498a2014-11-03 15:47:36 -080057 // |stdin| is a string to pipe into the process, and |stdout| and |stderr|
58 // will be filled with the corresponding process output. |error| will be
59 // set if process setup fails and the process was never able to run. All
60 // four of these parameters can be null.
61 // Returns the process exit code or kRunError on setup failure.
62 static int RunProcess(const std::string& command,
63 const ArgList& arguments,
64 bool requires_root,
Wei-Cheng Xiao88aee2412018-10-15 16:03:45 +080065 bool disable_sandbox,
David Pursell300498a2014-11-03 15:47:36 -080066 const std::string* stdin,
67 std::string* stdout,
68 std::string* stderr,
Eric Carusocc7106c2017-04-27 14:22:42 -070069 brillo::ErrorPtr* error);
David Pursell300498a2014-11-03 15:47:36 -080070
71 // Like RunProcess() but to run helper programs. |helper| should be specified
72 // relative to the helpers/ directory.
73 static int RunHelper(const std::string& helper,
74 const ArgList& arguments,
75 bool requires_root,
76 const std::string* stdin,
77 std::string* stdout,
78 std::string* stderr,
Eric Carusocc7106c2017-04-27 14:22:42 -070079 brillo::ErrorPtr* error);
David Pursell300498a2014-11-03 15:47:36 -080080
81 // Like RunProcess() but from within helper programs. This function will
82 // not use minijail0 or any sandboxing (since helper programs should already
83 // be sandboxed) and $PATH will be searched to execute |command|.
84 static int RunProcessFromHelper(const std::string& command,
85 const ArgList& arguments,
86 const std::string* stdin,
87 std::string* stdout,
88 std::string* stderr);
89
Elly Jones1c4c3a12011-12-20 15:01:59 -050090 private:
David Pursell300498a2014-11-03 15:47:36 -080091 base::FilePath outfile_path_, errfile_path_;
92 base::ScopedFILE outfile_, errfile_;
93 bool separate_stderr_, use_minijail_;
94
95 // Private function to do the work of running the process and handling I/O.
96 static int DoRunProcess(const std::string& command,
97 const ArgList& arguments,
98 const std::string* stdin,
99 std::string* stdout,
100 std::string* stderr,
Eric Carusocc7106c2017-04-27 14:22:42 -0700101 brillo::ErrorPtr* error,
David Pursell300498a2014-11-03 15:47:36 -0800102 ProcessWithOutput* process);
Elly Jones1c4c3a12011-12-20 15:01:59 -0500103};
104
Ben Chana0011d82014-05-13 00:19:29 -0700105} // namespace debugd
Elly Jones1c4c3a12011-12-20 15:01:59 -0500106
Alex Vakulenko262be3f2014-07-30 15:25:50 -0700107#endif // DEBUGD_SRC_PROCESS_WITH_OUTPUT_H_