Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
file_macos.cc
Go to the documentation of this 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
3// BSD-style license that can be found in the LICENSE file.
4
5#include "platform/globals.h"
6#if defined(DART_HOST_OS_MACOS)
7
8#include "bin/file.h"
9
10#include <copyfile.h> // NOLINT
11#include <errno.h> // NOLINT
12#include <fcntl.h> // NOLINT
13#include <libgen.h> // NOLINT
14#include <limits.h> // NOLINT
15#include <sys/mman.h> // NOLINT
16#include <sys/stat.h> // NOLINT
17#include <unistd.h> // NOLINT
18#include <utime.h> // NOLINT
19
20#include "bin/builtin.h"
21#include "bin/fdutils.h"
22#include "bin/namespace.h"
24#include "platform/syslog.h"
25#include "platform/utils.h"
26
27namespace dart {
28namespace bin {
29
30class FileHandle {
31 public:
32 explicit FileHandle(int fd) : fd_(fd) {}
33 ~FileHandle() {}
34 int fd() const { return fd_; }
35 void set_fd(int fd) { fd_ = fd; }
36
37 private:
38 int fd_;
39
40 DISALLOW_COPY_AND_ASSIGN(FileHandle);
41};
42
43File::~File() {
44 if (!IsClosed() && handle_->fd() != STDOUT_FILENO &&
45 handle_->fd() != STDERR_FILENO) {
46 Close();
47 }
48 delete handle_;
49}
50
51void File::Close() {
52 ASSERT(handle_->fd() >= 0);
53 if (handle_->fd() == STDOUT_FILENO) {
54 // If stdout, redirect fd to /dev/null.
55 intptr_t null_fd = TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY));
56 ASSERT(null_fd >= 0);
57 VOID_TEMP_FAILURE_RETRY(dup2(null_fd, handle_->fd()));
58 close(null_fd);
59 } else {
60 intptr_t err = close(handle_->fd());
61 if (err != 0) {
62 const int kBufferSize = 1024;
63 char error_message[kBufferSize];
64 Utils::StrError(errno, error_message, kBufferSize);
65 Syslog::PrintErr("%s\n", error_message);
66 }
67 }
68 handle_->set_fd(kClosedFd);
69}
70
71intptr_t File::GetFD() {
72 return handle_->fd();
73}
74
75bool File::IsClosed() {
76 return handle_->fd() == kClosedFd;
77}
78
79MappedMemory* File::Map(MapType type,
80 int64_t position,
81 int64_t length,
82 void* start) {
83 ASSERT(handle_->fd() >= 0);
84 ASSERT(length > 0);
85 void* hint = nullptr;
86 int prot = PROT_NONE;
87 int map_flags = MAP_PRIVATE;
88 switch (type) {
89 case kReadOnly:
90 prot = PROT_READ;
91 map_flags |= MAP_RESILIENT_CODESIGN;
92 break;
93 case kReadExecute:
94 // Try to allocate near the VM's binary.
95 hint = reinterpret_cast<void*>(&Dart_Initialize);
96 prot = PROT_READ | PROT_EXEC;
97 if (IsAtLeastOS10_14()) {
98 map_flags |= (MAP_JIT | MAP_ANONYMOUS);
99 }
100 break;
101 case kReadWrite:
102 prot = PROT_READ | PROT_WRITE;
103 break;
104 }
105 if (start != nullptr) {
106 hint = start;
107 map_flags |= MAP_FIXED;
108 }
109 void* addr = start;
110 if ((type == kReadExecute) && IsAtLeastOS10_14()) {
111 // Due to codesigning restrictions, we cannot map the file as executable
112 // directly. We must first copy it into an anonymous mapping and then mark
113 // the mapping as executable.
114 if (addr == nullptr) {
115 addr = mmap(hint, length, (PROT_READ | PROT_WRITE), map_flags, -1, 0);
116 if (addr == MAP_FAILED) {
117 Syslog::PrintErr("mmap failed %s\n", strerror(errno));
118 return nullptr;
119 }
120 }
121
122 const int64_t remaining_length = Length() - position;
123 SetPosition(position);
124 if (!ReadFully(addr, Utils::Minimum(length, remaining_length))) {
125 Syslog::PrintErr("ReadFully failed\n");
126 if (start == nullptr) {
127 munmap(addr, length);
128 }
129 return nullptr;
130 }
131
132 // If the requested mapping is larger than the file size, we should fill the
133 // extra memory with zeros.
134 if (length > remaining_length) {
135 memset(reinterpret_cast<uint8_t*>(addr) + remaining_length, 0,
136 length - remaining_length);
137 }
138
139 if (mprotect(addr, length, prot) != 0) {
140 Syslog::PrintErr("mprotect failed %s\n", strerror(errno));
141 if (start == nullptr) {
142 munmap(addr, length);
143 }
144 return nullptr;
145 }
146 } else {
147 addr = mmap(hint, length, prot, map_flags, handle_->fd(), position);
148 if (addr == MAP_FAILED) {
149 Syslog::PrintErr("mmap failed %s\n", strerror(errno));
150 return nullptr;
151 }
152 }
153 return new MappedMemory(addr, length, /*should_unmap=*/start == nullptr);
154}
155
156void MappedMemory::Unmap() {
157 int result = munmap(address_, size_);
158 ASSERT(result == 0);
159 address_ = nullptr;
160 size_ = 0;
161}
162
163int64_t File::Read(void* buffer, int64_t num_bytes) {
164 ASSERT(handle_->fd() >= 0);
165 return TEMP_FAILURE_RETRY(read(handle_->fd(), buffer, num_bytes));
166}
167
168int64_t File::Write(const void* buffer, int64_t num_bytes) {
169 // Invalid argument error will pop if num_bytes exceeds the limit.
170 ASSERT(handle_->fd() >= 0 && num_bytes <= kMaxInt32);
171 return TEMP_FAILURE_RETRY(write(handle_->fd(), buffer, num_bytes));
172}
173
174bool File::VPrint(const char* format, va_list args) {
175 // Measure.
176 va_list measure_args;
177 va_copy(measure_args, args);
178 intptr_t len = Utils::VSNPrint(nullptr, 0, format, measure_args);
179 va_end(measure_args);
180
181 char* buffer = reinterpret_cast<char*>(malloc(len + 1));
182
183 // Print.
184 va_list print_args;
185 va_copy(print_args, args);
186 Utils::VSNPrint(buffer, len + 1, format, print_args);
187 va_end(print_args);
188
189 bool result = WriteFully(buffer, len);
190 free(buffer);
191 return result;
192}
193
194int64_t File::Position() {
195 ASSERT(handle_->fd() >= 0);
196 return lseek(handle_->fd(), 0, SEEK_CUR);
197}
198
199bool File::SetPosition(int64_t position) {
200 ASSERT(handle_->fd() >= 0);
201 return lseek(handle_->fd(), position, SEEK_SET) >= 0;
202}
203
204bool File::Truncate(int64_t length) {
205 ASSERT(handle_->fd() >= 0);
206 return TEMP_FAILURE_RETRY(ftruncate(handle_->fd(), length)) != -1;
207}
208
209bool File::Flush() {
210 ASSERT(handle_->fd() >= 0);
211 return NO_RETRY_EXPECTED(fsync(handle_->fd())) != -1;
212}
213
214bool File::Lock(File::LockType lock, int64_t start, int64_t end) {
215 ASSERT(handle_->fd() >= 0);
216 ASSERT((end == -1) || (end > start));
217 struct flock fl;
218 switch (lock) {
220 fl.l_type = F_UNLCK;
221 break;
224 fl.l_type = F_RDLCK;
225 break;
228 fl.l_type = F_WRLCK;
229 break;
230 default:
231 return false;
232 }
233 fl.l_whence = SEEK_SET;
234 fl.l_start = start;
235 fl.l_len = end == -1 ? 0 : end - start;
236 int cmd = F_SETLK;
237 if ((lock == File::kLockBlockingShared) ||
239 cmd = F_SETLKW;
240 }
241 return TEMP_FAILURE_RETRY(fcntl(handle_->fd(), cmd, &fl)) != -1;
242}
243
244int64_t File::Length() {
245 ASSERT(handle_->fd() >= 0);
246 struct stat st;
247 if (NO_RETRY_EXPECTED(fstat(handle_->fd(), &st)) == 0) {
248 return st.st_size;
249 }
250 return -1;
251}
252
253File* File::FileOpenW(const wchar_t* system_name, FileOpenMode mode) {
254 UNREACHABLE();
255 return nullptr;
256}
257
258File* File::OpenFD(int fd) {
259 return new File(new FileHandle(fd));
260}
261
262File* File::Open(Namespace* namespc, const char* name, FileOpenMode mode) {
263 // Report errors for non-regular files.
264 struct stat st;
265 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) {
266 // Only accept regular files, character devices, and pipes.
267 if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode) && !S_ISFIFO(st.st_mode)) {
268 errno = (S_ISDIR(st.st_mode)) ? EISDIR : ENOENT;
269 return nullptr;
270 }
271 }
272 int flags = O_RDONLY;
273 if ((mode & kWrite) != 0) {
274 ASSERT((mode & kWriteOnly) == 0);
275 flags = (O_RDWR | O_CREAT);
276 }
277 if ((mode & kWriteOnly) != 0) {
278 ASSERT((mode & kWrite) == 0);
279 flags = (O_WRONLY | O_CREAT);
280 }
281 if ((mode & kTruncate) != 0) {
282 flags = flags | O_TRUNC;
283 }
284 int fd = TEMP_FAILURE_RETRY(open(name, flags, 0666));
285 if (fd < 0) {
286 return nullptr;
287 }
289 if ((((mode & kWrite) != 0) && ((mode & kTruncate) == 0)) ||
290 (((mode & kWriteOnly) != 0) && ((mode & kTruncate) == 0))) {
291 int64_t position = lseek(fd, 0, SEEK_END);
292 if (position < 0) {
293 return nullptr;
294 }
295 }
296 return new File(new FileHandle(fd));
297}
298
300 const char* path =
301 (strlen(uri) >= 8 && strncmp(uri, "file:///", 8) == 0) ? uri + 7 : uri;
302 UriDecoder uri_decoder(path);
303 if (uri_decoder.decoded() == nullptr) {
304 errno = EINVAL;
305 return Utils::CreateCStringUniquePtr(nullptr);
306 }
307 return Utils::CreateCStringUniquePtr(strdup(uri_decoder.decoded()));
308}
309
310File* File::OpenUri(Namespace* namespc, const char* uri, FileOpenMode mode) {
311 auto path = UriToPath(uri);
312 if (path == nullptr) {
313 return nullptr;
314 }
315 return File::Open(namespc, path.get(), mode);
316}
317
318File* File::OpenStdio(int fd) {
319 return new File(new FileHandle(fd));
320}
321
322bool File::Exists(Namespace* namespc, const char* name) {
323 struct stat st;
324 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) {
325 // Everything but a directory and a link is a file to Dart.
326 return !S_ISDIR(st.st_mode) && !S_ISLNK(st.st_mode);
327 } else {
328 return false;
329 }
330}
331
332bool File::ExistsUri(Namespace* namespc, const char* uri) {
333 auto path = UriToPath(uri);
334 if (path == nullptr) {
335 return false;
336 }
337 return File::Exists(namespc, path.get());
338}
339
340bool File::Create(Namespace* namespc, const char* name, bool exclusive) {
341 int flags = O_RDONLY | O_CREAT;
342 if (exclusive) {
343 flags |= O_EXCL;
344 }
345 int fd = TEMP_FAILURE_RETRY(open(name, flags, 0666));
346 if (fd < 0) {
347 return false;
348 }
349 // File.create returns a File, so we shouldn't be giving the illusion that the
350 // call has created a file or that a file already exists if there is already
351 // an entity at the same path that is a directory or a link.
352 bool is_file = true;
353 struct stat st;
354 if (NO_RETRY_EXPECTED(fstat(fd, &st)) == 0) {
355 if (S_ISDIR(st.st_mode)) {
356 errno = EISDIR;
357 is_file = false;
358 } else if (S_ISLNK(st.st_mode)) {
359 errno = ENOENT;
360 is_file = false;
361 }
362 }
364 return is_file;
365}
366
367bool File::CreateLink(Namespace* namespc,
368 const char* name,
369 const char* target) {
370 int status = NO_RETRY_EXPECTED(symlink(target, name));
371 return (status == 0);
372}
373
374bool File::CreatePipe(Namespace* namespc, File** readPipe, File** writePipe) {
375 int pipe_fds[2];
376 int status = NO_RETRY_EXPECTED(pipe(pipe_fds));
377 if (status != 0) {
378 return false;
379 }
380 *readPipe = OpenFD(pipe_fds[0]);
381 *writePipe = OpenFD(pipe_fds[1]);
382 return true;
383}
384
385File::Type File::GetType(Namespace* namespc,
386 const char* pathname,
387 bool follow_links) {
388 struct stat entry_info;
389 int stat_success;
390 if (follow_links) {
391 stat_success = NO_RETRY_EXPECTED(stat(pathname, &entry_info));
392 } else {
393 stat_success = NO_RETRY_EXPECTED(lstat(pathname, &entry_info));
394 }
395 if (stat_success == -1) {
396 return File::kDoesNotExist;
397 }
398 if (S_ISDIR(entry_info.st_mode)) {
399 return File::kIsDirectory;
400 }
401 if (S_ISREG(entry_info.st_mode)) {
402 return File::kIsFile;
403 }
404 if (S_ISLNK(entry_info.st_mode)) {
405 return File::kIsLink;
406 }
407 if (S_ISSOCK(entry_info.st_mode)) {
408 return File::kIsSock;
409 }
410 if (S_ISFIFO(entry_info.st_mode)) {
411 return File::kIsPipe;
412 }
413 return File::kDoesNotExist;
414}
415
416static void SetErrno(File::Type type) {
417 switch (type) {
419 errno = EISDIR;
420 break;
422 errno = ENOENT;
423 break;
424 default:
425 errno = EINVAL;
426 break;
427 }
428}
429
430static bool CheckTypeAndSetErrno(Namespace* namespc,
431 const char* name,
432 File::Type expected,
433 bool follow_links) {
434 File::Type actual = File::GetType(namespc, name, follow_links);
435 if (actual == expected) {
436 return true;
437 }
438 SetErrno(actual);
439 return false;
440}
441
442bool File::Delete(Namespace* namespc, const char* name) {
443 File::Type type = File::GetType(namespc, name, true);
444 if (type == kIsFile || type == kIsSock || type == kIsPipe) {
445 return (NO_RETRY_EXPECTED(unlink(name)) == 0);
446 }
447 SetErrno(type);
448 return false;
449}
450
451bool File::DeleteLink(Namespace* namespc, const char* name) {
452 return CheckTypeAndSetErrno(namespc, name, kIsLink, false) &&
453 (NO_RETRY_EXPECTED(unlink(name)) == 0);
454}
455
456bool File::Rename(Namespace* namespc,
457 const char* old_path,
458 const char* new_path) {
459 File::Type type = File::GetType(namespc, old_path, true);
460 if (type == kIsFile || type == kIsSock || type == kIsPipe) {
461 return (NO_RETRY_EXPECTED(rename(old_path, new_path)) == 0);
462 }
463 SetErrno(type);
464 return false;
465}
466
467bool File::RenameLink(Namespace* namespc,
468 const char* old_path,
469 const char* new_path) {
470 return CheckTypeAndSetErrno(namespc, old_path, kIsLink, false) &&
471 (NO_RETRY_EXPECTED(rename(old_path, new_path)) == 0);
472}
473
474bool File::Copy(Namespace* namespc,
475 const char* old_path,
476 const char* new_path) {
477 File::Type type = File::GetType(namespc, old_path, true);
478 if (type == kIsFile || type == kIsSock || type == kIsPipe) {
479 return (copyfile(old_path, new_path, nullptr, COPYFILE_ALL) == 0);
480 }
481 SetErrno(type);
482 return false;
483}
484
485static bool StatHelper(Namespace* namespc, const char* name, struct stat* st) {
486 if (NO_RETRY_EXPECTED(stat(name, st)) != 0) {
487 return false;
488 }
489 // Signal an error if it's a directory.
490 if (S_ISDIR(st->st_mode)) {
491 errno = EISDIR;
492 return false;
493 }
494 // Otherwise assume the caller knows what it's doing.
495 return true;
496}
497
498int64_t File::LengthFromPath(Namespace* namespc, const char* name) {
499 struct stat st;
500 if (!StatHelper(namespc, name, &st)) {
501 return -1;
502 }
503 return st.st_size;
504}
505
506static int64_t TimespecToMilliseconds(const struct timespec& t) {
507 return static_cast<int64_t>(t.tv_sec) * 1000L +
508 static_cast<int64_t>(t.tv_nsec) / 1000000L;
509}
510
511void File::Stat(Namespace* namespc, const char* name, int64_t* data) {
512 struct stat st;
513 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) {
514 if (S_ISREG(st.st_mode)) {
515 data[kType] = kIsFile;
516 } else if (S_ISDIR(st.st_mode)) {
518 } else if (S_ISLNK(st.st_mode)) {
519 data[kType] = kIsLink;
520 } else if (S_ISSOCK(st.st_mode)) {
521 data[kType] = kIsSock;
522 } else if (S_ISFIFO(st.st_mode)) {
523 data[kType] = kIsPipe;
524 } else {
526 }
527 data[kCreatedTime] = st.st_ctime;
528 data[kModifiedTime] = st.st_mtime;
529 data[kAccessedTime] = st.st_atime;
530 data[kCreatedTime] = TimespecToMilliseconds(st.st_ctimespec);
531 data[kModifiedTime] = TimespecToMilliseconds(st.st_mtimespec);
532 data[kAccessedTime] = TimespecToMilliseconds(st.st_atimespec);
533 data[kMode] = st.st_mode;
534 data[kSize] = st.st_size;
535 } else {
537 }
538}
539
540time_t File::LastModified(Namespace* namespc, const char* name) {
541 struct stat st;
542 if (!StatHelper(namespc, name, &st)) {
543 return -1;
544 }
545 return st.st_mtime;
546}
547
548time_t File::LastAccessed(Namespace* namespc, const char* name) {
549 struct stat st;
550 if (!StatHelper(namespc, name, &st)) {
551 return -1;
552 }
553 return st.st_atime;
554}
555
556bool File::SetLastAccessed(Namespace* namespc,
557 const char* name,
558 int64_t millis) {
559 // First get the current times.
560 struct stat st;
561 if (!StatHelper(namespc, name, &st)) {
562 return false;
563 }
564
565 // Set the new time:
566 struct utimbuf times;
567 times.actime = millis / kMillisecondsPerSecond;
568 times.modtime = st.st_mtime;
569 return utime(name, &times) == 0;
570}
571
572bool File::SetLastModified(Namespace* namespc,
573 const char* name,
574 int64_t millis) {
575 // First get the current times.
576 struct stat st;
577 if (!StatHelper(namespc, name, &st)) {
578 return false;
579 }
580
581 // Set the new time:
582 struct utimbuf times;
583 times.actime = st.st_atime;
584 times.modtime = millis / kMillisecondsPerSecond;
585 return utime(name, &times) == 0;
586}
587
588const char* File::LinkTarget(Namespace* namespc,
589 const char* pathname,
590 char* dest,
591 int dest_size) {
592 struct stat link_stats;
593 if (lstat(pathname, &link_stats) != 0) {
594 return nullptr;
595 }
596 if (!S_ISLNK(link_stats.st_mode)) {
597 errno = ENOENT;
598 return nullptr;
599 }
600 // Don't rely on the link_stats.st_size for the size of the link
601 // target. The link might have changed before the readlink call.
602 const int kBufferSize = 1024;
603 char target[kBufferSize];
604 size_t target_size =
605 TEMP_FAILURE_RETRY(readlink(pathname, target, kBufferSize));
606 if (target_size <= 0) {
607 return nullptr;
608 }
609 if (dest == nullptr) {
610 dest = DartUtils::ScopedCString(target_size + 1);
611 } else {
612 ASSERT(dest_size > 0);
613 if (static_cast<size_t>(dest_size) <= target_size) {
614 return nullptr;
615 }
616 }
617 memmove(dest, target, target_size);
618 dest[target_size] = '\0';
619 return dest;
620}
621
622bool File::IsAbsolutePath(const char* pathname) {
623 return (pathname != nullptr && pathname[0] == '/');
624}
625
626const char* File::GetCanonicalPath(Namespace* namespc,
627 const char* pathname,
628 char* dest,
629 int dest_size) {
630 char* abs_path = nullptr;
631 if (pathname != nullptr) {
632 // On some older MacOs versions the default behaviour of realpath allocating
633 // space for the dest when a nullptr is passed in does not seem to work, so
634 // we explicitly allocate space.
635 if (dest == nullptr) {
637 } else {
638 ASSERT(dest_size >= PATH_MAX);
639 }
640 do {
641 abs_path = realpath(pathname, dest);
642 } while ((abs_path == nullptr) && (errno == EINTR));
643 ASSERT((abs_path == nullptr) || IsAbsolutePath(abs_path));
644 ASSERT((abs_path == nullptr) || (abs_path == dest));
645 }
646 return abs_path;
647}
648
649const char* File::PathSeparator() {
650 return "/";
651}
652
654 return "/";
655}
656
658 struct stat buf;
659 int result = fstat(fd, &buf);
660 if (result == -1) {
661 return kTypeError;
662 }
663 if (S_ISCHR(buf.st_mode)) {
664 return kTerminal;
665 }
666 if (S_ISFIFO(buf.st_mode)) {
667 return kPipe;
668 }
669 if (S_ISSOCK(buf.st_mode)) {
670 return kSocket;
671 }
672 if (S_ISREG(buf.st_mode)) {
673 return kFile;
674 }
675 return kOther;
676}
677
678File::Identical File::AreIdentical(Namespace* namespc_1,
679 const char* file_1,
680 Namespace* namespc_2,
681 const char* file_2) {
682 USE(namespc_1);
683 USE(namespc_2);
684 struct stat file_1_info;
685 struct stat file_2_info;
686 if ((NO_RETRY_EXPECTED(lstat(file_1, &file_1_info)) == -1) ||
687 (NO_RETRY_EXPECTED(lstat(file_2, &file_2_info)) == -1)) {
688 return File::kError;
689 }
690 return ((file_1_info.st_ino == file_2_info.st_ino) &&
691 (file_1_info.st_dev == file_2_info.st_dev))
694}
695
696} // namespace bin
697} // namespace dart
698
699#endif // defined(DART_HOST_OS_MACOS)
static SkISize times(const SkISize &size, float factor)
static bool read(SkStream *stream, void *buffer, size_t amount)
static const size_t kBufferSize
Definition SkString.cpp:27
#define UNREACHABLE()
Definition assert.h:248
static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
static CStringUniquePtr CreateCStringUniquePtr(char *str)
Definition utils.cc:257
static int static int VSNPrint(char *str, size_t size, const char *format, va_list args)
static T Minimum(T x, T y)
Definition utils.h:21
std::unique_ptr< char, decltype(std::free) * > CStringUniquePtr
Definition utils.h:644
static char * StrError(int err, char *buffer, size_t bufsize)
static char * ScopedCString(intptr_t length)
Definition dartutils.h:224
static bool SetCloseOnExec(intptr_t fd)
static void SaveErrorAndClose(intptr_t fd)
static bool CreatePipe(Namespace *namespc, File **readPipe, File **writePipe)
static bool DeleteLink(Namespace *namespc, const char *path)
static bool IsAbsolutePath(const char *path)
MappedMemory * Map(MapType type, int64_t position, int64_t length, void *start=nullptr)
static const char * GetCanonicalPath(Namespace *namespc, const char *path, char *dest=nullptr, int dest_size=0)
int64_t Position()
int64_t Read(void *buffer, int64_t num_bytes)
static bool SetLastAccessed(Namespace *namespc, const char *path, int64_t millis)
static Utils::CStringUniquePtr UriToPath(const char *uri)
static File * OpenUri(Namespace *namespc, const char *uri, FileOpenMode mode)
@ kDoesNotExist
Definition file.h:81
static bool SetLastModified(Namespace *namespc, const char *path, int64_t millis)
static time_t LastModified(Namespace *namespc, const char *path)
static void Stat(Namespace *namespc, const char *path, int64_t *data)
static const char * PathSeparator()
static bool Create(Namespace *namespc, const char *path, bool exclusive)
bool VPrint(const char *format, va_list args)
static bool Rename(Namespace *namespc, const char *old_path, const char *new_path)
static bool Delete(Namespace *namespc, const char *path)
static const char * StringEscapedPathSeparator()
bool WriteFully(const void *buffer, int64_t num_bytes)
static int64_t LengthFromPath(Namespace *namespc, const char *path)
bool ReadFully(void *buffer, int64_t num_bytes)
static bool Copy(Namespace *namespc, const char *old_path, const char *new_path)
static time_t LastAccessed(Namespace *namespc, const char *path)
intptr_t GetFD()
bool result
Definition file.h:170
int64_t Write(const void *buffer, int64_t num_bytes)
static bool Exists(Namespace *namespc, const char *path)
static File * Open(Namespace *namespc, const char *path, FileOpenMode mode)
bool Lock(LockType lock, int64_t start, int64_t end)
bool SetPosition(int64_t position)
static Identical AreIdentical(Namespace *namespc_1, const char *file_1, Namespace *namespc_2, const char *file_2)
int64_t Length()
static File * OpenFD(int fd)
static const char * LinkTarget(Namespace *namespc, const char *pathname, char *dest=nullptr, int dest_size=0)
@ kLockBlockingShared
Definition file.h:113
@ kLockBlockingExclusive
Definition file.h:114
static bool CreateLink(Namespace *namespc, const char *path, const char *target)
static bool ExistsUri(Namespace *namespc, const char *uri)
static File * OpenStdio(int fd)
static StdioHandleType GetStdioHandleType(int fd)
static Type GetType(Namespace *namespc, const char *path, bool follow_links)
bool Truncate(int64_t length)
static bool RenameLink(Namespace *namespc, const char *old_path, const char *new_path)
#define ASSERT(E)
FlutterSemanticsFlag flags
glong glong end
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
static const uint8_t buffer[]
GAsyncResult * result
uint32_t uint32_t * format
uint32_t * target
size_t length
const char *const name
void * malloc(size_t size)
Definition allocation.cc:19
DART_EXPORT char * Dart_Initialize(Dart_InitializeParams *params)
constexpr intptr_t kMillisecondsPerSecond
Definition globals.h:560
static void USE(T &&)
Definition globals.h:618
constexpr int32_t kMaxInt32
Definition globals.h:483
static int8_t data[kExtLength]
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition switches.h:57
char * strdup(const char *str1)
dest
Definition zip.py:79
#define PATH_MAX
Definition globals.h:708
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition globals.h:581
fuchsia::ui::composition::ParentViewportWatcherHandle handle_
#define NO_RETRY_EXPECTED(expression)
#define VOID_TEMP_FAILURE_RETRY(expression)
#define TEMP_FAILURE_RETRY(expression)
void write(SkWStream *wStream, const T &text)
Definition skqp.cpp:188