Factored out Linux proc file reading into separate class.

Both NativeProcessLinux (in llgs branch) and Linux Host.cpp had similar code to handle /proc 
file reading.  I factored that out into a new Linux-specific ProcFileReader class and added a method
that the llgs branch will use for line-by-line parsing.

This change also adds numerous Linux-specific files to Xcode that were missing from the Xcode
project files.

Related to https://github.com/tfiala/lldb/issues/27

llvm-svn: 212015
diff --git a/lldb/source/Plugins/Process/Linux/ProcFileReader.cpp b/lldb/source/Plugins/Process/Linux/ProcFileReader.cpp
new file mode 100644
index 0000000..6b259fd
--- /dev/null
+++ b/lldb/source/Plugins/Process/Linux/ProcFileReader.cpp
@@ -0,0 +1,105 @@
+//===-- ProcFileReader.cpp --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/Process/Linux/ProcFileReader.h"
+
+// C Headers
+#include <fcntl.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <stdio.h>
+#include <sys/stat.h>
+
+// C++ Headers
+#include <fstream>
+
+// LLDB Headers
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Error.h"
+
+lldb::DataBufferSP
+lldb_private::ProcFileReader::ReadIntoDataBuffer (lldb::pid_t pid, const char *name)
+{
+    int fd;
+    char path[PATH_MAX];
+
+    // Make sure we've got a nil terminated buffer for all the folks calling
+    // GetBytes() directly off our returned DataBufferSP if we hit an error.
+    lldb::DataBufferSP buf_sp (new DataBufferHeap(1, 0));
+
+    // Ideally, we would simply create a FileSpec and call ReadFileContents.
+    // However, files in procfs have zero size (since they are, in general,
+    // dynamically generated by the kernel) which is incompatible with the
+    // current ReadFileContents implementation. Therefore we simply stream the
+    // data into a DataBuffer ourselves.
+    if (snprintf (path, PATH_MAX, "/proc/%" PRIu64 "/%s", pid, name) > 0)
+    {
+        if ((fd = open (path, O_RDONLY, 0)) >= 0)
+        {
+            size_t bytes_read = 0;
+            std::unique_ptr<DataBufferHeap> buf_ap(new DataBufferHeap(1024, 0));
+
+            for (;;)
+            {
+                size_t avail = buf_ap->GetByteSize() - bytes_read;
+                ssize_t status = read (fd, buf_ap->GetBytes() + bytes_read, avail);
+
+                if (status < 0)
+                    break;
+
+                if (status == 0)
+                {
+                    buf_ap->SetByteSize (bytes_read);
+                    buf_sp.reset (buf_ap.release());
+                    break;
+                }
+
+                bytes_read += status;
+
+                if (avail - status == 0)
+                    buf_ap->SetByteSize (2 * buf_ap->GetByteSize());
+            }
+            
+            close (fd);
+        }
+    }
+    
+    return buf_sp;
+}
+
+lldb_private::Error
+lldb_private::ProcFileReader::ProcessLineByLine (lldb::pid_t pid, const char *name, std::function<bool (const std::string &line)> line_parser)
+{
+    lldb_private::Error error;
+
+    // Try to open the /proc/{pid}/maps entry.
+    char filename [PATH_MAX];
+    snprintf (filename, sizeof(filename), "/proc/%" PRIu64 "/%s", pid, name);
+    filename[sizeof (filename) - 1] = '\0';
+
+    std::ifstream proc_file (filename);
+    if (proc_file.fail ())
+    {
+        error.SetErrorStringWithFormat ("failed to open file '%s'", filename);
+        return error;
+    }
+
+    // Read the file line by line, processing until either end of file or when the line_parser returns false.
+    std::string line;
+    bool should_continue = true;
+
+    while (should_continue && std::getline (proc_file, line))
+    {
+        // Pass the line over to the line_parser for processing.  If the line_parser returns false, we
+        // stop processing.
+        should_continue = line_parser (line);
+    }
+
+    return error;
+}