Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(728)

Side by Side Diff: runtime/bin/file_linux.cc

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

Powered by Google App Engine
This is Rietveld 408576698