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

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

Issue 63363010: Add support for working with large files, in dart:io. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 1 month 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 | Annotate | Revision Log
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_LINUX) 6 #if defined(TARGET_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
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 <unistd.h> // NOLINT 14 #include <unistd.h> // NOLINT
14 #include <libgen.h> // NOLINT 15 #include <libgen.h> // NOLINT
15 16
16 #include "bin/builtin.h" 17 #include "bin/builtin.h"
17 #include "bin/log.h" 18 #include "bin/log.h"
18 19
19 20
20 namespace dart { 21 namespace dart {
21 namespace bin { 22 namespace bin {
22 23
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 return TEMP_FAILURE_RETRY(read(handle_->fd(), buffer, num_bytes)); 66 return TEMP_FAILURE_RETRY(read(handle_->fd(), buffer, num_bytes));
66 } 67 }
67 68
68 69
69 int64_t File::Write(const void* buffer, int64_t num_bytes) { 70 int64_t File::Write(const void* buffer, int64_t num_bytes) {
70 ASSERT(handle_->fd() >= 0); 71 ASSERT(handle_->fd() >= 0);
71 return TEMP_FAILURE_RETRY(write(handle_->fd(), buffer, num_bytes)); 72 return TEMP_FAILURE_RETRY(write(handle_->fd(), buffer, num_bytes));
72 } 73 }
73 74
74 75
75 off_t File::Position() { 76 off64_t File::Position() {
76 ASSERT(handle_->fd() >= 0); 77 ASSERT(handle_->fd() >= 0);
77 return TEMP_FAILURE_RETRY(lseek(handle_->fd(), 0, SEEK_CUR)); 78 return lseek64(handle_->fd(), 0, SEEK_CUR);
78 } 79 }
79 80
80 81
81 bool File::SetPosition(int64_t position) { 82 bool File::SetPosition(off64_t position) {
82 ASSERT(handle_->fd() >= 0); 83 ASSERT(handle_->fd() >= 0);
83 return TEMP_FAILURE_RETRY(lseek(handle_->fd(), position, SEEK_SET) != -1); 84 return lseek64(handle_->fd(), position, SEEK_SET) >= 0;
84 } 85 }
85 86
86 87
87 bool File::Truncate(int64_t length) { 88 bool File::Truncate(off64_t length) {
88 ASSERT(handle_->fd() >= 0); 89 ASSERT(handle_->fd() >= 0);
89 return TEMP_FAILURE_RETRY(ftruncate(handle_->fd(), length) != -1); 90 return TEMP_FAILURE_RETRY(ftruncate64(handle_->fd(), length) != -1);
90 } 91 }
91 92
92 93
93 bool File::Flush() { 94 bool File::Flush() {
94 ASSERT(handle_->fd() >= 0); 95 ASSERT(handle_->fd() >= 0);
95 return TEMP_FAILURE_RETRY(fsync(handle_->fd()) != -1); 96 return TEMP_FAILURE_RETRY(fsync(handle_->fd()) != -1);
96 } 97 }
97 98
98 99
99 off_t File::Length() { 100 off64_t File::Length() {
100 ASSERT(handle_->fd() >= 0); 101 ASSERT(handle_->fd() >= 0);
101 struct stat st; 102 struct stat64 st;
102 if (TEMP_FAILURE_RETRY(fstat(handle_->fd(), &st)) == 0) { 103 if (TEMP_FAILURE_RETRY(fstat64(handle_->fd(), &st)) == 0) {
103 return st.st_size; 104 return st.st_size;
104 } 105 }
105 return -1; 106 return -1;
106 } 107 }
107 108
108 109
109 File* File::Open(const char* name, FileOpenMode mode) { 110 File* File::Open(const char* name, FileOpenMode mode) {
110 // Report errors for non-regular files. 111 // Report errors for non-regular files.
111 struct stat st; 112 struct stat64 st;
112 if (TEMP_FAILURE_RETRY(stat(name, &st)) == 0) { 113 if (TEMP_FAILURE_RETRY(stat64(name, &st)) == 0) {
113 // Only accept regular files and character devices. 114 // Only accept regular files and character devices.
114 if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode)) { 115 if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode)) {
115 errno = (S_ISDIR(st.st_mode)) ? EISDIR : ENOENT; 116 errno = (S_ISDIR(st.st_mode)) ? EISDIR : ENOENT;
116 return NULL; 117 return NULL;
117 } 118 }
118 } 119 }
119 int flags = O_RDONLY; 120 int flags = O_RDONLY;
120 if ((mode & kWrite) != 0) { 121 if ((mode & kWrite) != 0) {
121 flags = (O_RDWR | O_CREAT); 122 flags = (O_RDWR | O_CREAT);
122 } 123 }
123 if ((mode & kTruncate) != 0) { 124 if ((mode & kTruncate) != 0) {
124 flags = flags | O_TRUNC; 125 flags = flags | O_TRUNC;
125 } 126 }
126 flags |= O_CLOEXEC; 127 flags |= O_CLOEXEC;
127 int fd = TEMP_FAILURE_RETRY(open(name, flags, 0666)); 128 int fd = TEMP_FAILURE_RETRY(open64(name, flags, 0666));
128 if (fd < 0) { 129 if (fd < 0) {
129 return NULL; 130 return NULL;
130 } 131 }
131 if (((mode & kWrite) != 0) && ((mode & kTruncate) == 0)) { 132 if (((mode & kWrite) != 0) && ((mode & kTruncate) == 0)) {
132 int position = TEMP_FAILURE_RETRY(lseek(fd, 0, SEEK_END)); 133 off64_t position = lseek64(fd, 0, SEEK_END);
133 if (position < 0) { 134 if (position < 0) {
134 return NULL; 135 return NULL;
135 } 136 }
136 } 137 }
137 return new File(new FileHandle(fd)); 138 return new File(new FileHandle(fd));
138 } 139 }
139 140
140 141
141 File* File::OpenStdio(int fd) { 142 File* File::OpenStdio(int fd) {
142 if (fd < 0 || 2 < fd) return NULL; 143 if (fd < 0 || 2 < fd) return NULL;
143 return new File(new FileHandle(fd)); 144 return new File(new FileHandle(fd));
144 } 145 }
145 146
146 147
147 bool File::Exists(const char* name) { 148 bool File::Exists(const char* name) {
148 struct stat st; 149 struct stat64 st;
149 if (TEMP_FAILURE_RETRY(stat(name, &st)) == 0) { 150 if (TEMP_FAILURE_RETRY(stat64(name, &st)) == 0) {
150 return S_ISREG(st.st_mode); 151 return S_ISREG(st.st_mode);
151 } else { 152 } else {
152 return false; 153 return false;
153 } 154 }
154 } 155 }
155 156
156 157
157 bool File::Create(const char* name) { 158 bool File::Create(const char* name) {
158 int fd = TEMP_FAILURE_RETRY(open(name, O_RDONLY | O_CREAT | O_CLOEXEC, 0666)); 159 int fd = TEMP_FAILURE_RETRY(
160 open64(name, O_RDONLY | O_CREAT | O_CLOEXEC, 0666));
159 if (fd < 0) { 161 if (fd < 0) {
160 return false; 162 return false;
161 } 163 }
162 return (close(fd) == 0); 164 return (close(fd) == 0);
163 } 165 }
164 166
165 167
166 bool File::CreateLink(const char* name, const char* target) { 168 bool File::CreateLink(const char* name, const char* target) {
167 int status = TEMP_FAILURE_RETRY(symlink(target, name)); 169 int status = TEMP_FAILURE_RETRY(symlink(target, name));
168 return (status == 0); 170 return (status == 0);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 return TEMP_FAILURE_RETRY(rename(old_path, new_path)) == 0; 213 return TEMP_FAILURE_RETRY(rename(old_path, new_path)) == 0;
212 } else if (type == kIsDirectory) { 214 } else if (type == kIsDirectory) {
213 errno = EISDIR; 215 errno = EISDIR;
214 } else { 216 } else {
215 errno = EINVAL; 217 errno = EINVAL;
216 } 218 }
217 return false; 219 return false;
218 } 220 }
219 221
220 222
221 off_t File::LengthFromPath(const char* name) { 223 off64_t File::LengthFromPath(const char* name) {
222 struct stat st; 224 struct stat64 st;
223 if (TEMP_FAILURE_RETRY(stat(name, &st)) == 0) { 225 if (TEMP_FAILURE_RETRY(stat64(name, &st)) == 0) {
224 return st.st_size; 226 return st.st_size;
225 } 227 }
226 return -1; 228 return -1;
227 } 229 }
228 230
229 231
230 void File::Stat(const char* name, int64_t* data) { 232 void File::Stat(const char* name, int64_t* data) {
231 struct stat st; 233 struct stat64 st;
232 if (TEMP_FAILURE_RETRY(stat(name, &st)) == 0) { 234 if (TEMP_FAILURE_RETRY(stat64(name, &st)) == 0) {
233 if (S_ISREG(st.st_mode)) { 235 if (S_ISREG(st.st_mode)) {
234 data[kType] = kIsFile; 236 data[kType] = kIsFile;
235 } else if (S_ISDIR(st.st_mode)) { 237 } else if (S_ISDIR(st.st_mode)) {
236 data[kType] = kIsDirectory; 238 data[kType] = kIsDirectory;
237 } else if (S_ISLNK(st.st_mode)) { 239 } else if (S_ISLNK(st.st_mode)) {
238 data[kType] = kIsLink; 240 data[kType] = kIsLink;
239 } else { 241 } else {
240 data[kType] = kDoesNotExist; 242 data[kType] = kDoesNotExist;
241 } 243 }
242 data[kCreatedTime] = st.st_ctime; 244 data[kCreatedTime] = st.st_ctime;
243 data[kModifiedTime] = st.st_mtime; 245 data[kModifiedTime] = st.st_mtime;
244 data[kAccessedTime] = st.st_atime; 246 data[kAccessedTime] = st.st_atime;
245 data[kMode] = st.st_mode; 247 data[kMode] = st.st_mode;
246 data[kSize] = st.st_size; 248 data[kSize] = st.st_size;
247 } else { 249 } else {
248 data[kType] = kDoesNotExist; 250 data[kType] = kDoesNotExist;
249 } 251 }
250 } 252 }
251 253
252 254
253 time_t File::LastModified(const char* name) { 255 time_t File::LastModified(const char* name) {
254 struct stat st; 256 struct stat64 st;
255 if (TEMP_FAILURE_RETRY(stat(name, &st)) == 0) { 257 if (TEMP_FAILURE_RETRY(stat64(name, &st)) == 0) {
256 return st.st_mtime; 258 return st.st_mtime;
257 } 259 }
258 return -1; 260 return -1;
259 } 261 }
260 262
261 263
262 char* File::LinkTarget(const char* pathname) { 264 char* File::LinkTarget(const char* pathname) {
263 struct stat link_stats; 265 struct stat64 link_stats;
264 if (lstat(pathname, &link_stats) != 0) return NULL; 266 if (lstat64(pathname, &link_stats) != 0) return NULL;
265 if (!S_ISLNK(link_stats.st_mode)) { 267 if (!S_ISLNK(link_stats.st_mode)) {
266 errno = ENOENT; 268 errno = ENOENT;
267 return NULL; 269 return NULL;
268 } 270 }
269 size_t target_size = link_stats.st_size; 271 size_t target_size = link_stats.st_size;
270 char* target_name = reinterpret_cast<char*>(malloc(target_size + 1)); 272 char* target_name = reinterpret_cast<char*>(malloc(target_size + 1));
271 size_t read_size = readlink(pathname, target_name, target_size + 1); 273 size_t read_size = readlink(pathname, target_name, target_size + 1);
272 if (read_size != target_size) { 274 if (read_size != target_size) {
273 free(target_name); 275 free(target_name);
274 return NULL; 276 return NULL;
(...skipping 25 matching lines...) Expand all
300 } 302 }
301 303
302 304
303 const char* File::StringEscapedPathSeparator() { 305 const char* File::StringEscapedPathSeparator() {
304 return "/"; 306 return "/";
305 } 307 }
306 308
307 309
308 File::StdioHandleType File::GetStdioHandleType(int fd) { 310 File::StdioHandleType File::GetStdioHandleType(int fd) {
309 ASSERT(0 <= fd && fd <= 2); 311 ASSERT(0 <= fd && fd <= 2);
310 struct stat buf; 312 struct stat64 buf;
311 int result = fstat(fd, &buf); 313 int result = fstat64(fd, &buf);
312 if (result == -1) { 314 if (result == -1) {
313 const int kBufferSize = 1024; 315 const int kBufferSize = 1024;
314 char error_buf[kBufferSize]; 316 char error_buf[kBufferSize];
315 FATAL2("Failed stat on file descriptor %d: %s", fd, 317 FATAL2("Failed stat on file descriptor %d: %s", fd,
316 strerror_r(errno, error_buf, kBufferSize)); 318 strerror_r(errno, error_buf, kBufferSize));
317 } 319 }
318 if (S_ISCHR(buf.st_mode)) return kTerminal; 320 if (S_ISCHR(buf.st_mode)) return kTerminal;
319 if (S_ISFIFO(buf.st_mode)) return kPipe; 321 if (S_ISFIFO(buf.st_mode)) return kPipe;
320 if (S_ISSOCK(buf.st_mode)) return kSocket; 322 if (S_ISSOCK(buf.st_mode)) return kSocket;
321 if (S_ISREG(buf.st_mode)) return kFile; 323 if (S_ISREG(buf.st_mode)) return kFile;
322 return kOther; 324 return kOther;
323 } 325 }
324 326
325 327
326 File::Type File::GetType(const char* pathname, bool follow_links) { 328 File::Type File::GetType(const char* pathname, bool follow_links) {
327 struct stat entry_info; 329 struct stat64 entry_info;
328 int stat_success; 330 int stat_success;
329 if (follow_links) { 331 if (follow_links) {
330 stat_success = TEMP_FAILURE_RETRY(stat(pathname, &entry_info)); 332 stat_success = TEMP_FAILURE_RETRY(stat64(pathname, &entry_info));
331 } else { 333 } else {
332 stat_success = TEMP_FAILURE_RETRY(lstat(pathname, &entry_info)); 334 stat_success = TEMP_FAILURE_RETRY(lstat64(pathname, &entry_info));
333 } 335 }
334 if (stat_success == -1) return File::kDoesNotExist; 336 if (stat_success == -1) return File::kDoesNotExist;
335 if (S_ISDIR(entry_info.st_mode)) return File::kIsDirectory; 337 if (S_ISDIR(entry_info.st_mode)) return File::kIsDirectory;
336 if (S_ISREG(entry_info.st_mode)) return File::kIsFile; 338 if (S_ISREG(entry_info.st_mode)) return File::kIsFile;
337 if (S_ISLNK(entry_info.st_mode)) return File::kIsLink; 339 if (S_ISLNK(entry_info.st_mode)) return File::kIsLink;
338 return File::kDoesNotExist; 340 return File::kDoesNotExist;
339 } 341 }
340 342
341 343
342 File::Identical File::AreIdentical(const char* file_1, const char* file_2) { 344 File::Identical File::AreIdentical(const char* file_1, const char* file_2) {
343 struct stat file_1_info; 345 struct stat64 file_1_info;
344 struct stat file_2_info; 346 struct stat64 file_2_info;
345 if (TEMP_FAILURE_RETRY(lstat(file_1, &file_1_info)) == -1 || 347 if (TEMP_FAILURE_RETRY(lstat64(file_1, &file_1_info)) == -1 ||
346 TEMP_FAILURE_RETRY(lstat(file_2, &file_2_info)) == -1) { 348 TEMP_FAILURE_RETRY(lstat64(file_2, &file_2_info)) == -1) {
347 return File::kError; 349 return File::kError;
348 } 350 }
349 return (file_1_info.st_ino == file_2_info.st_ino && 351 return (file_1_info.st_ino == file_2_info.st_ino &&
350 file_1_info.st_dev == file_2_info.st_dev) ? 352 file_1_info.st_dev == file_2_info.st_dev) ?
351 File::kIdentical : 353 File::kIdentical :
352 File::kDifferent; 354 File::kDifferent;
353 } 355 }
354 356
355 } // namespace bin 357 } // namespace bin
356 } // namespace dart 358 } // namespace dart
357 359
358 #endif // defined(TARGET_OS_LINUX) 360 #endif // defined(TARGET_OS_LINUX)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698