1 //===-- FileSystem.cpp ------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/Host/FileSystem.h"
14 #include <sys/types.h>
17 #include "lldb/Core/Error.h"
18 #include "lldb/Core/StreamString.h"
19 #include "lldb/Host/Host.h"
22 using namespace lldb_private;
25 FileSystem::GetNativePathSyntax()
27 return FileSpec::ePathSyntaxPosix;
31 FileSystem::MakeDirectory(const char *path, uint32_t file_permissions)
36 if (::mkdir(path, file_permissions) != 0)
38 error.SetErrorToErrno();
39 switch (error.GetError())
43 // Parent directory doesn't exist, so lets make it if we can
44 FileSpec spec(path, false);
45 if (spec.GetDirectory() && spec.GetFilename())
47 // Make the parent directory and try again
48 Error error2 = MakeDirectory(spec.GetDirectory().GetCString(), file_permissions);
51 // Try and make the directory again now that the parent directory was made successfully
52 if (::mkdir(path, file_permissions) == 0)
55 error.SetErrorToErrno();
63 FileSpec path_spec(path, false);
64 if (path_spec.IsDirectory())
65 error.Clear(); // It is a directory and it already exists
73 error.SetErrorString("empty path");
79 FileSystem::DeleteDirectory(const char *path, bool recurse)
87 command.Printf("rm -rf \"%s\"", path);
88 int status = ::system(command.GetString().c_str());
90 error.SetError(status, eErrorTypeGeneric);
94 if (::rmdir(path) != 0)
95 error.SetErrorToErrno();
100 error.SetErrorString("empty path");
106 FileSystem::GetFilePermissions(const char *path, uint32_t &file_permissions)
109 struct stat file_stats;
110 if (::stat(path, &file_stats) == 0)
112 // The bits in "st_mode" currently match the definitions
113 // for the file mode bits in unix.
114 file_permissions = file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
118 error.SetErrorToErrno();
124 FileSystem::SetFilePermissions(const char *path, uint32_t file_permissions)
127 if (::chmod(path, file_permissions) != 0)
128 error.SetErrorToErrno();
133 FileSystem::GetFileSize(const FileSpec &file_spec)
135 return file_spec.GetByteSize();
139 FileSystem::GetFileExists(const FileSpec &file_spec)
141 return file_spec.Exists();
145 FileSystem::Symlink(const char *src, const char *dst)
148 if (::symlink(dst, src) == -1)
149 error.SetErrorToErrno();
154 FileSystem::Unlink(const char *path)
157 if (::unlink(path) == -1)
158 error.SetErrorToErrno();
163 FileSystem::Readlink(const char *path, char *buf, size_t buf_len)
166 ssize_t count = ::readlink(path, buf, buf_len);
168 error.SetErrorToErrno();
169 else if (static_cast<size_t>(count) < (buf_len - 1))
170 buf[count] = '\0'; // Success
172 error.SetErrorString("'buf' buffer is too small to contain link contents");
177 FileSystem::CalculateMD5(const FileSpec &file_spec, uint64_t &low, uint64_t &high)
179 #if defined(__APPLE__)
180 StreamString md5_cmd_line;
181 md5_cmd_line.Printf("md5 -q '%s'", file_spec.GetPath().c_str());
182 std::string hash_string;
183 Error err = Host::RunShellCommand(md5_cmd_line.GetData(), NULL, NULL, NULL, &hash_string, 60);
186 // a correctly formed MD5 is 16-bytes, that is 32 hex digits
187 // if the output is any other length it is probably wrong
188 if (hash_string.size() != 32)
190 std::string part1(hash_string, 0, 16);
191 std::string part2(hash_string, 16);
192 const char *part1_cstr = part1.c_str();
193 const char *part2_cstr = part2.c_str();
194 high = ::strtoull(part1_cstr, NULL, 16);
195 low = ::strtoull(part2_cstr, NULL, 16);
198 // your own MD5 implementation here