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