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 31namespace mcld { 32namespace sys { 33namespace fs { 34namespace detail { 35 36// FIXME: the extension depends on target machine, not host machine. 37Path::StringType static_library_extension = ".a"; 38Path::StringType shared_library_extension = ".so"; 39Path::StringType executable_extension = ".exe"; 40Path::StringType relocatable_extension = ".o"; 41Path::StringType assembly_extension = ".s"; 42Path::StringType bitcode_extension = ".bc"; 43 44void 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 66void close_dir(Directory& pDir) { 67 if (pDir.m_Handler) 68 FindClose(reinterpret_cast<HANDLE>(pDir.m_Handler)); 69 pDir.m_Handler = 0; 70} 71 72int open(const Path& pPath, int pOFlag) { 73 return ::_open(pPath.native().c_str(), pOFlag | _O_BINARY); 74} 75 76int 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 89ssize_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 111ssize_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 133int ftruncate(int pFD, size_t pLength) { 134 return ::_chsize(pFD, pLength); 135} 136 137void 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//===----------------------------------------------------------------------===// 150bool 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 156bool 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