blob: 6bfb5d6d9011089ffcb9b51f26b8f4a8bec0e536 [file] [log] [blame]
Greg Clayton60a63ae2011-02-08 17:49:02 +00001//===-- FileSpec.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
11#include "lldb/Host/File.h"
12
13#include <fcntl.h>
14
15#include "lldb/Core/Error.h"
Greg Claytond35305a2011-02-08 19:54:44 +000016#include "lldb/Host/FileSpec.h"
Greg Clayton60a63ae2011-02-08 17:49:02 +000017
18using namespace lldb;
19using namespace lldb_private;
20
21File::File(const char *path, uint32_t options, uint32_t permissions) :
Greg Clayton60a63ae2011-02-08 17:49:02 +000022 m_file_desc (-1)
23{
24 Open (path, options, permissions);
25}
26
27File::~File()
28{
29 Close ();
30}
31
32Error
33File::Open (const char *path, uint32_t options, uint32_t permissions)
34{
35 Error error;
36 if (IsValid())
37 Close ();
38
39 int oflag = 0;
40 if (options & eOpenOptionRead &&
41 options & eOpenOptionWrite )
42 oflag |= O_RDWR;
43 else if (options & eOpenOptionRead)
44 oflag |= O_RDONLY;
45 else if (options & eOpenOptionWrite)
46 oflag |= O_WRONLY;
47
48 if (options & eOpenOptionNonBlocking)
49 oflag |= O_NONBLOCK;
50
51 if (options & eOpenOptionAppend)
52 oflag |= O_APPEND;
53
54 if (options & eOpenOptionCanCreate)
55 oflag |= O_CREAT;
56
57 if (options & eOpenOptionCanCreateNewOnly)
58 oflag |= O_CREAT | O_EXCL;
59
60 if (options & eOpenOptionTruncate)
61 oflag |= O_TRUNC;
62
63 if (options & eOpenOptionSharedLock)
64 oflag |= O_SHLOCK;
65
66 if (options & eOpenOptionExclusiveLock)
67 oflag |= O_EXLOCK;
68
69 mode_t mode = 0;
70 if (permissions & ePermissionsUserRead) mode |= S_IRUSR;
71 if (permissions & ePermissionsUserWrite) mode |= S_IWUSR;
72 if (permissions & ePermissionsUserExecute) mode |= S_IXUSR;
73 if (permissions & ePermissionsGroupRead) mode |= S_IRGRP;
74 if (permissions & ePermissionsGroupWrite) mode |= S_IWGRP;
75 if (permissions & ePermissionsGroupExecute) mode |= S_IXGRP;
76 if (permissions & ePermissionsWorldRead) mode |= S_IROTH;
77 if (permissions & ePermissionsWorldWrite) mode |= S_IWOTH;
78 if (permissions & ePermissionsWorldExecute) mode |= S_IXOTH;
79
80 m_file_desc = ::open(path, oflag, mode);
81 if (m_file_desc == -1)
82 error.SetErrorToErrno();
Greg Clayton60a63ae2011-02-08 17:49:02 +000083
84 return error;
85}
86
87Error
88File::Close ()
89{
90 Error error;
91 if (IsValid ())
92 {
93 if (::close (m_file_desc) != 0)
94 error.SetErrorToErrno();
Greg Clayton882ef052011-02-08 19:10:53 +000095 m_file_desc = -1;
Greg Clayton60a63ae2011-02-08 17:49:02 +000096 }
97 return error;
98}
Greg Clayton882ef052011-02-08 19:10:53 +000099
100
101Error
102File::GetFileSpec (FileSpec &file_spec) const
103{
104 Error error;
105 if (IsValid ())
106 {
107 char path[PATH_MAX];
108 if (::fcntl(m_file_desc, F_GETPATH, path) == -1)
109 error.SetErrorToErrno();
110 else
111 file_spec.SetFile (path, false);
112 }
113 else
114 error.SetErrorString("invalid file handle");
115
116 if (error.Fail())
117 file_spec.Clear();
118 return error;
119}
120
121Error
122File::SeekFromStart (off_t& offset)
123{
124 Error error;
125 if (IsValid ())
126 {
127 offset = ::lseek (m_file_desc, offset, SEEK_SET);
128
129 if (offset == -1)
130 error.SetErrorToErrno();
131 }
132 else
133 {
134 error.SetErrorString("invalid file handle");
135 }
136 return error;
137}
138
139Error
140File::SeekFromCurrent (off_t& offset)
141{
142 Error error;
143 if (IsValid ())
144 {
145 offset = ::lseek (m_file_desc, offset, SEEK_CUR);
146
147 if (offset == -1)
148 error.SetErrorToErrno();
149 }
150 else
151 {
152 error.SetErrorString("invalid file handle");
153 }
154 return error;
155}
156
157Error
158File::SeekFromEnd (off_t& offset)
159{
160 Error error;
161 if (IsValid ())
162 {
163 offset = ::lseek (m_file_desc, offset, SEEK_CUR);
164
165 if (offset == -1)
166 error.SetErrorToErrno();
167 }
168 else
169 {
170 error.SetErrorString("invalid file handle");
171 }
172 return error;
173}
174
175Error
176File::Sync ()
177{
178 Error error;
179 if (IsValid ())
180 {
181 if (::fsync (m_file_desc) == -1)
182 error.SetErrorToErrno();
183 }
184 else
185 {
186 error.SetErrorString("invalid file handle");
187 }
188 return error;
189}
Greg Claytond35305a2011-02-08 19:54:44 +0000190
Greg Clayton60a63ae2011-02-08 17:49:02 +0000191Error
192File::Read (void *buf, size_t &num_bytes)
193{
194 Error error;
195 if (IsValid ())
196 {
197 ssize_t bytes_read = ::read (m_file_desc, buf, num_bytes);
198 if (bytes_read == -1)
199 {
200 error.SetErrorToErrno();
201 num_bytes = 0;
202 }
203 else
204 num_bytes = bytes_read;
205 }
206 else
207 {
208 num_bytes = 0;
209 error.SetErrorString("invalid file handle");
210 }
211 return error;
212}
213
214Error
215File::Write (const void *buf, size_t &num_bytes)
216{
217 Error error;
218 if (IsValid())
219 {
220 ssize_t bytes_written = ::write (m_file_desc, buf, num_bytes);
221 if (bytes_written == -1)
222 {
223 error.SetErrorToErrno();
224 num_bytes = 0;
225 }
226 else
227 num_bytes = bytes_written;
228 }
229 else
230 {
231 num_bytes = 0;
232 error.SetErrorString("invalid file handle");
233 }
234 return error;
235}
236
Greg Claytond35305a2011-02-08 19:54:44 +0000237
238Error
239File::Read (void *buf, size_t &num_bytes, off_t &offset)
240{
241 Error error;
242 if (IsValid ())
243 {
244 ssize_t bytes_read = ::pread (m_file_desc, buf, num_bytes, offset);
245 if (bytes_read < 0)
246 {
247 num_bytes = 0;
248 error.SetErrorToErrno();
249 }
250 else
251 {
252 offset += bytes_read;
253 num_bytes = bytes_read;
254 }
255 }
256 else
257 {
258 num_bytes = 0;
259 error.SetErrorString("invalid file handle");
260 }
261 return error;
262}
263
264Error
265File::Write (const void *buf, size_t &num_bytes, off_t &offset)
266{
267 Error error;
268 if (IsValid())
269 {
270 ssize_t bytes_written = ::pwrite (m_file_desc, buf, num_bytes, offset);
271 if (bytes_written < 0)
272 {
273 num_bytes = 0;
274 error.SetErrorToErrno();
275 }
276 else
277 {
278 offset += bytes_written;
279 num_bytes = bytes_written;
280 }
281 }
282 else
283 {
284 num_bytes = 0;
285 error.SetErrorString("invalid file handle");
286 }
287 return error;
288}
289
290
291