| //===- FileSystem.inc -----------------------------------------------------===// |
| // |
| // The MCLinker Project |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| #include "mcld/Support/FileHandle.h" |
| #include "mcld/Support/Directory.h" |
| |
| #include <string> |
| |
| #include <cstdlib> |
| #include <io.h> |
| #include <fcntl.h> |
| #include <limits.h> |
| #include <sys/stat.h> |
| #include <windows.h> |
| |
| #ifndef STDIN_FILENO |
| #define STDIN_FILENO 0 |
| #endif |
| #ifndef STDOUT_FILENO |
| #define STDOUT_FILENO 1 |
| #endif |
| #ifndef STDERR_FILENO |
| #define STDERR_FILENO 2 |
| #endif |
| |
| namespace mcld { |
| namespace sys { |
| namespace fs { |
| namespace detail { |
| |
| // FIXME: the extension depends on target machine, not host machine. |
| Path::StringType static_library_extension = ".a"; |
| Path::StringType shared_library_extension = ".so"; |
| Path::StringType executable_extension = ".exe"; |
| Path::StringType relocatable_extension = ".o"; |
| Path::StringType assembly_extension = ".s"; |
| Path::StringType bitcode_extension = ".bc"; |
| |
| void open_dir(Directory& pDir) { |
| fs::Path file_filter(pDir.path()); |
| file_filter.append("*"); |
| |
| WIN32_FIND_DATA FindFileData; |
| HANDLE hFile = FindFirstFile(file_filter.c_str(), &FindFileData); |
| pDir.m_Handler = reinterpret_cast<intptr_t>(hFile); |
| |
| if (INVALID_HANDLE_VALUE == hFile) { |
| // set cache is full, then Directory::begin() can return end(). |
| pDir.m_CacheFull = true; |
| return; |
| } |
| |
| // find a new directory and file |
| bool exist = false; |
| std::string path(FindFileData.cFileName); |
| fs::PathCache::entry_type* entry = pDir.m_Cache.insert(path, exist); |
| if (!exist) |
| entry->setValue(path); |
| } |
| |
| void close_dir(Directory& pDir) { |
| if (pDir.m_Handler) |
| FindClose(reinterpret_cast<HANDLE>(pDir.m_Handler)); |
| pDir.m_Handler = 0; |
| } |
| |
| int open(const Path& pPath, int pOFlag) { |
| return ::_open(pPath.native().c_str(), pOFlag | _O_BINARY); |
| } |
| |
| int open(const Path& pPath, int pOFlag, int pPerm) { |
| int perm = 0; |
| if (pPerm & FileHandle::ReadOwner || pPerm & FileHandle::ReadGroup || |
| pPerm & FileHandle::ReadOther) |
| perm |= _S_IREAD; |
| |
| if (pPerm & FileHandle::WriteOwner || pPerm & FileHandle::WriteGroup || |
| pPerm & FileHandle::WriteOther) |
| perm |= _S_IWRITE; |
| |
| return ::_open(pPath.native().c_str(), pOFlag | _O_BINARY, perm); |
| } |
| |
| ssize_t pread(int pFD, void* pBuf, size_t pCount, off_t pOffset) { |
| ssize_t ret; |
| off_t old_pos; |
| if (-1 == (old_pos = ::lseek(pFD, 0, SEEK_CUR))) |
| return -1; |
| |
| if (-1 == ::lseek(pFD, pOffset, SEEK_SET)) |
| return -1; |
| |
| if (-1 == (ret = ::read(pFD, pBuf, pCount))) { |
| int err = errno; |
| ::lseek(pFD, old_pos, SEEK_SET); |
| errno = err; |
| return -1; |
| } |
| |
| if (-1 == ::lseek(pFD, old_pos, SEEK_SET)) |
| return -1; |
| |
| return ret; |
| } |
| |
| ssize_t pwrite(int pFD, const void* pBuf, size_t pCount, off_t pOffset) { |
| ssize_t ret; |
| off_t old_pos; |
| if (-1 == (old_pos = ::lseek(pFD, 0, SEEK_CUR))) |
| return -1; |
| |
| if (-1 == ::lseek(pFD, pOffset, SEEK_SET)) |
| return -1; |
| |
| if (-1 == (ret = ::write(pFD, pBuf, pCount))) { |
| int err = errno; |
| ::lseek(pFD, old_pos, SEEK_SET); |
| errno = err; |
| return -1; |
| } |
| |
| if (-1 == ::lseek(pFD, old_pos, SEEK_SET)) |
| return -1; |
| |
| return ret; |
| } |
| |
| int ftruncate(int pFD, size_t pLength) { |
| return ::_chsize(pFD, pLength); |
| } |
| |
| void get_pwd(Path& pPWD) { |
| char* pwd = (char*)malloc(PATH_MAX); |
| pPWD.assign(_getcwd(pwd, PATH_MAX)); |
| free(pwd); |
| } |
| |
| } // namespace detail |
| } // namespace fs |
| } // namespace sys |
| |
| //===----------------------------------------------------------------------===// |
| // FileHandle |
| //===----------------------------------------------------------------------===// |
| bool FileHandle::mmap(void*& pMemBuffer, size_t pStartOffset, size_t pLength) { |
| // FIXME: This implementation reduces mmap to read. Use Windows APIs. |
| pMemBuffer = (void*)::malloc(pLength); |
| return read(pMemBuffer, pStartOffset, pLength); |
| } |
| |
| bool FileHandle::munmap(void* pMemBuffer, size_t pLength) { |
| // FIXME: This implementation reduces mmap to read. Use Windows APIs. |
| free(pMemBuffer); |
| return true; |
| } |
| |
| } // namespace mcld |