Skip to content
16 changes: 7 additions & 9 deletions lldb/include/lldb/Host/File.h
Original file line number Diff line number Diff line change
Expand Up @@ -382,15 +382,11 @@ class NativeFile : public File {
Unowned = false,
};

NativeFile() : m_descriptor(kInvalidDescriptor), m_stream(kInvalidStream) {}
NativeFile();

NativeFile(FILE *fh, bool transfer_ownership)
: m_descriptor(kInvalidDescriptor), m_own_descriptor(false), m_stream(fh),
m_options(), m_own_stream(transfer_ownership) {}
NativeFile(FILE *fh, bool transfer_ownership);

NativeFile(int fd, OpenOptions options, bool transfer_ownership)
: m_descriptor(fd), m_own_descriptor(transfer_ownership),
m_stream(kInvalidStream), m_options(options), m_own_stream(false) {}
NativeFile(int fd, OpenOptions options, bool transfer_ownership);

~NativeFile() override { Close(); }

Expand Down Expand Up @@ -444,17 +440,19 @@ class NativeFile : public File {
return ValueGuard(m_stream_mutex, StreamIsValidUnlocked());
}

int m_descriptor;
int m_descriptor = kInvalidDescriptor;
bool m_own_descriptor = false;
mutable std::mutex m_descriptor_mutex;

FILE *m_stream;
FILE *m_stream = kInvalidStream;
mutable std::mutex m_stream_mutex;

OpenOptions m_options{};
bool m_own_stream = false;
std::mutex offset_access_mutex;

bool is_windows_console = false;

private:
NativeFile(const NativeFile &) = delete;
const NativeFile &operator=(const NativeFile &) = delete;
Expand Down
40 changes: 40 additions & 0 deletions lldb/source/Host/common/File.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "llvm/Support/Errno.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/raw_ostream.h"

using namespace lldb;
using namespace lldb_private;
Expand Down Expand Up @@ -247,6 +248,32 @@ uint32_t File::GetPermissions(Status &error) const {
return file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
}

NativeFile::NativeFile() = default;

NativeFile::NativeFile(FILE *fh, bool transfer_ownership)
: m_stream(fh), m_own_stream(transfer_ownership) {
#ifdef _WIN32
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a comment here explains why we do something special on Windows and (just once sentence) on why/how this works?

// In order to properly display non ASCII characters in Windows, we need to
// use Windows APIs to print to the console. This is only required if the
// stream outputs to a console.
int fd = _fileno(fh);
is_windows_console =
::GetFileType((HANDLE)::_get_osfhandle(fd)) == FILE_TYPE_CHAR;
#endif
}

NativeFile::NativeFile(int fd, OpenOptions options, bool transfer_ownership)
: m_descriptor(fd), m_own_descriptor(transfer_ownership),
m_options(options) {
#ifdef _WIN32
// In order to properly display non ASCII characters in Windows, we need to
// use Windows APIs to print to the console. This is only required if the
// file outputs to a console.
is_windows_console =
::GetFileType((HANDLE)::_get_osfhandle(fd)) == FILE_TYPE_CHAR;
#endif
}

bool NativeFile::IsValid() const {
std::scoped_lock<std::mutex, std::mutex> lock(m_descriptor_mutex, m_stream_mutex);
return DescriptorIsValidUnlocked() || StreamIsValidUnlocked();
Expand Down Expand Up @@ -618,6 +645,12 @@ Status NativeFile::Write(const void *buf, size_t &num_bytes) {

ssize_t bytes_written = -1;
if (ValueGuard descriptor_guard = DescriptorIsValid()) {
#ifdef _WIN32
if (is_windows_console) {
llvm::raw_fd_ostream(m_descriptor, false).write((char *)buf, num_bytes);
return error;
}
#endif
bytes_written =
llvm::sys::RetryAfterSignal(-1, ::write, m_descriptor, buf, num_bytes);
if (bytes_written == -1) {
Expand All @@ -629,6 +662,13 @@ Status NativeFile::Write(const void *buf, size_t &num_bytes) {
}

if (ValueGuard stream_guard = StreamIsValid()) {
#ifdef _WIN32
if (is_windows_console) {
llvm::raw_fd_ostream(_fileno(m_stream), false)
.write((char *)buf, num_bytes);
return error;
}
#endif
bytes_written = ::fwrite(buf, 1, num_bytes, m_stream);

if (bytes_written == 0) {
Expand Down
Loading