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