blob: bd23874f5cdaf6b12428e3e78017c5d45d940576 [file] [log] [blame]
Ben Chan6f391cb2012-03-21 17:38:21 -07001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CROS_DISKS_PROCESS_H_
6#define CROS_DISKS_PROCESS_H_
7
8#include <string>
9#include <vector>
10
Sergei Datsenkocd676b72019-05-10 11:42:05 +100011#include <base/files/scoped_file.h>
Ben Chan3b832b92014-09-02 19:39:57 -070012#include <base/macros.h>
Sergei Datsenkocd676b72019-05-10 11:42:05 +100013
Ben Chan6f391cb2012-03-21 17:38:21 -070014#include <gtest/gtest_prod.h>
15
16namespace cros_disks {
17
18// A base class for executing a process.
19//
François Degrosc0b33b12019-09-12 14:50:43 +100020// TODO(crbug.com/1003654) This base class is not feature complete yet.
Ben Chan6f391cb2012-03-21 17:38:21 -070021class Process {
22 public:
Ben Chanacac3952012-04-24 22:50:01 -070023 // Invalid process ID assigned to a process that has not started.
24 static const pid_t kInvalidProcessId;
25
Sergei Datsenkocd676b72019-05-10 11:42:05 +100026 static const int kInvalidFD;
27
Ben Chan6f391cb2012-03-21 17:38:21 -070028 virtual ~Process();
29
30 // Adds an argument to the end of the argument list. Any argument added by
31 // this method does not affect the process that has been started by Start().
32 void AddArgument(const std::string& argument);
33
Sergei Datsenkocd676b72019-05-10 11:42:05 +100034 // Starts the process without waiting for it to terminate.
35 bool Start();
Ben Chan6f391cb2012-03-21 17:38:21 -070036
Sergei Datsenko9246e9c2019-03-22 10:26:47 +110037 // Waits for the process to finish and returns its exit status.
Sergei Datsenkocd676b72019-05-10 11:42:05 +100038 int Wait();
39
40 // Checks if the process finished.
41 bool IsFinished();
Sergei Datsenko9246e9c2019-03-22 10:26:47 +110042
François Degrosedaefc52019-10-03 12:00:20 +100043 // Starts a process, captures its output and waits for it to finish. Returns
44 // the same exit status as Wait().
45 //
46 // Precondition: output is non-null
47 int Run(std::vector<std::string>* output);
Sergei Datsenko9246e9c2019-03-22 10:26:47 +110048
Ben Chanacac3952012-04-24 22:50:01 -070049 pid_t pid() const { return pid_; }
50
Sergei Datsenko9246e9c2019-03-22 10:26:47 +110051 const std::vector<std::string>& arguments() const { return arguments_; }
52
Ben Chan6f391cb2012-03-21 17:38:21 -070053 protected:
54 Process();
55
56 // Returns the array of arguments used to start the process, or NULL if
57 // no arguments is added using AddArgument(). This method calls
58 // BuildArgumentsArray() to build |arguments_array_| only once (i.e.
59 // when |arguments_array_| is null). Once |arguments_array_| is built,
60 // subsequent calls to AddArgument() do not change the return value of
61 // this method. The returned array of arguments is managed by the base
62 // class.
François Degros5593b8c2019-07-25 12:27:42 +100063 char* const* GetArguments();
Ben Chan6f391cb2012-03-21 17:38:21 -070064
François Degros5593b8c2019-07-25 12:27:42 +100065 virtual pid_t StartImpl(base::ScopedFD* in_fd,
Sergei Datsenkocd676b72019-05-10 11:42:05 +100066 base::ScopedFD* out_fd,
67 base::ScopedFD* err_fd) = 0;
François Degros92bbea42019-09-13 10:42:52 +100068
69 // Once either WaitImpl() or WaitNonBlockingImpl() has returned a nonnegative
70 // exit status, none of these methods is called again.
71
François Degros01564642019-09-13 14:10:17 +100072 // Waits for the process to finish and returns its nonnegative exit status.
Sergei Datsenkocd676b72019-05-10 11:42:05 +100073 virtual int WaitImpl() = 0;
François Degros92bbea42019-09-13 10:42:52 +100074
François Degros01564642019-09-13 14:10:17 +100075 // Checks if the process has finished and returns its nonnegative exit status,
76 // or -1 if the process is still running.
François Degros92bbea42019-09-13 10:42:52 +100077 virtual int WaitNonBlockingImpl() = 0;
Ben Chanacac3952012-04-24 22:50:01 -070078
Ben Chan6f391cb2012-03-21 17:38:21 -070079 private:
Sergei Datsenkocd676b72019-05-10 11:42:05 +100080 // Waits for process to finish collecting process' stdout and stderr
81 // output and fills interleaved version of it.
82 void Communicate(std::vector<std::string>* output);
83
Ben Chan6f391cb2012-03-21 17:38:21 -070084 // Builds |arguments_array_| and |arguments_buffer_| from |arguments_|.
85 // Existing values of |arguments_array_| and |arguments_buffer_| are
86 // overridden. Return false if |arguments_| is empty.
87 bool BuildArgumentsArray();
88
François Degros01564642019-09-13 14:10:17 +100089 bool finished() const { return status_ >= 0; }
90
Ben Chan6f391cb2012-03-21 17:38:21 -070091 // Process arguments.
92 std::vector<std::string> arguments_;
Ben Chan5e3ca672014-08-25 15:53:58 -070093 std::vector<char*> arguments_array_;
94 std::vector<char> arguments_buffer_;
Ben Chan6f391cb2012-03-21 17:38:21 -070095
Ben Chanacac3952012-04-24 22:50:01 -070096 // Process ID (default to kInvalidProcessId when the process has not started).
Sergei Datsenkocd676b72019-05-10 11:42:05 +100097 pid_t pid_ = kInvalidProcessId;
98
99 base::ScopedFD in_fd_;
100 base::ScopedFD out_fd_;
101 base::ScopedFD err_fd_;
102
François Degros01564642019-09-13 14:10:17 +1000103 // Exit status. A nonnegative value indicates that the process has finished.
Sergei Datsenkocd676b72019-05-10 11:42:05 +1000104 int status_ = -1;
Ben Chanacac3952012-04-24 22:50:01 -0700105
Ben Chan6f391cb2012-03-21 17:38:21 -0700106 FRIEND_TEST(ProcessTest, GetArguments);
107 FRIEND_TEST(ProcessTest, GetArgumentsWithNoArgumentsAdded);
Ben Chan6f391cb2012-03-21 17:38:21 -0700108
109 DISALLOW_COPY_AND_ASSIGN(Process);
110};
111
112} // namespace cros_disks
113
114#endif // CROS_DISKS_PROCESS_H_