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