Home | History | Annotate | Download | only in Windows
      1 //===- FileSystem.inc -----------------------------------------------------===//
      2 //
      3 //                     The MCLinker Project
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 #include <string>
     10 #include <io.h>
     11 #include <fcntl.h>
     12 #include <cstdlib>
     13 #include <windows.h>
     14 #include <sys/stat.h>
     15 #include <limits.h>
     16 #include <mcld/Support/FileHandle.h>
     17 #include <mcld/Support/Directory.h>
     18 
     19 #ifndef STDIN_FILENO
     20 # define STDIN_FILENO 0
     21 #endif
     22 #ifndef STDOUT_FILENO
     23 # define STDOUT_FILENO 1
     24 #endif
     25 #ifndef STDERR_FILENO
     26 # define STDERR_FILENO 2
     27 #endif
     28 
     29 namespace mcld{
     30 namespace sys{
     31 namespace fs{
     32 namespace detail{
     33 
     34 // FIXME: the extension depends on target machine, not host machine.
     35 Path::StringType static_library_extension = ".a";
     36 Path::StringType shared_library_extension = ".so";
     37 Path::StringType executable_extension     = ".exe";
     38 Path::StringType relocatable_extension    = ".o";
     39 Path::StringType assembly_extension       = ".s";
     40 Path::StringType bitcode_extension        = ".bc";
     41 
     42 void open_dir(Directory& pDir)
     43 {
     44   fs::Path file_filter(pDir.path());
     45   file_filter.append("*");
     46 
     47   WIN32_FIND_DATA FindFileData;
     48   HANDLE hFile = FindFirstFile(file_filter.c_str(), &FindFileData);
     49   pDir.m_Handler = reinterpret_cast<intptr_t>(hFile);
     50 
     51   if (INVALID_HANDLE_VALUE == hFile) {
     52     // set cache is full, then Directory::begin() can return end().
     53     pDir.m_CacheFull = true;
     54     return;
     55   }
     56 
     57   // find a new directory and file
     58   bool exist = false;
     59   std::string path(FindFileData.cFileName);
     60   fs::PathCache::entry_type* entry = pDir.m_Cache.insert(path, exist);
     61   if (!exist)
     62     entry->setValue(path);
     63 }
     64 
     65 void close_dir(Directory& pDir)
     66 {
     67   if (pDir.m_Handler)
     68     FindClose(reinterpret_cast<HANDLE>(pDir.m_Handler));
     69   pDir.m_Handler = 0;
     70 }
     71 
     72 int open(const Path& pPath, int pOFlag)
     73 {
     74   return ::_open(pPath.native().c_str(), pOFlag | _O_BINARY);
     75 }
     76 
     77 int open(const Path& pPath, int pOFlag, int pPerm)
     78 {
     79   int perm = 0;
     80   if (pPerm & FileHandle::ReadOwner ||
     81       pPerm & FileHandle::ReadGroup ||
     82       pPerm & FileHandle::ReadOther)
     83     perm |= _S_IREAD;
     84 
     85   if (pPerm & FileHandle::WriteOwner ||
     86       pPerm & FileHandle::WriteGroup ||
     87       pPerm & FileHandle::WriteOther)
     88     perm |= _S_IWRITE;
     89 
     90   return ::_open(pPath.native().c_str(), pOFlag | _O_BINARY, perm);
     91 }
     92 
     93 ssize_t pread(int pFD, void* pBuf, size_t pCount, off_t pOffset)
     94 {
     95   ssize_t ret;
     96   off_t old_pos;
     97   if (-1 == (old_pos = ::lseek(pFD, 0, SEEK_CUR)))
     98      return -1;
     99 
    100   if (-1 == ::lseek(pFD, pOffset, SEEK_SET))
    101     return -1;
    102 
    103   if (-1 == (ret = ::read(pFD, pBuf, pCount))) {
    104     int err = errno;
    105     ::lseek(pFD, old_pos, SEEK_SET);
    106     errno = err;
    107      return -1;
    108   }
    109 
    110   if (-1 == ::lseek(pFD, old_pos, SEEK_SET))
    111     return -1;
    112 
    113   return ret;
    114 }
    115 
    116 ssize_t pwrite(int pFD, const void* pBuf, size_t pCount, off_t pOffset)
    117 {
    118   ssize_t ret;
    119   off_t old_pos;
    120   if (-1 == (old_pos = ::lseek(pFD, 0, SEEK_CUR)))
    121     return -1;
    122 
    123   if (-1 == ::lseek(pFD, pOffset, SEEK_SET))
    124     return -1;
    125 
    126   if (-1 == (ret = ::write(pFD, pBuf, pCount))) {
    127     int err = errno;
    128     ::lseek(pFD, old_pos, SEEK_SET);
    129     errno = err;
    130     return -1;
    131   }
    132 
    133   if (-1 == ::lseek(pFD, old_pos, SEEK_SET))
    134     return -1;
    135 
    136   return ret;
    137 }
    138 
    139 int ftruncate(int pFD, size_t pLength)
    140 {
    141   return ::_chsize(pFD, pLength);
    142 }
    143 
    144 void get_pwd(Path& pPWD)
    145 {
    146   char* pwd = (char*)malloc(PATH_MAX);
    147   pPWD.assign(_getcwd(pwd, PATH_MAX));
    148   free(pwd);
    149 }
    150 
    151 } // namespace of detail
    152 } // namespace of fs
    153 } // namespace of sys
    154 
    155 //===----------------------------------------------------------------------===//
    156 // FileHandle
    157 //===----------------------------------------------------------------------===//
    158 bool FileHandle::mmap(void*& pMemBuffer, size_t pStartOffset, size_t pLength)
    159 {
    160   // FIXME: This implementation reduces mmap to read. Use Windows APIs.
    161   pMemBuffer = (void*)::malloc(pLength);
    162   return read(pMemBuffer, pStartOffset, pLength);
    163 }
    164 
    165 bool FileHandle::munmap(void* pMemBuffer, size_t pLength)
    166 {
    167   // FIXME: This implementation reduces mmap to read. Use Windows APIs.
    168   free(pMemBuffer);
    169   return true;
    170 }
    171 
    172 } // namespace of mcld
    173 
    174