summaryrefslogtreecommitdiffstats
path: root/lldb/source/Host/android/ProcessLauncherAndroid.cpp
diff options
context:
space:
mode:
authorTamas Berghammer <tberghammer@google.com>2015-03-03 12:14:45 +0000
committerTamas Berghammer <tberghammer@google.com>2015-03-03 12:14:45 +0000
commitbd05108e53b26a8c5a68bfc867ca77e135a75c34 (patch)
treefa6fb9344af9ba0b7e969a20a652f107188204c1 /lldb/source/Host/android/ProcessLauncherAndroid.cpp
parent8f239f83b033b50294f21bbca7e79ae4b1ccb1ca (diff)
downloadbcm5719-llvm-bd05108e53b26a8c5a68bfc867ca77e135a75c34.tar.gz
bcm5719-llvm-bd05108e53b26a8c5a68bfc867ca77e135a75c34.zip
Fix execution of platform shell commands on android
* Add missing functionality to the process launcher * Fixup PATH environment variable to workaround an OS bug * Add default shell path to the host info structure Differential revision: http://reviews.llvm.org/D8009 llvm-svn: 231065
Diffstat (limited to 'lldb/source/Host/android/ProcessLauncherAndroid.cpp')
-rw-r--r--lldb/source/Host/android/ProcessLauncherAndroid.cpp62
1 files changed, 55 insertions, 7 deletions
diff --git a/lldb/source/Host/android/ProcessLauncherAndroid.cpp b/lldb/source/Host/android/ProcessLauncherAndroid.cpp
index f90ba2fe41d..16c1d9b5888 100644
--- a/lldb/source/Host/android/ProcessLauncherAndroid.cpp
+++ b/lldb/source/Host/android/ProcessLauncherAndroid.cpp
@@ -18,6 +18,33 @@
using namespace lldb;
using namespace lldb_private;
+static bool
+DupDescriptor(const char *path, int fd, int flags)
+{
+ int target_fd = ::open(path, flags, 0666);
+
+ if (target_fd == -1)
+ return false;
+
+ if (::dup2(target_fd, fd) == -1)
+ return false;
+
+ return (::close(target_fd) == -1) ? false : true;
+}
+
+// If there is no PATH variable specified inside the environment then set the path to /system/bin.
+// It is required because the default path used by execve() is wrong on android.
+static void
+FixupEnvironment(Args& env)
+{
+ static const char* path = "PATH=";
+ static const int path_len = ::strlen(path);
+ for (const char** args = env.GetConstArgumentVector(); *args; ++args)
+ if (::strncmp(path, *args, path_len) == 0)
+ return;
+ env.AppendArgument("PATH=/system/bin");
+}
+
HostProcess
ProcessLauncherAndroid::LaunchProcess(const ProcessLaunchInfo &launch_info, Error &error)
{
@@ -26,11 +53,8 @@ ProcessLauncherAndroid::LaunchProcess(const ProcessLaunchInfo &launch_info, Erro
char exe_path[PATH_MAX];
launch_info.GetExecutableFile().GetPath(exe_path, sizeof(exe_path));
- const size_t err_len = 1024;
- char err_str[err_len];
-
- lldb::pid_t pid = ::fork ();
- if (pid < 0)
+ lldb::pid_t pid = ::fork();
+ if (pid == static_cast<lldb::pid_t>(-1))
{
// Fork failed
error.SetErrorStringWithFormat("Fork failed with error message: %s", strerror(errno));
@@ -38,11 +62,35 @@ ProcessLauncherAndroid::LaunchProcess(const ProcessLaunchInfo &launch_info, Erro
}
else if (pid == 0)
{
+ if (const lldb_private::FileAction *file_action = launch_info.GetFileActionForFD(STDIN_FILENO)) {
+ const char* path = file_action->GetPath();
+ if (path && ::strlen(path))
+ if (!DupDescriptor(path, STDIN_FILENO, O_RDONLY))
+ exit(-1);
+ }
+
+ if (const lldb_private::FileAction *file_action = launch_info.GetFileActionForFD(STDOUT_FILENO)) {
+ const char* path = file_action->GetPath();
+ if (path && ::strlen(path))
+ if (!DupDescriptor(path, STDOUT_FILENO, O_WRONLY | O_CREAT | O_TRUNC))
+ exit(-1);
+ }
+
+ if (const lldb_private::FileAction *file_action = launch_info.GetFileActionForFD(STDERR_FILENO)) {
+ const char* path = file_action->GetPath();
+ if (path && ::strlen(path))
+ if (!DupDescriptor(path, STDERR_FILENO, O_WRONLY | O_CREAT | O_TRUNC))
+ exit(-1);
+ }
+
// Child process
const char **argv = launch_info.GetArguments().GetConstArgumentVector();
- const char **envp = launch_info.GetEnvironmentEntries().GetConstArgumentVector();
+
+ Args env = launch_info.GetEnvironmentEntries();
+ FixupEnvironment(env);
+ const char **envp = env.GetConstArgumentVector();
+
const char *working_dir = launch_info.GetWorkingDirectory();
-
if (working_dir != nullptr && working_dir[0])
{
if (::chdir(working_dir) != 0)
OpenPOWER on IntegriCloud