//===- llvm/Support/Unix/PathV2.cpp - Unix Path Implementation --*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Unix specific implementation of the PathV2 API.
//
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only generic UNIX code that
//===          is guaranteed to work on *all* UNIX variants.
//===----------------------------------------------------------------------===//

#include "Unix.h"
#include "llvm/Support/Process.h"
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#if HAVE_DIRENT_H
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
#else
# define dirent direct
# define NAMLEN(dirent) (dirent)->d_namlen
# if HAVE_SYS_NDIR_H
#  include <sys/ndir.h>
# endif
# if HAVE_SYS_DIR_H
#  include <sys/dir.h>
# endif
# if HAVE_NDIR_H
#  include <ndir.h>
# endif
#endif
#if HAVE_STDIO_H
#include <stdio.h>
#endif
#if HAVE_LIMITS_H
#include <limits.h>
#endif

// Both stdio.h and cstdio are included via different pathes and
// stdcxx's cstdio doesn't include stdio.h, so it doesn't #undef the macros
// either.
#undef ferror
#undef feof

// For GNU Hurd
#if defined(__GNU__) && !defined(PATH_MAX)
# define PATH_MAX 4096
#endif

extern "C" int truncate (const char*, off_t);

using namespace llvm;

namespace {
  /// This class automatically closes the given file descriptor when it goes out
  /// of scope. You can take back explicit ownership of the file descriptor by
  /// calling take(). The destructor does not verify that close was successful.
  /// Therefore, never allow this class to call close on a file descriptor that
  /// has been read from or written to.
  struct AutoFD {
    int FileDescriptor;

    AutoFD(int fd) : FileDescriptor(fd) {}
    ~AutoFD() {
      if (FileDescriptor >= 0)
        ::close(FileDescriptor);
    }

    int take() {
      int ret = FileDescriptor;
      FileDescriptor = -1;
      return ret;
    }

    operator int() const {return FileDescriptor;}
  };

  error_code TempDir(SmallVectorImpl<char> &result) {
    // FIXME: Don't use TMPDIR if program is SUID or SGID enabled.
    const char *dir = 0;
    (dir = std::getenv("TMPDIR" )) ||
    (dir = std::getenv("TMP"    )) ||
    (dir = std::getenv("TEMP"   )) ||
    (dir = std::getenv("TEMPDIR")) ||
#ifdef P_tmpdir
    (dir = P_tmpdir) ||
#endif
    (dir = "/tmp");

    result.clear();
    StringRef d(dir);
    result.append(d.begin(), d.end());
    return error_code::success();
  }
}

namespace llvm {
namespace sys  {
namespace fs {

error_code current_path(SmallVectorImpl<char> &result) {
#ifdef MAXPATHLEN
  result.reserve(MAXPATHLEN);
#else
// For GNU Hurd
  result.reserve(1024);
#endif

  while (true) {
    if (::getcwd(result.data(), result.capacity()) == 0) {
      // See if there was a real error.
      if (errno != errc::not_enough_memory)
        return error_code(errno, system_category());
      // Otherwise there just wasn't enough space.
      result.reserve(result.capacity() * 2);
    } else
      break;
  }

  result.set_size(strlen(result.data()));
  return error_code::success();
}

error_code copy_file(const Twine &from, const Twine &to, copy_option copt) {
 // Get arguments.
  SmallString<128> from_storage;
  SmallString<128> to_storage;
  StringRef f = from.toNullTerminatedStringRef(from_storage);
  StringRef t = to.toNullTerminatedStringRef(to_storage);

  const size_t buf_sz = 32768;
  char buffer[buf_sz];
  int from_file = -1, to_file = -1;

  // Open from.
  if ((from_file = ::open(f.begin(), O_RDONLY)) < 0)
    return error_code(errno, system_category());
  AutoFD from_fd(from_file);

  // Stat from.
  struct stat from_stat;
  if (::stat(f.begin(), &from_stat) != 0)
    return error_code(errno, system_category());

  // Setup to flags.
  int to_flags = O_CREAT | O_WRONLY;
  if (copt == copy_option::fail_if_exists)
    to_flags |= O_EXCL;

  // Open to.
  if ((to_file = ::open(t.begin(), to_flags, from_stat.st_mode)) < 0)
    return error_code(errno, system_category());
  AutoFD to_fd(to_file);

  // Copy!
  ssize_t sz, sz_read = 1, sz_write;
  while (sz_read > 0 &&
         (sz_read = ::read(from_fd, buffer, buf_sz)) > 0) {
    // Allow for partial writes - see Advanced Unix Programming (2nd Ed.),
    // Marc Rochkind, Addison-Wesley, 2004, page 94
    sz_write = 0;
    do {
      if ((sz = ::write(to_fd, buffer + sz_write, sz_read - sz_write)) < 0) {
        sz_read = sz;  // cause read loop termination.
        break;         // error.
      }
      sz_write += sz;
    } while (sz_write < sz_read);
  }

  // After all the file operations above the return value of close actually
  // matters.
  if (::close(from_fd.take()) < 0) sz_read = -1;
  if (::close(to_fd.take()) < 0) sz_read = -1;

  // Check for errors.
  if (sz_read < 0)
    return error_code(errno, system_category());

  return error_code::success();
}

error_code create_directory(const Twine &path, bool &existed) {
  SmallString<128> path_storage;
  StringRef p = path.toNullTerminatedStringRef(path_storage);

  if (::mkdir(p.begin(), S_IRWXU | S_IRWXG) == -1) {
    if (errno != errc::file_exists)
      return error_code(errno, system_category());
    existed = true;
  } else
    existed = false;

  return error_code::success();
}

error_code create_hard_link(const Twine &to, const Twine &from) {
  // Get arguments.
  SmallString<128> from_storage;
  SmallString<128> to_storage;
  StringRef f = from.toNullTerminatedStringRef(from_storage);
  StringRef t = to.toNullTerminatedStringRef(to_storage);

  if (::link(t.begin(), f.begin()) == -1)
    return error_code(errno, system_category());

  return error_code::success();
}

error_code create_symlink(const Twine &to, const Twine &from) {
  // Get arguments.
  SmallString<128> from_storage;
  SmallString<128> to_storage;
  StringRef f = from.toNullTerminatedStringRef(from_storage);
  StringRef t = to.toNullTerminatedStringRef(to_storage);

  if (::symlink(t.begin(), f.begin()) == -1)
    return error_code(errno, system_category());

  return error_code::success();
}

error_code remove(const Twine &path, bool &existed) {
  SmallString<128> path_storage;
  StringRef p = path.toNullTerminatedStringRef(path_storage);

  if (::remove(p.begin()) == -1) {
    if (errno != errc::no_such_file_or_directory)
      return error_code(errno, system_category());
    existed = false;
  } else
    existed = true;

  return error_code::success();
}

error_code rename(const Twine &from, const Twine &to) {
  // Get arguments.
  SmallString<128> from_storage;
  SmallString<128> to_storage;
  StringRef f = from.toNullTerminatedStringRef(from_storage);
  StringRef t = to.toNullTerminatedStringRef(to_storage);

  if (::rename(f.begin(), t.begin()) == -1) {
    // If it's a cross device link, copy then delete, otherwise return the error
    if (errno == EXDEV) {
      if (error_code ec = copy_file(from, to, copy_option::overwrite_if_exists))
        return ec;
      bool Existed;
      if (error_code ec = remove(from, Existed))
        return ec;
    } else
      return error_code(errno, system_category());
  }

  return error_code::success();
}

error_code resize_file(const Twine &path, uint64_t size) {
  SmallString<128> path_storage;
  StringRef p = path.toNullTerminatedStringRef(path_storage);

  if (::truncate(p.begin(), size) == -1)
    return error_code(errno, system_category());

  return error_code::success();
}

error_code exists(const Twine &path, bool &result) {
  SmallString<128> path_storage;
  StringRef p = path.toNullTerminatedStringRef(path_storage);

  if (::access(p.begin(), F_OK) == -1) {
    if (errno != errc::no_such_file_or_directory)
      return error_code(errno, system_category());
    result = false;
  } else
    result = true;

  return error_code::success();
}

bool equivalent(file_status A, file_status B) {
  assert(status_known(A) && status_known(B));
  return A.fs_st_dev == B.fs_st_dev &&
         A.fs_st_ino == B.fs_st_ino;
}

error_code equivalent(const Twine &A, const Twine &B, bool &result) {
  file_status fsA, fsB;
  if (error_code ec = status(A, fsA)) return ec;
  if (error_code ec = status(B, fsB)) return ec;
  result = equivalent(fsA, fsB);
  return error_code::success();
}

error_code file_size(const Twine &path, uint64_t &result) {
  SmallString<128> path_storage;
  StringRef p = path.toNullTerminatedStringRef(path_storage);

  struct stat status;
  if (::stat(p.begin(), &status) == -1)
    return error_code(errno, system_category());
  if (!S_ISREG(status.st_mode))
    return make_error_code(errc::operation_not_permitted);

  result = status.st_size;
  return error_code::success();
}

error_code status(const Twine &path, file_status &result) {
  SmallString<128> path_storage;
  StringRef p = path.toNullTerminatedStringRef(path_storage);

  struct stat status;
  if (::stat(p.begin(), &status) != 0) {
    error_code ec(errno, system_category());
    if (ec == errc::no_such_file_or_directory)
      result = file_status(file_type::file_not_found);
    else
      result = file_status(file_type::status_error);
    return ec;
  }

  perms prms = static_cast<perms>(status.st_mode & perms_mask);
  
  if (S_ISDIR(status.st_mode))
    result = file_status(file_type::directory_file, prms);
  else if (S_ISREG(status.st_mode))
    result = file_status(file_type::regular_file, prms);
  else if (S_ISBLK(status.st_mode))
    result = file_status(file_type::block_file, prms);
  else if (S_ISCHR(status.st_mode))
    result = file_status(file_type::character_file, prms);
  else if (S_ISFIFO(status.st_mode))
    result = file_status(file_type::fifo_file, prms);
  else if (S_ISSOCK(status.st_mode))
    result = file_status(file_type::socket_file, prms);
  else
    result = file_status(file_type::type_unknown, prms);

  result.fs_st_dev = status.st_dev;
  result.fs_st_ino = status.st_ino;

  return error_code::success();
}

// Modifies permissions on a file.
error_code permissions(const Twine &path, perms prms) {
  if ((prms & add_perms) && (prms & remove_perms))
    llvm_unreachable("add_perms and remove_perms are mutually exclusive");

  // Get current permissions
  file_status info;
  if (error_code ec = status(path, info)) {
    return ec;
  }
  
  // Set updated permissions.
  SmallString<128> path_storage;
  StringRef p = path.toNullTerminatedStringRef(path_storage);
  perms permsToSet;
  if (prms & add_perms) {
    permsToSet = (info.permissions() | prms) & perms_mask;
  } else if (prms & remove_perms) {
    permsToSet = (info.permissions() & ~prms) & perms_mask;
  } else {
    permsToSet = prms & perms_mask;
  }
  if (::chmod(p.begin(), static_cast<mode_t>(permsToSet))) {
    return error_code(errno, system_category()); 
  }

  return error_code::success();
}

// Since this is most often used for temporary files, mode defaults to 0600.
error_code unique_file(const Twine &model, int &result_fd,
                       SmallVectorImpl<char> &result_path,
                       bool makeAbsolute, unsigned mode) {
  SmallString<128> Model;
  model.toVector(Model);
  // Null terminate.
  Model.c_str();

  if (makeAbsolute) {
    // Make model absolute by prepending a temp directory if it's not already.
    bool absolute = path::is_absolute(Twine(Model));
    if (!absolute) {
      SmallString<128> TDir;
      if (error_code ec = TempDir(TDir)) return ec;
      path::append(TDir, Twine(Model));
      Model.swap(TDir);
    }
  }

  // From here on, DO NOT modify model. It may be needed if the randomly chosen
  // path already exists.
  SmallString<128> RandomPath = Model;

retry_random_path:
  // Replace '%' with random chars.
  for (unsigned i = 0, e = Model.size(); i != e; ++i) {
    if (Model[i] == '%')
      RandomPath[i] = "0123456789abcdef"[sys::Process::GetRandomNumber() & 15];
  }

  // Make sure we don't fall into an infinite loop by constantly trying
  // to create the parent path.
  bool TriedToCreateParent = false;

  // Try to open + create the file.
rety_open_create:
  int RandomFD = ::open(RandomPath.c_str(), O_RDWR | O_CREAT | O_EXCL, mode);
  if (RandomFD == -1) {
    int SavedErrno = errno;
    // If the file existed, try again, otherwise, error.
    if (SavedErrno == errc::file_exists)
      goto retry_random_path;
    // If path prefix doesn't exist, try to create it.
    if (SavedErrno == errc::no_such_file_or_directory &&
        !exists(path::parent_path(RandomPath)) &&
        !TriedToCreateParent) {
      TriedToCreateParent = true;
      StringRef p(RandomPath);
      SmallString<64> dir_to_create;
      for (path::const_iterator i = path::begin(p),
                                e = --path::end(p); i != e; ++i) {
        path::append(dir_to_create, *i);
        bool Exists;
        if (error_code ec = exists(Twine(dir_to_create), Exists)) return ec;
        if (!Exists) {
          // Don't try to create network paths.
          if (i->size() > 2 && (*i)[0] == '/' &&
                               (*i)[1] == '/' &&
                               (*i)[2] != '/')
            return make_error_code(errc::no_such_file_or_directory);
          if (::mkdir(dir_to_create.c_str(), 0700) == -1 &&
              errno != errc::file_exists)
            return error_code(errno, system_category());
        }
      }
      goto rety_open_create;
    }

    return error_code(SavedErrno, system_category());
  }

   // Make the path absolute.
  char real_path_buff[PATH_MAX + 1];
  if (realpath(RandomPath.c_str(), real_path_buff) == NULL) {
    int error = errno;
    ::close(RandomFD);
    ::unlink(RandomPath.c_str());
    return error_code(error, system_category());
  }

  result_path.clear();
  StringRef d(real_path_buff);
  result_path.append(d.begin(), d.end());

  result_fd = RandomFD;
  return error_code::success();
}

error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset) {
  AutoFD ScopedFD(FD);
  if (!CloseFD)
    ScopedFD.take();

  // Figure out how large the file is.
  struct stat FileInfo;
  if (fstat(FD, &FileInfo) == -1)
    return error_code(errno, system_category());
  uint64_t FileSize = FileInfo.st_size;

  if (Size == 0)
    Size = FileSize;
  else if (FileSize < Size) {
    // We need to grow the file.
    if (ftruncate(FD, Size) == -1)
      return error_code(errno, system_category());
  }

  int flags = (Mode == readwrite) ? MAP_SHARED : MAP_PRIVATE;
  int prot = (Mode == readonly) ? PROT_READ : (PROT_READ | PROT_WRITE);
#ifdef MAP_FILE
  flags |= MAP_FILE;
#endif
  Mapping = ::mmap(0, Size, prot, flags, FD, Offset);
  if (Mapping == MAP_FAILED)
    return error_code(errno, system_category());
  return error_code::success();
}

mapped_file_region::mapped_file_region(const Twine &path,
                                       mapmode mode,
                                       uint64_t length,
                                       uint64_t offset,
                                       error_code &ec)
  : Mode(mode)
  , Size(length)
  , Mapping() {
  // Make sure that the requested size fits within SIZE_T.
  if (length > std::numeric_limits<size_t>::max()) {
    ec = make_error_code(errc::invalid_argument);
    return;
  }

  SmallString<128> path_storage;
  StringRef name = path.toNullTerminatedStringRef(path_storage);
  int oflags = (mode == readonly) ? O_RDONLY : O_RDWR;
  int ofd = ::open(name.begin(), oflags);
  if (ofd == -1) {
    ec = error_code(errno, system_category());
    return;
  }

  ec = init(ofd, true, offset);
  if (ec)
    Mapping = 0;
}

mapped_file_region::mapped_file_region(int fd,
                                       bool closefd,
                                       mapmode mode,
                                       uint64_t length,
                                       uint64_t offset,
                                       error_code &ec)
  : Mode(mode)
  , Size(length)
  , Mapping() {
  // Make sure that the requested size fits within SIZE_T.
  if (length > std::numeric_limits<size_t>::max()) {
    ec = make_error_code(errc::invalid_argument);
    return;
  }

  ec = init(fd, closefd, offset);
  if (ec)
    Mapping = 0;
}

mapped_file_region::~mapped_file_region() {
  if (Mapping)
    ::munmap(Mapping, Size);
}

#if LLVM_HAS_RVALUE_REFERENCES
mapped_file_region::mapped_file_region(mapped_file_region &&other)
  : Mode(other.Mode), Size(other.Size), Mapping(other.Mapping) {
  other.Mapping = 0;
}
#endif

mapped_file_region::mapmode mapped_file_region::flags() const {
  assert(Mapping && "Mapping failed but used anyway!");
  return Mode;
}

uint64_t mapped_file_region::size() const {
  assert(Mapping && "Mapping failed but used anyway!");
  return Size;
}

char *mapped_file_region::data() const {
  assert(Mapping && "Mapping failed but used anyway!");
  assert(Mode != readonly && "Cannot get non const data for readonly mapping!");
  return reinterpret_cast<char*>(Mapping);
}

const char *mapped_file_region::const_data() const {
  assert(Mapping && "Mapping failed but used anyway!");
  return reinterpret_cast<const char*>(Mapping);
}

int mapped_file_region::alignment() {
  return process::get_self()->page_size();
}

error_code detail::directory_iterator_construct(detail::DirIterState &it,
                                                StringRef path){
  SmallString<128> path_null(path);
  DIR *directory = ::opendir(path_null.c_str());
  if (directory == 0)
    return error_code(errno, system_category());

  it.IterationHandle = reinterpret_cast<intptr_t>(directory);
  // Add something for replace_filename to replace.
  path::append(path_null, ".");
  it.CurrentEntry = directory_entry(path_null.str());
  return directory_iterator_increment(it);
}

error_code detail::directory_iterator_destruct(detail::DirIterState &it) {
  if (it.IterationHandle)
    ::closedir(reinterpret_cast<DIR *>(it.IterationHandle));
  it.IterationHandle = 0;
  it.CurrentEntry = directory_entry();
  return error_code::success();
}

error_code detail::directory_iterator_increment(detail::DirIterState &it) {
  errno = 0;
  dirent *cur_dir = ::readdir(reinterpret_cast<DIR *>(it.IterationHandle));
  if (cur_dir == 0 && errno != 0) {
    return error_code(errno, system_category());
  } else if (cur_dir != 0) {
    StringRef name(cur_dir->d_name, NAMLEN(cur_dir));
    if ((name.size() == 1 && name[0] == '.') ||
        (name.size() == 2 && name[0] == '.' && name[1] == '.'))
      return directory_iterator_increment(it);
    it.CurrentEntry.replace_filename(name);
  } else
    return directory_iterator_destruct(it);

  return error_code::success();
}

error_code get_magic(const Twine &path, uint32_t len,
                     SmallVectorImpl<char> &result) {
  SmallString<128> PathStorage;
  StringRef Path = path.toNullTerminatedStringRef(PathStorage);
  result.set_size(0);

  // Open path.
  std::FILE *file = std::fopen(Path.data(), "rb");
  if (file == 0)
    return error_code(errno, system_category());

  // Reserve storage.
  result.reserve(len);

  // Read magic!
  size_t size = std::fread(result.data(), 1, len, file);
  if (std::ferror(file) != 0) {
    std::fclose(file);
    return error_code(errno, system_category());
  } else if (size != result.size()) {
    if (std::feof(file) != 0) {
      std::fclose(file);
      result.set_size(size);
      return make_error_code(errc::value_too_large);
    }
  }
  std::fclose(file);
  result.set_size(len);
  return error_code::success();
}

error_code map_file_pages(const Twine &path, off_t file_offset, size_t size,  
                                            bool map_writable, void *&result) {
  SmallString<128> path_storage;
  StringRef name = path.toNullTerminatedStringRef(path_storage);
  int oflags = map_writable ? O_RDWR : O_RDONLY;
  int ofd = ::open(name.begin(), oflags);
  if ( ofd == -1 )
    return error_code(errno, system_category());
  AutoFD fd(ofd);
  int flags = map_writable ? MAP_SHARED : MAP_PRIVATE;
  int prot = map_writable ? (PROT_READ|PROT_WRITE) : PROT_READ;
#ifdef MAP_FILE
  flags |= MAP_FILE;
#endif
  result = ::mmap(0, size, prot, flags, fd, file_offset);
  if (result == MAP_FAILED) {
    return error_code(errno, system_category());
  }
  
  return error_code::success();
}

error_code unmap_file_pages(void *base, size_t size) {
  if ( ::munmap(base, size) == -1 )
    return error_code(errno, system_category());
   
  return error_code::success();
}


} // end namespace fs
} // end namespace sys
} // end namespace llvm
