OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "platform/globals.h" | 5 #include "platform/globals.h" |
6 #if defined(HOST_OS_FUCHSIA) | 6 #if defined(HOST_OS_FUCHSIA) |
7 | 7 |
8 #include "bin/file.h" | 8 #include "bin/file.h" |
9 | 9 |
10 #include <errno.h> // NOLINT | 10 #include <errno.h> // NOLINT |
(...skipping 20 matching lines...) Expand all Loading... |
31 ~FileHandle() {} | 31 ~FileHandle() {} |
32 int fd() const { return fd_; } | 32 int fd() const { return fd_; } |
33 void set_fd(int fd) { fd_ = fd; } | 33 void set_fd(int fd) { fd_ = fd; } |
34 | 34 |
35 private: | 35 private: |
36 int fd_; | 36 int fd_; |
37 | 37 |
38 DISALLOW_COPY_AND_ASSIGN(FileHandle); | 38 DISALLOW_COPY_AND_ASSIGN(FileHandle); |
39 }; | 39 }; |
40 | 40 |
41 | |
42 File::~File() { | 41 File::~File() { |
43 if (!IsClosed()) { | 42 if (!IsClosed()) { |
44 Close(); | 43 Close(); |
45 } | 44 } |
46 delete handle_; | 45 delete handle_; |
47 } | 46 } |
48 | 47 |
49 | |
50 void File::Close() { | 48 void File::Close() { |
51 ASSERT(handle_->fd() >= 0); | 49 ASSERT(handle_->fd() >= 0); |
52 if (handle_->fd() == STDOUT_FILENO) { | 50 if (handle_->fd() == STDOUT_FILENO) { |
53 // If stdout, redirect fd to /dev/null. | 51 // If stdout, redirect fd to /dev/null. |
54 int null_fd = NO_RETRY_EXPECTED(open("/dev/null", O_WRONLY)); | 52 int null_fd = NO_RETRY_EXPECTED(open("/dev/null", O_WRONLY)); |
55 ASSERT(null_fd >= 0); | 53 ASSERT(null_fd >= 0); |
56 VOID_NO_RETRY_EXPECTED(dup2(null_fd, handle_->fd())); | 54 VOID_NO_RETRY_EXPECTED(dup2(null_fd, handle_->fd())); |
57 VOID_NO_RETRY_EXPECTED(close(null_fd)); | 55 VOID_NO_RETRY_EXPECTED(close(null_fd)); |
58 } else { | 56 } else { |
59 int err = NO_RETRY_EXPECTED(close(handle_->fd())); | 57 int err = NO_RETRY_EXPECTED(close(handle_->fd())); |
60 if (err != 0) { | 58 if (err != 0) { |
61 const int kBufferSize = 1024; | 59 const int kBufferSize = 1024; |
62 char error_buf[kBufferSize]; | 60 char error_buf[kBufferSize]; |
63 Log::PrintErr("%s\n", Utils::StrError(errno, error_buf, kBufferSize)); | 61 Log::PrintErr("%s\n", Utils::StrError(errno, error_buf, kBufferSize)); |
64 } | 62 } |
65 } | 63 } |
66 handle_->set_fd(kClosedFd); | 64 handle_->set_fd(kClosedFd); |
67 } | 65 } |
68 | 66 |
69 | |
70 intptr_t File::GetFD() { | 67 intptr_t File::GetFD() { |
71 return handle_->fd(); | 68 return handle_->fd(); |
72 } | 69 } |
73 | 70 |
74 | |
75 bool File::IsClosed() { | 71 bool File::IsClosed() { |
76 return handle_->fd() == kClosedFd; | 72 return handle_->fd() == kClosedFd; |
77 } | 73 } |
78 | 74 |
79 | |
80 MappedMemory* File::Map(MapType type, int64_t position, int64_t length) { | 75 MappedMemory* File::Map(MapType type, int64_t position, int64_t length) { |
81 UNIMPLEMENTED(); | 76 UNIMPLEMENTED(); |
82 return NULL; | 77 return NULL; |
83 } | 78 } |
84 | 79 |
85 | |
86 void MappedMemory::Unmap() { | 80 void MappedMemory::Unmap() { |
87 UNIMPLEMENTED(); | 81 UNIMPLEMENTED(); |
88 } | 82 } |
89 | 83 |
90 | |
91 int64_t File::Read(void* buffer, int64_t num_bytes) { | 84 int64_t File::Read(void* buffer, int64_t num_bytes) { |
92 ASSERT(handle_->fd() >= 0); | 85 ASSERT(handle_->fd() >= 0); |
93 return NO_RETRY_EXPECTED(read(handle_->fd(), buffer, num_bytes)); | 86 return NO_RETRY_EXPECTED(read(handle_->fd(), buffer, num_bytes)); |
94 } | 87 } |
95 | 88 |
96 | |
97 int64_t File::Write(const void* buffer, int64_t num_bytes) { | 89 int64_t File::Write(const void* buffer, int64_t num_bytes) { |
98 ASSERT(handle_->fd() >= 0); | 90 ASSERT(handle_->fd() >= 0); |
99 return NO_RETRY_EXPECTED(write(handle_->fd(), buffer, num_bytes)); | 91 return NO_RETRY_EXPECTED(write(handle_->fd(), buffer, num_bytes)); |
100 } | 92 } |
101 | 93 |
102 | |
103 bool File::VPrint(const char* format, va_list args) { | 94 bool File::VPrint(const char* format, va_list args) { |
104 // Measure. | 95 // Measure. |
105 va_list measure_args; | 96 va_list measure_args; |
106 va_copy(measure_args, args); | 97 va_copy(measure_args, args); |
107 intptr_t len = vsnprintf(NULL, 0, format, measure_args); | 98 intptr_t len = vsnprintf(NULL, 0, format, measure_args); |
108 va_end(measure_args); | 99 va_end(measure_args); |
109 | 100 |
110 char* buffer = reinterpret_cast<char*>(malloc(len + 1)); | 101 char* buffer = reinterpret_cast<char*>(malloc(len + 1)); |
111 | 102 |
112 // Print. | 103 // Print. |
113 va_list print_args; | 104 va_list print_args; |
114 va_copy(print_args, args); | 105 va_copy(print_args, args); |
115 vsnprintf(buffer, len + 1, format, print_args); | 106 vsnprintf(buffer, len + 1, format, print_args); |
116 va_end(print_args); | 107 va_end(print_args); |
117 | 108 |
118 bool result = WriteFully(buffer, len); | 109 bool result = WriteFully(buffer, len); |
119 free(buffer); | 110 free(buffer); |
120 return result; | 111 return result; |
121 } | 112 } |
122 | 113 |
123 | |
124 int64_t File::Position() { | 114 int64_t File::Position() { |
125 ASSERT(handle_->fd() >= 0); | 115 ASSERT(handle_->fd() >= 0); |
126 return NO_RETRY_EXPECTED(lseek(handle_->fd(), 0, SEEK_CUR)); | 116 return NO_RETRY_EXPECTED(lseek(handle_->fd(), 0, SEEK_CUR)); |
127 } | 117 } |
128 | 118 |
129 | |
130 bool File::SetPosition(int64_t position) { | 119 bool File::SetPosition(int64_t position) { |
131 ASSERT(handle_->fd() >= 0); | 120 ASSERT(handle_->fd() >= 0); |
132 return NO_RETRY_EXPECTED(lseek(handle_->fd(), position, SEEK_SET)) >= 0; | 121 return NO_RETRY_EXPECTED(lseek(handle_->fd(), position, SEEK_SET)) >= 0; |
133 } | 122 } |
134 | 123 |
135 | |
136 bool File::Truncate(int64_t length) { | 124 bool File::Truncate(int64_t length) { |
137 ASSERT(handle_->fd() >= 0); | 125 ASSERT(handle_->fd() >= 0); |
138 return NO_RETRY_EXPECTED(ftruncate(handle_->fd(), length) != -1); | 126 return NO_RETRY_EXPECTED(ftruncate(handle_->fd(), length) != -1); |
139 } | 127 } |
140 | 128 |
141 | |
142 bool File::Flush() { | 129 bool File::Flush() { |
143 ASSERT(handle_->fd() >= 0); | 130 ASSERT(handle_->fd() >= 0); |
144 return NO_RETRY_EXPECTED(fsync(handle_->fd())) != -1; | 131 return NO_RETRY_EXPECTED(fsync(handle_->fd())) != -1; |
145 } | 132 } |
146 | 133 |
147 | |
148 bool File::Lock(File::LockType lock, int64_t start, int64_t end) { | 134 bool File::Lock(File::LockType lock, int64_t start, int64_t end) { |
149 ASSERT(handle_->fd() >= 0); | 135 ASSERT(handle_->fd() >= 0); |
150 ASSERT((end == -1) || (end > start)); | 136 ASSERT((end == -1) || (end > start)); |
151 struct flock fl; | 137 struct flock fl; |
152 switch (lock) { | 138 switch (lock) { |
153 case File::kLockUnlock: | 139 case File::kLockUnlock: |
154 fl.l_type = F_UNLCK; | 140 fl.l_type = F_UNLCK; |
155 break; | 141 break; |
156 case File::kLockShared: | 142 case File::kLockShared: |
157 case File::kLockBlockingShared: | 143 case File::kLockBlockingShared: |
(...skipping 10 matching lines...) Expand all Loading... |
168 fl.l_start = start; | 154 fl.l_start = start; |
169 fl.l_len = end == -1 ? 0 : end - start; | 155 fl.l_len = end == -1 ? 0 : end - start; |
170 int cmd = F_SETLK; | 156 int cmd = F_SETLK; |
171 if ((lock == File::kLockBlockingShared) || | 157 if ((lock == File::kLockBlockingShared) || |
172 (lock == File::kLockBlockingExclusive)) { | 158 (lock == File::kLockBlockingExclusive)) { |
173 cmd = F_SETLKW; | 159 cmd = F_SETLKW; |
174 } | 160 } |
175 return NO_RETRY_EXPECTED(fcntl(handle_->fd(), cmd, &fl)) != -1; | 161 return NO_RETRY_EXPECTED(fcntl(handle_->fd(), cmd, &fl)) != -1; |
176 } | 162 } |
177 | 163 |
178 | |
179 int64_t File::Length() { | 164 int64_t File::Length() { |
180 ASSERT(handle_->fd() >= 0); | 165 ASSERT(handle_->fd() >= 0); |
181 struct stat st; | 166 struct stat st; |
182 if (NO_RETRY_EXPECTED(fstat(handle_->fd(), &st)) == 0) { | 167 if (NO_RETRY_EXPECTED(fstat(handle_->fd(), &st)) == 0) { |
183 return st.st_size; | 168 return st.st_size; |
184 } | 169 } |
185 return -1; | 170 return -1; |
186 } | 171 } |
187 | 172 |
188 | |
189 File* File::FileOpenW(const wchar_t* system_name, FileOpenMode mode) { | 173 File* File::FileOpenW(const wchar_t* system_name, FileOpenMode mode) { |
190 UNREACHABLE(); | 174 UNREACHABLE(); |
191 return NULL; | 175 return NULL; |
192 } | 176 } |
193 | 177 |
194 | |
195 File* File::Open(const char* name, FileOpenMode mode) { | 178 File* File::Open(const char* name, FileOpenMode mode) { |
196 // Report errors for non-regular files. | 179 // Report errors for non-regular files. |
197 struct stat st; | 180 struct stat st; |
198 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { | 181 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { |
199 if (S_ISDIR(st.st_mode)) { | 182 if (S_ISDIR(st.st_mode)) { |
200 errno = EISDIR; | 183 errno = EISDIR; |
201 return NULL; | 184 return NULL; |
202 } | 185 } |
203 } | 186 } |
204 int flags = O_RDONLY; | 187 int flags = O_RDONLY; |
(...skipping 16 matching lines...) Expand all Loading... |
221 if ((((mode & kWrite) != 0) && ((mode & kTruncate) == 0)) || | 204 if ((((mode & kWrite) != 0) && ((mode & kTruncate) == 0)) || |
222 (((mode & kWriteOnly) != 0) && ((mode & kTruncate) == 0))) { | 205 (((mode & kWriteOnly) != 0) && ((mode & kTruncate) == 0))) { |
223 int64_t position = lseek(fd, 0, SEEK_END); | 206 int64_t position = lseek(fd, 0, SEEK_END); |
224 if (position < 0) { | 207 if (position < 0) { |
225 return NULL; | 208 return NULL; |
226 } | 209 } |
227 } | 210 } |
228 return new File(new FileHandle(fd)); | 211 return new File(new FileHandle(fd)); |
229 } | 212 } |
230 | 213 |
231 | |
232 File* File::OpenStdio(int fd) { | 214 File* File::OpenStdio(int fd) { |
233 return ((fd < 0) || (2 < fd)) ? NULL : new File(new FileHandle(fd)); | 215 return ((fd < 0) || (2 < fd)) ? NULL : new File(new FileHandle(fd)); |
234 } | 216 } |
235 | 217 |
236 | |
237 bool File::Exists(const char* name) { | 218 bool File::Exists(const char* name) { |
238 struct stat64 st; | 219 struct stat64 st; |
239 if (NO_RETRY_EXPECTED(stat64(name, &st)) == 0) { | 220 if (NO_RETRY_EXPECTED(stat64(name, &st)) == 0) { |
240 // Everything but a directory and a link is a file to Dart. | 221 // Everything but a directory and a link is a file to Dart. |
241 return !S_ISDIR(st.st_mode) && !S_ISLNK(st.st_mode); | 222 return !S_ISDIR(st.st_mode) && !S_ISLNK(st.st_mode); |
242 } else { | 223 } else { |
243 return false; | 224 return false; |
244 } | 225 } |
245 } | 226 } |
246 | 227 |
247 | |
248 bool File::Create(const char* name) { | 228 bool File::Create(const char* name) { |
249 int fd = | 229 int fd = |
250 NO_RETRY_EXPECTED(open64(name, O_RDONLY | O_CREAT | O_CLOEXEC, 0666)); | 230 NO_RETRY_EXPECTED(open64(name, O_RDONLY | O_CREAT | O_CLOEXEC, 0666)); |
251 if (fd < 0) { | 231 if (fd < 0) { |
252 return false; | 232 return false; |
253 } | 233 } |
254 // File.create returns a File, so we shouldn't be giving the illusion that the | 234 // File.create returns a File, so we shouldn't be giving the illusion that the |
255 // call has created a file or that a file already exists if there is already | 235 // call has created a file or that a file already exists if there is already |
256 // an entity at the same path that is a directory or a link. | 236 // an entity at the same path that is a directory or a link. |
257 bool is_file = true; | 237 bool is_file = true; |
258 struct stat64 st; | 238 struct stat64 st; |
259 if (NO_RETRY_EXPECTED(fstat64(fd, &st)) == 0) { | 239 if (NO_RETRY_EXPECTED(fstat64(fd, &st)) == 0) { |
260 if (S_ISDIR(st.st_mode)) { | 240 if (S_ISDIR(st.st_mode)) { |
261 errno = EISDIR; | 241 errno = EISDIR; |
262 is_file = false; | 242 is_file = false; |
263 } else if (S_ISLNK(st.st_mode)) { | 243 } else if (S_ISLNK(st.st_mode)) { |
264 errno = ENOENT; | 244 errno = ENOENT; |
265 is_file = false; | 245 is_file = false; |
266 } | 246 } |
267 } | 247 } |
268 FDUtils::SaveErrorAndClose(fd); | 248 FDUtils::SaveErrorAndClose(fd); |
269 return is_file; | 249 return is_file; |
270 } | 250 } |
271 | 251 |
272 | |
273 bool File::CreateLink(const char* name, const char* target) { | 252 bool File::CreateLink(const char* name, const char* target) { |
274 return NO_RETRY_EXPECTED(symlink(target, name)) == 0; | 253 return NO_RETRY_EXPECTED(symlink(target, name)) == 0; |
275 } | 254 } |
276 | 255 |
277 | |
278 File::Type File::GetType(const char* pathname, bool follow_links) { | 256 File::Type File::GetType(const char* pathname, bool follow_links) { |
279 struct stat entry_info; | 257 struct stat entry_info; |
280 int stat_success; | 258 int stat_success; |
281 if (follow_links) { | 259 if (follow_links) { |
282 stat_success = NO_RETRY_EXPECTED(stat(pathname, &entry_info)); | 260 stat_success = NO_RETRY_EXPECTED(stat(pathname, &entry_info)); |
283 } else { | 261 } else { |
284 stat_success = NO_RETRY_EXPECTED(lstat(pathname, &entry_info)); | 262 stat_success = NO_RETRY_EXPECTED(lstat(pathname, &entry_info)); |
285 } | 263 } |
286 if (stat_success == -1) { | 264 if (stat_success == -1) { |
287 return File::kDoesNotExist; | 265 return File::kDoesNotExist; |
288 } | 266 } |
289 if (S_ISDIR(entry_info.st_mode)) { | 267 if (S_ISDIR(entry_info.st_mode)) { |
290 return File::kIsDirectory; | 268 return File::kIsDirectory; |
291 } | 269 } |
292 if (S_ISREG(entry_info.st_mode)) { | 270 if (S_ISREG(entry_info.st_mode)) { |
293 return File::kIsFile; | 271 return File::kIsFile; |
294 } | 272 } |
295 if (S_ISLNK(entry_info.st_mode)) { | 273 if (S_ISLNK(entry_info.st_mode)) { |
296 return File::kIsLink; | 274 return File::kIsLink; |
297 } | 275 } |
298 return File::kDoesNotExist; | 276 return File::kDoesNotExist; |
299 } | 277 } |
300 | 278 |
301 | |
302 static bool CheckTypeAndSetErrno(const char* name, | 279 static bool CheckTypeAndSetErrno(const char* name, |
303 File::Type expected, | 280 File::Type expected, |
304 bool follow_links) { | 281 bool follow_links) { |
305 File::Type actual = File::GetType(name, follow_links); | 282 File::Type actual = File::GetType(name, follow_links); |
306 if (actual == expected) { | 283 if (actual == expected) { |
307 return true; | 284 return true; |
308 } | 285 } |
309 switch (actual) { | 286 switch (actual) { |
310 case File::kIsDirectory: | 287 case File::kIsDirectory: |
311 errno = EISDIR; | 288 errno = EISDIR; |
312 break; | 289 break; |
313 case File::kDoesNotExist: | 290 case File::kDoesNotExist: |
314 errno = ENOENT; | 291 errno = ENOENT; |
315 break; | 292 break; |
316 default: | 293 default: |
317 errno = EINVAL; | 294 errno = EINVAL; |
318 break; | 295 break; |
319 } | 296 } |
320 return false; | 297 return false; |
321 } | 298 } |
322 | 299 |
323 | |
324 bool File::Delete(const char* name) { | 300 bool File::Delete(const char* name) { |
325 return CheckTypeAndSetErrno(name, kIsFile, true) && | 301 return CheckTypeAndSetErrno(name, kIsFile, true) && |
326 (NO_RETRY_EXPECTED(unlink(name)) == 0); | 302 (NO_RETRY_EXPECTED(unlink(name)) == 0); |
327 } | 303 } |
328 | 304 |
329 | |
330 bool File::DeleteLink(const char* name) { | 305 bool File::DeleteLink(const char* name) { |
331 return CheckTypeAndSetErrno(name, kIsLink, false) && | 306 return CheckTypeAndSetErrno(name, kIsLink, false) && |
332 (NO_RETRY_EXPECTED(unlink(name)) == 0); | 307 (NO_RETRY_EXPECTED(unlink(name)) == 0); |
333 } | 308 } |
334 | 309 |
335 | |
336 bool File::Rename(const char* old_path, const char* new_path) { | 310 bool File::Rename(const char* old_path, const char* new_path) { |
337 return CheckTypeAndSetErrno(old_path, kIsFile, true) && | 311 return CheckTypeAndSetErrno(old_path, kIsFile, true) && |
338 (NO_RETRY_EXPECTED(rename(old_path, new_path)) == 0); | 312 (NO_RETRY_EXPECTED(rename(old_path, new_path)) == 0); |
339 } | 313 } |
340 | 314 |
341 | |
342 bool File::RenameLink(const char* old_path, const char* new_path) { | 315 bool File::RenameLink(const char* old_path, const char* new_path) { |
343 return CheckTypeAndSetErrno(old_path, kIsLink, false) && | 316 return CheckTypeAndSetErrno(old_path, kIsLink, false) && |
344 (NO_RETRY_EXPECTED(rename(old_path, new_path)) == 0); | 317 (NO_RETRY_EXPECTED(rename(old_path, new_path)) == 0); |
345 } | 318 } |
346 | 319 |
347 | |
348 bool File::Copy(const char* old_path, const char* new_path) { | 320 bool File::Copy(const char* old_path, const char* new_path) { |
349 if (!CheckTypeAndSetErrno(old_path, kIsFile, true)) { | 321 if (!CheckTypeAndSetErrno(old_path, kIsFile, true)) { |
350 return false; | 322 return false; |
351 } | 323 } |
352 struct stat64 st; | 324 struct stat64 st; |
353 if (NO_RETRY_EXPECTED(stat64(old_path, &st)) != 0) { | 325 if (NO_RETRY_EXPECTED(stat64(old_path, &st)) != 0) { |
354 return false; | 326 return false; |
355 } | 327 } |
356 int old_fd = NO_RETRY_EXPECTED(open64(old_path, O_RDONLY | O_CLOEXEC)); | 328 int old_fd = NO_RETRY_EXPECTED(open64(old_path, O_RDONLY | O_CLOEXEC)); |
357 if (old_fd < 0) { | 329 if (old_fd < 0) { |
(...skipping 20 matching lines...) Expand all Loading... |
378 FDUtils::SaveErrorAndClose(new_fd); | 350 FDUtils::SaveErrorAndClose(new_fd); |
379 if (result < 0) { | 351 if (result < 0) { |
380 int e = errno; | 352 int e = errno; |
381 VOID_NO_RETRY_EXPECTED(unlink(new_path)); | 353 VOID_NO_RETRY_EXPECTED(unlink(new_path)); |
382 errno = e; | 354 errno = e; |
383 return false; | 355 return false; |
384 } | 356 } |
385 return true; | 357 return true; |
386 } | 358 } |
387 | 359 |
388 | |
389 static bool StatHelper(const char* name, struct stat64* st) { | 360 static bool StatHelper(const char* name, struct stat64* st) { |
390 if (NO_RETRY_EXPECTED(stat64(name, st)) != 0) { | 361 if (NO_RETRY_EXPECTED(stat64(name, st)) != 0) { |
391 return false; | 362 return false; |
392 } | 363 } |
393 // Signal an error if it's a directory. | 364 // Signal an error if it's a directory. |
394 if (S_ISDIR(st->st_mode)) { | 365 if (S_ISDIR(st->st_mode)) { |
395 errno = EISDIR; | 366 errno = EISDIR; |
396 return false; | 367 return false; |
397 } | 368 } |
398 // Otherwise assume the caller knows what it's doing. | 369 // Otherwise assume the caller knows what it's doing. |
399 return true; | 370 return true; |
400 } | 371 } |
401 | 372 |
402 | |
403 int64_t File::LengthFromPath(const char* name) { | 373 int64_t File::LengthFromPath(const char* name) { |
404 struct stat64 st; | 374 struct stat64 st; |
405 if (!StatHelper(name, &st)) { | 375 if (!StatHelper(name, &st)) { |
406 return -1; | 376 return -1; |
407 } | 377 } |
408 return st.st_size; | 378 return st.st_size; |
409 } | 379 } |
410 | 380 |
411 | |
412 void File::Stat(const char* name, int64_t* data) { | 381 void File::Stat(const char* name, int64_t* data) { |
413 struct stat st; | 382 struct stat st; |
414 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { | 383 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { |
415 if (S_ISREG(st.st_mode)) { | 384 if (S_ISREG(st.st_mode)) { |
416 data[kType] = kIsFile; | 385 data[kType] = kIsFile; |
417 } else if (S_ISDIR(st.st_mode)) { | 386 } else if (S_ISDIR(st.st_mode)) { |
418 data[kType] = kIsDirectory; | 387 data[kType] = kIsDirectory; |
419 } else if (S_ISLNK(st.st_mode)) { | 388 } else if (S_ISLNK(st.st_mode)) { |
420 data[kType] = kIsLink; | 389 data[kType] = kIsLink; |
421 } else { | 390 } else { |
422 data[kType] = kDoesNotExist; | 391 data[kType] = kDoesNotExist; |
423 } | 392 } |
424 data[kCreatedTime] = static_cast<int64_t>(st.st_ctime) * 1000; | 393 data[kCreatedTime] = static_cast<int64_t>(st.st_ctime) * 1000; |
425 data[kModifiedTime] = static_cast<int64_t>(st.st_mtime) * 1000; | 394 data[kModifiedTime] = static_cast<int64_t>(st.st_mtime) * 1000; |
426 data[kAccessedTime] = static_cast<int64_t>(st.st_atime) * 1000; | 395 data[kAccessedTime] = static_cast<int64_t>(st.st_atime) * 1000; |
427 data[kMode] = st.st_mode; | 396 data[kMode] = st.st_mode; |
428 data[kSize] = st.st_size; | 397 data[kSize] = st.st_size; |
429 } else { | 398 } else { |
430 data[kType] = kDoesNotExist; | 399 data[kType] = kDoesNotExist; |
431 } | 400 } |
432 } | 401 } |
433 | 402 |
434 | |
435 time_t File::LastModified(const char* name) { | 403 time_t File::LastModified(const char* name) { |
436 struct stat st; | 404 struct stat st; |
437 if (!StatHelper(name, &st)) { | 405 if (!StatHelper(name, &st)) { |
438 return -1; | 406 return -1; |
439 } | 407 } |
440 return st.st_mtime; | 408 return st.st_mtime; |
441 } | 409 } |
442 | 410 |
443 | |
444 time_t File::LastAccessed(const char* name) { | 411 time_t File::LastAccessed(const char* name) { |
445 struct stat st; | 412 struct stat st; |
446 if (!StatHelper(name, &st)) { | 413 if (!StatHelper(name, &st)) { |
447 return -1; | 414 return -1; |
448 } | 415 } |
449 return st.st_atime; | 416 return st.st_atime; |
450 } | 417 } |
451 | 418 |
452 | |
453 bool File::SetLastAccessed(const char* name, int64_t millis) { | 419 bool File::SetLastAccessed(const char* name, int64_t millis) { |
454 // First get the current times. | 420 // First get the current times. |
455 struct stat st; | 421 struct stat st; |
456 if (!StatHelper(name, &st)) { | 422 if (!StatHelper(name, &st)) { |
457 return false; | 423 return false; |
458 } | 424 } |
459 | 425 |
460 // Set the new time: | 426 // Set the new time: |
461 struct utimbuf times; | 427 struct utimbuf times; |
462 times.actime = millis / kMillisecondsPerSecond; | 428 times.actime = millis / kMillisecondsPerSecond; |
463 times.modtime = st.st_mtime; | 429 times.modtime = st.st_mtime; |
464 return utime(name, ×) == 0; | 430 return utime(name, ×) == 0; |
465 } | 431 } |
466 | 432 |
467 | |
468 bool File::SetLastModified(const char* name, int64_t millis) { | 433 bool File::SetLastModified(const char* name, int64_t millis) { |
469 // First get the current times. | 434 // First get the current times. |
470 struct stat st; | 435 struct stat st; |
471 if (!StatHelper(name, &st)) { | 436 if (!StatHelper(name, &st)) { |
472 return false; | 437 return false; |
473 } | 438 } |
474 | 439 |
475 // Set the new time: | 440 // Set the new time: |
476 struct utimbuf times; | 441 struct utimbuf times; |
477 times.actime = st.st_atime; | 442 times.actime = st.st_atime; |
478 times.modtime = millis / kMillisecondsPerSecond; | 443 times.modtime = millis / kMillisecondsPerSecond; |
479 return utime(name, ×) == 0; | 444 return utime(name, ×) == 0; |
480 } | 445 } |
481 | 446 |
482 | |
483 const char* File::LinkTarget(const char* pathname) { | 447 const char* File::LinkTarget(const char* pathname) { |
484 struct stat link_stats; | 448 struct stat link_stats; |
485 if (lstat(pathname, &link_stats) != 0) { | 449 if (lstat(pathname, &link_stats) != 0) { |
486 return NULL; | 450 return NULL; |
487 } | 451 } |
488 if (!S_ISLNK(link_stats.st_mode)) { | 452 if (!S_ISLNK(link_stats.st_mode)) { |
489 errno = ENOENT; | 453 errno = ENOENT; |
490 return NULL; | 454 return NULL; |
491 } | 455 } |
492 size_t target_size = link_stats.st_size; | 456 size_t target_size = link_stats.st_size; |
493 char* target_name = DartUtils::ScopedCString(target_size + 1); | 457 char* target_name = DartUtils::ScopedCString(target_size + 1); |
494 ASSERT(target_name != NULL); | 458 ASSERT(target_name != NULL); |
495 size_t read_size = readlink(pathname, target_name, target_size + 1); | 459 size_t read_size = readlink(pathname, target_name, target_size + 1); |
496 if (read_size != target_size) { | 460 if (read_size != target_size) { |
497 return NULL; | 461 return NULL; |
498 } | 462 } |
499 target_name[target_size] = '\0'; | 463 target_name[target_size] = '\0'; |
500 return target_name; | 464 return target_name; |
501 } | 465 } |
502 | 466 |
503 | |
504 bool File::IsAbsolutePath(const char* pathname) { | 467 bool File::IsAbsolutePath(const char* pathname) { |
505 return ((pathname != NULL) && (pathname[0] == '/')); | 468 return ((pathname != NULL) && (pathname[0] == '/')); |
506 } | 469 } |
507 | 470 |
508 | |
509 const char* File::GetCanonicalPath(const char* pathname) { | 471 const char* File::GetCanonicalPath(const char* pathname) { |
510 char* abs_path = NULL; | 472 char* abs_path = NULL; |
511 if (pathname != NULL) { | 473 if (pathname != NULL) { |
512 char* resolved_path = DartUtils::ScopedCString(PATH_MAX + 1); | 474 char* resolved_path = DartUtils::ScopedCString(PATH_MAX + 1); |
513 ASSERT(resolved_path != NULL); | 475 ASSERT(resolved_path != NULL); |
514 abs_path = realpath(pathname, resolved_path); | 476 abs_path = realpath(pathname, resolved_path); |
515 ASSERT((abs_path == NULL) || IsAbsolutePath(abs_path)); | 477 ASSERT((abs_path == NULL) || IsAbsolutePath(abs_path)); |
516 ASSERT((abs_path == NULL) || (abs_path == resolved_path)); | 478 ASSERT((abs_path == NULL) || (abs_path == resolved_path)); |
517 } | 479 } |
518 return abs_path; | 480 return abs_path; |
519 } | 481 } |
520 | 482 |
521 | |
522 const char* File::PathSeparator() { | 483 const char* File::PathSeparator() { |
523 return "/"; | 484 return "/"; |
524 } | 485 } |
525 | 486 |
526 | |
527 const char* File::StringEscapedPathSeparator() { | 487 const char* File::StringEscapedPathSeparator() { |
528 return "/"; | 488 return "/"; |
529 } | 489 } |
530 | 490 |
531 | |
532 File::StdioHandleType File::GetStdioHandleType(int fd) { | 491 File::StdioHandleType File::GetStdioHandleType(int fd) { |
533 ASSERT((0 <= fd) && (fd <= 2)); | 492 ASSERT((0 <= fd) && (fd <= 2)); |
534 struct stat buf; | 493 struct stat buf; |
535 int result = fstat(fd, &buf); | 494 int result = fstat(fd, &buf); |
536 if (result == -1) { | 495 if (result == -1) { |
537 return kOther; | 496 return kOther; |
538 } | 497 } |
539 if (S_ISCHR(buf.st_mode)) { | 498 if (S_ISCHR(buf.st_mode)) { |
540 return kTerminal; | 499 return kTerminal; |
541 } | 500 } |
542 if (S_ISFIFO(buf.st_mode)) { | 501 if (S_ISFIFO(buf.st_mode)) { |
543 return kPipe; | 502 return kPipe; |
544 } | 503 } |
545 if (S_ISSOCK(buf.st_mode)) { | 504 if (S_ISSOCK(buf.st_mode)) { |
546 return kSocket; | 505 return kSocket; |
547 } | 506 } |
548 if (S_ISREG(buf.st_mode)) { | 507 if (S_ISREG(buf.st_mode)) { |
549 return kFile; | 508 return kFile; |
550 } | 509 } |
551 return kOther; | 510 return kOther; |
552 } | 511 } |
553 | 512 |
554 | |
555 File::Identical File::AreIdentical(const char* file_1, const char* file_2) { | 513 File::Identical File::AreIdentical(const char* file_1, const char* file_2) { |
556 struct stat file_1_info; | 514 struct stat file_1_info; |
557 struct stat file_2_info; | 515 struct stat file_2_info; |
558 if ((NO_RETRY_EXPECTED(lstat(file_1, &file_1_info)) == -1) || | 516 if ((NO_RETRY_EXPECTED(lstat(file_1, &file_1_info)) == -1) || |
559 (NO_RETRY_EXPECTED(lstat(file_2, &file_2_info)) == -1)) { | 517 (NO_RETRY_EXPECTED(lstat(file_2, &file_2_info)) == -1)) { |
560 return File::kError; | 518 return File::kError; |
561 } | 519 } |
562 return ((file_1_info.st_ino == file_2_info.st_ino) && | 520 return ((file_1_info.st_ino == file_2_info.st_ino) && |
563 (file_1_info.st_dev == file_2_info.st_dev)) | 521 (file_1_info.st_dev == file_2_info.st_dev)) |
564 ? File::kIdentical | 522 ? File::kIdentical |
565 : File::kDifferent; | 523 : File::kDifferent; |
566 } | 524 } |
567 | 525 |
568 } // namespace bin | 526 } // namespace bin |
569 } // namespace dart | 527 } // namespace dart |
570 | 528 |
571 #endif // defined(HOST_OS_FUCHSIA) | 529 #endif // defined(HOST_OS_FUCHSIA) |
OLD | NEW |