163 lines
4.1 KiB
C++
163 lines
4.1 KiB
C++
//===- 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
|