adb: Look for shell executable in alternate places

 * Honor persist.sys.adb.shell.

Change-Id: I02ac651397021097fe865436c982e2b720d7917f
diff --git a/daemon/shell_service.cpp b/daemon/shell_service.cpp
index dbca4ad..4c03776 100644
--- a/daemon/shell_service.cpp
+++ b/daemon/shell_service.cpp
@@ -85,6 +85,7 @@
 #include <paths.h>
 #include <pty.h>
 #include <pwd.h>
+#include <sys/stat.h>
 #include <termios.h>
 
 #include <memory>
@@ -113,6 +114,17 @@
 
 namespace {
 
+static std::string GetShellPath() {
+    std::string shell = android::base::GetProperty("persist.sys.adb.shell", "");
+    struct stat st;
+
+    if (!shell.empty() && stat(shell.c_str(), &st) != -1) {
+        return shell;
+    }
+
+    return _PATH_BSHELL;
+}
+
 // Reads from |fd| until close or failure.
 std::string ReadAll(borrowed_fd fd) {
     char buffer[512];
@@ -386,13 +398,16 @@
         }
 #endif
 
+        std::string sh_path = GetShellPath();
+
         if (command_.empty()) {
             // Spawn a login shell if we don't have a command.
-            execle(_PATH_BSHELL, "-" _PATH_BSHELL, nullptr, cenv.data());
+            execle(sh_path.c_str(), sh_path.c_str(), "-", nullptr, cenv.data());
         } else {
-            execle(_PATH_BSHELL, _PATH_BSHELL, "-c", command_.c_str(), nullptr, cenv.data());
+            execle(sh_path.c_str(), sh_path.c_str(), "-c", command_.c_str(), nullptr, cenv.data());
         }
-        WriteFdExactly(child_error_sfd, "exec '" _PATH_BSHELL "' failed: ");
+        WriteFdExactly(child_error_sfd,
+                       android::base::StringPrintf("Exec '%s' failed: ", sh_path.c_str()).c_str());
         WriteFdExactly(child_error_sfd, strerror(errno));
         child_error_sfd.reset(-1);
         _Exit(1);