[Lldb-commits] [lldb] r154350 - in /lldb/branches/lldb-platform-work: include/lldb/Host/File.h include/lldb/Host/FileSpec.h source/Commands/CommandObjectPlatform.cpp source/Host/common/File.cpp source/Host/common/FileSpec.cpp source/Host/common/Host.cpp source/Host/macosx/Host.mm source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp

Enrico Granata egranata at apple.com
Mon Apr 9 15:35:27 PDT 2012


Author: enrico
Date: Mon Apr  9 17:35:26 2012
New Revision: 154350

URL: http://llvm.org/viewvc/llvm-project?rev=154350&view=rev
Log:
Initial implementation of a put-file command. This is a basic Platform building block that uses the lower-level open,read,write and close primitives to transfer a file from the local system to the remote end. Better implementations are possible given more knowledge of the command toolchains available on the remote end, exploiting the RunShellCommand() feature, but this basic mechanism should work everywhere lldb_private::File works

Modified:
    lldb/branches/lldb-platform-work/include/lldb/Host/File.h
    lldb/branches/lldb-platform-work/include/lldb/Host/FileSpec.h
    lldb/branches/lldb-platform-work/source/Commands/CommandObjectPlatform.cpp
    lldb/branches/lldb-platform-work/source/Host/common/File.cpp
    lldb/branches/lldb-platform-work/source/Host/common/FileSpec.cpp
    lldb/branches/lldb-platform-work/source/Host/common/Host.cpp
    lldb/branches/lldb-platform-work/source/Host/macosx/Host.mm
    lldb/branches/lldb-platform-work/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
    lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp

Modified: lldb/branches/lldb-platform-work/include/lldb/Host/File.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Host/File.h?rev=154350&r1=154349&r2=154350&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Host/File.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/Host/File.h Mon Apr  9 17:35:26 2012
@@ -117,6 +117,27 @@
           uint32_t options,
           uint32_t permissions = ePermissionsDefault);
 
+    //------------------------------------------------------------------
+    /// Constructor with FileSpec.
+    ///
+    /// Takes a FileSpec pointing to a file which can be just a filename, or a full
+    /// path. If \a path is not NULL or empty, this function will call
+    /// File::Open (const char *path, uint32_t options, uint32_t permissions).
+    ///
+    /// @param[in] path
+    ///     The FileSpec for this file.
+    ///
+    /// @param[in] options
+    ///     Options to use when opening (see File::OpenOptions)
+    ///
+    /// @param[in] permissions
+    ///     Options to use when opening (see File::Permissions)
+    ///
+    /// @see File::Open (const char *path, uint32_t options, uint32_t permissions)
+    //------------------------------------------------------------------
+    File (const FileSpec& filespec,
+          uint32_t options,
+          uint32_t permissions = ePermissionsDefault);
     
     File (int fd, bool tranfer_ownership) : 
         m_descriptor (fd),

Modified: lldb/branches/lldb-platform-work/include/lldb/Host/FileSpec.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Host/FileSpec.h?rev=154350&r1=154349&r2=154350&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Host/FileSpec.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/Host/FileSpec.h Mon Apr  9 17:35:26 2012
@@ -358,6 +358,22 @@
     GetPath (char *path, size_t max_path_length) const;
 
     //------------------------------------------------------------------
+    /// Extract the full path to the file.
+    ///
+    /// Extract the directory and path into a std::string. This is
+    /// needed as the directory and path are stored in separate string
+    /// values.
+    ///
+    /// @param[out] path
+    ///     The buffer in which to place the extracted full path.
+    ///
+    /// @return
+    ///     Returns the number of characters that make up this path.
+    //------------------------------------------------------------------
+    size_t
+    GetPath (std::string& path) const;
+    
+    //------------------------------------------------------------------
     /// Extract the extension of the file.
     ///
     /// Returns a ConstString that represents the extension of the filename

Modified: lldb/branches/lldb-platform-work/source/Commands/CommandObjectPlatform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Commands/CommandObjectPlatform.cpp?rev=154350&r1=154349&r2=154350&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Commands/CommandObjectPlatform.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Commands/CommandObjectPlatform.cpp Mon Apr  9 17:35:26 2012
@@ -512,7 +512,7 @@
 
 
 //----------------------------------------------------------------------
-// "platform fread"
+// "platform fwrite"
 //----------------------------------------------------------------------
 class CommandObjectPlatformFWrite : public CommandObject
 {
@@ -632,6 +632,49 @@
 };
 
 //----------------------------------------------------------------------
+// "platform put-file"
+//----------------------------------------------------------------------
+class CommandObjectPlatformPutFile : public CommandObject
+{
+public:
+    CommandObjectPlatformPutFile (CommandInterpreter &interpreter) :
+    CommandObject (interpreter,
+                   "platform put-file",
+                   "Transfer a file from this system to the remote end.",
+                   NULL,
+                   0)
+    {
+    }
+    
+    virtual
+    ~CommandObjectPlatformPutFile ()
+    {
+    }
+    
+    virtual bool
+    Execute (Args& args, CommandReturnObject &result)
+    {
+        const char* src = args.GetArgumentAtIndex(0);
+        const char* dst = args.GetArgumentAtIndex(1);
+
+        FileSpec src_fs(src, true);
+        FileSpec dst_fs(dst, false);
+        
+        PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+        if (platform_sp)
+        {
+            platform_sp->PutFile(src_fs, dst_fs);
+        }
+        else
+        {
+            result.AppendError ("no platform currently selected\n");
+            result.SetStatus (eReturnStatusFailed);
+        }
+        return result.Succeeded();
+    }
+};
+
+//----------------------------------------------------------------------
 // "platform connect <connect-url>"
 //----------------------------------------------------------------------
 class CommandObjectPlatformConnect : public CommandObject
@@ -1306,6 +1349,7 @@
     LoadSubCommand ("fclose", CommandObjectSP (new CommandObjectPlatformFClose  (interpreter)));
     LoadSubCommand ("fread", CommandObjectSP (new CommandObjectPlatformFRead  (interpreter)));
     LoadSubCommand ("fwrite", CommandObjectSP (new CommandObjectPlatformFWrite  (interpreter)));
+    LoadSubCommand ("put-file", CommandObjectSP (new CommandObjectPlatformPutFile  (interpreter)));
 #endif
 }
 

Modified: lldb/branches/lldb-platform-work/source/Host/common/File.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Host/common/File.cpp?rev=154350&r1=154349&r2=154350&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Host/common/File.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Host/common/File.cpp Mon Apr  9 17:35:26 2012
@@ -79,6 +79,22 @@
     Open (path, options, permissions);
 }
 
+File::File (const FileSpec& filespec,
+            uint32_t options,
+            uint32_t permissions) :
+    m_descriptor (kInvalidDescriptor),
+    m_stream (kInvalidStream),
+    m_options (0),
+    m_owned (false)
+{
+    if (filespec)
+    {
+        std::string path;
+        filespec.GetPath(path);
+        Open (path.c_str(), options, permissions);
+    }
+}
+
 File::File (const File &rhs) :
     m_descriptor (kInvalidDescriptor),
     m_stream (kInvalidStream),

Modified: lldb/branches/lldb-platform-work/source/Host/common/FileSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Host/common/FileSpec.cpp?rev=154350&r1=154349&r2=154350&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Host/common/FileSpec.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Host/common/FileSpec.cpp Mon Apr  9 17:35:26 2012
@@ -676,6 +676,34 @@
     return m_filename;
 }
 
+size_t
+FileSpec::GetPath (std::string& path) const
+{
+    const char *dirname = m_directory.GetCString();
+    const char *filename = m_filename.GetCString();
+    
+    uint32_t max_len = strlen(dirname) + strlen(filename) + 2;
+    
+    path.resize(max_len);
+        
+    if (dirname)
+    {
+        if (filename)
+            return ::snprintf (&path[0], max_len, "%s/%s", dirname, filename);
+        else
+            return ::snprintf (&path[0], max_len, "%s", dirname);
+    }
+    else if (filename)
+    {
+        return ::snprintf (&path[0], max_len, "%s", filename);
+    }
+    else
+    {
+        path.clear();
+        return 0;
+    }
+}
+
 //------------------------------------------------------------------
 // Extract the directory and path into a fixed buffer. This is
 // needed as the directory and path are stored in separate string

Modified: lldb/branches/lldb-platform-work/source/Host/common/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Host/common/Host.cpp?rev=154350&r1=154349&r2=154350&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Host/common/Host.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Host/common/Host.cpp Mon Apr  9 17:35:26 2012
@@ -1287,7 +1287,7 @@
                 uint32_t flags,
                 mode_t mode)
 {
-    std::string path(512, ' ');
+    std::string path(512, 0);
     uint32_t len = file_spec.GetPath(&path[0], 512);
     if (len >= 512)
     {

Modified: lldb/branches/lldb-platform-work/source/Host/macosx/Host.mm
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Host/macosx/Host.mm?rev=154350&r1=154349&r2=154350&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Host/macosx/Host.mm (original)
+++ lldb/branches/lldb-platform-work/source/Host/macosx/Host.mm Mon Apr  9 17:35:26 2012
@@ -1847,7 +1847,7 @@
 uint32_t
 Host::RunProgramAndGetExitCode (const FileSpec& file_spec)
 {
-    std::string path(512, ' ');
+    std::string path(512, 0);
     uint32_t len = file_spec.GetPath(&path[0], 512);
     if (len >= 512)
     {

Modified: lldb/branches/lldb-platform-work/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp?rev=154350&r1=154349&r2=154350&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp Mon Apr  9 17:35:26 2012
@@ -14,10 +14,14 @@
 #include <sys/sysctl.h>
 
 // C++ Includes
+
+#include <sstream>
+
 // Other libraries and framework includes
 // Project includes
 #include "lldb/Core/Error.h"
 #include "lldb/Breakpoint/BreakpointLocation.h"
+#include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleList.h"
 #include "lldb/Core/PluginManager.h"
@@ -234,5 +238,85 @@
                          uint32_t uid,
                          uint32_t gid)
 {
+#define PUTFILE_CHUNK_SIZE 1024
+    if (IsHost())
+    {
+        if (FileSpec::Equal(source, destination, true))
+            return Error();
+        // cp src dst
+        // chown uid:gid dst
+        std::string src_path(512, 0);
+        uint32_t len = source.GetPath(&src_path[0], 512);
+        if (len >= 512)
+        {
+            src_path = std::string(len+1,0);
+            len = source.GetPath(&src_path[0], len);
+        }
+        std::string dst_path(512, 0);
+        len = destination.GetPath(&dst_path[0], 512);
+        if (len >= 512)
+        {
+            src_path = std::string(len+1,0);
+            len = destination.GetPath(&dst_path[0], len);
+        }
+        std::stringstream cp_command("cp ");
+        cp_command << src_path << ' ' << dst_path;
+        if (RunShellCommand(cp_command.str()) != 0)
+            return Error("unable to perform copy");
+        if (uid == UINT32_MAX && gid == UINT32_MAX)
+            return Error();
+        std::stringstream chown_command("chown ");
+        if (uid != UINT32_MAX)
+            chown_command << uid;
+        if (gid != UINT32_MAX)
+            chown_command << ':' << gid;
+        chown_command << ' ' << dst_path;
+        if (RunShellCommand(chown_command.str()) != 0)
+            return Error("unable to perform chown");
+        return Error();
+    }
+    if (IsRemote() && m_remote_platform_sp)
+    {
+        // open
+        // read, write, read, write, ...
+        // close
+        // chown uid:gid dst
+        File source_file(source, File::eOpenOptionRead, File::ePermissionsUserRW);
+        if (!source_file.IsValid())
+            return Error("unable to open source file");
+        lldb::user_id_t dest_file = OpenFile(destination, File::eOpenOptionCanCreate | File::eOpenOptionWrite | File::eOpenOptionTruncate,
+            File::ePermissionsUserRWX | File::ePermissionsGroupRX | File::ePermissionsWorldRX);
+        if (dest_file == UINT64_MAX)
+            return Error("unable to open target file");
+        lldb::DataBufferSP buffer_sp(new DataBufferHeap(PUTFILE_CHUNK_SIZE, 0));
+        Error err;
+        uint64_t offset = 0;
+        while (err.Success())
+        {
+            size_t read_data = PUTFILE_CHUNK_SIZE;
+            err = source_file.Read(buffer_sp->GetBytes(), read_data);
+            if (read_data)
+            {
+                WriteFile(dest_file, offset, buffer_sp->GetBytes(), read_data);
+                offset += read_data;
+            }
+            else
+                break;
+        }
+        CloseFile(dest_file);
+        if (uid == UINT32_MAX && gid == UINT32_MAX)
+            return Error();
+        std::string dst_path;
+        destination.GetPath(dst_path);
+        std::stringstream chown_command("chown ");
+        if (uid != UINT32_MAX)
+            chown_command << uid;
+        if (gid != UINT32_MAX)
+            chown_command << ':' << gid;
+        chown_command << ' ' << dst_path;
+        if (RunShellCommand(chown_command.str()) != 0)
+            return Error("unable to perform chown");
+        return Error();
+    }
     return Platform::PutFile(source,destination,uid,gid);
 }

Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp?rev=154350&r1=154349&r2=154350&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Mon Apr  9 17:35:26 2012
@@ -1920,7 +1920,7 @@
 {
     lldb_private::StreamString stream;
     stream.PutCString("vFile:open:");
-    std::string path(512, ' ');
+    std::string path(512, 0);
     uint32_t len = file_spec.GetPath(&path[0], 512);
     if (len >= 512)
     {





More information about the lldb-commits mailing list