Aggressively disallow a TTY stdin for assemble_cvd and run_cvd.
These processes expect to be passed lists of files on stdin and have
stdin close on completion of the list. A TTY will most likely not pass a
list of files and then close the file descriptor.
This supports the following invocations:
$ fetch_cvd -run_next_stage
$ fetch_cvd | launch_cvd
$ launch_cvd
$ fetch_cvd | assemble_cvd | run_cvd
Bug: 135293952
Test: Run launch_cvd, assemble_cvd, run_cvd
Change-Id: I203b5c4f620e3b2955408672a32e7df0d47e879b
diff --git a/host/commands/assemble_cvd/assemble_cvd.cc b/host/commands/assemble_cvd/assemble_cvd.cc
index 4e434c5..9efc0dd 100644
--- a/host/commands/assemble_cvd/assemble_cvd.cc
+++ b/host/commands/assemble_cvd/assemble_cvd.cc
@@ -23,6 +23,19 @@
int main(int argc, char** argv) {
::android::base::InitLogging(argv, android::base::StderrLogger);
+ if (isatty(0)) {
+ LOG(FATAL) << "stdin was a tty, expected to be passed the output of a previous stage. "
+ << "Did you mean to run launch_cvd?";
+ return cvd::AssemblerExitCodes::kInvalidHostConfiguration;
+ } else {
+ int error_num = errno;
+ if (error_num == EBADF) {
+ LOG(FATAL) << "stdin was not a valid file descriptor, expected to be passed the output "
+ << "of assemble_cvd. Did you mean to run launch_cvd?";
+ return cvd::AssemblerExitCodes::kInvalidHostConfiguration;
+ }
+ }
+
auto config = InitFilesystemAndCreateConfig(&argc, &argv);
std::cout << GetConfigFilePath(*config) << "\n";
diff --git a/host/commands/launch/launch_cvd.cc b/host/commands/launch/launch_cvd.cc
index 857b471..11d07c1 100644
--- a/host/commands/launch/launch_cvd.cc
+++ b/host/commands/launch/launch_cvd.cc
@@ -22,17 +22,38 @@
#include "flag_forwarder.h"
+/**
+ * If stdin is a tty, that means a user is invoking launch_cvd on the command
+ * line and wants automatic file detection for assemble_cvd.
+ *
+ * If stdin is not a tty, that means launch_cvd is being passed a list of files
+ * and that list should be forwarded to assemble_cvd.
+ *
+ * Controllable with a flag for extraordinary scenarios such as running from a
+ * daemon which closes its own stdin.
+ */
+DEFINE_bool(run_file_discovery, (bool) isatty(0),
+ "Whether to run file discovery or get input files from stdin.");
+
namespace {
std::string kAssemblerBin = vsoc::DefaultHostArtifactsPath("bin/assemble_cvd");
std::string kRunnerBin = vsoc::DefaultHostArtifactsPath("bin/run_cvd");
-cvd::Subprocess StartAssembler(cvd::SharedFD assembler_stdout,
+void AvailableFilesReport(cvd::SharedFD) {
+ // TODO(schuffelen): Scan directories like ANDROID_PRODUCT_OUT, ANDROID_HOST_OUT, HOME
+}
+
+cvd::Subprocess StartAssembler(cvd::SharedFD assembler_stdin,
+ cvd::SharedFD assembler_stdout,
const std::vector<std::string>& argv) {
cvd::Command assemble_cmd(kAssemblerBin);
for (const auto& arg : argv) {
assemble_cmd.AddParameter(arg);
}
+ if (assembler_stdin->IsOpen()) {
+ assemble_cmd.RedirectStdIO(cvd::Subprocess::StdIOChannel::kStdIn, assembler_stdin);
+ }
assemble_cmd.RedirectStdIO(cvd::Subprocess::StdIOChannel::kStdOut, assembler_stdout);
return assemble_cmd.Start();
}
@@ -63,13 +84,24 @@
cvd::SharedFD assembler_stdout, runner_stdin;
cvd::SharedFD::Pipe(&runner_stdin, &assembler_stdout);
+ cvd::SharedFD launcher_report, assembler_stdin;
+ bool should_generate_report = FLAGS_run_file_discovery;
+ if (should_generate_report) {
+ cvd::SharedFD::Pipe(&assembler_stdin, &launcher_report);
+ }
+
// SharedFDs are std::move-d in to avoid dangling references.
// Removing the std::move will probably make run_cvd hang as its stdin never closes.
- auto assemble_proc = StartAssembler(std::move(assembler_stdout),
+ auto assemble_proc = StartAssembler(std::move(assembler_stdin),
+ std::move(assembler_stdout),
forwarder.ArgvForSubprocess(kAssemblerBin));
auto run_proc = StartRunner(std::move(runner_stdin),
forwarder.ArgvForSubprocess(kRunnerBin));
+ if (should_generate_report) {
+ AvailableFilesReport(std::move(launcher_report));
+ }
+
auto assemble_ret = assemble_proc.Wait();
if (assemble_ret != 0) {
LOG(ERROR) << "assemble_cvd returned " << assemble_ret;
diff --git a/host/commands/run_cvd/main.cc b/host/commands/run_cvd/main.cc
index 55b8704..5ea68a3 100644
--- a/host/commands/run_cvd/main.cc
+++ b/host/commands/run_cvd/main.cc
@@ -324,6 +324,19 @@
::android::base::InitLogging(argv, android::base::StderrLogger);
google::ParseCommandLineFlags(&argc, &argv, false);
+ if (isatty(0)) {
+ LOG(FATAL) << "stdin was a tty, expected to be passed the output of a previous stage. "
+ << "Did you mean to run launch_cvd?";
+ return cvd::RunnerExitCodes::kInvalidHostConfiguration;
+ } else {
+ int error_num = errno;
+ if (error_num == EBADF) {
+ LOG(FATAL) << "stdin was not a valid file descriptor, expected to be passed the output "
+ << "of assemble_cvd. Did you mean to run launch_cvd?";
+ return cvd::RunnerExitCodes::kInvalidHostConfiguration;
+ }
+ }
+
std::string input_files_str;
{
auto input_fd = cvd::SharedFD::Dup(0);