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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits