//===-- File.cpp ----------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Host/File.h"

#include <cerrno>
#include <climits>
#include <cstdarg>
#include <cstdio>
#include <fcntl.h>
#include <optional>

#ifdef _WIN32
#include "lldb/Host/windows/windows.h"
#else
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <termios.h>
#include <unistd.h>
#endif

#include "lldb/Host/Config.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/VASPrintf.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/ConvertUTF.h"
#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;
using llvm::Expected;

Expected<const char *>
File::GetStreamOpenModeFromOptions(File::OpenOptions options) {
  File::OpenOptions rw =
      options & (File::eOpenOptionReadOnly | File::eOpenOptionWriteOnly |
                 File::eOpenOptionReadWrite);

  if (options & File::eOpenOptionAppend) {
    if (rw == File::eOpenOptionReadWrite) {
      if (options & File::eOpenOptionCanCreateNewOnly)
        return "a+x";
      else
        return "a+";
    } else if (rw == File::eOpenOptionWriteOnly) {
      if (options & File::eOpenOptionCanCreateNewOnly)
        return "ax";
      else
        return "a";
    }
  } else if (rw == File::eOpenOptionReadWrite) {
    if (options & File::eOpenOptionCanCreate) {
      if (options & File::eOpenOptionCanCreateNewOnly)
        return "w+x";
      else
        return "w+";
    } else
      return "r+";
  } else if (rw == File::eOpenOptionWriteOnly) {
    return "w";
  } else if (rw == File::eOpenOptionReadOnly) {
    return "r";
  }
  return llvm::createStringError(
      llvm::inconvertibleErrorCode(),
      "invalid options, cannot convert to mode string");
}

Expected<File::OpenOptions> File::GetOptionsFromMode(llvm::StringRef mode) {
  OpenOptions opts =
      llvm::StringSwitch<OpenOptions>(mode)
          .Cases({"r", "rb"}, eOpenOptionReadOnly)
          .Cases({"w", "wb"}, eOpenOptionWriteOnly)
          .Cases({"a", "ab"}, eOpenOptionWriteOnly | eOpenOptionAppend |
                                  eOpenOptionCanCreate)
          .Cases({"r+", "rb+", "r+b"}, eOpenOptionReadWrite)
          .Cases({"w+", "wb+", "w+b"}, eOpenOptionReadWrite |
                                           eOpenOptionCanCreate |
                                           eOpenOptionTruncate)
          .Cases({"a+", "ab+", "a+b"}, eOpenOptionReadWrite |
                                           eOpenOptionAppend |
                                           eOpenOptionCanCreate)
          .Default(eOpenOptionInvalid);
  if (opts != eOpenOptionInvalid)
    return opts;
  return llvm::createStringError(
      llvm::inconvertibleErrorCode(),
      "invalid mode, cannot convert to File::OpenOptions");
}

int File::kInvalidDescriptor = -1;
FILE *File::kInvalidStream = nullptr;

Status File::Read(void *buf, size_t &num_bytes) {
  return std::error_code(ENOTSUP, std::system_category());
}
Status File::Write(const void *buf, size_t &num_bytes) {
  return std::error_code(ENOTSUP, std::system_category());
}

bool File::IsValid() const { return false; }

Status File::Close() { return Flush(); }

IOObject::WaitableHandle File::GetWaitableHandle() {
  return IOObject::kInvalidHandleValue;
}

Status File::GetFileSpec(FileSpec &file_spec) const {
  file_spec.Clear();
  return std::error_code(ENOTSUP, std::system_category());
}

int File::GetDescriptor() const { return kInvalidDescriptor; }

FILE *File::GetStream() { return nullptr; }

off_t File::SeekFromStart(off_t offset, Status *error_ptr) {
  if (error_ptr)
    *error_ptr = std::error_code(ENOTSUP, std::system_category());
  return -1;
}

off_t File::SeekFromCurrent(off_t offset, Status *error_ptr) {
  if (error_ptr)
    *error_ptr = std::error_code(ENOTSUP, std::system_category());
  return -1;
}

off_t File::SeekFromEnd(off_t offset, Status *error_ptr) {
  if (error_ptr)
    *error_ptr = std::error_code(ENOTSUP, std::system_category());
  return -1;
}

Status File::Read(void *dst, size_t &num_bytes, off_t &offset) {
  return std::error_code(ENOTSUP, std::system_category());
}

Status File::Write(const void *src, size_t &num_bytes, off_t &offset) {
  return std::error_code(ENOTSUP, std::system_category());
}

Status File::Flush() { return Status(); }

Status File::Sync() { return Flush(); }

void File::CalculateInteractiveAndTerminal() {
  const int fd = GetDescriptor();
  if (!DescriptorIsValid(fd)) {
    m_is_interactive = eLazyBoolNo;
    m_is_real_terminal = eLazyBoolNo;
    m_supports_colors = eLazyBoolNo;
    return;
  }
  m_is_interactive = eLazyBoolNo;
  m_is_real_terminal = eLazyBoolNo;
#if defined(_WIN32)
  if (_isatty(fd)) {
    m_is_interactive = eLazyBoolYes;
    m_is_real_terminal = eLazyBoolYes;
#if defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING)
    m_supports_colors = eLazyBoolYes;
#endif
  }
#else
  if (isatty(fd)) {
    m_is_interactive = eLazyBoolYes;
    struct winsize window_size;
    if (::ioctl(fd, TIOCGWINSZ, &window_size) == 0) {
      if (window_size.ws_col > 0) {
        m_is_real_terminal = eLazyBoolYes;
        if (llvm::sys::Process::FileDescriptorHasColors(fd))
          m_supports_colors = eLazyBoolYes;
      }
    }
  }
#endif
}

bool File::GetIsInteractive() {
  if (m_is_interactive == eLazyBoolCalculate)
    CalculateInteractiveAndTerminal();
  return m_is_interactive == eLazyBoolYes;
}

bool File::GetIsRealTerminal() {
  if (m_is_real_terminal == eLazyBoolCalculate)
    CalculateInteractiveAndTerminal();
  return m_is_real_terminal == eLazyBoolYes;
}

bool File::GetIsTerminalWithColors() {
  if (m_supports_colors == eLazyBoolCalculate)
    CalculateInteractiveAndTerminal();
  return m_supports_colors == eLazyBoolYes;
}

size_t File::Printf(const char *format, ...) {
  va_list args;
  va_start(args, format);
  size_t result = PrintfVarArg(format, args);
  va_end(args);
  return result;
}

size_t File::PrintfVarArg(const char *format, va_list args) {
  llvm::SmallString<0> s;
  if (VASprintf(s, format, args)) {
    size_t written = s.size();
    Write(s.data(), written);
    return written;
  }
  return 0;
}

Expected<File::OpenOptions> File::GetOptions() const {
  return llvm::createStringError(
      llvm::inconvertibleErrorCode(),
      "GetOptions() not implemented for this File class");
}

uint32_t File::GetPermissions(Status &error) const {
  int fd = GetDescriptor();
  if (!DescriptorIsValid(fd)) {
    error = std::error_code(ENOTSUP, std::system_category());
    return 0;
  }
  struct stat file_stats;
  if (::fstat(fd, &file_stats) == -1) {
    error = Status::FromErrno();
    return 0;
  }
  error.Clear();
  return file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
}

NativeFile::NativeFile() = default;

NativeFile::NativeFile(FILE *fh, OpenOptions options, bool transfer_ownership)
    : m_stream(fh), m_options(options), m_own_stream(transfer_ownership) {
#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
  // stream outputs to a console.
  {
    HANDLE h = INVALID_HANDLE_VALUE;
    if (fh == stdin)
      h = ::GetStdHandle(STD_INPUT_HANDLE);
    else if (fh == stdout)
      h = ::GetStdHandle(STD_OUTPUT_HANDLE);
    else if (fh == stderr)
      h = ::GetStdHandle(STD_ERROR_HANDLE);
    is_windows_console =
        h != INVALID_HANDLE_VALUE && ::GetFileType(h) == FILE_TYPE_CHAR;
  }
#else
#ifndef NDEBUG
  int fd = fileno(fh);
  if (fd != -1) {
    int required_mode = ConvertOpenOptionsForPOSIXOpen(options) & O_ACCMODE;
    int mode = fcntl(fd, F_GETFL);
    if (mode != -1) {
      mode &= O_ACCMODE;
      // Check that the file is open with a valid subset of the requested file
      // access mode, e.g. if we expected the file to be writable then ensure it
      // was opened with O_WRONLY or O_RDWR.
      assert(
          (required_mode == O_RDWR && mode == O_RDWR) ||
          (required_mode == O_RDONLY && (mode == O_RDWR || mode == O_RDONLY) ||
           (required_mode == O_WRONLY &&
            (mode == O_RDWR || mode == O_WRONLY))) &&
              "invalid file access mode");
    }
  }
#endif
#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.
  {
    HANDLE h = INVALID_HANDLE_VALUE;
    if (fd == STDIN_FILENO)
      h = ::GetStdHandle(STD_INPUT_HANDLE);
    else if (fd == STDOUT_FILENO)
      h = ::GetStdHandle(STD_OUTPUT_HANDLE);
    else if (fd == STDERR_FILENO)
      h = ::GetStdHandle(STD_ERROR_HANDLE);
    is_windows_console =
        h != INVALID_HANDLE_VALUE && ::GetFileType(h) == 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();
}

Expected<File::OpenOptions> NativeFile::GetOptions() const { return m_options; }

int NativeFile::GetDescriptor() const {
  if (ValueGuard descriptor_guard = DescriptorIsValid()) {
    return m_descriptor;
  }

  // Don't open the file descriptor if we don't need to, just get it from the
  // stream if we have one.
  if (ValueGuard stream_guard = StreamIsValid()) {
#if defined(_WIN32)
    return _fileno(m_stream);
#else
    return fileno(m_stream);
#endif
  }

  // Invalid descriptor and invalid stream, return invalid descriptor.
  return kInvalidDescriptor;
}

IOObject::WaitableHandle NativeFile::GetWaitableHandle() {
#ifdef _WIN32
  return (HANDLE)_get_osfhandle(GetDescriptor());
#else
  return GetDescriptor();
#endif
}

FILE *NativeFile::GetStream() {
  ValueGuard stream_guard = StreamIsValid();
  if (!stream_guard) {
    if (ValueGuard descriptor_guard = DescriptorIsValid()) {
      auto mode = GetStreamOpenModeFromOptions(m_options);
      if (!mode)
        llvm::consumeError(mode.takeError());
      else {
        if (!m_own_descriptor) {
// We must duplicate the file descriptor if we don't own it because when you
// call fdopen, the stream will own the fd
#ifdef _WIN32
          m_descriptor = ::_dup(m_descriptor);
#else
          m_descriptor = dup(m_descriptor);
#endif
          m_own_descriptor = true;
        }

        m_stream = llvm::sys::RetryAfterSignal(nullptr, ::fdopen, m_descriptor,
                                               mode.get());

        // If we got a stream, then we own the stream and should no longer own
        // the descriptor because fclose() will close it for us

        if (m_stream) {
          m_own_stream = true;
          m_own_descriptor = false;
        }
      }
    }
  }
  return m_stream;
}

Status NativeFile::Close() {
  std::scoped_lock<std::mutex, std::mutex> lock(m_descriptor_mutex,
                                                m_stream_mutex);

  Status error;

  if (StreamIsValidUnlocked()) {
    if (m_own_stream) {
      if (::fclose(m_stream) == EOF)
        error = Status::FromErrno();
    } else {
      File::OpenOptions rw =
          m_options & (File::eOpenOptionReadOnly | File::eOpenOptionWriteOnly |
                       File::eOpenOptionReadWrite);

      if (rw == eOpenOptionWriteOnly || rw == eOpenOptionReadWrite) {
        if (::fflush(m_stream) == EOF)
          error = Status::FromErrno();
      }
    }
  }

  if (DescriptorIsValidUnlocked() && m_own_descriptor) {
    if (::close(m_descriptor) != 0)
      error = Status::FromErrno();
  }

  m_stream = kInvalidStream;
  m_own_stream = false;
  m_descriptor = kInvalidDescriptor;
  m_own_descriptor = false;
  m_options = OpenOptions(0);
  m_is_interactive = eLazyBoolCalculate;
  m_is_real_terminal = eLazyBoolCalculate;
  return error;
}

Status NativeFile::GetFileSpec(FileSpec &file_spec) const {
  Status error;
#ifdef F_GETPATH
  if (IsValid()) {
    char path[PATH_MAX];
    if (::fcntl(GetDescriptor(), F_GETPATH, path) == -1)
      error = Status::FromErrno();
    else
      file_spec.SetFile(path, FileSpec::Style::native);
  } else {
    error = Status::FromErrorString("invalid file handle");
  }
#elif defined(__linux__)
  char proc[64];
  char path[PATH_MAX];
  if (::snprintf(proc, sizeof(proc), "/proc/self/fd/%d", GetDescriptor()) < 0)
    error = Status::FromErrorString("cannot resolve file descriptor");
  else {
    ssize_t len;
    if ((len = ::readlink(proc, path, sizeof(path) - 1)) == -1)
      error = Status::FromErrno();
    else {
      path[len] = '\0';
      file_spec.SetFile(path, FileSpec::Style::native);
    }
  }
#else
  error = Status::FromErrorString(
      "NativeFile::GetFileSpec is not supported on this platform");
#endif

  if (error.Fail())
    file_spec.Clear();
  return error;
}

off_t NativeFile::SeekFromStart(off_t offset, Status *error_ptr) {
  off_t result = 0;
  if (ValueGuard descriptor_guard = DescriptorIsValid()) {
    result = ::lseek(m_descriptor, offset, SEEK_SET);

    if (error_ptr) {
      if (result == -1)
        *error_ptr = Status::FromErrno();
      else
        error_ptr->Clear();
    }
    return result;
  }

  if (ValueGuard stream_guard = StreamIsValid()) {
    result = ::fseek(m_stream, offset, SEEK_SET);

    if (error_ptr) {
      if (result == -1)
        *error_ptr = Status::FromErrno();
      else
        error_ptr->Clear();
    }
    return result;
  }

  if (error_ptr)
    *error_ptr = Status::FromErrorString("invalid file handle");
  return result;
}

off_t NativeFile::SeekFromCurrent(off_t offset, Status *error_ptr) {
  off_t result = -1;
  if (ValueGuard descriptor_guard = DescriptorIsValid()) {
    result = ::lseek(m_descriptor, offset, SEEK_CUR);

    if (error_ptr) {
      if (result == -1)
        *error_ptr = Status::FromErrno();
      else
        error_ptr->Clear();
    }
    return result;
  }

  if (ValueGuard stream_guard = StreamIsValid()) {
    result = ::fseek(m_stream, offset, SEEK_CUR);

    if (error_ptr) {
      if (result == -1)
        *error_ptr = Status::FromErrno();
      else
        error_ptr->Clear();
    }
    return result;
  }

  if (error_ptr)
    *error_ptr = Status::FromErrorString("invalid file handle");
  return result;
}

off_t NativeFile::SeekFromEnd(off_t offset, Status *error_ptr) {
  off_t result = -1;
  if (ValueGuard descriptor_guard = DescriptorIsValid()) {
    result = ::lseek(m_descriptor, offset, SEEK_END);

    if (error_ptr) {
      if (result == -1)
        *error_ptr = Status::FromErrno();
      else
        error_ptr->Clear();
    }
    return result;
  }

  if (ValueGuard stream_guard = StreamIsValid()) {
    result = ::fseek(m_stream, offset, SEEK_END);

    if (error_ptr) {
      if (result == -1)
        *error_ptr = Status::FromErrno();
      else
        error_ptr->Clear();
    }
    return result;
  }

  if (error_ptr)
    *error_ptr = Status::FromErrorString("invalid file handle");
  return result;
}

Status NativeFile::Flush() {
  Status error;
  if (ValueGuard stream_guard = StreamIsValid()) {
    if (llvm::sys::RetryAfterSignal(EOF, ::fflush, m_stream) == EOF)
      error = Status::FromErrno();
    return error;
  }

  {
    ValueGuard descriptor_guard = DescriptorIsValid();
    if (!descriptor_guard)
      error = Status::FromErrorString("invalid file handle");
  }
  return error;
}

Status NativeFile::Sync() {
  Status error;
  if (ValueGuard descriptor_guard = DescriptorIsValid()) {
#ifdef _WIN32
    int err = FlushFileBuffers((HANDLE)_get_osfhandle(m_descriptor));
    if (err == 0)
      error = Status::FromErrorString("unknown error");
#else
    if (llvm::sys::RetryAfterSignal(-1, ::fsync, m_descriptor) == -1)
      error = Status::FromErrno();
#endif
  } else {
    error = Status::FromErrorString("invalid file handle");
  }
  return error;
}

#if defined(__APPLE__)
// Darwin kernels only can read/write <= INT_MAX bytes
#define MAX_READ_SIZE INT_MAX
#define MAX_WRITE_SIZE INT_MAX
#endif

Status NativeFile::Read(void *buf, size_t &num_bytes) {
  Status error;

  // Ensure the file is open for reading.
  if ((m_options & File::OpenOptionsModeMask) == eOpenOptionWriteOnly)
    return Status(std::make_error_code(std::errc::bad_file_descriptor));

#if defined(MAX_READ_SIZE)
  if (num_bytes > MAX_READ_SIZE) {
    uint8_t *p = (uint8_t *)buf;
    size_t bytes_left = num_bytes;
    // Init the num_bytes read to zero
    num_bytes = 0;

    while (bytes_left > 0) {
      size_t curr_num_bytes;
      if (bytes_left > MAX_READ_SIZE)
        curr_num_bytes = MAX_READ_SIZE;
      else
        curr_num_bytes = bytes_left;

      error = Read(p + num_bytes, curr_num_bytes);

      // Update how many bytes were read
      num_bytes += curr_num_bytes;
      if (bytes_left < curr_num_bytes)
        bytes_left = 0;
      else
        bytes_left -= curr_num_bytes;

      if (error.Fail())
        break;
    }
    return error;
  }
#endif

  ssize_t bytes_read = -1;
  if (ValueGuard descriptor_guard = DescriptorIsValid()) {
    bytes_read =
        llvm::sys::RetryAfterSignal(-1, ::read, m_descriptor, buf, num_bytes);
    if (bytes_read == -1) {
      error = Status::FromErrno();
      num_bytes = 0;
    } else
      num_bytes = bytes_read;
    return error;
  }

  if (ValueGuard file_lock = StreamIsValid()) {
    bytes_read = ::fread(buf, 1, num_bytes, m_stream);

    if (bytes_read == 0) {
      if (::feof(m_stream))
        error = Status::FromErrorString("feof");
      else if (::ferror(m_stream))
        error = Status::FromErrorString("ferror");
      num_bytes = 0;
    } else
      num_bytes = bytes_read;
    return error;
  }

  num_bytes = 0;
  error = Status::FromErrorString("invalid file handle");
  return error;
}

Status NativeFile::Write(const void *buf, size_t &num_bytes) {
  Status error;

  // Ensure the file is open for writing.
  if ((m_options & File::OpenOptionsModeMask) == File::eOpenOptionReadOnly)
    return Status(std::make_error_code(std::errc::bad_file_descriptor));

#if defined(MAX_WRITE_SIZE)
  if (num_bytes > MAX_WRITE_SIZE) {
    const uint8_t *p = (const uint8_t *)buf;
    size_t bytes_left = num_bytes;
    // Init the num_bytes written to zero
    num_bytes = 0;

    while (bytes_left > 0) {
      size_t curr_num_bytes;
      if (bytes_left > MAX_WRITE_SIZE)
        curr_num_bytes = MAX_WRITE_SIZE;
      else
        curr_num_bytes = bytes_left;

      error = Write(p + num_bytes, curr_num_bytes);

      // Update how many bytes were read
      num_bytes += curr_num_bytes;
      if (bytes_left < curr_num_bytes)
        bytes_left = 0;
      else
        bytes_left -= curr_num_bytes;

      if (error.Fail())
        break;
    }
    return error;
  }
#endif

  ssize_t bytes_written = -1;
  if (ValueGuard descriptor_guard = DescriptorIsValid()) {
    bytes_written =
        llvm::sys::RetryAfterSignal(-1, ::write, m_descriptor, buf, num_bytes);
    if (bytes_written == -1) {
      error = Status::FromErrno();
      num_bytes = 0;
    } else
      num_bytes = bytes_written;
    return error;
  }

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

    if (bytes_written == 0) {
      if (::feof(m_stream))
        error = Status::FromErrorString("feof");
      else if (::ferror(m_stream))
        error = Status::FromErrorString("ferror");
      num_bytes = 0;
    } else
      num_bytes = bytes_written;
    return error;
  }

  num_bytes = 0;
  error = Status::FromErrorString("invalid file handle");
  return error;
}

Status NativeFile::Read(void *buf, size_t &num_bytes, off_t &offset) {
  Status error;

#if defined(MAX_READ_SIZE)
  if (num_bytes > MAX_READ_SIZE) {
    uint8_t *p = (uint8_t *)buf;
    size_t bytes_left = num_bytes;
    // Init the num_bytes read to zero
    num_bytes = 0;

    while (bytes_left > 0) {
      size_t curr_num_bytes;
      if (bytes_left > MAX_READ_SIZE)
        curr_num_bytes = MAX_READ_SIZE;
      else
        curr_num_bytes = bytes_left;

      error = Read(p + num_bytes, curr_num_bytes, offset);

      // Update how many bytes were read
      num_bytes += curr_num_bytes;
      if (bytes_left < curr_num_bytes)
        bytes_left = 0;
      else
        bytes_left -= curr_num_bytes;

      if (error.Fail())
        break;
    }
    return error;
  }
#endif

#ifndef _WIN32
  int fd = GetDescriptor();
  if (fd != kInvalidDescriptor) {
    ssize_t bytes_read =
        llvm::sys::RetryAfterSignal(-1, ::pread, fd, buf, num_bytes, offset);
    if (bytes_read < 0) {
      num_bytes = 0;
      error = Status::FromErrno();
    } else {
      offset += bytes_read;
      num_bytes = bytes_read;
    }
  } else {
    num_bytes = 0;
    error = Status::FromErrorString("invalid file handle");
  }
#else
  std::lock_guard<std::mutex> guard(offset_access_mutex);
  long cur = ::lseek(m_descriptor, 0, SEEK_CUR);
  SeekFromStart(offset);
  error = Read(buf, num_bytes);
  if (!error.Fail())
    SeekFromStart(cur);
#endif
  return error;
}

Status NativeFile::Write(const void *buf, size_t &num_bytes, off_t &offset) {
  Status error;

#if defined(MAX_WRITE_SIZE)
  if (num_bytes > MAX_WRITE_SIZE) {
    const uint8_t *p = (const uint8_t *)buf;
    size_t bytes_left = num_bytes;
    // Init the num_bytes written to zero
    num_bytes = 0;

    while (bytes_left > 0) {
      size_t curr_num_bytes;
      if (bytes_left > MAX_WRITE_SIZE)
        curr_num_bytes = MAX_WRITE_SIZE;
      else
        curr_num_bytes = bytes_left;

      error = Write(p + num_bytes, curr_num_bytes, offset);

      // Update how many bytes were read
      num_bytes += curr_num_bytes;
      if (bytes_left < curr_num_bytes)
        bytes_left = 0;
      else
        bytes_left -= curr_num_bytes;

      if (error.Fail())
        break;
    }
    return error;
  }
#endif

  int fd = GetDescriptor();
  if (fd != kInvalidDescriptor) {
#ifndef _WIN32
    ssize_t bytes_written = llvm::sys::RetryAfterSignal(
        -1, ::pwrite, m_descriptor, buf, num_bytes, offset);
    if (bytes_written < 0) {
      num_bytes = 0;
      error = Status::FromErrno();
    } else {
      offset += bytes_written;
      num_bytes = bytes_written;
    }
#else
    std::lock_guard<std::mutex> guard(offset_access_mutex);
    long cur = ::lseek(m_descriptor, 0, SEEK_CUR);
    SeekFromStart(offset);
    error = Write(buf, num_bytes);
    long after = ::lseek(m_descriptor, 0, SEEK_CUR);

    if (!error.Fail())
      SeekFromStart(cur);

    offset = after;
#endif
  } else {
    num_bytes = 0;
    error = Status::FromErrorString("invalid file handle");
  }
  return error;
}

size_t NativeFile::PrintfVarArg(const char *format, va_list args) {
  if (StreamIsValid()) {
    return ::vfprintf(m_stream, format, args);
  } else {
    return File::PrintfVarArg(format, args);
  }
}

mode_t File::ConvertOpenOptionsForPOSIXOpen(OpenOptions open_options) {
  mode_t mode = 0;
  File::OpenOptions rw =
      open_options & (File::eOpenOptionReadOnly | File::eOpenOptionWriteOnly |
                      File::eOpenOptionReadWrite);
  if (rw == eOpenOptionReadWrite)
    mode |= O_RDWR;
  else if (rw == eOpenOptionWriteOnly)
    mode |= O_WRONLY;
  else if (rw == eOpenOptionReadOnly)
    mode |= O_RDONLY;

  if (open_options & eOpenOptionAppend)
    mode |= O_APPEND;

  if (open_options & eOpenOptionTruncate)
    mode |= O_TRUNC;

  if (open_options & eOpenOptionNonBlocking)
    mode |= O_NONBLOCK;

  if (open_options & eOpenOptionCanCreateNewOnly)
    mode |= O_CREAT | O_EXCL;
  else if (open_options & eOpenOptionCanCreate)
    mode |= O_CREAT;

  return mode;
}

llvm::Expected<SerialPort::Options>
SerialPort::OptionsFromURL(llvm::StringRef urlqs) {
  SerialPort::Options serial_options;
  for (llvm::StringRef x : llvm::split(urlqs, '&')) {
    if (x.consume_front("baud=")) {
      unsigned int baud_rate;
      if (!llvm::to_integer(x, baud_rate, 10))
        return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                       "Invalid baud rate: %s",
                                       x.str().c_str());
      serial_options.BaudRate = baud_rate;
    } else if (x.consume_front("parity=")) {
      serial_options.Parity =
          llvm::StringSwitch<std::optional<Terminal::Parity>>(x)
              .Case("no", Terminal::Parity::No)
              .Case("even", Terminal::Parity::Even)
              .Case("odd", Terminal::Parity::Odd)
              .Case("mark", Terminal::Parity::Mark)
              .Case("space", Terminal::Parity::Space)
              .Default(std::nullopt);
      if (!serial_options.Parity)
        return llvm::createStringError(
            llvm::inconvertibleErrorCode(),
            "Invalid parity (must be no, even, odd, mark or space): %s",
            x.str().c_str());
    } else if (x.consume_front("parity-check=")) {
      serial_options.ParityCheck =
          llvm::StringSwitch<std::optional<Terminal::ParityCheck>>(x)
              .Case("no", Terminal::ParityCheck::No)
              .Case("replace", Terminal::ParityCheck::ReplaceWithNUL)
              .Case("ignore", Terminal::ParityCheck::Ignore)
              // "mark" mode is not currently supported as it requires special
              // input processing
              // .Case("mark", Terminal::ParityCheck::Mark)
              .Default(std::nullopt);
      if (!serial_options.ParityCheck)
        return llvm::createStringError(
            llvm::inconvertibleErrorCode(),
            "Invalid parity-check (must be no, replace, ignore or mark): %s",
            x.str().c_str());
    } else if (x.consume_front("stop-bits=")) {
      unsigned int stop_bits;
      if (!llvm::to_integer(x, stop_bits, 10) ||
          (stop_bits != 1 && stop_bits != 2))
        return llvm::createStringError(
            llvm::inconvertibleErrorCode(),
            "Invalid stop bit number (must be 1 or 2): %s", x.str().c_str());
      serial_options.StopBits = stop_bits;
    } else
      return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                     "Unknown parameter: %s", x.str().c_str());
  }
  return serial_options;
}

llvm::Expected<std::unique_ptr<SerialPort>>
SerialPort::Create(int fd, OpenOptions options, Options serial_options,
                   bool transfer_ownership) {
  std::unique_ptr<SerialPort> out{
      new SerialPort(fd, options, serial_options, transfer_ownership)};

  if (!out->GetIsInteractive())
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "the specified file is not a teletype");

  Terminal term{fd};
  if (llvm::Error error = term.SetRaw())
    return std::move(error);
  if (serial_options.BaudRate) {
    if (llvm::Error error = term.SetBaudRate(*serial_options.BaudRate))
      return std::move(error);
  }
  if (serial_options.Parity) {
    if (llvm::Error error = term.SetParity(*serial_options.Parity))
      return std::move(error);
  }
  if (serial_options.ParityCheck) {
    if (llvm::Error error = term.SetParityCheck(*serial_options.ParityCheck))
      return std::move(error);
  }
  if (serial_options.StopBits) {
    if (llvm::Error error = term.SetStopBits(*serial_options.StopBits))
      return std::move(error);
  }

  return std::move(out);
}

SerialPort::SerialPort(int fd, OpenOptions options,
                       SerialPort::Options serial_options,
                       bool transfer_ownership)
    : NativeFile(fd, options, transfer_ownership), m_state(fd) {}

Status SerialPort::Close() {
  m_state.Restore();
  return NativeFile::Close();
}

char File::ID = 0;
char NativeFile::ID = 0;
char SerialPort::ID = 0;
