1 //
2 // Copyright (C) 2019 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 #include "host/commands/run_cvd/launch/launch.h"
17
18 #include <string>
19 #include <unordered_set>
20 #include <utility>
21 #include <vector>
22
23 #include <fruit/fruit.h>
24
25 #include "common/libs/utils/result.h"
26 #include "host/commands/run_cvd/reporting.h"
27 #include "host/libs/config/command_source.h"
28 #include "host/libs/config/known_paths.h"
29
30 namespace cuttlefish {
31 namespace {
32
33 class ConsoleForwarder : public CommandSource, public DiagnosticInformation {
34 public:
INJECT(ConsoleForwarder (const CuttlefishConfig::InstanceSpecific & instance))35 INJECT(ConsoleForwarder(const CuttlefishConfig::InstanceSpecific& instance))
36 : instance_(instance) {}
37 // DiagnosticInformation
Diagnostics() const38 std::vector<std::string> Diagnostics() const override {
39 if (Enabled()) {
40 return {"To access the console run: screen " + instance_.console_path()};
41 } else {
42 return {"Serial console is disabled; use -console=true to enable it."};
43 }
44 }
45
46 // CommandSource
Commands()47 Result<std::vector<MonitorCommand>> Commands() override {
48 Command console_forwarder_cmd(ConsoleForwarderBinary());
49 console_forwarder_cmd.AddParameter("--console_in_fd=",
50 console_forwarder_in_wr_);
51 console_forwarder_cmd.AddParameter("--console_out_fd=",
52 console_forwarder_out_rd_);
53 std::vector<MonitorCommand> commands;
54 commands.emplace_back(std::move(console_forwarder_cmd));
55 return commands;
56 }
57
58 // SetupFeature
Name() const59 std::string Name() const override { return "ConsoleForwarder"; }
Enabled() const60 bool Enabled() const override { return instance_.console(); }
61
62 private:
Dependencies() const63 std::unordered_set<SetupFeature*> Dependencies() const override { return {}; }
ResultSetup()64 Result<void> ResultSetup() override {
65 auto console_in_pipe_name = instance_.console_in_pipe_name();
66 CF_EXPECT(
67 mkfifo(console_in_pipe_name.c_str(), 0600) == 0,
68 "Failed to create console input fifo for crosvm: " << strerror(errno));
69
70 auto console_out_pipe_name = instance_.console_out_pipe_name();
71 CF_EXPECT(
72 mkfifo(console_out_pipe_name.c_str(), 0660) == 0,
73 "Failed to create console output fifo for crosvm: " << strerror(errno));
74
75 // These fds will only be read from or written to, but open them with
76 // read and write access to keep them open in case the subprocesses exit
77 console_forwarder_in_wr_ =
78 SharedFD::Open(console_in_pipe_name.c_str(), O_RDWR);
79 CF_EXPECT(console_forwarder_in_wr_->IsOpen(),
80 "Failed to open console_forwarder input fifo for writes: "
81 << console_forwarder_in_wr_->StrError());
82
83 console_forwarder_out_rd_ =
84 SharedFD::Open(console_out_pipe_name.c_str(), O_RDWR);
85 CF_EXPECT(console_forwarder_out_rd_->IsOpen(),
86 "Failed to open console_forwarder output fifo for reads: "
87 << console_forwarder_out_rd_->StrError());
88 return {};
89 }
90
91 const CuttlefishConfig::InstanceSpecific& instance_;
92 SharedFD console_forwarder_in_wr_;
93 SharedFD console_forwarder_out_rd_;
94 };
95
96 } // namespace
97
98 fruit::Component<fruit::Required<const CuttlefishConfig::InstanceSpecific>>
ConsoleForwarderComponent()99 ConsoleForwarderComponent() {
100 return fruit::createComponent()
101 .addMultibinding<CommandSource, ConsoleForwarder>()
102 .addMultibinding<SetupFeature, ConsoleForwarder>();
103 }
104
105 } // namespace cuttlefish
106