FileSystem.inc revision f7ac0f19a1c8d0ad14bcf6456ce368b830fea886
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
29namespace mcld{
30namespace sys{
31namespace fs{
32namespace detail{
33
34// FIXME: the extension depends on target machine, not host machine.
35Path::StringType static_library_extension = ".a";
36Path::StringType shared_library_extension = ".so";
37Path::StringType executable_extension     = ".exe";
38Path::StringType relocatable_extension    = ".o";
39Path::StringType assembly_extension       = ".s";
40Path::StringType bitcode_extension        = ".bc";
41
42void 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
65void 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
72int open(const Path& pPath, int pOFlag)
73{
74  return ::_open(pPath.native().c_str(), pOFlag | _O_BINARY);
75}
76
77int 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
93ssize_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
116ssize_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
139int ftruncate(int pFD, size_t pLength)
140{
141  return ::_chsize(pFD, pLength);
142}
143
144void 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//===----------------------------------------------------------------------===//
158bool 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
165bool 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