diff options
author | Jason Molenda <jmolenda@apple.com> | 2017-11-02 02:02:56 +0000 |
---|---|---|
committer | Jason Molenda <jmolenda@apple.com> | 2017-11-02 02:02:56 +0000 |
commit | c139a402b2349e61d3e6f7494179a5ed949c3206 (patch) | |
tree | 9b7ae26ebc8fc2da512c140c12aa403f97f4c6a7 /lldb/source/Host/common/File.cpp | |
parent | 09d4efee5200cc25860e202cf693e988174b111b (diff) | |
download | bcm5719-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.cpp | 124 |
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), |