summaryrefslogtreecommitdiffstats
path: root/lldb/source/Host/common/File.cpp
diff options
context:
space:
mode:
authorJason Molenda <jmolenda@apple.com>2017-11-02 02:02:56 +0000
committerJason Molenda <jmolenda@apple.com>2017-11-02 02:02:56 +0000
commitc139a402b2349e61d3e6f7494179a5ed949c3206 (patch)
tree9b7ae26ebc8fc2da512c140c12aa403f97f4c6a7 /lldb/source/Host/common/File.cpp
parent09d4efee5200cc25860e202cf693e988174b111b (diff)
downloadbcm5719-llvm-c139a402b2349e61d3e6f7494179a5ed949c3206.tar.gz
bcm5719-llvm-c139a402b2349e61d3e6f7494179a5ed949c3206.zip
Commit Lawrence D'Anna's patch to change
SetOututFileHandle to work with IOBase. I did make one change after checking with Larry -- I renamed SBDebugger::Flush to FlushDebuggerOutputHandles and added a short docstring to the .i file to make it a little clearer under which context programs may need to use this API. Differential Revision: https://reviews.llvm.org/D38829 llvm-svn: 317180
Diffstat (limited to 'lldb/source/Host/common/File.cpp')
-rw-r--r--lldb/source/Host/common/File.cpp124
1 files changed, 124 insertions, 0 deletions
diff --git a/lldb/source/Host/common/File.cpp b/lldb/source/Host/common/File.cpp
index 6ee4e894756..ec5c435d778 100644
--- a/lldb/source/Host/common/File.cpp
+++ b/lldb/source/Host/common/File.cpp
@@ -14,6 +14,7 @@
#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
+#include <assert.h>
#ifdef _WIN32
#include "lldb/Host/windows/windows.h"
@@ -71,6 +72,129 @@ static const char *GetStreamOpenModeFromOptions(uint32_t options) {
int File::kInvalidDescriptor = -1;
FILE *File::kInvalidStream = NULL;
+File::File(File &&rhs)
+ : IOObject(eFDTypeFile, false), m_descriptor(kInvalidDescriptor),
+ m_stream(kInvalidStream), m_options(), m_own_stream(false),
+ m_is_interactive(eLazyBoolCalculate),
+ m_is_real_terminal(eLazyBoolCalculate),
+ m_supports_colors(eLazyBoolCalculate)
+{
+ Swap(rhs);
+}
+
+File& File::operator= (File &&rhs)
+{
+ Close();
+ Swap(rhs);
+ return *this;
+}
+
+void File::Swap(File &rhs)
+{
+ std::swap(m_descriptor, rhs.m_descriptor);
+ std::swap(m_stream, rhs.m_stream);
+ std::swap(m_own_stream, rhs.m_own_stream);
+ std::swap(m_options, rhs.m_options);
+ std::swap(m_is_interactive, rhs.m_is_interactive);
+ std::swap(m_is_real_terminal, rhs.m_is_real_terminal);
+ std::swap(m_supports_colors, rhs.m_supports_colors);
+}
+
+#if defined(__linux__)
+
+struct context {
+ void *cookie;
+ int (*readfn)(void *, char *, int);
+ int (*writefn)(void *, const char *, int);
+ int (*closefn)(void *);
+};
+
+static ssize_t
+write_wrapper(void *c, const char *buf, size_t size)
+{
+ auto ctx = (struct context *)c;
+ if (size > INT_MAX) {
+ size = INT_MAX;
+ }
+ ssize_t wrote = ctx->writefn(ctx->cookie, buf, (int)size);
+ assert(wrote < 0 || (size_t)wrote <= size);
+ if (wrote < 0) {
+ return -1;
+ } else {
+ return (int)wrote;
+ }
+}
+
+static ssize_t
+read_wrapper(void *c, char *buf, size_t size)
+{
+ auto ctx = (struct context *)c;
+ if (size > INT_MAX) {
+ size = INT_MAX;
+ }
+ ssize_t read = ctx->writefn(ctx->cookie, buf, (int)size);
+ assert(read < 0 || (size_t)read <= size);
+ if (read < 0) {
+ return -1;
+ } else {
+ return (int)read;
+ }
+}
+
+static int
+close_wrapper(void *c)
+{
+ auto ctx = (struct context *)c;
+ int ret = ctx->closefn(ctx->cookie);
+ delete ctx;
+ return ret;
+}
+
+#endif
+
+File::File(void *cookie,
+ int (*readfn)(void *, char *, int),
+ int (*writefn)(void *, const char *, int),
+ int (*closefn)(void *))
+ : IOObject(eFDTypeFile, false), m_descriptor(kInvalidDescriptor),
+ m_stream(kInvalidStream), m_options(), m_own_stream(false),
+ m_is_interactive(eLazyBoolCalculate),
+ m_is_real_terminal(eLazyBoolCalculate),
+ m_supports_colors(eLazyBoolCalculate)
+{
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
+ m_stream = funopen(cookie, readfn, writefn, NULL, closefn);
+#elif defined(__linux__)
+ cookie_io_functions_t io_funcs = {};
+ io_funcs.read = read_wrapper;
+ io_funcs.write = write_wrapper;
+ io_funcs.close = close_wrapper;
+ const char *mode = NULL;
+ if (readfn && writefn) {
+ mode = "r+";
+ } else if (readfn) {
+ mode = "r";
+ } else if (writefn) {
+ mode = "w";
+ }
+ if (mode) {
+ struct context *ctx = new context;
+ ctx->readfn = readfn;
+ ctx->writefn = writefn;
+ ctx->closefn = closefn;
+ ctx->cookie = cookie;
+ m_stream = fopencookie(ctx, mode, io_funcs);
+ if (!m_stream) {
+ delete ctx;
+ }
+ }
+#endif
+ if (m_stream) {
+ m_own_stream = true;
+ }
+}
+
+
File::File(const char *path, uint32_t options, uint32_t permissions)
: IOObject(eFDTypeFile, false), m_descriptor(kInvalidDescriptor),
m_stream(kInvalidStream), m_options(), m_own_stream(false),
OpenPOWER on IntegriCloud