mib updated this revision to Diff 288597.
mib edited the summary of this revision.
mib added a comment.

Removed `bool run_in_shell` argument from `Platform` classes.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86667/new/

https://reviews.llvm.org/D86667

Files:
  lldb/bindings/interface/SBPlatform.i
  lldb/include/lldb/API/SBPlatform.h
  lldb/include/lldb/Host/Host.h
  lldb/include/lldb/Target/Platform.h
  lldb/include/lldb/Target/RemoteAwarePlatform.h
  lldb/source/API/SBPlatform.cpp
  lldb/source/Commands/CommandObjectPlatform.cpp
  lldb/source/Commands/Options.td
  lldb/source/Host/common/Host.cpp
  lldb/source/Host/macosx/objcxx/Host.mm
  lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
  lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
  lldb/source/Target/Platform.cpp
  lldb/source/Target/RemoteAwarePlatform.cpp
  lldb/test/API/commands/platform/basic/Makefile
  lldb/test/API/commands/platform/basic/TestPlatformCommand.py
  lldb/test/API/commands/platform/basic/TestPlatformPython.py
  lldb/test/API/commands/platform/basic/myshell.c

Index: lldb/test/API/commands/platform/basic/myshell.c
===================================================================
--- /dev/null
+++ lldb/test/API/commands/platform/basic/myshell.c
@@ -0,0 +1,24 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int main(int argc, char *argv[]) {
+  if (argc < 3) {
+    fprintf(stderr, "ERROR: Too few arguments (count: %d).\n", argc - 1);
+    exit(1);
+  }
+
+#ifdef WIN32
+  char *cmd_opt = "/C";
+#else
+  char *cmd_opt = "-c";
+#endif
+
+  if (strncmp(argv[1], cmd_opt, 2)) {
+    fprintf(stderr, "ERROR: Missing shell command option ('%s').\n", cmd_opt);
+    exit(1);
+  }
+
+  printf("SUCCESS: %s\n", argv[0]);
+  return 0;
+}
Index: lldb/test/API/commands/platform/basic/TestPlatformPython.py
===================================================================
--- lldb/test/API/commands/platform/basic/TestPlatformPython.py
+++ lldb/test/API/commands/platform/basic/TestPlatformPython.py
@@ -13,6 +13,7 @@
 class PlatformPythonTestCase(TestBase):
 
     mydir = TestBase.compute_mydir(__file__)
+    NO_DEBUG_INFO_TESTCASE = True
 
     @add_test_categories(['pyapi'])
     @no_debug_info_test
@@ -79,3 +80,20 @@
             self.assertEqual(
                 desc_data.GetType(), lldb.eStructuredDataTypeString,
                 'Platform description is a string')
+
+    @add_test_categories(['pyapi'])
+    @no_debug_info_test
+    def test_shell_interpreter(self):
+        """ Test a shell with a custom interpreter """
+        platform = self.dbg.GetSelectedPlatform()
+        self.assertTrue(platform.IsValid())
+
+        sh_cmd = lldb.SBPlatformShellCommand('/bin/zsh', 'echo $0')
+        self.assertIn('/bin/zsh', sh_cmd.GetInterpreter())
+        self.assertIn('echo $0', sh_cmd.GetCommand())
+
+        self.build()
+        sh_cmd.SetInterpreter(self.getBuildArtifact('a.out'))
+        err = platform.Run(sh_cmd)
+        self.assertTrue(err.Success())
+        self.assertIn("SUCCESS", sh_cmd.GetOutput())
Index: lldb/test/API/commands/platform/basic/TestPlatformCommand.py
===================================================================
--- lldb/test/API/commands/platform/basic/TestPlatformCommand.py
+++ lldb/test/API/commands/platform/basic/TestPlatformCommand.py
@@ -13,6 +13,7 @@
 class PlatformCommandTestCase(TestBase):
 
     mydir = TestBase.compute_mydir(__file__)
+    NO_DEBUG_INFO_TESTCASE = True
 
     @no_debug_info_test
     def test_help_platform(self):
@@ -92,3 +93,11 @@
                     "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"])
+
+    @no_debug_info_test
+    def test_host_shell_interpreter(self):
+        """ Test the host platform shell with a different interpreter """
+        self.build()
+        exe = self.getBuildArtifact('a.out')
+        self.expect("platform shell -h -s " + exe + " -- 'echo $0'",
+                    substrs=['SUCCESS', 'a.out'])
Index: lldb/test/API/commands/platform/basic/Makefile
===================================================================
--- /dev/null
+++ lldb/test/API/commands/platform/basic/Makefile
@@ -0,0 +1,5 @@
+C_SOURCES := myshell.c
+CFLAGS_EXTRAS := -g0 # No debug info.
+MAKE_DSYM := NO
+
+include Makefile.rules
Index: lldb/source/Target/RemoteAwarePlatform.cpp
===================================================================
--- lldb/source/Target/RemoteAwarePlatform.cpp
+++ lldb/source/Target/RemoteAwarePlatform.cpp
@@ -171,15 +171,24 @@
 }
 
 Status RemoteAwarePlatform::RunShellCommand(
-    const char *command, const FileSpec &working_dir, int *status_ptr,
+    llvm::StringRef command, const FileSpec &working_dir, int *status_ptr,
     int *signo_ptr, std::string *command_output,
     const Timeout<std::micro> &timeout) {
+  return RunShellCommand(llvm::StringRef(), command, working_dir, status_ptr,
+                         signo_ptr, command_output, timeout);
+}
+
+Status RemoteAwarePlatform::RunShellCommand(
+    llvm::StringRef interpreter, llvm::StringRef command,
+    const FileSpec &working_dir, int *status_ptr, int *signo_ptr,
+    std::string *command_output, const Timeout<std::micro> &timeout) {
   if (IsHost())
-    return Host::RunShellCommand(command, working_dir, status_ptr, signo_ptr,
-                                 command_output, timeout);
+    return Host::RunShellCommand(interpreter, command, working_dir, status_ptr,
+                                 signo_ptr, command_output, timeout);
   if (m_remote_platform_sp)
     return m_remote_platform_sp->RunShellCommand(
-        command, working_dir, status_ptr, signo_ptr, command_output, timeout);
+        interpreter, command, working_dir, status_ptr, signo_ptr,
+        command_output, timeout);
   return Status("unable to run a remote command without a platform");
 }
 
Index: lldb/source/Target/Platform.cpp
===================================================================
--- lldb/source/Target/Platform.cpp
+++ lldb/source/Target/Platform.cpp
@@ -1319,7 +1319,23 @@
 }
 
 lldb_private::Status Platform::RunShellCommand(
-    const char *command, // Shouldn't be nullptr
+    llvm::StringRef command, // Shouldn't be empty
+    const FileSpec &
+        working_dir, // Pass empty FileSpec to use the current working directory
+    int *status_ptr, // Pass nullptr if you don't want the process exit status
+    int *signo_ptr, // Pass nullptr if you don't want the signal that caused the
+                    // process to exit
+    std::string
+        *command_output, // Pass nullptr if you don't want the command output
+    const Timeout<std::micro> &timeout) {
+  return RunShellCommand(llvm::StringRef(), command, working_dir, status_ptr,
+                         signo_ptr, command_output, timeout);
+}
+
+lldb_private::Status Platform::RunShellCommand(
+    llvm::StringRef interpreter, // Pass empty if you want to use the default
+                                 // shell interpreter
+    llvm::StringRef command,     // Shouldn't be empty
     const FileSpec &
         working_dir, // Pass empty FileSpec to use the current working directory
     int *status_ptr, // Pass nullptr if you don't want the process exit status
@@ -1329,8 +1345,8 @@
         *command_output, // Pass nullptr if you don't want the command output
     const Timeout<std::micro> &timeout) {
   if (IsHost())
-    return Host::RunShellCommand(command, working_dir, status_ptr, signo_ptr,
-                                 command_output, timeout);
+    return Host::RunShellCommand(interpreter, command, working_dir, status_ptr,
+                                 signo_ptr, command_output, timeout);
   else
     return Status("unimplemented");
 }
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -399,7 +399,7 @@
   bool GetFileExists(const FileSpec &file_spec);
 
   Status RunShellCommand(
-      const char *command,         // Shouldn't be nullptr
+      llvm::StringRef command,
       const FileSpec &working_dir, // Pass empty FileSpec to use the current
                                    // working directory
       int *status_ptr, // Pass nullptr if you don't want the process exit status
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -2812,7 +2812,7 @@
 }
 
 lldb_private::Status GDBRemoteCommunicationClient::RunShellCommand(
-    const char *command, // Shouldn't be NULL
+    llvm::StringRef command,
     const FileSpec &
         working_dir, // Pass empty FileSpec to use the current working directory
     int *status_ptr, // Pass NULL if you don't want the process exit status
@@ -2823,7 +2823,7 @@
     const Timeout<std::micro> &timeout) {
   lldb_private::StreamString stream;
   stream.PutCString("qPlatform_shell:");
-  stream.PutBytesAsRawHex8(command, strlen(command));
+  stream.PutBytesAsRawHex8(command.data(), command.size());
   stream.PutChar(',');
   uint32_t timeout_sec = UINT32_MAX;
   if (timeout) {
Index: lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
===================================================================
--- lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
+++ lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
@@ -140,7 +140,7 @@
   Status Unlink(const FileSpec &path) override;
 
   Status RunShellCommand(
-      const char *command,         // Shouldn't be NULL
+      llvm::StringRef interpreter, llvm::StringRef command,
       const FileSpec &working_dir, // Pass empty FileSpec to use the current
                                    // working directory
       int *status_ptr, // Pass NULL if you don't want the process exit status
Index: lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
===================================================================
--- lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -711,7 +711,7 @@
 }
 
 Status PlatformRemoteGDBServer::RunShellCommand(
-    const char *command, // Shouldn't be NULL
+    llvm::StringRef interpreter, llvm::StringRef command,
     const FileSpec &
         working_dir, // Pass empty FileSpec to use the current working directory
     int *status_ptr, // Pass NULL if you don't want the process exit status
Index: lldb/source/Host/macosx/objcxx/Host.mm
===================================================================
--- lldb/source/Host/macosx/objcxx/Host.mm
+++ lldb/source/Host/macosx/objcxx/Host.mm
@@ -1323,11 +1323,11 @@
         launch_info.SetWorkingDirectory(working_dir);
       }
     }
-    bool run_in_default_shell = true;
+    bool run_in_shell = true;
     bool hide_stderr = true;
-    Status e = RunShellCommand(expand_command, cwd, &status, nullptr, &output,
-                               std::chrono::seconds(10), run_in_default_shell,
-                               hide_stderr);
+    Status e =
+        RunShellCommand(expand_command, cwd, &status, nullptr, &output,
+                        std::chrono::seconds(10), run_in_shell, hide_stderr);
 
     if (e.Fail())
       return e;
Index: lldb/source/Host/common/Host.cpp
===================================================================
--- lldb/source/Host/common/Host.cpp
+++ lldb/source/Host/common/Host.cpp
@@ -467,14 +467,24 @@
   return true;
 }
 
-Status Host::RunShellCommand(const char *command, const FileSpec &working_dir,
-                             int *status_ptr, int *signo_ptr,
-                             std::string *command_output_ptr,
+Status Host::RunShellCommand(llvm::StringRef command,
+                             const FileSpec &working_dir, int *status_ptr,
+                             int *signo_ptr, std::string *command_output_ptr,
+                             const Timeout<std::micro> &timeout,
+                             bool run_in_shell, bool hide_stderr) {
+  return RunShellCommand(llvm::StringRef(), Args(command), working_dir,
+                         status_ptr, signo_ptr, command_output_ptr, timeout,
+                         run_in_shell, hide_stderr);
+}
+
+Status Host::RunShellCommand(llvm::StringRef interpreter,
+                             llvm::StringRef command,
+                             const FileSpec &working_dir, int *status_ptr,
+                             int *signo_ptr, std::string *command_output_ptr,
                              const Timeout<std::micro> &timeout,
-                             bool run_in_default_shell,
-                             bool hide_stderr) {
-  return RunShellCommand(Args(command), working_dir, status_ptr, signo_ptr,
-                         command_output_ptr, timeout, run_in_default_shell,
+                             bool run_in_shell, bool hide_stderr) {
+  return RunShellCommand(interpreter, Args(command), working_dir, status_ptr,
+                         signo_ptr, command_output_ptr, timeout, run_in_shell,
                          hide_stderr);
 }
 
@@ -482,14 +492,27 @@
                              int *status_ptr, int *signo_ptr,
                              std::string *command_output_ptr,
                              const Timeout<std::micro> &timeout,
-                             bool run_in_default_shell,
-                             bool hide_stderr) {
+                             bool run_in_shell, bool hide_stderr) {
+  return RunShellCommand(llvm::StringRef(), args, working_dir, status_ptr,
+                         signo_ptr, command_output_ptr, timeout, run_in_shell,
+                         hide_stderr);
+}
+
+Status Host::RunShellCommand(llvm::StringRef interpreter, const Args &args,
+                             const FileSpec &working_dir, int *status_ptr,
+                             int *signo_ptr, std::string *command_output_ptr,
+                             const Timeout<std::micro> &timeout,
+                             bool run_in_shell, bool hide_stderr) {
   Status error;
   ProcessLaunchInfo launch_info;
   launch_info.SetArchitecture(HostInfo::GetArchitecture());
-  if (run_in_default_shell) {
+  if (run_in_shell) {
     // Run the command in a shell
-    launch_info.SetShell(HostInfo::GetDefaultShell());
+    FileSpec shell = HostInfo::GetDefaultShell();
+    if (!interpreter.empty())
+      shell.SetPath(interpreter);
+
+    launch_info.SetShell(shell);
     launch_info.GetArguments().AppendArguments(args);
     const bool localhost = true;
     const bool will_debug = false;
Index: lldb/source/Commands/Options.td
===================================================================
--- lldb/source/Commands/Options.td
+++ lldb/source/Commands/Options.td
@@ -631,6 +631,8 @@
     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.">;
+  def platform_shell_interpreter : Option<"shell", "s">, Arg<"Path">,
+    Desc<"Shell interpreter path. This is the binary used to run the command.">;
 }
 
 let Command = "process attach" in {
Index: lldb/source/Commands/CommandObjectPlatform.cpp
===================================================================
--- lldb/source/Commands/CommandObjectPlatform.cpp
+++ lldb/source/Commands/CommandObjectPlatform.cpp
@@ -1611,6 +1611,16 @@
         else
           m_timeout = std::chrono::seconds(timeout_sec);
         break;
+      case 's': {
+        if (option_arg.empty()) {
+          error.SetErrorStringWithFormat(
+              "missing shell interpreter path for option -i|--interpreter.");
+          return error;
+        }
+
+        m_shell_interpreter = option_arg.str();
+        break;
+      }
       default:
         llvm_unreachable("Unimplemented option");
       }
@@ -1621,10 +1631,12 @@
     void OptionParsingStarting(ExecutionContext *execution_context) override {
       m_timeout.reset();
       m_use_host_platform = false;
+      m_shell_interpreter.clear();
     }
 
     Timeout<std::micro> m_timeout = std::chrono::seconds(10);
     bool m_use_host_platform;
+    std::string m_shell_interpreter;
   };
 
   CommandObjectPlatformShell(CommandInterpreter &interpreter)
@@ -1650,7 +1662,6 @@
 
     const bool is_alias = !raw_command_line.contains("platform");
     OptionsWithRaw args(raw_command_line);
-    const char *expr = args.GetRawPart().c_str();
 
     if (args.HasArgs())
       if (!ParseOptions(args.GetArgs(), result))
@@ -1662,6 +1673,8 @@
       return false;
     }
 
+    llvm::StringRef cmd = args.GetRawPart();
+
     PlatformSP platform_sp(
         m_options.m_use_host_platform
             ? Platform::GetHostPlatform()
@@ -1672,7 +1685,8 @@
       std::string output;
       int status = -1;
       int signo = -1;
-      error = (platform_sp->RunShellCommand(expr, working_dir, &status, &signo,
+      error = (platform_sp->RunShellCommand(m_options.m_shell_interpreter, cmd,
+                                            working_dir, &status, &signo,
                                             &output, m_options.m_timeout));
       if (!output.empty())
         result.GetOutputStream().PutCString(output);
Index: lldb/source/API/SBPlatform.cpp
===================================================================
--- lldb/source/API/SBPlatform.cpp
+++ lldb/source/API/SBPlatform.cpp
@@ -50,14 +50,25 @@
 
 // PlatformShellCommand
 struct PlatformShellCommand {
-  PlatformShellCommand(const char *shell_command = nullptr)
+  PlatformShellCommand(llvm::StringRef command_interpreter,
+                       llvm::StringRef shell_command)
       : m_command(), m_working_dir(), m_status(0), m_signo(0) {
-    if (shell_command && shell_command[0])
-      m_command = shell_command;
+    if (!command_interpreter.empty())
+      m_interpreter = command_interpreter.str();
+
+    if (!m_interpreter.empty() && !shell_command.empty())
+      m_command = shell_command.str();
+  }
+
+  PlatformShellCommand(llvm::StringRef shell_command = llvm::StringRef())
+      : m_interpreter(), m_command(), m_working_dir(), m_status(0), m_signo(0) {
+    if (!shell_command.empty())
+      m_command = shell_command.str();
   }
 
   ~PlatformShellCommand() = default;
 
+  std::string m_interpreter;
   std::string m_command;
   std::string m_working_dir;
   std::string m_output;
@@ -163,6 +174,13 @@
 }
 
 // SBPlatformShellCommand
+SBPlatformShellCommand::SBPlatformShellCommand(const char *shell_interpreter,
+                                               const char *shell_command)
+    : m_opaque_ptr(new PlatformShellCommand(shell_interpreter, shell_command)) {
+  LLDB_RECORD_CONSTRUCTOR(SBPlatformShellCommand, (const char *, const char *),
+                          shell_interpreter, shell_command);
+}
+
 SBPlatformShellCommand::SBPlatformShellCommand(const char *shell_command)
     : m_opaque_ptr(new PlatformShellCommand(shell_command)) {
   LLDB_RECORD_CONSTRUCTOR(SBPlatformShellCommand, (const char *),
@@ -200,6 +218,25 @@
   m_opaque_ptr->m_signo = 0;
 }
 
+const char *SBPlatformShellCommand::GetInterpreter() {
+  LLDB_RECORD_METHOD_NO_ARGS(const char *, SBPlatformShellCommand,
+                             GetInterpreter);
+
+  if (m_opaque_ptr->m_interpreter.empty())
+    return nullptr;
+  return m_opaque_ptr->m_interpreter.c_str();
+}
+
+void SBPlatformShellCommand::SetInterpreter(const char *shell_interpreter) {
+  LLDB_RECORD_METHOD(void, SBPlatformShellCommand, SetInterpreter,
+                     (const char *), shell_interpreter);
+
+  if (shell_interpreter && shell_interpreter[0])
+    m_opaque_ptr->m_interpreter = shell_interpreter;
+  else
+    m_opaque_ptr->m_interpreter.clear();
+}
+
 const char *SBPlatformShellCommand::GetCommand() {
   LLDB_RECORD_METHOD_NO_ARGS(const char *, SBPlatformShellCommand, GetCommand);
 
@@ -557,11 +594,12 @@
       if (working_dir)
         shell_command.SetWorkingDirectory(working_dir);
     }
-    return platform_sp->RunShellCommand(command, FileSpec(working_dir),
-                                        &shell_command.m_opaque_ptr->m_status,
-                                        &shell_command.m_opaque_ptr->m_signo,
-                                        &shell_command.m_opaque_ptr->m_output,
-                                        shell_command.m_opaque_ptr->m_timeout);
+    return platform_sp->RunShellCommand(
+        shell_command.m_opaque_ptr->m_interpreter, command,
+        FileSpec(working_dir), &shell_command.m_opaque_ptr->m_status,
+        &shell_command.m_opaque_ptr->m_signo,
+        &shell_command.m_opaque_ptr->m_output,
+        shell_command.m_opaque_ptr->m_timeout);
   }));
 }
 
@@ -699,6 +737,10 @@
       SBPlatformShellCommand &,
       SBPlatformShellCommand, operator=,(const lldb::SBPlatformShellCommand &));
   LLDB_REGISTER_METHOD(void, SBPlatformShellCommand, Clear, ());
+  LLDB_REGISTER_METHOD(const char *, SBPlatformShellCommand, GetInterpreter,
+                       ());
+  LLDB_REGISTER_METHOD(void, SBPlatformShellCommand, SetInterpreter,
+                       (const char *));
   LLDB_REGISTER_METHOD(const char *, SBPlatformShellCommand, GetCommand, ());
   LLDB_REGISTER_METHOD(void, SBPlatformShellCommand, SetCommand,
                        (const char *));
Index: lldb/include/lldb/Target/RemoteAwarePlatform.h
===================================================================
--- lldb/include/lldb/Target/RemoteAwarePlatform.h
+++ lldb/include/lldb/Target/RemoteAwarePlatform.h
@@ -68,11 +68,16 @@
   bool GetRemoteOSKernelDescription(std::string &s) override;
   ArchSpec GetRemoteSystemArchitecture() override;
 
-  Status RunShellCommand(const char *command, const FileSpec &working_dir,
+  Status RunShellCommand(llvm::StringRef command, const FileSpec &working_dir,
                          int *status_ptr, int *signo_ptr,
                          std::string *command_output,
                          const Timeout<std::micro> &timeout) override;
 
+  Status RunShellCommand(llvm::StringRef interpreter, llvm::StringRef command,
+                         const FileSpec &working_dir, int *status_ptr,
+                         int *signo_ptr, std::string *command_output,
+                         const Timeout<std::micro> &timeout) override;
+
   const char *GetHostname() override;
   UserIDResolver &GetUserIDResolver() override;
   lldb_private::Environment GetEnvironment() override;
Index: lldb/include/lldb/Target/Platform.h
===================================================================
--- lldb/include/lldb/Target/Platform.h
+++ lldb/include/lldb/Target/Platform.h
@@ -621,7 +621,18 @@
   }
 
   virtual lldb_private::Status RunShellCommand(
-      const char *command,         // Shouldn't be nullptr
+      llvm::StringRef command,
+      const FileSpec &working_dir, // Pass empty FileSpec to use the current
+                                   // working directory
+      int *status_ptr, // Pass nullptr if you don't want the process exit status
+      int *signo_ptr,  // Pass nullptr if you don't want the signal that caused
+                       // the process to exit
+      std::string
+          *command_output, // Pass nullptr if you don't want the command output
+      const Timeout<std::micro> &timeout);
+
+  virtual lldb_private::Status RunShellCommand(
+      llvm::StringRef interpreter, llvm::StringRef command,
       const FileSpec &working_dir, // Pass empty FileSpec to use the current
                                    // working directory
       int *status_ptr, // Pass nullptr if you don't want the process exit status
Index: lldb/include/lldb/Host/Host.h
===================================================================
--- lldb/include/lldb/Host/Host.h
+++ lldb/include/lldb/Host/Host.h
@@ -196,19 +196,36 @@
   static Status ShellExpandArguments(ProcessLaunchInfo &launch_info);
 
   /// Run a shell command.
-  /// \arg command  shouldn't be NULL
+  /// \arg command  shouldn't be empty
   /// \arg working_dir Pass empty FileSpec to use the current working directory
   /// \arg status_ptr  Pass NULL if you don't want the process exit status
   /// \arg signo_ptr   Pass NULL if you don't want the signal that caused the
   ///                  process to exit
   /// \arg command_output  Pass NULL if you don't want the command output
   /// \arg hide_stderr if this is false, redirect stderr to stdout
-  /// TODO: Convert this function to take a StringRef.
-  static Status RunShellCommand(const char *command,
+  static Status RunShellCommand(llvm::StringRef command,
                                 const FileSpec &working_dir, int *status_ptr,
                                 int *signo_ptr, std::string *command_output,
                                 const Timeout<std::micro> &timeout,
-                                bool run_in_default_shell = true,
+                                bool run_in_shell = true,
+                                bool hide_stderr = false);
+
+  /// Run a shell command.
+  /// \arg interpreter  Pass an empty string if you want to use the default
+  ///                   shell interpreter
+  /// \arg command      Shouldn't be NUL
+  /// \arg working_dir  Pass empty FileSpec to use the current working directory
+  /// \arg status_ptr   Pass NULL if you don't want the process exit status
+  /// \arg signo_ptr    Pass NULL if you don't want the signal that caused
+  ///                   the process to exit
+  /// \arg command_output  Pass NULL if you don't want the command output
+  /// \arg hide_stderr  If this is \b false, redirect stderr to stdout
+  static Status RunShellCommand(llvm::StringRef interpreter,
+                                llvm::StringRef command,
+                                const FileSpec &working_dir, int *status_ptr,
+                                int *signo_ptr, std::string *command_output,
+                                const Timeout<std::micro> &timeout,
+                                bool run_in_shell = true,
                                 bool hide_stderr = false);
 
   /// Run a shell command.
@@ -222,7 +239,23 @@
                                 int *status_ptr, int *signo_ptr,
                                 std::string *command_output,
                                 const Timeout<std::micro> &timeout,
-                                bool run_in_default_shell = true,
+                                bool run_in_shell = true,
+                                bool hide_stderr = false);
+
+  /// Run a shell command.
+  /// \arg interpreter Pass an empty string if you want to use the default
+  ///                  shell interpreter
+  /// \arg working_dir Pass empty FileSpec to use the current working directory
+  /// \arg status_ptr  Pass NULL if you don't want the process exit status
+  /// \arg signo_ptr   Pass NULL if you don't want the signal that caused the
+  ///                  process to exit
+  /// \arg command_output  Pass NULL if you don't want the command output
+  /// \arg hide_stderr If this is \b false, redirect stderr to stdout
+  static Status RunShellCommand(llvm::StringRef interpreter, const Args &args,
+                                const FileSpec &working_dir, int *status_ptr,
+                                int *signo_ptr, std::string *command_output,
+                                const Timeout<std::micro> &timeout,
+                                bool run_in_shell = true,
                                 bool hide_stderr = false);
 
   static bool OpenFileInExternalEditor(const FileSpec &file_spec,
Index: lldb/include/lldb/API/SBPlatform.h
===================================================================
--- lldb/include/lldb/API/SBPlatform.h
+++ lldb/include/lldb/API/SBPlatform.h
@@ -51,6 +51,8 @@
 
 class LLDB_API SBPlatformShellCommand {
 public:
+  SBPlatformShellCommand(const char *shell_interpreter,
+                         const char *shell_command);
   SBPlatformShellCommand(const char *shell_command);
 
   SBPlatformShellCommand(const SBPlatformShellCommand &rhs);
@@ -61,6 +63,10 @@
 
   void Clear();
 
+  const char *GetInterpreter();
+
+  void SetInterpreter(const char *shell_interpreter);
+
   const char *GetCommand();
 
   void SetCommand(const char *shell_command);
Index: lldb/bindings/interface/SBPlatform.i
===================================================================
--- lldb/bindings/interface/SBPlatform.i
+++ lldb/bindings/interface/SBPlatform.i
@@ -45,6 +45,7 @@
 class SBPlatformShellCommand
 {
 public:
+    SBPlatformShellCommand (const char *shell_interpreter, const char *shell_command);
     SBPlatformShellCommand (const char *shell_command);
 
     SBPlatformShellCommand (const SBPlatformShellCommand &rhs);
@@ -54,6 +55,12 @@
     void
     Clear();
 
+    const char *
+    GetInterpreter();
+
+    void
+    SetInterpreter(const char *shell_interpreter);
+
     const char *
     GetCommand();
 
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to