summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/source/Plugins/Platform/Android/AdbClient.cpp49
-rw-r--r--lldb/source/Plugins/Platform/Android/AdbClient.h3
-rw-r--r--lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp15
-rw-r--r--lldb/source/Plugins/Platform/Android/PlatformAndroid.h8
4 files changed, 73 insertions, 2 deletions
diff --git a/lldb/source/Plugins/Platform/Android/AdbClient.cpp b/lldb/source/Plugins/Platform/Android/AdbClient.cpp
index 2e574bcbe94..27e21695be8 100644
--- a/lldb/source/Plugins/Platform/Android/AdbClient.cpp
+++ b/lldb/source/Plugins/Platform/Android/AdbClient.cpp
@@ -12,6 +12,7 @@
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/DataEncoder.h"
#include "lldb/Core/DataExtractor.h"
+#include "lldb/Host/FileSpec.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/STLExtras.h"
@@ -36,6 +37,10 @@ const uint32_t kReadTimeout = 1000000; // 1 second
const char * kOKAY = "OKAY";
const char * kFAIL = "FAIL";
const size_t kSyncPacketLen = 8;
+// Maximum size of a filesync DATA packet.
+const size_t kMaxPushData = 2*1024;
+// Default mode for pushed files.
+const uint32_t kDefaultMode = 0100770; // S_IFREG | S_IRWXU | S_IRWXG
} // namespace
@@ -281,6 +286,47 @@ AdbClient::PullFile (const char *remote_file, const char *local_file)
}
Error
+AdbClient::PushFile (const lldb_private::FileSpec& source, const lldb_private::FileSpec& destination)
+{
+ auto error = SwitchDeviceTransport ();
+ if (error.Fail ())
+ return Error ("Failed to switch to device transport: %s", error.AsCString ());
+
+ error = Sync ();
+ if (error.Fail ())
+ return Error ("Sync failed: %s", error.AsCString ());
+
+ std::ifstream src (source.GetPath().c_str(), std::ios::in | std::ios::binary);
+ if (!src.is_open ())
+ return Error ("Unable to open local file %s", source.GetPath().c_str());
+
+ std::stringstream file_description;
+ file_description << destination.GetPath(false).c_str() << "," << kDefaultMode;
+ std::string file_description_str = file_description.str();
+ error = SendSyncRequest ("SEND", file_description_str.length(), file_description_str.c_str());
+ if (error.Fail ())
+ return error;
+
+ char chunk[kMaxPushData];
+ while (!src.eof() && !src.read(chunk, kMaxPushData).bad())
+ {
+ size_t chunk_size = src.gcount();
+ error = SendSyncRequest("DATA", chunk_size, chunk);
+ if (error.Fail ())
+ return Error ("Failed to send file chunk: %s", error.AsCString ());
+ }
+ error = SendSyncRequest("DONE", source.GetModificationTime().seconds(), nullptr);
+ if (error.Fail ())
+ return error;
+ error = ReadResponseStatus();
+ // If there was an error reading the source file, finish the adb file
+ // transfer first so that adb isn't expecting any more data.
+ if (src.bad())
+ return Error ("Failed read on %s", source.GetPath().c_str());
+ return error;
+}
+
+Error
AdbClient::Sync ()
{
auto error = SendMessage ("sync:", false);
@@ -330,7 +376,8 @@ AdbClient::SendSyncRequest (const char *request_id, const uint32_t data_len, con
if (error.Fail ())
return error;
- m_conn.Write (data, data_len, status, &error);
+ if (data)
+ m_conn.Write (data, data_len, status, &error);
return error;
}
diff --git a/lldb/source/Plugins/Platform/Android/AdbClient.h b/lldb/source/Plugins/Platform/Android/AdbClient.h
index 783e5804b6d..d307b6a298a 100644
--- a/lldb/source/Plugins/Platform/Android/AdbClient.h
+++ b/lldb/source/Plugins/Platform/Android/AdbClient.h
@@ -53,6 +53,9 @@ public:
Error
PullFile (const char *remote_file, const char *local_file);
+ Error
+ PushFile (const lldb_private::FileSpec& source, const lldb_private::FileSpec& destination);
+
private:
Error
Connect ();
diff --git a/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp b/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp
index 806714ac174..7a6e85cc333 100644
--- a/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp
+++ b/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp
@@ -207,6 +207,21 @@ PlatformAndroid::ConnectRemote(Args& args)
return error;
}
+lldb_private::Error
+PlatformAndroid::PutFile (const lldb_private::FileSpec& source,
+ const lldb_private::FileSpec& destination,
+ uint32_t uid,
+ uint32_t gid)
+{
+ if (!IsHost() && m_remote_platform_sp)
+ {
+ AdbClient adb (m_device_id);
+ // TODO: Set correct uid and gid on remote file.
+ return adb.PushFile(source, destination);
+ }
+ return PlatformLinux::PutFile(source, destination, uid, gid);
+}
+
const char *
PlatformAndroid::GetCacheHostname ()
{
diff --git a/lldb/source/Plugins/Platform/Android/PlatformAndroid.h b/lldb/source/Plugins/Platform/Android/PlatformAndroid.h
index 02aa2265f71..f1d34e64eb0 100644
--- a/lldb/source/Plugins/Platform/Android/PlatformAndroid.h
+++ b/lldb/source/Plugins/Platform/Android/PlatformAndroid.h
@@ -64,7 +64,13 @@ namespace platform_android {
Error
ConnectRemote (Args& args) override;
- protected:
+ lldb_private::Error
+ PutFile (const lldb_private::FileSpec& source,
+ const lldb_private::FileSpec& destination,
+ uint32_t uid = UINT32_MAX,
+ uint32_t gid = UINT32_MAX) override;
+
+ protected:
const char *
GetCacheHostname () override;
OpenPOWER on IntegriCloud