Android-cuttlefish cvd tool
commandline.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef COMMANDLINE_H
18#define COMMANDLINE_H
19
21#include <google/protobuf/text_format.h>
22
23#include <stdlib.h>
24#include <optional>
25
26#include "adb.h"
27#include "adb_client.h"
28#include "adb_unique_fd.h"
29#include "transport.h"
30
31// Callback used to handle the standard streams (stdout and stderr) sent by the
32// device's upon receiving a command.
33
34//
36 public:
38 }
39 // Handles the stdout output from devices supporting the Shell protocol.
40 // Returns true on success and false on failure.
41 virtual bool OnStdoutReceived(const char* buffer, size_t length) = 0;
42
43 // Handles the stderr output from devices supporting the Shell protocol.
44 // Returns true on success and false on failure.
45 virtual bool OnStderrReceived(const char* buffer, size_t length) = 0;
46
47 // Indicates the communication is finished and returns the appropriate error
48 // code.
49 //
50 // |status| has the status code returning by the underlying communication
51 // channels
52 virtual int Done(int status) = 0;
53
54 protected:
55 static bool SendTo(std::string* string, FILE* stream, const char* buffer, size_t length,
56 bool returnErrors) {
57 if (string != nullptr) {
58 string->append(buffer, length);
59 return true;
60 } else {
61 bool okay = (fwrite(buffer, 1, length, stream) == length);
62 fflush(stream);
63 return returnErrors ? okay : true;
64 }
65 }
66
67 private:
69};
70
71// Default implementation that redirects the streams to the equivalent host
72// stream or to a string passed to the constructor.
74 public:
75 // If |stdout_str| is non-null, OnStdoutReceived will append to it.
76 // If |stderr_str| is non-null, OnStderrReceived will append to it.
77 DefaultStandardStreamsCallback(std::string* stdout_str, std::string* stderr_str)
78 : stdout_str_(stdout_str), stderr_str_(stderr_str), returnErrors_(false) {
79 }
80 DefaultStandardStreamsCallback(std::string* stdout_str, std::string* stderr_str,
81 bool returnErrors)
82 : stdout_str_(stdout_str), stderr_str_(stderr_str), returnErrors_(returnErrors) {
83 }
84
85 // Called when receiving from the device standard input stream
86 bool OnStdoutReceived(const char* buffer, size_t length) override {
87 return SendToOut(buffer, length);
88 }
89
90 // Called when receiving from the device error input stream
91 bool OnStderrReceived(const char* buffer, size_t length) override {
92 return SendToErr(buffer, length);
93 }
94
95 // Send to local standard input stream (or stdout_str if one was provided).
96 bool SendToOut(const char* buffer, size_t length) {
97 return SendTo(stdout_str_, stdout, buffer, length, returnErrors_);
98 }
99
100 // Send to local standard error stream (or stderr_str if one was provided).
101 bool SendToErr(const char* buffer, size_t length) {
102 return SendTo(stderr_str_, stderr, buffer, length, returnErrors_);
103 }
104
105 int Done(int status) {
106 return status;
107 }
108
109 void ReturnErrors(bool returnErrors) {
110 returnErrors_ = returnErrors;
111 }
112
113 private:
114 std::string* stdout_str_;
115 std::string* stderr_str_;
117
119};
120
122 public:
124 bool OnStdoutReceived(const char*, size_t) final { return true; }
125 bool OnStderrReceived(const char*, size_t) final { return true; }
126 int Done(int status) final { return status; }
127};
128
129// Singleton.
131
132// Prints out human-readable form of the protobuf message received in binary format.
133// Expected input is a stream of (<hex4>, [binary protobuf]).
134template <typename T>
136 public:
137 explicit ProtoBinaryToText(const std::string& m, std::string* std_out = nullptr,
138 std::string* std_err = nullptr)
139 : DefaultStandardStreamsCallback(std_out, std_err), message(m) {}
140 bool OnStdoutReceived(const char* b, size_t l) override {
141 constexpr size_t kHeader_size = 4;
142
143 // Add the incoming bytes to our internal buffer.
144 std::copy_n(b, l, std::back_inserter(buffer_));
145
146 // Do we have at least the header?
147 if (buffer_.size() < kHeader_size) {
148 return true;
149 }
150
151 // We have a header. Convert <hex4> to size_t and check if we have received all
152 // the payload.
153 const std::string expected_size_hex = std::string(buffer_.data(), kHeader_size);
154 const size_t expected_size = strtoull(expected_size_hex.c_str(), nullptr, 16);
155
156 // Do we have the header + all expected payload?
157 if (buffer_.size() < expected_size + kHeader_size) {
158 return true;
159 }
160
161 // Convert binary to text proto.
162 T binary_proto;
163 binary_proto.ParseFromString(std::string(buffer_.data() + kHeader_size, expected_size));
164 std::string string_proto;
165 google::protobuf::TextFormat::PrintToString(binary_proto, &string_proto);
166
167 // Drop bytes that we just consumed.
168 buffer_.erase(buffer_.begin(), buffer_.begin() + kHeader_size + expected_size);
169
170 SendToOut(message.data(), message.length());
171 SendToOut(string_proto.data(), string_proto.length());
172
173 // Recurse if there is still data in our buffer (there may be more messages).
174 if (!buffer_.empty()) {
175 OnStdoutReceived("", 0);
176 }
177
178 return true;
179 }
180
181 private:
183 // We buffer bytes here until we get all the header and payload bytes
184 std::vector<char> buffer_;
185 std::string message;
186};
187
188int adb_commandline(int argc, const char** argv);
189
190// Helper retrieval function.
191const std::optional<FeatureSet>& adb_get_feature_set_or_die();
192
193bool copy_to_file(int inFd, int outFd);
194
195// Connects to the device "shell" service with |command| and prints the
196// resulting output.
197// if |callback| is non-null, stdout/stderr output will be handled by it.
199 const std::string& command, bool disable_shell_protocol = false,
201
202// Reads from |fd| and prints received data. If |use_shell_protocol| is true
203// this expects that incoming data will use the shell protocol, in which case
204// stdout/stderr are routed independently and the remote exit code will be
205// returned.
206// if |callback| is non-null, stdout/stderr output will be handled by it.
207int read_and_dump(borrowed_fd fd, bool use_shell_protocol = false,
209
210// Connects to the device "abb" service with |command| and returns the fd.
211template <typename ContainerT>
212unique_fd send_abb_exec_command(const ContainerT& command_args, std::string* error) {
213 std::string service_string = "abb_exec:" + android::base::Join(command_args, ABB_ARG_DELIMETER);
214
215 unique_fd fd(adb_connect(service_string, error));
216 if (fd < 0) {
217 fprintf(stderr, "adb: failed to run abb_exec. Error: %s\n", error->c_str());
218 return unique_fd{};
219 }
220 return fd;
221}
222
223#endif // COMMANDLINE_H
#define ABB_ARG_DELIMETER
Definition: adb.h:209
int adb_connect(std::string_view service, std::string *error)
Definition: adb_client.cpp:238
Definition: commandline.h:73
bool OnStdoutReceived(const char *buffer, size_t length) override
Definition: commandline.h:86
DefaultStandardStreamsCallback(std::string *stdout_str, std::string *stderr_str, bool returnErrors)
Definition: commandline.h:80
bool returnErrors_
Definition: commandline.h:116
DefaultStandardStreamsCallback(std::string *stdout_str, std::string *stderr_str)
Definition: commandline.h:77
void ReturnErrors(bool returnErrors)
Definition: commandline.h:109
int Done(int status)
Definition: commandline.h:105
std::string * stderr_str_
Definition: commandline.h:115
bool SendToErr(const char *buffer, size_t length)
Definition: commandline.h:101
bool SendToOut(const char *buffer, size_t length)
Definition: commandline.h:96
std::string * stdout_str_
Definition: commandline.h:114
DISALLOW_COPY_AND_ASSIGN(DefaultStandardStreamsCallback)
bool OnStderrReceived(const char *buffer, size_t length) override
Definition: commandline.h:91
Definition: commandline.h:135
bool OnStdoutReceived(const char *b, size_t l) override
Definition: commandline.h:140
DISALLOW_COPY_AND_ASSIGN(ProtoBinaryToText)
std::string message
Definition: commandline.h:185
std::vector< char > buffer_
Definition: commandline.h:184
ProtoBinaryToText(const std::string &m, std::string *std_out=nullptr, std::string *std_err=nullptr)
Definition: commandline.h:137
Definition: commandline.h:121
int Done(int status) final
Definition: commandline.h:126
bool OnStderrReceived(const char *, size_t) final
Definition: commandline.h:125
bool OnStdoutReceived(const char *, size_t) final
Definition: commandline.h:124
Definition: commandline.h:35
virtual int Done(int status)=0
StandardStreamsCallbackInterface()
Definition: commandline.h:37
virtual bool OnStderrReceived(const char *buffer, size_t length)=0
static bool SendTo(std::string *string, FILE *stream, const char *buffer, size_t length, bool returnErrors)
Definition: commandline.h:55
DISALLOW_COPY_AND_ASSIGN(StandardStreamsCallbackInterface)
virtual bool OnStdoutReceived(const char *buffer, size_t length)=0
Definition: unique_fd.h:61
unique_fd send_abb_exec_command(const ContainerT &command_args, std::string *error)
Definition: commandline.h:212
int read_and_dump(borrowed_fd fd, bool use_shell_protocol=false, StandardStreamsCallbackInterface *callback=&DEFAULT_STANDARD_STREAMS_CALLBACK)
Definition: commandline.cpp:324
int send_shell_command(const std::string &command, bool disable_shell_protocol=false, StandardStreamsCallbackInterface *callback=&DEFAULT_STANDARD_STREAMS_CALLBACK)
Definition: commandline.cpp:1110
int adb_commandline(int argc, const char **argv)
Definition: commandline.cpp:1524
DefaultStandardStreamsCallback DEFAULT_STANDARD_STREAMS_CALLBACK
const std::optional< FeatureSet > & adb_get_feature_set_or_die()
Definition: commandline.cpp:1441
bool copy_to_file(int inFd, int outFd)
Definition: commandline.cpp:390
#define error(format, args...)
Definition: fec_private.h:201
int status()
Definition: health.cpp:42
std::string Join(const ContainerT &things, SeparatorT separator)
Definition: strings.h:98
Definition: unique_fd.h:292