[Lldb-commits] [lldb] r234455 - Darwin read()/pread()/fread() and write()/pwrite()/fwrite() calls can only write INT_MAX bytes at a time.

Greg Clayton gclayton at apple.com
Wed Apr 8 17:06:44 PDT 2015


Author: gclayton
Date: Wed Apr  8 19:06:44 2015
New Revision: 234455

URL: http://llvm.org/viewvc/llvm-project?rev=234455&view=rev
Log:
Darwin read()/pread()/fread() and write()/pwrite()/fwrite() calls can only write INT_MAX bytes at a time.

Modify all read/write calls to allow any system to define MAX_READ_SIZE or MAX_WRITE_SIZE so large reads and writes can be divided up correctly.

<rdar://problem/20471411>


Modified:
    lldb/trunk/source/Host/common/File.cpp

Modified: lldb/trunk/source/Host/common/File.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/File.cpp?rev=234455&r1=234454&r2=234455&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/File.cpp (original)
+++ lldb/trunk/source/Host/common/File.cpp Wed Apr  8 19:06:44 2015
@@ -595,10 +595,49 @@ File::Sync ()
     return error;
 }
 
+#if defined (__APPLE__)
+// Darwin kernels only can read/write <= INT_MAX bytes
+#define MAX_READ_SIZE INT_MAX
+#define MAX_WRITE_SIZE INT_MAX
+#endif
+
 Error
 File::Read (void *buf, size_t &num_bytes)
 {
     Error error;
+
+#if defined (MAX_READ_SIZE)
+    if (num_bytes > MAX_READ_SIZE)
+    {
+        uint8_t *p = (uint8_t *)buf;
+        size_t bytes_left = num_bytes;
+        // Init the num_bytes read to zero
+        num_bytes = 0;
+
+        while (bytes_left > 0)
+        {
+            size_t curr_num_bytes;
+            if (bytes_left > MAX_READ_SIZE)
+                curr_num_bytes = MAX_READ_SIZE;
+            else
+                curr_num_bytes = bytes_left;
+
+            error = Read (p + num_bytes, curr_num_bytes);
+
+            // Update how many bytes were read
+            num_bytes += curr_num_bytes;
+            if (bytes_left < curr_num_bytes)
+                bytes_left = 0;
+            else
+                bytes_left -= curr_num_bytes;
+
+            if (error.Fail())
+                break;
+        }
+        return error;
+    }
+#endif
+
     ssize_t bytes_read = -1;
     if (DescriptorIsValid())
     {
@@ -642,6 +681,39 @@ Error
 File::Write (const void *buf, size_t &num_bytes)
 {
     Error error;
+
+#if defined (MAX_WRITE_SIZE)
+    if (num_bytes > MAX_WRITE_SIZE)
+    {
+        const uint8_t *p = (const uint8_t *)buf;
+        size_t bytes_left = num_bytes;
+        // Init the num_bytes written to zero
+        num_bytes = 0;
+
+        while (bytes_left > 0)
+        {
+            size_t curr_num_bytes;
+            if (bytes_left > MAX_WRITE_SIZE)
+                curr_num_bytes = MAX_WRITE_SIZE;
+            else
+                curr_num_bytes = bytes_left;
+
+            error = Write (p + num_bytes, curr_num_bytes);
+
+            // Update how many bytes were read
+            num_bytes += curr_num_bytes;
+            if (bytes_left < curr_num_bytes)
+                bytes_left = 0;
+            else
+                bytes_left -= curr_num_bytes;
+
+            if (error.Fail())
+                break;
+        }
+        return error;
+    }
+#endif
+
     ssize_t bytes_written = -1;
     if (DescriptorIsValid())
     {
@@ -687,8 +759,41 @@ File::Write (const void *buf, size_t &nu
 Error
 File::Read (void *buf, size_t &num_bytes, off_t &offset)
 {
-#ifndef _WIN32
     Error error;
+
+#if defined (MAX_READ_SIZE)
+    if (num_bytes > MAX_READ_SIZE)
+    {
+        uint8_t *p = (uint8_t *)buf;
+        size_t bytes_left = num_bytes;
+        // Init the num_bytes read to zero
+        num_bytes = 0;
+
+        while (bytes_left > 0)
+        {
+            size_t curr_num_bytes;
+            if (bytes_left > MAX_READ_SIZE)
+                curr_num_bytes = MAX_READ_SIZE;
+            else
+                curr_num_bytes = bytes_left;
+
+            error = Read (p + num_bytes, curr_num_bytes, offset);
+
+            // Update how many bytes were read
+            num_bytes += curr_num_bytes;
+            if (bytes_left < curr_num_bytes)
+                bytes_left = 0;
+            else
+                bytes_left -= curr_num_bytes;
+
+            if (error.Fail())
+                break;
+        }
+        return error;
+    }
+#endif
+
+#ifndef _WIN32
     int fd = GetDescriptor();
     if (fd != kInvalidDescriptor)
     {
@@ -714,15 +819,14 @@ File::Read (void *buf, size_t &num_bytes
         num_bytes = 0;
         error.SetErrorString("invalid file handle");
     }
-    return error;
 #else
     long cur = ::lseek(m_descriptor, 0, SEEK_CUR);
     SeekFromStart(offset);
-    Error error = Read(buf, num_bytes);
+    error = Read(buf, num_bytes);
     if (!error.Fail())
         SeekFromStart(cur);
-    return error;
 #endif
+    return error;
 }
 
 Error
@@ -746,7 +850,8 @@ File::Read (size_t &num_bytes, off_t &of
                         
                     size_t num_bytes_plus_nul_char = num_bytes + (null_terminate ? 1 : 0);
                     std::unique_ptr<DataBufferHeap> data_heap_ap;
-                    data_heap_ap.reset(new DataBufferHeap(num_bytes_plus_nul_char, '\0'));
+                    data_heap_ap.reset(new DataBufferHeap());
+                    data_heap_ap->SetByteSize(num_bytes_plus_nul_char);
                         
                     if (data_heap_ap.get())
                     {
@@ -782,6 +887,38 @@ File::Read (size_t &num_bytes, off_t &of
 Error
 File::Write (const void *buf, size_t &num_bytes, off_t &offset)
 {
+#if defined (MAX_WRITE_SIZE)
+    if (num_bytes > MAX_WRITE_SIZE)
+    {
+        const uint8_t *p = (const uint8_t *)buf;
+        size_t bytes_left = num_bytes;
+        // Init the num_bytes written to zero
+        num_bytes = 0;
+
+        while (bytes_left > 0)
+        {
+            size_t curr_num_bytes;
+            if (bytes_left > MAX_WRITE_SIZE)
+                curr_num_bytes = MAX_WRITE_SIZE;
+            else
+                curr_num_bytes = bytes_left;
+
+            error = Write (p + num_bytes, curr_num_bytes, offset);
+
+            // Update how many bytes were read
+            num_bytes += curr_num_bytes;
+            if (bytes_left < curr_num_bytes)
+                bytes_left = 0;
+            else
+                bytes_left -= curr_num_bytes;
+
+            if (error.Fail())
+                break;
+        }
+        return error;
+    }
+#endif
+
     Error error;
     int fd = GetDescriptor();
     if (fd != kInvalidDescriptor)





More information about the lldb-commits mailing list