15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- FileSystem.inc -----------------------------------------------------===// 25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// The MCLinker Project 45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source 65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details. 75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/FileHandle.h" 1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/Directory.h" 1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines 125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <string> 1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines 1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <cstdlib> 15f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <io.h> 16f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <fcntl.h> 17f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <limits.h> 1837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <sys/stat.h> 1937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <windows.h> 20f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 21f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#ifndef STDIN_FILENO 2237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#define STDIN_FILENO 0 23f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#endif 24f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#ifndef STDOUT_FILENO 2537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#define STDOUT_FILENO 1 26f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#endif 27f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#ifndef STDERR_FILENO 2837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#define STDERR_FILENO 2 29f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#endif 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld { 3237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace sys { 3337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace fs { 3437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace detail { 355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 36f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines// FIXME: the extension depends on target machine, not host machine. 37f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen HinesPath::StringType static_library_extension = ".a"; 38f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen HinesPath::StringType shared_library_extension = ".so"; 3937b74a387bb3993387029859c2d9d051c41c724eStephen HinesPath::StringType executable_extension = ".exe"; 4037b74a387bb3993387029859c2d9d051c41c724eStephen HinesPath::StringType relocatable_extension = ".o"; 4137b74a387bb3993387029859c2d9d051c41c724eStephen HinesPath::StringType assembly_extension = ".s"; 4237b74a387bb3993387029859c2d9d051c41c724eStephen HinesPath::StringType bitcode_extension = ".bc"; 43f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 4437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid open_dir(Directory& pDir) { 45f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines fs::Path file_filter(pDir.path()); 46f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines file_filter.append("*"); 47f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 48f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines WIN32_FIND_DATA FindFileData; 49f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines HANDLE hFile = FindFirstFile(file_filter.c_str(), &FindFileData); 50f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pDir.m_Handler = reinterpret_cast<intptr_t>(hFile); 51f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 52f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (INVALID_HANDLE_VALUE == hFile) { 53f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // set cache is full, then Directory::begin() can return end(). 54f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pDir.m_CacheFull = true; 55f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return; 56f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 57f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 58f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // find a new directory and file 59f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool exist = false; 60f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::string path(FindFileData.cFileName); 61f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines fs::PathCache::entry_type* entry = pDir.m_Cache.insert(path, exist); 62f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (!exist) 63f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines entry->setValue(path); 64f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 65f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 6637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid close_dir(Directory& pDir) { 67f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (pDir.m_Handler) 68f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines FindClose(reinterpret_cast<HANDLE>(pDir.m_Handler)); 69f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pDir.m_Handler = 0; 70f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 71f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 7237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesint open(const Path& pPath, int pOFlag) { 73f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return ::_open(pPath.native().c_str(), pOFlag | _O_BINARY); 74f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 75f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 7637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesint open(const Path& pPath, int pOFlag, int pPerm) { 77f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines int perm = 0; 7837b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (pPerm & FileHandle::ReadOwner || pPerm & FileHandle::ReadGroup || 79f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pPerm & FileHandle::ReadOther) 80f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines perm |= _S_IREAD; 81f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 8237b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (pPerm & FileHandle::WriteOwner || pPerm & FileHandle::WriteGroup || 83f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pPerm & FileHandle::WriteOther) 84f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines perm |= _S_IWRITE; 85f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 86f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return ::_open(pPath.native().c_str(), pOFlag | _O_BINARY, perm); 87f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 88f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 8937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesssize_t pread(int pFD, void* pBuf, size_t pCount, off_t pOffset) { 90f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ssize_t ret; 91f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines off_t old_pos; 92f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (-1 == (old_pos = ::lseek(pFD, 0, SEEK_CUR))) 9337b74a387bb3993387029859c2d9d051c41c724eStephen Hines return -1; 94f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 95f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (-1 == ::lseek(pFD, pOffset, SEEK_SET)) 96f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return -1; 97f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 98f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (-1 == (ret = ::read(pFD, pBuf, pCount))) { 99f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines int err = errno; 100f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ::lseek(pFD, old_pos, SEEK_SET); 101f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines errno = err; 10237b74a387bb3993387029859c2d9d051c41c724eStephen Hines return -1; 103f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 105f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (-1 == ::lseek(pFD, old_pos, SEEK_SET)) 106f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return -1; 107f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 108f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return ret; 109f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 110f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 11137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesssize_t pwrite(int pFD, const void* pBuf, size_t pCount, off_t pOffset) { 112f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ssize_t ret; 113f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines off_t old_pos; 114f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (-1 == (old_pos = ::lseek(pFD, 0, SEEK_CUR))) 115f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return -1; 116f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 117f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (-1 == ::lseek(pFD, pOffset, SEEK_SET)) 118f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return -1; 119f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 120f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (-1 == (ret = ::write(pFD, pBuf, pCount))) { 121f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines int err = errno; 122f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ::lseek(pFD, old_pos, SEEK_SET); 123f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines errno = err; 124f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return -1; 125f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 126f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 127f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (-1 == ::lseek(pFD, old_pos, SEEK_SET)) 128f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return -1; 129f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 130f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return ret; 131f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 132f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 13337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesint ftruncate(int pFD, size_t pLength) { 134f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return ::_chsize(pFD, pLength); 135f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 136f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 13737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid get_pwd(Path& pPWD) { 138f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines char* pwd = (char*)malloc(PATH_MAX); 139f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pPWD.assign(_getcwd(pwd, PATH_MAX)); 140f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines free(pwd); 141f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14337b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace detail 14437b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace fs 14537b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace sys 146f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 147f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines//===----------------------------------------------------------------------===// 148f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines// FileHandle 149f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines//===----------------------------------------------------------------------===// 15037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool FileHandle::mmap(void*& pMemBuffer, size_t pStartOffset, size_t pLength) { 151f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // FIXME: This implementation reduces mmap to read. Use Windows APIs. 152f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pMemBuffer = (void*)::malloc(pLength); 153f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return read(pMemBuffer, pStartOffset, pLength); 154f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 155f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 15637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool FileHandle::munmap(void* pMemBuffer, size_t pLength) { 157f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // FIXME: This implementation reduces mmap to read. Use Windows APIs. 158f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines free(pMemBuffer); 159f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 160f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 161f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 16237b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 163