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//===----------------------------------------------------------------------===//
95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <string>
10f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <io.h>
11f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <fcntl.h>
12f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <cstdlib>
13f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <windows.h>
14f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <sys/stat.h>
15f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <limits.h>
16f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <mcld/Support/FileHandle.h>
17f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <mcld/Support/Directory.h>
18f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
19f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#ifndef STDIN_FILENO
20f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines# define STDIN_FILENO 0
21f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#endif
22f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#ifndef STDOUT_FILENO
23f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines# define STDOUT_FILENO 1
24f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#endif
25f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#ifndef STDERR_FILENO
26f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines# define STDERR_FILENO 2
27f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#endif
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld{
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace sys{
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace fs{
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace detail{
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
34f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines// FIXME: the extension depends on target machine, not host machine.
35f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen HinesPath::StringType static_library_extension = ".a";
36f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen HinesPath::StringType shared_library_extension = ".so";
37f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen HinesPath::StringType executable_extension     = ".exe";
38f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen HinesPath::StringType relocatable_extension    = ".o";
39f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen HinesPath::StringType assembly_extension       = ".s";
40f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen HinesPath::StringType bitcode_extension        = ".bc";
41f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
42f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid open_dir(Directory& pDir)
43f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{
44f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  fs::Path file_filter(pDir.path());
45f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  file_filter.append("*");
46f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
47f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  WIN32_FIND_DATA FindFileData;
48f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  HANDLE hFile = FindFirstFile(file_filter.c_str(), &FindFileData);
49f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  pDir.m_Handler = reinterpret_cast<intptr_t>(hFile);
50f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
51f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (INVALID_HANDLE_VALUE == hFile) {
52f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    // set cache is full, then Directory::begin() can return end().
53f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    pDir.m_CacheFull = true;
54f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    return;
55f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  }
56f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
57f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  // find a new directory and file
58f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  bool exist = false;
59f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  std::string path(FindFileData.cFileName);
60f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  fs::PathCache::entry_type* entry = pDir.m_Cache.insert(path, exist);
61f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (!exist)
62f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    entry->setValue(path);
63f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines}
64f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
65f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid close_dir(Directory& pDir)
66f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{
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
72f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesint open(const Path& pPath, int pOFlag)
73f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{
74f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  return ::_open(pPath.native().c_str(), pOFlag | _O_BINARY);
75f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines}
76f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
77f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesint open(const Path& pPath, int pOFlag, int pPerm)
78f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{
79f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  int perm = 0;
80f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (pPerm & FileHandle::ReadOwner ||
81f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      pPerm & FileHandle::ReadGroup ||
82f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      pPerm & FileHandle::ReadOther)
83f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    perm |= _S_IREAD;
84f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
85f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (pPerm & FileHandle::WriteOwner ||
86f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      pPerm & FileHandle::WriteGroup ||
87f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      pPerm & FileHandle::WriteOther)
88f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    perm |= _S_IWRITE;
89f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
90f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  return ::_open(pPath.native().c_str(), pOFlag | _O_BINARY, perm);
91f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines}
92f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
93f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesssize_t pread(int pFD, void* pBuf, size_t pCount, off_t pOffset)
94f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{
95f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  ssize_t ret;
96f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  off_t old_pos;
97f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (-1 == (old_pos = ::lseek(pFD, 0, SEEK_CUR)))
98f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines     return -1;
99f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
100f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (-1 == ::lseek(pFD, pOffset, SEEK_SET))
101f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    return -1;
102f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
103f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (-1 == (ret = ::read(pFD, pBuf, pCount))) {
104f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    int err = errno;
105f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    ::lseek(pFD, old_pos, SEEK_SET);
106f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    errno = err;
107f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines     return -1;
108f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  }
1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
110f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (-1 == ::lseek(pFD, old_pos, SEEK_SET))
111f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    return -1;
112f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
113f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  return ret;
114f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines}
115f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
116f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesssize_t pwrite(int pFD, const void* pBuf, size_t pCount, off_t pOffset)
117f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{
118f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  ssize_t ret;
119f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  off_t old_pos;
120f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (-1 == (old_pos = ::lseek(pFD, 0, SEEK_CUR)))
121f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    return -1;
122f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
123f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (-1 == ::lseek(pFD, pOffset, SEEK_SET))
124f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    return -1;
125f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
126f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (-1 == (ret = ::write(pFD, pBuf, pCount))) {
127f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    int err = errno;
128f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    ::lseek(pFD, old_pos, SEEK_SET);
129f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    errno = err;
130f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    return -1;
131f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  }
132f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
133f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (-1 == ::lseek(pFD, old_pos, SEEK_SET))
134f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    return -1;
135f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
136f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  return ret;
137f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines}
138f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
139f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesint ftruncate(int pFD, size_t pLength)
140f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{
141f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  return ::_chsize(pFD, pLength);
142f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines}
143f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
144f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid get_pwd(Path& pPWD)
145f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{
146f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  char* pwd = (char*)malloc(PATH_MAX);
147f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  pPWD.assign(_getcwd(pwd, PATH_MAX));
148f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  free(pwd);
149f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines}
1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of detail
1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of fs
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of sys
154f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
155f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines//===----------------------------------------------------------------------===//
156f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines// FileHandle
157f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines//===----------------------------------------------------------------------===//
158f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool FileHandle::mmap(void*& pMemBuffer, size_t pStartOffset, size_t pLength)
159f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{
160f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  // FIXME: This implementation reduces mmap to read. Use Windows APIs.
161f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  pMemBuffer = (void*)::malloc(pLength);
162f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  return read(pMemBuffer, pStartOffset, pLength);
163f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines}
164f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
165f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool FileHandle::munmap(void* pMemBuffer, size_t pLength)
166f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{
167f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  // FIXME: This implementation reduces mmap to read. Use Windows APIs.
168f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  free(pMemBuffer);
169f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  return true;
170f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines}
171f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld
1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
174