-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathprocess.h
147 lines (109 loc) · 4.93 KB
/
process.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CROS_DISKS_PROCESS_H_
#define CROS_DISKS_PROCESS_H_
#include <string>
#include <utility>
#include <vector>
#include <base/files/scoped_file.h>
#include <base/strings/string_piece.h>
#include <gtest/gtest_prod.h>
namespace cros_disks {
// A base class for executing a process.
//
// TODO(crbug.com/1003654) This base class is not feature complete yet.
class Process {
public:
// Invalid process ID assigned to a process that has not started.
static const pid_t kInvalidProcessId;
static const int kInvalidFD;
Process(const Process&) = delete;
Process& operator=(const Process&) = delete;
virtual ~Process();
// Adds an argument to the end of the argument list.
// Precondition: Start() has not been called yet.
void AddArgument(std::string argument);
// Adds a variable to the environment that will be passed to the process.
// Precondition: Start() has not been called yet.
// Precondition: `name` is not empty and doesn't contain '='.
void AddEnvironmentVariable(base::StringPiece name, base::StringPiece value);
// Sets the string to pass to the process stdin.
// Might be silently truncated if it doesn't fit in a pipe's buffer.
// Precondition: Start() has not been called yet.
void SetStdIn(std::string input) { input_ = std::move(input); }
// Starts the process. The started process has its stdin, stdout and stderr
// connected to /dev/null. Returns true in case of success. Once started, the
// process can be waiting for to finish using Wait().
bool Start();
// Waits for the process to finish and returns its exit status.
int Wait();
// Checks if the process finished.
bool IsFinished();
// Starts a process, captures its output and waits for it to finish. Returns
// the same exit status as Wait().
//
// Precondition: output is non-null
int Run(std::vector<std::string>* output);
pid_t pid() const { return pid_; }
const std::vector<std::string>& arguments() const { return arguments_; }
const std::vector<std::string>& environment() const { return environment_; }
const std::string& input() const { return input_; }
protected:
Process();
// Gets the arguments used to start the process. This method calls
// BuildArgumentsArray() to build |arguments_array_| only once (i.e. when
// |arguments_array_| is empty). Once |arguments_array_| is built, subsequent
// calls to AddArgument() are not allowed. The returned array of arguments is
// owned by this Process object.
char* const* GetArguments();
// Gets the environment to pass to the subprocess. The returned array of
// environment variables is owned by this Process object.
char* const* GetEnvironment();
// Starts a process, and connects to its stdin, stdout and stderr the given
// file descriptors.
//
// Returns the PID of the started process, or -1 in case of error.
virtual pid_t StartImpl(base::ScopedFD in_fd,
base::ScopedFD out_fd,
base::ScopedFD err_fd) = 0;
// Once either WaitImpl() or WaitNonBlockingImpl() has returned a nonnegative
// exit status, none of these methods is called again.
// Waits for the process to finish and returns its nonnegative exit status.
virtual int WaitImpl() = 0;
// Checks if the process has finished and returns its nonnegative exit status,
// or -1 if the process is still running.
virtual int WaitNonBlockingImpl() = 0;
private:
// Starts the process. The started process has its stdin, stdout and stderr
// redirected to the given file descriptors. Returns true in case of success.
bool Start(base::ScopedFD in_fd,
base::ScopedFD out_fd,
base::ScopedFD err_fd);
// Waits for process to finish collecting process' stdout and stderr
// output and fills interleaved version of it.
void Communicate(std::vector<std::string>* output,
base::ScopedFD out_fd,
base::ScopedFD err_fd);
// Builds |arguments_array_| from |arguments_|. Existing values of
// |arguments_array_| are overridden.
void BuildArgumentsArray();
bool finished() const { return status_ >= 0; }
// Process arguments.
std::vector<std::string> arguments_;
std::vector<char*> arguments_array_;
// Extra environment variables.
std::vector<std::string> environment_;
// Full environment for the subprocess.
std::vector<char*> environment_array_;
// String to pass to the process stdin.
std::string input_;
// Process ID (default to kInvalidProcessId when the process has not started).
pid_t pid_ = kInvalidProcessId;
// Exit status. A nonnegative value indicates that the process has finished.
int status_ = -1;
FRIEND_TEST(ProcessTest, GetArguments);
FRIEND_TEST(ProcessTest, GetArgumentsWithNoArgumentsAdded);
};
} // namespace cros_disks
#endif // CROS_DISKS_PROCESS_H_