diff options
author | Yunzhong Gao <Yunzhong_Gao@playstation.sony.com> | 2016-01-06 00:50:06 +0000 |
---|---|---|
committer | Yunzhong Gao <Yunzhong_Gao@playstation.sony.com> | 2016-01-06 00:50:06 +0000 |
commit | fb2a9c420914235d2e52fdb11451cefab4d2d47c (patch) | |
tree | e487fd0f0c441151af6e72d08325139d764274ae /llvm/lib/Support/raw_ostream.cpp | |
parent | 3d07ec973f045f1f38b982c82aa3332466ce45d4 (diff) | |
download | bcm5719-llvm-fb2a9c420914235d2e52fdb11451cefab4d2d47c.tar.gz bcm5719-llvm-fb2a9c420914235d2e52fdb11451cefab4d2d47c.zip |
Fixing PR25717: fatal IO error writing large outputs to console on Windows.
This patch is similar to the Python issue#11395. We need to cap the output
size to 32767 on Windows to work around the size limit of WriteConsole().
Reference: https://bugs.python.org/issue11395
Writing a test for this bug turns out to be harder than I thought. I am
still working on it (see phabricator review D15705).
Differential Revision: http://reviews.llvm.org/D15553
llvm-svn: 256892
Diffstat (limited to 'llvm/lib/Support/raw_ostream.cpp')
-rw-r--r-- | llvm/lib/Support/raw_ostream.cpp | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp index 57c7ac32f55..57162dc6e95 100644 --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp @@ -57,6 +57,10 @@ #endif #endif +#ifdef LLVM_ON_WIN32 +#include "Windows/WindowsSupport.h" +#endif + using namespace llvm; raw_ostream::~raw_ostream() { @@ -567,8 +571,21 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) { assert(FD >= 0 && "File already closed."); pos += Size; +#ifndef LLVM_ON_WIN32 + bool ShouldWriteInChunks = false; +#else + // Writing a large size of output to Windows console returns ENOMEM. It seems + // that, prior to Windows 8, WriteFile() is redirecting to WriteConsole(), and + // the latter has a size limit (66000 bytes or less, depending on heap usage). + bool ShouldWriteInChunks = !!::_isatty(FD) && !IsWindows8OrGreater(); +#endif + do { - ssize_t ret = ::write(FD, Ptr, Size); + size_t ChunkSize = Size; + if (ChunkSize > 32767 && ShouldWriteInChunks) + ChunkSize = 32767; + + ssize_t ret = ::write(FD, Ptr, ChunkSize); if (ret < 0) { // If it's a recoverable error, swallow it and retry the write. |