diff --git a/lldb/source/Commands/CommandObjectPlatform.cpp b/lldb/source/Commands/CommandObjectPlatform.cpp --- a/lldb/source/Commands/CommandObjectPlatform.cpp +++ b/lldb/source/Commands/CommandObjectPlatform.cpp @@ -1567,6 +1567,9 @@ const char short_option = (char)GetDefinitions()[option_idx].short_option; switch (short_option) { + case 'h': + m_use_host_platform = true; + break; case 't': uint32_t timeout_sec; if (option_arg.getAsInteger(10, timeout_sec)) @@ -1574,7 +1577,7 @@ "could not convert \"%s\" to a numeric value.", option_arg.str().c_str()); else - timeout = std::chrono::seconds(timeout_sec); + m_timeout = std::chrono::seconds(timeout_sec); break; default: llvm_unreachable("Unimplemented option"); @@ -1583,9 +1586,13 @@ return error; } - void OptionParsingStarting(ExecutionContext *execution_context) override {} + void OptionParsingStarting(ExecutionContext *execution_context) override { + m_timeout.reset(); + m_use_host_platform = false; + } - Timeout timeout = std::chrono::seconds(10); + Timeout m_timeout = std::chrono::seconds(10); + bool m_use_host_platform; }; CommandObjectPlatformShell(CommandInterpreter &interpreter) @@ -1609,6 +1616,7 @@ return true; } + const bool is_alias = !raw_command_line.contains("platform"); OptionsWithRaw args(raw_command_line); const char *expr = args.GetRawPart().c_str(); @@ -1616,8 +1624,16 @@ if (!ParseOptions(args.GetArgs(), result)) return false; + if (args.GetRawPart().empty()) { + result.GetOutputStream().Printf("%s \n", + is_alias ? "shell" : "platform shell"); + return false; + } + PlatformSP platform_sp( - GetDebugger().GetPlatformList().GetSelectedPlatform()); + m_options.m_use_host_platform + ? Platform::GetHostPlatform() + : GetDebugger().GetPlatformList().GetSelectedPlatform()); Status error; if (platform_sp) { FileSpec working_dir{}; @@ -1625,7 +1641,7 @@ int status = -1; int signo = -1; error = (platform_sp->RunShellCommand(expr, working_dir, &status, &signo, - &output, m_options.timeout)); + &output, m_options.m_timeout)); if (!output.empty()) result.GetOutputStream().PutCString(output); if (status > 0) { diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -624,6 +624,8 @@ } let Command = "platform shell" in { + def platform_shell_host : Option<"host", "h">, + Desc<"Run the commands on the host shell when enabled.">; def platform_shell_timeout : Option<"timeout", "t">, Arg<"Value">, Desc<"Seconds to wait for the remote host to finish running the command.">; } @@ -703,6 +705,7 @@ Desc<"Set the synchronicity of this command's executions with regard to " "LLDB event system.">; } + let Command = "source info" in { def source_info_count : Option<"count", "c">, Arg<"Count">, Desc<"The number of line entries to display.">; diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp --- a/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/source/Interpreter/CommandInterpreter.cpp @@ -381,6 +381,16 @@ } } + cmd_obj_sp = GetCommandSPExact("platform shell", false); + if (cmd_obj_sp) { + CommandAlias *shell_alias = AddAlias("shell", cmd_obj_sp, " --host --"); + if (shell_alias) { + shell_alias->SetHelp("Run a shell command on the host."); + shell_alias->SetHelpLong(""); + shell_alias->SetSyntax("shell "); + } + } + cmd_obj_sp = GetCommandSPExact("process kill", false); if (cmd_obj_sp) { AddAlias("kill", cmd_obj_sp); diff --git a/lldb/test/API/commands/platform/basic/TestPlatformCommand.py b/lldb/test/API/commands/platform/basic/TestPlatformCommand.py --- a/lldb/test/API/commands/platform/basic/TestPlatformCommand.py +++ b/lldb/test/API/commands/platform/basic/TestPlatformCommand.py @@ -19,6 +19,12 @@ self.runCmd("help platform") @no_debug_info_test + def test_help_platform(self): + self.expect("help shell", substrs=["Run a shell command on the host.", + "shell "]) + + + @no_debug_info_test def test_list(self): self.expect("platform list", patterns=['^Available platforms:']) @@ -55,6 +61,7 @@ self.expect( "platform shell dir c:\\", substrs=[ "Windows", "Program Files"]) + self.expect("shell dir c:\\", substrs=["Windows", "Program Files"]) elif re.match(".*-.*-.*-android", triple): self.expect( "platform shell ls /", @@ -62,19 +69,26 @@ "cache", "dev", "system"]) + self.expect("shell ls /", + substrs=["cache", "dev", "system"]) else: self.expect("platform shell ls /", substrs=["dev", "tmp", "usr"]) + self.expect("shell ls /", substrs=["dev", "tmp", "usr"]) @no_debug_info_test def test_shell_builtin(self): """ Test a shell built-in command (echo) """ self.expect("platform shell echo hello lldb", substrs=["hello lldb"]) + self.expect("shell echo hello lldb", + substrs=["hello lldb"]) + - # FIXME: re-enable once platform shell -t can specify the desired timeout @no_debug_info_test def test_shell_timeout(self): """ Test a shell built-in command (sleep) that times out """ - self.skipTest("due to taking too long to complete.") - self.expect("platform shell sleep 15", error=True, substrs=[ + self.skipTest("Alias with option not supported by the command interpreter.") + self.expect("platform shell -t 1 -- sleep 15", error=True, substrs=[ + "error: timed out waiting for shell command to complete"]) + self.expect("shell -t 1 -- sleep 3", error=True, substrs=[ "error: timed out waiting for shell command to complete"])