blob: b8a455727ae56a842539c5f80b2d7bf2ce2138ae [file] [log] [blame]
Zachary Turnerc00cf4a2014-08-15 22:04:21 +00001//===-- FileSystem.cpp ------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Host/FileSystem.h"
11
12// C includes
Greg Clayton736888c2015-02-23 23:47:09 +000013#include <sys/mount.h>
14#include <sys/param.h>
Zachary Turnerc00cf4a2014-08-15 22:04:21 +000015#include <sys/stat.h>
16#include <sys/types.h>
17
18// lldb Includes
19#include "lldb/Core/Error.h"
20#include "lldb/Core/StreamString.h"
21#include "lldb/Host/Host.h"
22
23using namespace lldb;
24using namespace lldb_private;
25
26FileSpec::PathSyntax
27FileSystem::GetNativePathSyntax()
28{
29 return FileSpec::ePathSyntaxPosix;
30}
31
32Error
33FileSystem::MakeDirectory(const char *path, uint32_t file_permissions)
34{
35 Error error;
36 if (path && path[0])
37 {
38 if (::mkdir(path, file_permissions) != 0)
39 {
40 error.SetErrorToErrno();
41 switch (error.GetError())
42 {
43 case ENOENT:
44 {
45 // Parent directory doesn't exist, so lets make it if we can
46 FileSpec spec(path, false);
47 if (spec.GetDirectory() && spec.GetFilename())
48 {
49 // Make the parent directory and try again
50 Error error2 = MakeDirectory(spec.GetDirectory().GetCString(), file_permissions);
51 if (error2.Success())
52 {
53 // Try and make the directory again now that the parent directory was made successfully
54 if (::mkdir(path, file_permissions) == 0)
55 error.Clear();
56 else
57 error.SetErrorToErrno();
58 }
59 }
60 }
61 break;
62
63 case EEXIST:
64 {
65 FileSpec path_spec(path, false);
66 if (path_spec.IsDirectory())
67 error.Clear(); // It is a directory and it already exists
68 }
69 break;
70 }
71 }
72 }
73 else
74 {
75 error.SetErrorString("empty path");
76 }
77 return error;
78}
79
80Error
81FileSystem::DeleteDirectory(const char *path, bool recurse)
82{
83 Error error;
84 if (path && path[0])
85 {
86 if (recurse)
87 {
88 StreamString command;
89 command.Printf("rm -rf \"%s\"", path);
90 int status = ::system(command.GetString().c_str());
91 if (status != 0)
92 error.SetError(status, eErrorTypeGeneric);
93 }
94 else
95 {
96 if (::rmdir(path) != 0)
97 error.SetErrorToErrno();
98 }
99 }
100 else
101 {
102 error.SetErrorString("empty path");
103 }
104 return error;
105}
106
107Error
108FileSystem::GetFilePermissions(const char *path, uint32_t &file_permissions)
109{
110 Error error;
111 struct stat file_stats;
112 if (::stat(path, &file_stats) == 0)
113 {
114 // The bits in "st_mode" currently match the definitions
115 // for the file mode bits in unix.
116 file_permissions = file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
117 }
118 else
119 {
120 error.SetErrorToErrno();
121 }
122 return error;
123}
124
125Error
126FileSystem::SetFilePermissions(const char *path, uint32_t file_permissions)
127{
128 Error error;
129 if (::chmod(path, file_permissions) != 0)
130 error.SetErrorToErrno();
131 return error;
132}
133
134lldb::user_id_t
135FileSystem::GetFileSize(const FileSpec &file_spec)
136{
137 return file_spec.GetByteSize();
138}
139
140bool
141FileSystem::GetFileExists(const FileSpec &file_spec)
142{
143 return file_spec.Exists();
144}
145
146Error
147FileSystem::Symlink(const char *src, const char *dst)
148{
149 Error error;
150 if (::symlink(dst, src) == -1)
151 error.SetErrorToErrno();
152 return error;
153}
154
155Error
156FileSystem::Unlink(const char *path)
157{
158 Error error;
159 if (::unlink(path) == -1)
160 error.SetErrorToErrno();
161 return error;
162}
163
164Error
165FileSystem::Readlink(const char *path, char *buf, size_t buf_len)
166{
167 Error error;
168 ssize_t count = ::readlink(path, buf, buf_len);
169 if (count < 0)
170 error.SetErrorToErrno();
171 else if (static_cast<size_t>(count) < (buf_len - 1))
172 buf[count] = '\0'; // Success
173 else
174 error.SetErrorString("'buf' buffer is too small to contain link contents");
175 return error;
176}
Greg Clayton736888c2015-02-23 23:47:09 +0000177
178bool
179FileSystem::IsLocal(const FileSpec &spec)
180{
181 struct statfs statfs_info;
182 std::string path (spec.GetPath());
183 if (statfs(path.c_str(), &statfs_info) == 0)
184 return (statfs_info.f_flags & MNT_LOCAL) != 0;
185 return false;
186}