LLDB  mainline
windows/FileSystem.cpp
Go to the documentation of this file.
1 //===-- FileSystem.cpp ----------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 
11 #include <share.h>
12 #include <shellapi.h>
13 #include <sys/stat.h>
14 #include <sys/types.h>
15 
16 #include "lldb/Host/FileSystem.h"
19 
20 #include "llvm/Support/ConvertUTF.h"
21 #include "llvm/Support/FileSystem.h"
22 
23 using namespace lldb_private;
24 
25 const char *FileSystem::DEV_NULL = "nul";
26 
28  "Error converting path between UTF-8 and native encoding";
29 
30 Status FileSystem::Symlink(const FileSpec &src, const FileSpec &dst) {
31  Status error;
32  std::wstring wsrc, wdst;
33  if (!llvm::ConvertUTF8toWide(src.GetCString(), wsrc) ||
34  !llvm::ConvertUTF8toWide(dst.GetCString(), wdst))
35  error.SetErrorString(PATH_CONVERSION_ERROR);
36  if (error.Fail())
37  return error;
38  DWORD attrib = ::GetFileAttributesW(wdst.c_str());
39  if (attrib == INVALID_FILE_ATTRIBUTES) {
40  error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
41  return error;
42  }
43  bool is_directory = !!(attrib & FILE_ATTRIBUTE_DIRECTORY);
44  DWORD flag = is_directory ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0;
45  BOOL result = ::CreateSymbolicLinkW(wsrc.c_str(), wdst.c_str(), flag);
46  if (!result)
47  error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
48  return error;
49 }
50 
51 Status FileSystem::Readlink(const FileSpec &src, FileSpec &dst) {
52  Status error;
53  std::wstring wsrc;
54  if (!llvm::ConvertUTF8toWide(src.GetCString(), wsrc)) {
55  error.SetErrorString(PATH_CONVERSION_ERROR);
56  return error;
57  }
58 
59  HANDLE h = ::CreateFileW(wsrc.c_str(), GENERIC_READ,
60  FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
61  OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT, NULL);
62  if (h == INVALID_HANDLE_VALUE) {
63  error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
64  return error;
65  }
66 
67  std::vector<wchar_t> buf(PATH_MAX + 1);
68  // Subtract 1 from the path length since this function does not add a null
69  // terminator.
70  DWORD result = ::GetFinalPathNameByHandleW(
71  h, buf.data(), buf.size() - 1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
72  std::string path;
73  if (result == 0)
74  error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
75  else if (!llvm::convertWideToUTF8(buf.data(), path))
76  error.SetErrorString(PATH_CONVERSION_ERROR);
77  else
78  dst.SetFile(path, FileSpec::Style::native);
79 
80  ::CloseHandle(h);
81  return error;
82 }
83 
85  return Status("ResolveSymbolicLink() isn't implemented on Windows");
86 }
87 
88 FILE *FileSystem::Fopen(const char *path, const char *mode) {
89  Collect(path);
90  std::wstring wpath, wmode;
91  if (!llvm::ConvertUTF8toWide(path, wpath))
92  return nullptr;
93  if (!llvm::ConvertUTF8toWide(mode, wmode))
94  return nullptr;
95  FILE *file;
96  if (_wfopen_s(&file, wpath.c_str(), wmode.c_str()) != 0)
97  return nullptr;
98  return file;
99 }
100 
101 int FileSystem::Open(const char *path, int flags, int mode) {
102  Collect(path);
103  std::wstring wpath;
104  if (!llvm::ConvertUTF8toWide(path, wpath))
105  return -1;
106  int result;
107  ::_wsopen_s(&result, wpath.c_str(), flags, _SH_DENYNO, mode);
108  return result;
109 }
lldb_private::FileSystem::Open
int Open(const char *path, int flags, int mode)
Wraps ::open in a platform-independent way.
Definition: FileSystemPosix.cpp:79
lldb_private::FileSystem::Collect
void Collect(const FileSpec &file_spec)
Definition: common/FileSystem.cpp:499
FileSystem.h
lldb_private::FileSystem::Fopen
FILE * Fopen(const char *path, const char *mode)
Wraps ::fopen in a platform-independent way.
Definition: FileSystemPosix.cpp:74
lldb_private::FileSystem::DEV_NULL
static const char * DEV_NULL
Definition: FileSystem.h:31
lldb::eErrorTypeWin32
@ eErrorTypeWin32
Standard Win32 error codes.
Definition: lldb-enumerations.h:312
AutoHandle.h
lldb_private::FileSpec::GetCString
const char * GetCString(bool denormalize=true) const
Definition: FileSpec.cpp:362
lldb_private::FileSpec
Definition: FileSpec.h:56
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
lldb_private::FileSystem::ResolveSymbolicLink
Status ResolveSymbolicLink(const FileSpec &src, FileSpec &dst)
Definition: FileSystemPosix.cpp:56
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:40
lldb_private::FileSystem::Readlink
Status Readlink(const FileSpec &src, FileSpec &dst)
Definition: FileSystemPosix.cpp:43
PosixApi.h
lldb_private::Status
Definition: Status.h:44
lldb_private::FileSystem::PATH_CONVERSION_ERROR
static const char * PATH_CONVERSION_ERROR
Definition: FileSystem.h:32
windows.h
lldb_private::FileSystem::Symlink
Status Symlink(const FileSpec &src, const FileSpec &dst)
Definition: FileSystemPosix.cpp:36
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::FileSpec::SetFile
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
Definition: FileSpec.cpp:172
PATH_MAX
#define PATH_MAX
Definition: windows/PosixApi.h:25