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

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

Issue 2168193002: Fuchsia: Build standalone VM. Make it run "Hello, World!". (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Address comments Created 4 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/extensions_fuchsia.cc ('k') | runtime/bin/file_system_watcher_fuchsia.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) 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(TARGET_OS_MACOS) 6 #if defined(TARGET_OS_FUCHSIA)
7 7
8 #include "bin/file.h" 8 #include "bin/file.h"
9 9
10 #include <copyfile.h> // NOLINT
11 #include <errno.h> // NOLINT 10 #include <errno.h> // NOLINT
12 #include <fcntl.h> // NOLINT 11 #include <fcntl.h> // NOLINT
13 #include <libgen.h> // NOLINT 12 #include <libgen.h> // NOLINT
14 #include <limits.h> // NOLINT
15 #include <sys/mman.h> // NOLINT 13 #include <sys/mman.h> // NOLINT
16 #include <sys/stat.h> // NOLINT 14 #include <sys/stat.h> // NOLINT
15 #include <sys/types.h> // NOLINT
17 #include <unistd.h> // NOLINT 16 #include <unistd.h> // NOLINT
18 17
19 #include "bin/builtin.h" 18 #include "bin/builtin.h"
20 #include "bin/fdutils.h"
21 #include "bin/log.h" 19 #include "bin/log.h"
22
23 #include "platform/signal_blocker.h" 20 #include "platform/signal_blocker.h"
24 #include "platform/utils.h" 21 #include "platform/utils.h"
25 22
26 namespace dart { 23 namespace dart {
27 namespace bin { 24 namespace bin {
28 25
29 class FileHandle { 26 class FileHandle {
30 public: 27 public:
31 explicit FileHandle(int fd) : fd_(fd) { } 28 explicit FileHandle(int fd) : fd_(fd) { }
32 ~FileHandle() { } 29 ~FileHandle() { }
(...skipping 12 matching lines...) Expand all
45 Close(); 42 Close();
46 } 43 }
47 delete handle_; 44 delete handle_;
48 } 45 }
49 46
50 47
51 void File::Close() { 48 void File::Close() {
52 ASSERT(handle_->fd() >= 0); 49 ASSERT(handle_->fd() >= 0);
53 if (handle_->fd() == STDOUT_FILENO) { 50 if (handle_->fd() == STDOUT_FILENO) {
54 // If stdout, redirect fd to /dev/null. 51 // If stdout, redirect fd to /dev/null.
55 intptr_t null_fd = TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY)); 52 int null_fd = NO_RETRY_EXPECTED(open("/dev/null", O_WRONLY));
56 ASSERT(null_fd >= 0); 53 ASSERT(null_fd >= 0);
57 VOID_TEMP_FAILURE_RETRY(dup2(null_fd, handle_->fd())); 54 VOID_NO_RETRY_EXPECTED(dup2(null_fd, handle_->fd()));
58 VOID_TEMP_FAILURE_RETRY(close(null_fd)); 55 VOID_NO_RETRY_EXPECTED(close(null_fd));
59 } else { 56 } else {
60 intptr_t err = TEMP_FAILURE_RETRY(close(handle_->fd())); 57 int err = NO_RETRY_EXPECTED(close(handle_->fd()));
61 if (err != 0) { 58 if (err != 0) {
62 const int kBufferSize = 1024; 59 const int kBufferSize = 1024;
63 char error_message[kBufferSize]; 60 char error_buf[kBufferSize];
64 Utils::StrError(errno, error_message, kBufferSize); 61 Log::PrintErr("%s\n", Utils::StrError(errno, error_buf, kBufferSize));
65 Log::PrintErr("%s\n", error_message);
66 } 62 }
67 } 63 }
68 handle_->set_fd(kClosedFd); 64 handle_->set_fd(kClosedFd);
69 } 65 }
70 66
71 67
72 intptr_t File::GetFD() { 68 intptr_t File::GetFD() {
73 return handle_->fd(); 69 return handle_->fd();
74 } 70 }
75 71
76 72
77 bool File::IsClosed() { 73 bool File::IsClosed() {
78 return handle_->fd() == kClosedFd; 74 return handle_->fd() == kClosedFd;
79 } 75 }
80 76
81 77
82 void* File::MapExecutable(intptr_t* len) { 78 void* File::MapExecutable(intptr_t* len) {
83 ASSERT(handle_->fd() >= 0); 79 UNIMPLEMENTED();
84 intptr_t length = Length(); 80 return NULL;
85 void* addr = mmap(0, length,
86 PROT_READ | PROT_EXEC, MAP_PRIVATE,
87 handle_->fd(), 0);
88 if (addr == MAP_FAILED) {
89 *len = -1;
90 } else {
91 *len = length;
92 }
93 return addr;
94 } 81 }
95 82
96 83
97 int64_t File::Read(void* buffer, int64_t num_bytes) { 84 int64_t File::Read(void* buffer, int64_t num_bytes) {
98 ASSERT(handle_->fd() >= 0); 85 ASSERT(handle_->fd() >= 0);
99 return TEMP_FAILURE_RETRY(read(handle_->fd(), buffer, num_bytes)); 86 return NO_RETRY_EXPECTED(read(handle_->fd(), buffer, num_bytes));
100 } 87 }
101 88
102 89
103 int64_t File::Write(const void* buffer, int64_t num_bytes) { 90 int64_t File::Write(const void* buffer, int64_t num_bytes) {
104 ASSERT(handle_->fd() >= 0); 91 ASSERT(handle_->fd() >= 0);
105 return TEMP_FAILURE_RETRY(write(handle_->fd(), buffer, num_bytes)); 92 return NO_RETRY_EXPECTED(write(handle_->fd(), buffer, num_bytes));
106 } 93 }
107 94
108 95
109 int64_t File::Position() { 96 int64_t File::Position() {
110 ASSERT(handle_->fd() >= 0); 97 ASSERT(handle_->fd() >= 0);
111 return lseek(handle_->fd(), 0, SEEK_CUR); 98 return NO_RETRY_EXPECTED(lseek(handle_->fd(), 0, SEEK_CUR));
112 } 99 }
113 100
114 101
115 bool File::SetPosition(int64_t position) { 102 bool File::SetPosition(int64_t position) {
116 ASSERT(handle_->fd() >= 0); 103 ASSERT(handle_->fd() >= 0);
117 return lseek(handle_->fd(), position, SEEK_SET) >= 0; 104 return NO_RETRY_EXPECTED(lseek(handle_->fd(), position, SEEK_SET)) >= 0;
118 } 105 }
119 106
120 107
121 bool File::Truncate(int64_t length) { 108 bool File::Truncate(int64_t length) {
122 ASSERT(handle_->fd() >= 0); 109 ASSERT(handle_->fd() >= 0);
123 return TEMP_FAILURE_RETRY(ftruncate(handle_->fd(), length)) != -1; 110 return NO_RETRY_EXPECTED(ftruncate(handle_->fd(), length) != -1);
124 } 111 }
125 112
126 113
127 bool File::Flush() { 114 bool File::Flush() {
128 ASSERT(handle_->fd() >= 0); 115 ASSERT(handle_->fd() >= 0);
129 return NO_RETRY_EXPECTED(fsync(handle_->fd())) != -1; 116 return NO_RETRY_EXPECTED(fsync(handle_->fd())) != -1;
130 } 117 }
131 118
132 119
133 bool File::Lock(File::LockType lock, int64_t start, int64_t end) { 120 bool File::Lock(File::LockType lock, int64_t start, int64_t end) {
(...skipping 16 matching lines...) Expand all
150 return false; 137 return false;
151 } 138 }
152 fl.l_whence = SEEK_SET; 139 fl.l_whence = SEEK_SET;
153 fl.l_start = start; 140 fl.l_start = start;
154 fl.l_len = end == -1 ? 0 : end - start; 141 fl.l_len = end == -1 ? 0 : end - start;
155 int cmd = F_SETLK; 142 int cmd = F_SETLK;
156 if ((lock == File::kLockBlockingShared) || 143 if ((lock == File::kLockBlockingShared) ||
157 (lock == File::kLockBlockingExclusive)) { 144 (lock == File::kLockBlockingExclusive)) {
158 cmd = F_SETLKW; 145 cmd = F_SETLKW;
159 } 146 }
160 return TEMP_FAILURE_RETRY(fcntl(handle_->fd(), cmd, &fl)) != -1; 147 return NO_RETRY_EXPECTED(fcntl(handle_->fd(), cmd, &fl)) != -1;
161 } 148 }
162 149
163 150
164 int64_t File::Length() { 151 int64_t File::Length() {
165 ASSERT(handle_->fd() >= 0); 152 ASSERT(handle_->fd() >= 0);
166 struct stat st; 153 struct stat st;
167 if (NO_RETRY_EXPECTED(fstat(handle_->fd(), &st)) == 0) { 154 if (NO_RETRY_EXPECTED(fstat(handle_->fd(), &st)) == 0) {
168 return st.st_size; 155 return st.st_size;
169 } 156 }
170 return -1; 157 return -1;
171 } 158 }
172 159
173 160
174 File* File::FileOpenW(const wchar_t* system_name, FileOpenMode mode) { 161 File* File::FileOpenW(const wchar_t* system_name, FileOpenMode mode) {
175 UNREACHABLE(); 162 UNREACHABLE();
176 return NULL; 163 return NULL;
177 } 164 }
178 165
179 166
180 File* File::ScopedOpen(const char* name, FileOpenMode mode) { 167 File* File::ScopedOpen(const char* name, FileOpenMode mode) {
181 // Report errors for non-regular files. 168 // Report errors for non-regular files.
182 struct stat st; 169 struct stat st;
183 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { 170 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) {
184 // Only accept regular files, character devices, and pipes. 171 if (!S_ISREG(st.st_mode)) {
185 if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode) && !S_ISFIFO(st.st_mode)) {
186 errno = (S_ISDIR(st.st_mode)) ? EISDIR : ENOENT; 172 errno = (S_ISDIR(st.st_mode)) ? EISDIR : ENOENT;
187 return NULL; 173 return NULL;
188 } 174 }
189 } 175 }
190 int flags = O_RDONLY; 176 int flags = O_RDONLY;
191 if ((mode & kWrite) != 0) { 177 if ((mode & kWrite) != 0) {
192 ASSERT((mode & kWriteOnly) == 0); 178 ASSERT((mode & kWriteOnly) == 0);
193 flags = (O_RDWR | O_CREAT); 179 flags = (O_RDWR | O_CREAT);
194 } 180 }
195 if ((mode & kWriteOnly) != 0) { 181 if ((mode & kWriteOnly) != 0) {
196 ASSERT((mode & kWrite) == 0); 182 ASSERT((mode & kWrite) == 0);
197 flags = (O_WRONLY | O_CREAT); 183 flags = (O_WRONLY | O_CREAT);
198 } 184 }
199 if ((mode & kTruncate) != 0) { 185 if ((mode & kTruncate) != 0) {
200 flags = flags | O_TRUNC; 186 flags = flags | O_TRUNC;
201 } 187 }
202 int fd = TEMP_FAILURE_RETRY(open(name, flags, 0666)); 188 flags |= O_CLOEXEC;
189 int fd = NO_RETRY_EXPECTED(open(name, flags, 0666));
203 if (fd < 0) { 190 if (fd < 0) {
204 return NULL; 191 return NULL;
205 } 192 }
206 FDUtils::SetCloseOnExec(fd);
207 if ((((mode & kWrite) != 0) && ((mode & kTruncate) == 0)) || 193 if ((((mode & kWrite) != 0) && ((mode & kTruncate) == 0)) ||
208 (((mode & kWriteOnly) != 0) && ((mode & kTruncate) == 0))) { 194 (((mode & kWriteOnly) != 0) && ((mode & kTruncate) == 0))) {
209 int64_t position = lseek(fd, 0, SEEK_END); 195 int64_t position = lseek(fd, 0, SEEK_END);
210 if (position < 0) { 196 if (position < 0) {
211 return NULL; 197 return NULL;
212 } 198 }
213 } 199 }
214 return new File(new FileHandle(fd)); 200 return new File(new FileHandle(fd));
215 } 201 }
216 202
(...skipping 13 matching lines...) Expand all
230 struct stat st; 216 struct stat st;
231 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { 217 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) {
232 return S_ISREG(st.st_mode); 218 return S_ISREG(st.st_mode);
233 } else { 219 } else {
234 return false; 220 return false;
235 } 221 }
236 } 222 }
237 223
238 224
239 bool File::Create(const char* name) { 225 bool File::Create(const char* name) {
240 int fd = TEMP_FAILURE_RETRY(open(name, O_RDONLY | O_CREAT, 0666)); 226 int fd = NO_RETRY_EXPECTED(open(name, O_RDONLY | O_CREAT | O_CLOEXEC, 0666));
241 if (fd < 0) { 227 if (fd < 0) {
242 return false; 228 return false;
243 } 229 }
244 return (close(fd) == 0); 230 return (close(fd) == 0);
245 } 231 }
246 232
247 233
248 bool File::CreateLink(const char* name, const char* target) { 234 bool File::CreateLink(const char* name, const char* target) {
249 int status = NO_RETRY_EXPECTED(symlink(target, name)); 235 return NO_RETRY_EXPECTED(symlink(target, name)) == 0;
250 return (status == 0);
251 } 236 }
252 237
253 238
254 bool File::Delete(const char* name) { 239 bool File::Delete(const char* name) {
255 File::Type type = File::GetType(name, true); 240 File::Type type = File::GetType(name, true);
256 if (type == kIsFile) { 241 if (type == kIsFile) {
257 return NO_RETRY_EXPECTED(unlink(name)) == 0; 242 return NO_RETRY_EXPECTED(unlink(name)) == 0;
258 } else if (type == kIsDirectory) { 243 } else if (type == kIsDirectory) {
259 errno = EISDIR; 244 errno = EISDIR;
260 } else { 245 } else {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 } else if (type == kIsDirectory) { 279 } else if (type == kIsDirectory) {
295 errno = EISDIR; 280 errno = EISDIR;
296 } else { 281 } else {
297 errno = EINVAL; 282 errno = EINVAL;
298 } 283 }
299 return false; 284 return false;
300 } 285 }
301 286
302 287
303 bool File::Copy(const char* old_path, const char* new_path) { 288 bool File::Copy(const char* old_path, const char* new_path) {
304 File::Type type = File::GetType(old_path, true); 289 UNIMPLEMENTED();
305 if (type == kIsFile) {
306 return copyfile(old_path, new_path, NULL, COPYFILE_ALL) == 0;
307 } else if (type == kIsDirectory) {
308 errno = EISDIR;
309 } else {
310 errno = ENOENT;
311 }
312 return false; 290 return false;
313 } 291 }
314 292
315 293
316 int64_t File::LengthFromPath(const char* name) { 294 int64_t File::LengthFromPath(const char* name) {
317 struct stat st; 295 struct stat st;
318 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { 296 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) {
319 return st.st_size; 297 return st.st_size;
320 } 298 }
321 return -1; 299 return -1;
322 } 300 }
323 301
324 302
325 static int64_t TimespecToMilliseconds(const struct timespec& t) {
326 return static_cast<int64_t>(t.tv_sec) * 1000L +
327 static_cast<int64_t>(t.tv_nsec) / 1000000L;
328 }
329
330
331 void File::Stat(const char* name, int64_t* data) { 303 void File::Stat(const char* name, int64_t* data) {
332 struct stat st; 304 struct stat st;
333 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { 305 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) {
334 if (S_ISREG(st.st_mode)) { 306 if (S_ISREG(st.st_mode)) {
335 data[kType] = kIsFile; 307 data[kType] = kIsFile;
336 } else if (S_ISDIR(st.st_mode)) { 308 } else if (S_ISDIR(st.st_mode)) {
337 data[kType] = kIsDirectory; 309 data[kType] = kIsDirectory;
338 } else if (S_ISLNK(st.st_mode)) { 310 } else if (S_ISLNK(st.st_mode)) {
339 data[kType] = kIsLink; 311 data[kType] = kIsLink;
340 } else { 312 } else {
341 data[kType] = kDoesNotExist; 313 data[kType] = kDoesNotExist;
342 } 314 }
343 data[kCreatedTime] = st.st_ctime; 315 data[kCreatedTime] = static_cast<int64_t>(st.st_ctime) * 1000;
344 data[kModifiedTime] = st.st_mtime; 316 data[kModifiedTime] = static_cast<int64_t>(st.st_mtime) * 1000;
345 data[kAccessedTime] = st.st_atime; 317 data[kAccessedTime] = static_cast<int64_t>(st.st_atime) * 1000;
346 data[kCreatedTime] = TimespecToMilliseconds(st.st_ctimespec);
347 data[kModifiedTime] = TimespecToMilliseconds(st.st_mtimespec);
348 data[kAccessedTime] = TimespecToMilliseconds(st.st_atimespec);
349 data[kMode] = st.st_mode; 318 data[kMode] = st.st_mode;
350 data[kSize] = st.st_size; 319 data[kSize] = st.st_size;
351 } else { 320 } else {
352 data[kType] = kDoesNotExist; 321 data[kType] = kDoesNotExist;
353 } 322 }
354 } 323 }
355 324
356 325
357 time_t File::LastModified(const char* name) { 326 time_t File::LastModified(const char* name) {
358 struct stat st; 327 struct stat st;
359 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { 328 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) {
360 return st.st_mtime; 329 return st.st_mtime;
361 } 330 }
362 return -1; 331 return -1;
363 } 332 }
364 333
365 334
366 const char* File::LinkTarget(const char* pathname) { 335 const char* File::LinkTarget(const char* pathname) {
367 struct stat link_stats; 336 struct stat link_stats;
368 if (lstat(pathname, &link_stats) != 0) { 337 if (lstat(pathname, &link_stats) != 0) {
369 return NULL; 338 return NULL;
370 } 339 }
371 if (!S_ISLNK(link_stats.st_mode)) { 340 if (!S_ISLNK(link_stats.st_mode)) {
372 errno = ENOENT; 341 errno = ENOENT;
373 return NULL; 342 return NULL;
374 } 343 }
375 // Don't rely on the link_stats.st_size for the size of the link 344 size_t target_size = link_stats.st_size;
376 // target. The link might have changed before the readlink call. 345 char* target_name = DartUtils::ScopedCString(target_size + 1);
377 const int kBufferSize = 1024; 346 ASSERT(target_name != NULL);
378 char target[kBufferSize]; 347 size_t read_size = readlink(pathname, target_name, target_size + 1);
379 size_t target_size = TEMP_FAILURE_RETRY( 348 if (read_size != target_size) {
380 readlink(pathname, target, kBufferSize));
381 if (target_size <= 0) {
382 return NULL; 349 return NULL;
383 } 350 }
384 char* target_name = DartUtils::ScopedCString(target_size + 1);
385 ASSERT(target_name != NULL);
386 memmove(target_name, target, target_size);
387 target_name[target_size] = '\0'; 351 target_name[target_size] = '\0';
388 return target_name; 352 return target_name;
389 } 353 }
390 354
391 355
392 bool File::IsAbsolutePath(const char* pathname) { 356 bool File::IsAbsolutePath(const char* pathname) {
393 return (pathname != NULL && pathname[0] == '/'); 357 return ((pathname != NULL) && (pathname[0] == '/'));
394 } 358 }
395 359
396 360
397 const char* File::GetCanonicalPath(const char* pathname) { 361 const char* File::GetCanonicalPath(const char* pathname) {
398 char* abs_path = NULL; 362 char* abs_path = NULL;
399 if (pathname != NULL) { 363 if (pathname != NULL) {
400 // On some older MacOs versions the default behaviour of realpath allocating
401 // space for the resolved_path when a NULL is passed in does not seem to
402 // work, so we explicitly allocate space.
403 char* resolved_path = DartUtils::ScopedCString(PATH_MAX + 1); 364 char* resolved_path = DartUtils::ScopedCString(PATH_MAX + 1);
404 ASSERT(resolved_path != NULL); 365 ASSERT(resolved_path != NULL);
405 do { 366 do {
406 abs_path = realpath(pathname, resolved_path); 367 abs_path = realpath(pathname, resolved_path);
407 } while ((abs_path == NULL) && (errno == EINTR)); 368 } while ((abs_path == NULL) && (errno == EINTR));
408 ASSERT((abs_path == NULL) || IsAbsolutePath(abs_path)); 369 ASSERT((abs_path == NULL) || IsAbsolutePath(abs_path));
409 ASSERT((abs_path == NULL) || (abs_path == resolved_path)); 370 ASSERT((abs_path == NULL) || (abs_path == resolved_path));
410 } 371 }
411 return abs_path; 372 return abs_path;
412 } 373 }
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 } 442 }
482 return ((file_1_info.st_ino == file_2_info.st_ino) && 443 return ((file_1_info.st_ino == file_2_info.st_ino) &&
483 (file_1_info.st_dev == file_2_info.st_dev)) ? 444 (file_1_info.st_dev == file_2_info.st_dev)) ?
484 File::kIdentical : 445 File::kIdentical :
485 File::kDifferent; 446 File::kDifferent;
486 } 447 }
487 448
488 } // namespace bin 449 } // namespace bin
489 } // namespace dart 450 } // namespace dart
490 451
491 #endif // defined(TARGET_OS_MACOS) 452 #endif // defined(TARGET_OS_FUCHSIA)
OLDNEW
« no previous file with comments | « runtime/bin/extensions_fuchsia.cc ('k') | runtime/bin/file_system_watcher_fuchsia.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698