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

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

Issue 1559053002: Refs #10260 OpenBSD support #25327 Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Replace // FIXME with // TODO(mulander) Created 4 years, 11 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
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(TARGET_OS_ANDROID) 6 #if defined(TARGET_OS_OPENBSD)
7 7
8 #include "bin/file.h" 8 #include "bin/file.h"
9 9
10 #include <errno.h> // NOLINT 10 #include <errno.h> // NOLINT
11 #include <fcntl.h> // NOLINT 11 #include <fcntl.h> // NOLINT
12 #include <sys/stat.h> // NOLINT 12 #include <sys/stat.h> // NOLINT
13 #include <sys/types.h> // NOLINT 13 #include <sys/types.h> // NOLINT
14 #include <sys/sendfile.h> // NOLINT
15 #include <unistd.h> // NOLINT 14 #include <unistd.h> // NOLINT
16 #include <libgen.h> // NOLINT 15 #include <libgen.h> // NOLINT
17 16
18 #include "bin/builtin.h" 17 #include "bin/builtin.h"
19 #include "bin/log.h" 18 #include "bin/log.h"
20 19
21 #include "platform/signal_blocker.h" 20 #include "platform/signal_blocker.h"
22 #include "platform/utils.h"
23 21
24 22
25 namespace dart { 23 namespace dart {
26 namespace bin { 24 namespace bin {
27 25
28 class FileHandle { 26 class FileHandle {
29 public: 27 public:
30 explicit FileHandle(int fd) : fd_(fd) { } 28 explicit FileHandle(int fd) : fd_(fd) { }
31 ~FileHandle() { } 29 ~FileHandle() { }
32 int fd() const { return fd_; } 30 int fd() const { return fd_; }
(...skipping 18 matching lines...) Expand all
51 // If stdout, redirect fd to /dev/null. 49 // If stdout, redirect fd to /dev/null.
52 int null_fd = TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY)); 50 int null_fd = TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY));
53 ASSERT(null_fd >= 0); 51 ASSERT(null_fd >= 0);
54 VOID_TEMP_FAILURE_RETRY(dup2(null_fd, handle_->fd())); 52 VOID_TEMP_FAILURE_RETRY(dup2(null_fd, handle_->fd()));
55 VOID_TEMP_FAILURE_RETRY(close(null_fd)); 53 VOID_TEMP_FAILURE_RETRY(close(null_fd));
56 } else { 54 } else {
57 int err = TEMP_FAILURE_RETRY(close(handle_->fd())); 55 int err = TEMP_FAILURE_RETRY(close(handle_->fd()));
58 if (err != 0) { 56 if (err != 0) {
59 const int kBufferSize = 1024; 57 const int kBufferSize = 1024;
60 char error_message[kBufferSize]; 58 char error_message[kBufferSize];
61 Utils::StrError(errno, error_message, kBufferSize); 59 strerror_r(errno, error_message, kBufferSize);
62 Log::PrintErr("%s\n", error_message); 60 Log::PrintErr("%s\n", error_message);
63 } 61 }
64 } 62 }
65 handle_->set_fd(kClosedFd); 63 handle_->set_fd(kClosedFd);
66 } 64 }
67 65
68 66
69 intptr_t File::GetFD() { 67 intptr_t File::GetFD() {
70 return handle_->fd(); 68 return handle_->fd();
71 } 69 }
(...skipping 11 matching lines...) Expand all
83 81
84 82
85 int64_t File::Write(const void* buffer, int64_t num_bytes) { 83 int64_t File::Write(const void* buffer, int64_t num_bytes) {
86 ASSERT(handle_->fd() >= 0); 84 ASSERT(handle_->fd() >= 0);
87 return TEMP_FAILURE_RETRY(write(handle_->fd(), buffer, num_bytes)); 85 return TEMP_FAILURE_RETRY(write(handle_->fd(), buffer, num_bytes));
88 } 86 }
89 87
90 88
91 int64_t File::Position() { 89 int64_t File::Position() {
92 ASSERT(handle_->fd() >= 0); 90 ASSERT(handle_->fd() >= 0);
93 return NO_RETRY_EXPECTED(lseek64(handle_->fd(), 0, SEEK_CUR)); 91 return NO_RETRY_EXPECTED(lseek(handle_->fd(), 0, SEEK_CUR));
94 } 92 }
95 93
96 94
97 bool File::SetPosition(int64_t position) { 95 bool File::SetPosition(int64_t position) {
98 ASSERT(handle_->fd() >= 0); 96 ASSERT(handle_->fd() >= 0);
99 return NO_RETRY_EXPECTED(lseek64(handle_->fd(), position, SEEK_SET)) >= 0; 97 return NO_RETRY_EXPECTED(lseek(handle_->fd(), position, SEEK_SET)) >= 0;
100 } 98 }
101 99
102 100
103 bool File::Truncate(int64_t length) { 101 bool File::Truncate(int64_t length) {
104 ASSERT(handle_->fd() >= 0); 102 ASSERT(handle_->fd() >= 0);
105 return TEMP_FAILURE_RETRY(ftruncate(handle_->fd(), length) != -1); 103 return TEMP_FAILURE_RETRY(ftruncate(handle_->fd(), length) != -1);
106 } 104 }
107 105
108 106
109 bool File::Flush() { 107 bool File::Flush() {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 if ((mode & kTruncate) != 0) { 167 if ((mode & kTruncate) != 0) {
170 flags = flags | O_TRUNC; 168 flags = flags | O_TRUNC;
171 } 169 }
172 flags |= O_CLOEXEC; 170 flags |= O_CLOEXEC;
173 int fd = TEMP_FAILURE_RETRY(open(name, flags, 0666)); 171 int fd = TEMP_FAILURE_RETRY(open(name, flags, 0666));
174 if (fd < 0) { 172 if (fd < 0) {
175 return NULL; 173 return NULL;
176 } 174 }
177 if ((((mode & kWrite) != 0) && ((mode & kTruncate) == 0)) || 175 if ((((mode & kWrite) != 0) && ((mode & kTruncate) == 0)) ||
178 (((mode & kWriteOnly) != 0) && ((mode & kTruncate) == 0))) { 176 (((mode & kWriteOnly) != 0) && ((mode & kTruncate) == 0))) {
179 int64_t position = lseek64(fd, 0, SEEK_END); 177 int64_t position = lseek(fd, 0, SEEK_END);
180 if (position < 0) { 178 if (position < 0) {
181 return NULL; 179 return NULL;
182 } 180 }
183 } 181 }
184 return new File(new FileHandle(fd)); 182 return new File(new FileHandle(fd));
185 } 183 }
186 184
187 185
188 File* File::OpenStdio(int fd) { 186 File* File::OpenStdio(int fd) {
189 if (fd < 0 || 2 < fd) return NULL; 187 if (fd < 0 || 2 < fd) return NULL;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 int old_fd = TEMP_FAILURE_RETRY(open(old_path, O_RDONLY | O_CLOEXEC)); 273 int old_fd = TEMP_FAILURE_RETRY(open(old_path, O_RDONLY | O_CLOEXEC));
276 if (old_fd < 0) { 274 if (old_fd < 0) {
277 return false; 275 return false;
278 } 276 }
279 int new_fd = TEMP_FAILURE_RETRY( 277 int new_fd = TEMP_FAILURE_RETRY(
280 open(new_path, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, st.st_mode)); 278 open(new_path, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, st.st_mode));
281 if (new_fd < 0) { 279 if (new_fd < 0) {
282 VOID_TEMP_FAILURE_RETRY(close(old_fd)); 280 VOID_TEMP_FAILURE_RETRY(close(old_fd));
283 return false; 281 return false;
284 } 282 }
285 off_t offset = 0; 283
286 int result = 1; 284 int result = 1;
287 while (result > 0) { 285 // OpenBSD has no sendfile so use read(2)/write(2) to copy the file
288 // Loop to ensure we copy everything, and not only up to 2GB. 286 const intptr_t kBufferSize = 8 * KB;
289 result = NO_RETRY_EXPECTED( 287 uint8_t buffer[kBufferSize];
290 sendfile(new_fd, old_fd, &offset, kMaxUint32)); 288 while ((result = TEMP_FAILURE_RETRY(read(old_fd,
291 } 289 buffer,
292 // From sendfile man pages: 290 kBufferSize))) > 0) {
293 // Applications may wish to fall back to read(2)/write(2) in the case 291 int wrote = TEMP_FAILURE_RETRY(write(new_fd, buffer, result));
Ivan Posva 2016/01/11 23:58:40 Please add a TODO to deal with short writes. We wi
mulander 2016/01/12 00:22:45 Acknowledged.
294 // where sendfile() fails with EINVAL or ENOSYS. 292 if (wrote != result) {
295 if (result < 0 && (errno == EINVAL || errno == ENOSYS)) { 293 result = -1;
296 const intptr_t kBufferSize = 8 * KB; 294 break;
297 uint8_t buffer[kBufferSize];
298 while ((result = TEMP_FAILURE_RETRY(
299 read(old_fd, buffer, kBufferSize))) > 0) {
300 int wrote = TEMP_FAILURE_RETRY(write(new_fd, buffer, result));
301 if (wrote != result) {
302 result = -1;
303 break;
304 }
305 } 295 }
306 } 296 }
297
307 int e = errno; 298 int e = errno;
308 VOID_TEMP_FAILURE_RETRY(close(old_fd)); 299 VOID_TEMP_FAILURE_RETRY(close(old_fd));
309 VOID_TEMP_FAILURE_RETRY(close(new_fd)); 300 VOID_TEMP_FAILURE_RETRY(close(new_fd));
310 if (result < 0) { 301 if (result < 0) {
311 VOID_NO_RETRY_EXPECTED(unlink(new_path)); 302 VOID_NO_RETRY_EXPECTED(unlink(new_path));
312 errno = e; 303 errno = e;
313 return false; 304 return false;
314 } 305 }
315 return true; 306 return true;
316 } else if (type == kIsDirectory) { 307 } else if (type == kIsDirectory) {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 } 407 }
417 408
418 409
419 File::StdioHandleType File::GetStdioHandleType(int fd) { 410 File::StdioHandleType File::GetStdioHandleType(int fd) {
420 ASSERT(0 <= fd && fd <= 2); 411 ASSERT(0 <= fd && fd <= 2);
421 struct stat buf; 412 struct stat buf;
422 int result = fstat(fd, &buf); 413 int result = fstat(fd, &buf);
423 if (result == -1) { 414 if (result == -1) {
424 const int kBufferSize = 1024; 415 const int kBufferSize = 1024;
425 char error_message[kBufferSize]; 416 char error_message[kBufferSize];
426 Utils::StrError(errno, error_message, kBufferSize); 417 strerror_r(errno, error_message, kBufferSize);
427 FATAL2("Failed stat on file descriptor %d: %s", fd, error_message); 418 FATAL2("Failed stat on file descriptor %d: %s", fd, error_message);
428 } 419 }
429 if (S_ISCHR(buf.st_mode)) return kTerminal; 420 if (S_ISCHR(buf.st_mode)) return kTerminal;
430 if (S_ISFIFO(buf.st_mode)) return kPipe; 421 if (S_ISFIFO(buf.st_mode)) return kPipe;
431 if (S_ISSOCK(buf.st_mode)) return kSocket; 422 if (S_ISSOCK(buf.st_mode)) return kSocket;
432 if (S_ISREG(buf.st_mode)) return kFile; 423 if (S_ISREG(buf.st_mode)) return kFile;
433 return kOther; 424 return kOther;
434 } 425 }
435 426
436 427
(...skipping 22 matching lines...) Expand all
459 } 450 }
460 return (file_1_info.st_ino == file_2_info.st_ino && 451 return (file_1_info.st_ino == file_2_info.st_ino &&
461 file_1_info.st_dev == file_2_info.st_dev) ? 452 file_1_info.st_dev == file_2_info.st_dev) ?
462 File::kIdentical : 453 File::kIdentical :
463 File::kDifferent; 454 File::kDifferent;
464 } 455 }
465 456
466 } // namespace bin 457 } // namespace bin
467 } // namespace dart 458 } // namespace dart
468 459
469 #endif // defined(TARGET_OS_ANDROID) 460 #endif // defined(TARGET_OS_OPENBSD)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698