ovyalov created this revision.
ovyalov added reviewers: tberghammer, labath.
ovyalov added a subscriber: lldb-commits.
Herald added subscribers: danalbert, tberghammer.

adbd may fail to access a file due security constraints - in such case 
sync:stat command returns file's mode as 0. If it's the case - use shell cat a 
workaround then.

http://reviews.llvm.org/D22081

Files:
  source/Plugins/Platform/Android/AdbClient.cpp
  source/Plugins/Platform/Android/AdbClient.h
  source/Plugins/Platform/Android/PlatformAndroid.cpp

Index: source/Plugins/Platform/Android/PlatformAndroid.cpp
===================================================================
--- source/Plugins/Platform/Android/PlatformAndroid.cpp
+++ source/Plugins/Platform/Android/PlatformAndroid.cpp
@@ -230,6 +230,22 @@
     if (error.Fail ())
         return error;
 
+    uint32_t mode = 0, size = 0, mtime = 0;
+    error = sync_service->Stat (source_spec, mode, size, mtime);
+    if (error.Fail ())
+        return error;
+
+    if (mode == 0)
+    {
+        // mode == 0 can signify that adbd cannot access the file
+        // due security constraints - try "cat ..." as a fallback. 
+        AdbClient adb(m_device_id);
+        char cmd[PATH_MAX];
+        snprintf (cmd, sizeof (cmd), "cat '%s'", source_spec.GetCString (false));
+
+        return adb.ShellToFile(cmd, 60000 /* ms */, destination);
+    }
+
     return sync_service->PullFile (source_spec, destination);
 }
 
Index: source/Plugins/Platform/Android/AdbClient.h
===================================================================
--- source/Plugins/Platform/Android/AdbClient.h
+++ source/Plugins/Platform/Android/AdbClient.h
@@ -119,6 +119,9 @@
     Error
     Shell (const char* command, uint32_t timeout_ms, std::string* output);
 
+    Error
+    ShellToFile (const char* command, uint32_t timeout_ms, const FileSpec &output_file_spec);
+
     std::unique_ptr<SyncService>
     GetSyncService (Error &error);
 
@@ -157,6 +160,9 @@
     StartSync ();
 
     Error
+    internalShell (const char* command, uint32_t timeout_ms, std::vector<char> &output_buf);
+
+    Error
     ReadAllBytes (void *buffer, size_t size);
 
     std::string m_device_id;
Index: source/Plugins/Platform/Android/AdbClient.cpp
===================================================================
--- source/Plugins/Platform/Android/AdbClient.cpp
+++ source/Plugins/Platform/Android/AdbClient.cpp
@@ -378,8 +378,10 @@
 }
 
 Error
-AdbClient::Shell (const char* command, uint32_t timeout_ms, std::string* output)
+AdbClient::internalShell (const char* command, uint32_t timeout_ms, std::vector<char> &output_buf)
 {
+    output_buf.clear ();
+
     auto error = SwitchDeviceTransport ();
     if (error.Fail ())
         return Error ("Failed to switch to device transport: %s", error.AsCString ());
@@ -394,16 +396,39 @@
     if (error.Fail ())
         return error;
 
-    std::vector<char> in_buffer;
-    error = ReadMessageStream (in_buffer, timeout_ms);
-    if (error.Fail())
+    return ReadMessageStream (output_buf, timeout_ms);
+}
+
+Error
+AdbClient::Shell (const char* command, uint32_t timeout_ms, std::string* output)
+{
+    std::vector<char> output_buffer;
+    auto error = internalShell (command, timeout_ms, output_buffer);
+    if (error.Fail ())
         return error;
 
     if (output)
-        output->assign(in_buffer.begin(), in_buffer.end());
+        output->assign(output_buffer.begin(), output_buffer.end());
     return error;
 }
 
+Error
+AdbClient::ShellToFile (const char* command, uint32_t timeout_ms, const FileSpec &output_file_spec)
+{
+    std::vector<char> output_buffer;
+    auto error = internalShell (command, timeout_ms, output_buffer);
+    if (error.Fail ())
+        return error;
+
+    const auto output_filename = output_file_spec.GetPath ();
+    std::ofstream dst (output_filename, std::ios::out | std::ios::binary);
+    if (!dst.is_open ())
+        return Error ("Unable to open local file %s", output_filename.c_str());
+    
+    dst.write (&output_buffer[0], output_buffer.size ());
+    return Error ();
+}
+
 std::unique_ptr<AdbClient::SyncService>
 AdbClient::GetSyncService (Error &error)
 {
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to