//===-- sanitizer_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
//
//===---------------------------------------------------------------------===//
//
// This file is shared between AddressSanitizer and ThreadSanitizer
// run-time libraries.  It defines filesystem-related interfaces.  This
// is separate from sanitizer_common.cpp so that it's simpler to disable
// all the filesystem support code for a port that doesn't use it.
//
//===---------------------------------------------------------------------===//

#include "sanitizer_platform.h"

#if !SANITIZER_FUCHSIA

#include "sanitizer_common.h"
#include "sanitizer_file.h"

namespace __sanitizer {

void CatastrophicErrorWrite(const char *buffer, uptr length) {
  WriteToFile(kStderrFd, buffer, length);
}

StaticSpinMutex report_file_mu;
ReportFile report_file = {&report_file_mu, kStderrFd, "", "", 0};

void RawWrite(const char *buffer) {
  report_file.Write(buffer, internal_strlen(buffer));
}

void ReportFile::ReopenIfNecessary() {
  mu->CheckLocked();
  if (fd == kStdoutFd || fd == kStderrFd) return;

  uptr pid = internal_getpid();
  // If in tracer, use the parent's file.
  if (pid == stoptheworld_tracer_pid)
    pid = stoptheworld_tracer_ppid;
  if (fd != kInvalidFd) {
    // If the report file is already opened by the current process,
    // do nothing. Otherwise the report file was opened by the parent
    // process, close it now.
    if (fd_pid == pid)
      return;
    else
      CloseFile(fd);
  }

  const char *exe_name = GetProcessName();
  if (common_flags()->log_exe_name && exe_name) {
    internal_snprintf(full_path, kMaxPathLength, "%s.%s.%zu", path_prefix,
                      exe_name, pid);
  } else {
    internal_snprintf(full_path, kMaxPathLength, "%s.%zu", path_prefix, pid);
  }
  error_t err;
  fd = OpenFile(full_path, WrOnly, &err);
  if (fd == kInvalidFd) {
    const char *ErrorMsgPrefix = "ERROR: Can't open file: ";
    WriteToFile(kStderrFd, ErrorMsgPrefix, internal_strlen(ErrorMsgPrefix));
    WriteToFile(kStderrFd, full_path, internal_strlen(full_path));
    char errmsg[100];
    internal_snprintf(errmsg, sizeof(errmsg), " (reason: %d)", err);
    WriteToFile(kStderrFd, errmsg, internal_strlen(errmsg));
    Die();
  }
  fd_pid = pid;
}

void ReportFile::SetReportPath(const char *path) {
  if (path) {
    uptr len = internal_strlen(path);
    if (len > sizeof(path_prefix) - 100) {
      Report("ERROR: Path is too long: %c%c%c%c%c%c%c%c...\n", path[0], path[1],
             path[2], path[3], path[4], path[5], path[6], path[7]);
      Die();
    }
  }

  SpinMutexLock l(mu);
  if (fd != kStdoutFd && fd != kStderrFd && fd != kInvalidFd)
    CloseFile(fd);
  fd = kInvalidFd;
  if (!path || internal_strcmp(path, "stderr") == 0) {
    fd = kStderrFd;
  } else if (internal_strcmp(path, "stdout") == 0) {
    fd = kStdoutFd;
  } else {
    internal_snprintf(path_prefix, kMaxPathLength, "%s", path);
  }
}

const char *ReportFile::GetReportPath() {
  SpinMutexLock l(mu);
  ReopenIfNecessary();
  return full_path;
}

bool ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size,
                      uptr *read_len, uptr max_len, error_t *errno_p) {
  *buff = nullptr;
  *buff_size = 0;
  *read_len = 0;
  if (!max_len)
    return true;
  uptr PageSize = GetPageSizeCached();
  uptr kMinFileLen = Min(PageSize, max_len);

  // The files we usually open are not seekable, so try different buffer sizes.
  for (uptr size = kMinFileLen;; size = Min(size * 2, max_len)) {
    UnmapOrDie(*buff, *buff_size);
    *buff = (char*)MmapOrDie(size, __func__);
    *buff_size = size;
    fd_t fd = OpenFile(file_name, RdOnly, errno_p);
    if (fd == kInvalidFd) {
      UnmapOrDie(*buff, *buff_size);
      return false;
    }
    *read_len = 0;
    // Read up to one page at a time.
    bool reached_eof = false;
    while (*read_len < size) {
      uptr just_read;
      if (!ReadFromFile(fd, *buff + *read_len, size - *read_len, &just_read,
                        errno_p)) {
        UnmapOrDie(*buff, *buff_size);
        CloseFile(fd);
        return false;
      }
      *read_len += just_read;
      if (just_read == 0 || *read_len == max_len) {
        reached_eof = true;
        break;
      }
    }
    CloseFile(fd);
    if (reached_eof)  // We've read the whole file.
      break;
  }
  return true;
}

bool ReadFileToVector(const char *file_name,
                      InternalMmapVectorNoCtor<char> *buff, uptr max_len,
                      error_t *errno_p) {
  buff->clear();
  if (!max_len)
    return true;
  uptr PageSize = GetPageSizeCached();
  fd_t fd = OpenFile(file_name, RdOnly, errno_p);
  if (fd == kInvalidFd)
    return false;
  uptr read_len = 0;
  while (read_len < max_len) {
    if (read_len >= buff->size())
      buff->resize(Min(Max(PageSize, read_len * 2), max_len));
    CHECK_LT(read_len, buff->size());
    CHECK_LE(buff->size(), max_len);
    uptr just_read;
    if (!ReadFromFile(fd, buff->data() + read_len, buff->size() - read_len,
                      &just_read, errno_p)) {
      CloseFile(fd);
      return false;
    }
    read_len += just_read;
    if (!just_read)
      break;
  }
  CloseFile(fd);
  buff->resize(read_len);
  return true;
}

static const char kPathSeparator = SANITIZER_WINDOWS ? ';' : ':';

char *FindPathToBinary(const char *name) {
  if (FileExists(name)) {
    return internal_strdup(name);
  }

  const char *path = GetEnv("PATH");
  if (!path)
    return nullptr;
  uptr name_len = internal_strlen(name);
  InternalMmapVector<char> buffer(kMaxPathLength);
  const char *beg = path;
  while (true) {
    const char *end = internal_strchrnul(beg, kPathSeparator);
    uptr prefix_len = end - beg;
    if (prefix_len + name_len + 2 <= kMaxPathLength) {
      internal_memcpy(buffer.data(), beg, prefix_len);
      buffer[prefix_len] = '/';
      internal_memcpy(&buffer[prefix_len + 1], name, name_len);
      buffer[prefix_len + 1 + name_len] = '\0';
      if (FileExists(buffer.data()))
        return internal_strdup(buffer.data());
    }
    if (*end == '\0') break;
    beg = end + 1;
  }
  return nullptr;
}

} // namespace __sanitizer

using namespace __sanitizer;

extern "C" {
void __sanitizer_set_report_path(const char *path) {
  report_file.SetReportPath(path);
}

void __sanitizer_set_report_fd(void *fd) {
  report_file.fd = (fd_t)reinterpret_cast<uptr>(fd);
  report_file.fd_pid = internal_getpid();
}

const char *__sanitizer_get_report_path() {
  return report_file.GetReportPath();
}
} // extern "C"

#endif  // !SANITIZER_FUCHSIA
