<rdar://problem/10507811>

Be better at detecting when DWARF changes and handle this more
gracefully than asserting and exiting.

Also fixed up a bunch of system calls that weren't properly checking
for EINTR.



git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@147559 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Host/common/File.cpp b/source/Host/common/File.cpp
index a12cd3a..a84266f 100644
--- a/source/Host/common/File.cpp
+++ b/source/Host/common/File.cpp
@@ -10,11 +10,13 @@
 
 #include "lldb/Host/File.h"
 
+#include <errno.h>
 #include <fcntl.h>
 #include <limits.h>
 #include <stdarg.h>
 #include <sys/stat.h>
 
+#include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/Error.h"
 #include "lldb/Host/Config.h"
 #include "lldb/Host/FileSpec.h"
@@ -135,7 +137,12 @@
         {
             const char *mode = GetStreamOpenModeFromOptions (m_options);
             if (mode)
-                m_stream = ::fdopen (m_descriptor, mode);
+            {
+                do
+                {
+                    m_stream = ::fdopen (m_descriptor, mode);
+                } while (m_stream == NULL && errno == EINTR);
+            }
         }
     }
     return m_stream;
@@ -184,40 +191,54 @@
         Close ();
 
     int oflag = 0;
-    if (options & eOpenOptionRead && 
-        options & eOpenOptionWrite )
-        oflag |= O_RDWR;
-    else if (options & eOpenOptionRead)
+    const bool read = options & eOpenOptionRead;
+    const bool write = options & eOpenOptionWrite;
+    if (write)
+    {
+        if (read)
+            oflag |= O_RDWR;
+        else
+            oflag |= O_WRONLY;
+        
+        if (options & eOpenOptionAppend)
+            oflag |= O_APPEND;
+
+        if (options & eOpenOptionTruncate)
+            oflag |= O_TRUNC;
+
+        if (options & eOpenOptionCanCreate)
+            oflag |= O_CREAT;
+        
+        if (options & eOpenOptionCanCreateNewOnly)
+            oflag |= O_CREAT | O_EXCL;
+    }
+    else if (read)
+    {
         oflag |= O_RDONLY;
-    else if (options & eOpenOptionWrite)
-        oflag |= O_WRONLY;
+    }
     
     if (options & eOpenOptionNonBlocking)
         oflag |= O_NONBLOCK;
 
-    if (options & eOpenOptionAppend)
-        oflag |= O_APPEND;
-    else
-        oflag |= O_TRUNC;
-
-    if (options & eOpenOptionCanCreate)
-        oflag |= O_CREAT;
-    
-    if (options & eOpenOptionCanCreateNewOnly)
-        oflag |= O_CREAT | O_EXCL;
-    
     mode_t mode = 0;
-    if (permissions & ePermissionsUserRead)     mode |= S_IRUSR;
-    if (permissions & ePermissionsUserWrite)    mode |= S_IWUSR;
-    if (permissions & ePermissionsUserExecute)  mode |= S_IXUSR;
-    if (permissions & ePermissionsGroupRead)    mode |= S_IRGRP;
-    if (permissions & ePermissionsGroupWrite)   mode |= S_IWGRP;
-    if (permissions & ePermissionsGroupExecute) mode |= S_IXGRP;
-    if (permissions & ePermissionsWorldRead)    mode |= S_IROTH;
-    if (permissions & ePermissionsWorldWrite)   mode |= S_IWOTH;
-    if (permissions & ePermissionsWorldExecute) mode |= S_IXOTH;
+    if (oflag & O_CREAT)
+    {
+        if (permissions & ePermissionsUserRead)     mode |= S_IRUSR;
+        if (permissions & ePermissionsUserWrite)    mode |= S_IWUSR;
+        if (permissions & ePermissionsUserExecute)  mode |= S_IXUSR;
+        if (permissions & ePermissionsGroupRead)    mode |= S_IRGRP;
+        if (permissions & ePermissionsGroupWrite)   mode |= S_IWGRP;
+        if (permissions & ePermissionsGroupExecute) mode |= S_IXGRP;
+        if (permissions & ePermissionsWorldRead)    mode |= S_IROTH;
+        if (permissions & ePermissionsWorldWrite)   mode |= S_IWOTH;
+        if (permissions & ePermissionsWorldExecute) mode |= S_IXOTH;
+    }
 
-    m_descriptor = ::open(path, oflag, mode);
+    do
+    {
+        m_descriptor = ::open(path, oflag, mode);
+    } while (m_descriptor < 0 && errno == EINTR);
+
     if (!DescriptorIsValid())
         error.SetErrorToErrno();
     else
@@ -357,7 +378,13 @@
     Error error;
     if (StreamIsValid())
     {
-        if (::fflush (m_stream) == EOF)
+        int err = 0;
+        do
+        {
+            err = ::fflush (m_stream);
+        } while (err == EOF && errno == EINTR);
+        
+        if (err == EOF)
             error.SetErrorToErrno();
     }
     else if (!DescriptorIsValid())
@@ -374,7 +401,13 @@
     Error error;
     if (DescriptorIsValid())
     {
-        if (::fsync (m_descriptor) == -1)
+        int err = 0;
+        do
+        {
+            err = ::fsync (m_descriptor);
+        } while (err == -1 && errno == EINTR);
+        
+        if (err == -1)
             error.SetErrorToErrno();
     }
     else 
@@ -388,9 +421,14 @@
 File::Read (void *buf, size_t &num_bytes)
 {
     Error error;
+    ssize_t bytes_read = -1;
     if (DescriptorIsValid())
     {
-        ssize_t bytes_read = ::read (m_descriptor, buf, num_bytes);
+        do
+        {
+            bytes_read = ::read (m_descriptor, buf, num_bytes);
+        } while (bytes_read < 0 && errno == EINTR);
+
         if (bytes_read == -1)
         {
             error.SetErrorToErrno();
@@ -401,7 +439,8 @@
     }
     else if (StreamIsValid())
     {
-        size_t bytes_read = ::fread (buf, 1, num_bytes, m_stream);
+        bytes_read = ::fread (buf, 1, num_bytes, m_stream);
+
         if (bytes_read == 0)
         {
             if (::feof(m_stream))
@@ -425,9 +464,14 @@
 File::Write (const void *buf, size_t &num_bytes)
 {
     Error error;
+    ssize_t bytes_written = -1;
     if (DescriptorIsValid())
     {
-        ssize_t bytes_written = ::write (m_descriptor, buf, num_bytes);
+        do
+        {
+            bytes_written = ::write (m_descriptor, buf, num_bytes);
+        } while (bytes_written < 0 && errno == EINTR);
+
         if (bytes_written == -1)
         {
             error.SetErrorToErrno();
@@ -438,7 +482,8 @@
     }
     else if (StreamIsValid())
     {
-        size_t bytes_written = ::fwrite (buf, 1, num_bytes, m_stream);
+        bytes_written = ::fwrite (buf, 1, num_bytes, m_stream);
+
         if (bytes_written == 0)
         {
             if (::feof(m_stream))
@@ -467,7 +512,12 @@
     int fd = GetDescriptor();
     if (fd != kInvalidDescriptor)
     {
-        ssize_t bytes_read = ::pread (fd, buf, num_bytes, offset);
+        ssize_t bytes_read = -1;
+        do
+        {
+            bytes_read = ::pread (fd, buf, num_bytes, offset);
+        } while (bytes_read < 0 && errno == EINTR);
+
         if (bytes_read < 0)
         {
             num_bytes = 0;
@@ -488,13 +538,71 @@
 }
 
 Error
+File::Read (size_t &num_bytes, off_t &offset, DataBufferSP &data_buffer_sp)
+{
+    Error error;
+    
+    if (num_bytes > 0)
+    {
+        int fd = GetDescriptor();
+        if (fd != kInvalidDescriptor)
+        {
+            struct stat file_stats;
+            if (::fstat (fd, &file_stats) == 0)
+            {
+                if (file_stats.st_size > offset)
+                {
+                    const size_t bytes_left = file_stats.st_size - offset;
+                    if (num_bytes > bytes_left)
+                        num_bytes = bytes_left;
+                        
+                    std::auto_ptr<DataBufferHeap> data_heap_ap;
+                    data_heap_ap.reset(new DataBufferHeap(num_bytes, '\0'));
+                        
+                    if (data_heap_ap.get())
+                    {
+                        error = Read (data_heap_ap->GetBytes(), num_bytes, offset);
+                        if (error.Success())
+                        {
+                            // Make sure we read exactly what we asked for and if we got
+                            // less, adjust the array
+                            if (num_bytes < data_heap_ap->GetByteSize())
+                                data_heap_ap->SetByteSize(num_bytes);
+                            data_buffer_sp.reset(data_heap_ap.release());
+                            return error;
+                        }
+                    }
+                }
+                else 
+                    error.SetErrorString("file is empty");
+            }
+            else
+                error.SetErrorToErrno();
+        }
+        else 
+            error.SetErrorString("invalid file handle");
+    }
+    else
+        error.SetErrorString("invalid file handle");
+
+    num_bytes = 0;
+    data_buffer_sp.reset();
+    return error;
+}
+
+Error
 File::Write (const void *buf, size_t &num_bytes, off_t &offset)
 {
     Error error;
     int fd = GetDescriptor();
     if (fd != kInvalidDescriptor)
     {
-        ssize_t bytes_written = ::pwrite (m_descriptor, buf, num_bytes, offset);
+        ssize_t bytes_written = -1;
+        do
+        {
+            bytes_written = ::pwrite (m_descriptor, buf, num_bytes, offset);
+        } while (bytes_written < 0 && errno == EINTR);
+
         if (bytes_written < 0)
         {
             num_bytes = 0;