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

Side by Side Diff: base/platform_file_posix.cc

Issue 17779003: Port base/files/file_util_proxy to Native Client. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Comment tweaks. Created 7 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 | Annotate | Revision Log
« no previous file with comments | « base/platform_file.cc ('k') | no next file » | 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 Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/platform_file.h" 5 #include "base/platform_file.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <errno.h> 8 #include <errno.h>
9 #include <sys/stat.h> 9 #include <sys/stat.h>
10 #include <unistd.h> 10 #include <unistd.h>
11 11
12 #include "base/files/file_path.h" 12 #include "base/files/file_path.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/metrics/sparse_histogram.h" 14 #include "base/metrics/sparse_histogram.h"
15 #include "base/posix/eintr_wrapper.h" 15 #include "base/posix/eintr_wrapper.h"
16 #include "base/strings/utf_string_conversions.h" 16 #include "base/strings/utf_string_conversions.h"
17 #include "base/threading/thread_restrictions.h" 17 #include "base/threading/thread_restrictions.h"
18 18
19 #if defined(OS_ANDROID) 19 #if defined(OS_ANDROID)
20 #include "base/os_compat_android.h" 20 #include "base/os_compat_android.h"
21 #endif 21 #endif
22 22
23 namespace base { 23 namespace base {
24 24
25 // Make sure our Whence mappings match the system headers. 25 // Make sure our Whence mappings match the system headers.
26 COMPILE_ASSERT(PLATFORM_FILE_FROM_BEGIN == SEEK_SET && 26 COMPILE_ASSERT(PLATFORM_FILE_FROM_BEGIN == SEEK_SET &&
27 PLATFORM_FILE_FROM_CURRENT == SEEK_CUR && 27 PLATFORM_FILE_FROM_CURRENT == SEEK_CUR &&
28 PLATFORM_FILE_FROM_END == SEEK_END, whence_matches_system); 28 PLATFORM_FILE_FROM_END == SEEK_END, whence_matches_system);
29 29
30 #if defined(OS_BSD) || defined(OS_MACOSX) 30 namespace {
31
32 #if defined(OS_BSD) || defined(OS_MACOSX) || defined(OS_NACL)
31 typedef struct stat stat_wrapper_t; 33 typedef struct stat stat_wrapper_t;
32 static int CallFstat(int fd, stat_wrapper_t *sb) { 34 static int CallFstat(int fd, stat_wrapper_t *sb) {
33 base::ThreadRestrictions::AssertIOAllowed(); 35 base::ThreadRestrictions::AssertIOAllowed();
34 return fstat(fd, sb); 36 return fstat(fd, sb);
35 } 37 }
36 #else 38 #else
37 typedef struct stat64 stat_wrapper_t; 39 typedef struct stat64 stat_wrapper_t;
38 static int CallFstat(int fd, stat_wrapper_t *sb) { 40 static int CallFstat(int fd, stat_wrapper_t *sb) {
39 base::ThreadRestrictions::AssertIOAllowed(); 41 base::ThreadRestrictions::AssertIOAllowed();
40 return fstat64(fd, sb); 42 return fstat64(fd, sb);
41 } 43 }
42 #endif 44 #endif
43 45
46 // NaCl doesn't provide the following system calls, so either simulate them or
47 // wrap them in order to minimize the number of #ifdef's in this file.
48 #if !defined(OS_NACL)
49 static int DoPread(PlatformFile file, char* data, int size, int64 offset) {
50 return HANDLE_EINTR(pread(file, data, size, offset));
51 }
52
53 static int DoPwrite(PlatformFile file, const char* data, int size,
54 int64 offset) {
55 return HANDLE_EINTR(pwrite(file, data, size, offset));
56 }
57
58 static bool IsOpenAppend(PlatformFile file) {
59 return (fcntl(file, F_GETFL) & O_APPEND) != 0;
60 }
61
62 static int CallFtruncate(PlatformFile file, int64 length) {
63 return HANDLE_EINTR(ftruncate(file, length));
64 }
65
66 static int CallFsync(PlatformFile file) {
67 return HANDLE_EINTR(fsync(file));
68 }
69
70 static int CallFutimes(PlatformFile file, const struct timeval times[2]) {
71 #ifdef __USE_XOPEN2K8
72 // futimens should be available, but futimes might not be
73 // http://pubs.opengroup.org/onlinepubs/9699919799/
74
75 timespec ts_times[2];
76 ts_times[0].tv_sec = times[0].tv_sec;
77 ts_times[0].tv_nsec = times[0].tv_usec * 1000;
78 ts_times[1].tv_sec = times[1].tv_sec;
79 ts_times[1].tv_nsec = times[1].tv_usec * 1000;
80
81 return futimens(file, ts_times);
82 #else
83 return futimes(file, times);
84 #endif
85 }
86 #else // defined(OS_NACL)
87 // TODO(bbudge) Remove DoPread, DoPwrite when NaCl implements pread, pwrite.
88 static int DoPread(PlatformFile file, char* data, int size, int64 offset) {
89 lseek(file, static_cast<off_t>(offset), SEEK_SET);
90 return HANDLE_EINTR(read(file, data, size));
91 }
92
93 static int DoPwrite(PlatformFile file, const char* data, int size,
94 int64 offset) {
95 lseek(file, static_cast<off_t>(offset), SEEK_SET);
96 return HANDLE_EINTR(write(file, data, size));
97 }
98
99 static bool IsOpenAppend(PlatformFile file) {
100 // NaCl doesn't implement fcntl. Since NaCl's write conforms to the POSIX
101 // standard and always appends if the file is opened with O_APPEND, just
102 // return false here.
103 return false;
104 }
105
106 static int CallFtruncate(PlatformFile file, int64 length) {
107 NOTIMPLEMENTED(); // NaCl doesn't implement ftruncate.
108 return 0;
109 }
110
111 static int CallFsync(PlatformFile file) {
112 NOTIMPLEMENTED(); // NaCl doesn't implement fsync.
113 return 0;
114 }
115
116 static int CallFutimes(PlatformFile file, const struct timeval times[2]) {
117 NOTIMPLEMENTED(); // NaCl doesn't implement futimes.
118 return 0;
119 }
120 #endif // defined(OS_NACL)
121
122 } // namespace
123
124 // NaCl doesn't implement system calls to open files directly.
125 #if !defined(OS_NACL)
44 // TODO(erikkay): does it make sense to support PLATFORM_FILE_EXCLUSIVE_* here? 126 // TODO(erikkay): does it make sense to support PLATFORM_FILE_EXCLUSIVE_* here?
45 PlatformFile CreatePlatformFileUnsafe(const FilePath& name, 127 PlatformFile CreatePlatformFileUnsafe(const FilePath& name,
46 int flags, 128 int flags,
47 bool* created, 129 bool* created,
48 PlatformFileError* error) { 130 PlatformFileError* error) {
49 base::ThreadRestrictions::AssertIOAllowed(); 131 base::ThreadRestrictions::AssertIOAllowed();
50 132
51 int open_flags = 0; 133 int open_flags = 0;
52 if (flags & PLATFORM_FILE_CREATE) 134 if (flags & PLATFORM_FILE_CREATE)
53 open_flags = O_CREAT | O_EXCL; 135 open_flags = O_CREAT | O_EXCL;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 else 214 else
133 *error = ErrnoToPlatformFileError(errno); 215 *error = ErrnoToPlatformFileError(errno);
134 } 216 }
135 217
136 return descriptor; 218 return descriptor;
137 } 219 }
138 220
139 FILE* FdopenPlatformFile(PlatformFile file, const char* mode) { 221 FILE* FdopenPlatformFile(PlatformFile file, const char* mode) {
140 return fdopen(file, mode); 222 return fdopen(file, mode);
141 } 223 }
224 #endif // !defined(OS_NACL)
142 225
143 bool ClosePlatformFile(PlatformFile file) { 226 bool ClosePlatformFile(PlatformFile file) {
144 base::ThreadRestrictions::AssertIOAllowed(); 227 base::ThreadRestrictions::AssertIOAllowed();
145 return !HANDLE_EINTR(close(file)); 228 return !HANDLE_EINTR(close(file));
146 } 229 }
147 230
148 int64 SeekPlatformFile(PlatformFile file, 231 int64 SeekPlatformFile(PlatformFile file,
149 PlatformFileWhence whence, 232 PlatformFileWhence whence,
150 int64 offset) { 233 int64 offset) {
151 base::ThreadRestrictions::AssertIOAllowed(); 234 base::ThreadRestrictions::AssertIOAllowed();
152 if (file < 0 || offset < 0) 235 if (file < 0 || offset < 0)
153 return -1; 236 return -1;
154 237
155 return lseek(file, static_cast<off_t>(offset), static_cast<int>(whence)); 238 return lseek(file, static_cast<off_t>(offset), static_cast<int>(whence));
156 } 239 }
157 240
158 int ReadPlatformFile(PlatformFile file, int64 offset, char* data, int size) { 241 int ReadPlatformFile(PlatformFile file, int64 offset, char* data, int size) {
159 base::ThreadRestrictions::AssertIOAllowed(); 242 base::ThreadRestrictions::AssertIOAllowed();
160 if (file < 0 || size < 0) 243 if (file < 0 || size < 0)
161 return -1; 244 return -1;
162 245
163 int bytes_read = 0; 246 int bytes_read = 0;
164 int rv; 247 int rv;
165 do { 248 do {
166 rv = HANDLE_EINTR(pread(file, data + bytes_read, 249 rv = DoPread(file, data + bytes_read,
167 size - bytes_read, offset + bytes_read)); 250 size - bytes_read, offset + bytes_read);
168 if (rv <= 0) 251 if (rv <= 0)
169 break; 252 break;
170 253
171 bytes_read += rv; 254 bytes_read += rv;
172 } while (bytes_read < size); 255 } while (bytes_read < size);
173 256
174 return bytes_read ? bytes_read : rv; 257 return bytes_read ? bytes_read : rv;
175 } 258 }
176 259
177 int ReadPlatformFileAtCurrentPos(PlatformFile file, char* data, int size) { 260 int ReadPlatformFileAtCurrentPos(PlatformFile file, char* data, int size) {
(...skipping 13 matching lines...) Expand all
191 274
192 return bytes_read ? bytes_read : rv; 275 return bytes_read ? bytes_read : rv;
193 } 276 }
194 277
195 int ReadPlatformFileNoBestEffort(PlatformFile file, int64 offset, 278 int ReadPlatformFileNoBestEffort(PlatformFile file, int64 offset,
196 char* data, int size) { 279 char* data, int size) {
197 base::ThreadRestrictions::AssertIOAllowed(); 280 base::ThreadRestrictions::AssertIOAllowed();
198 if (file < 0) 281 if (file < 0)
199 return -1; 282 return -1;
200 283
201 return HANDLE_EINTR(pread(file, data, size, offset)); 284 return DoPread(file, data, size, offset);
202 } 285 }
203 286
204 int ReadPlatformFileCurPosNoBestEffort(PlatformFile file, 287 int ReadPlatformFileCurPosNoBestEffort(PlatformFile file,
205 char* data, int size) { 288 char* data, int size) {
206 base::ThreadRestrictions::AssertIOAllowed(); 289 base::ThreadRestrictions::AssertIOAllowed();
207 if (file < 0 || size < 0) 290 if (file < 0 || size < 0)
208 return -1; 291 return -1;
209 292
210 return HANDLE_EINTR(read(file, data, size)); 293 return HANDLE_EINTR(read(file, data, size));
211 } 294 }
212 295
213 int WritePlatformFile(PlatformFile file, int64 offset, 296 int WritePlatformFile(PlatformFile file, int64 offset,
214 const char* data, int size) { 297 const char* data, int size) {
215 base::ThreadRestrictions::AssertIOAllowed(); 298 base::ThreadRestrictions::AssertIOAllowed();
216 299
217 if (fcntl(file, F_GETFL) & O_APPEND) 300 if (IsOpenAppend(file))
218 return WritePlatformFileAtCurrentPos(file, data, size); 301 return WritePlatformFileAtCurrentPos(file, data, size);
219 302
220 if (file < 0 || size < 0) 303 if (file < 0 || size < 0)
221 return -1; 304 return -1;
222 305
223 int bytes_written = 0; 306 int bytes_written = 0;
224 int rv; 307 int rv;
225 do { 308 do {
226 rv = HANDLE_EINTR(pwrite(file, data + bytes_written, 309 rv = DoPwrite(file, data + bytes_written,
227 size - bytes_written, offset + bytes_written)); 310 size - bytes_written, offset + bytes_written);
228 if (rv <= 0) 311 if (rv <= 0)
229 break; 312 break;
230 313
231 bytes_written += rv; 314 bytes_written += rv;
232 } while (bytes_written < size); 315 } while (bytes_written < size);
233 316
234 return bytes_written ? bytes_written : rv; 317 return bytes_written ? bytes_written : rv;
235 } 318 }
236 319
237 int WritePlatformFileAtCurrentPos(PlatformFile file, 320 int WritePlatformFileAtCurrentPos(PlatformFile file,
(...skipping 19 matching lines...) Expand all
257 const char* data, int size) { 340 const char* data, int size) {
258 base::ThreadRestrictions::AssertIOAllowed(); 341 base::ThreadRestrictions::AssertIOAllowed();
259 if (file < 0 || size < 0) 342 if (file < 0 || size < 0)
260 return -1; 343 return -1;
261 344
262 return HANDLE_EINTR(write(file, data, size)); 345 return HANDLE_EINTR(write(file, data, size));
263 } 346 }
264 347
265 bool TruncatePlatformFile(PlatformFile file, int64 length) { 348 bool TruncatePlatformFile(PlatformFile file, int64 length) {
266 base::ThreadRestrictions::AssertIOAllowed(); 349 base::ThreadRestrictions::AssertIOAllowed();
267 return ((file >= 0) && !HANDLE_EINTR(ftruncate(file, length))); 350 return ((file >= 0) && !CallFtruncate(file, length));
268 } 351 }
269 352
270 bool FlushPlatformFile(PlatformFile file) { 353 bool FlushPlatformFile(PlatformFile file) {
271 base::ThreadRestrictions::AssertIOAllowed(); 354 base::ThreadRestrictions::AssertIOAllowed();
272 return !HANDLE_EINTR(fsync(file)); 355 return !CallFsync(file);
273 } 356 }
274 357
275 bool TouchPlatformFile(PlatformFile file, const base::Time& last_access_time, 358 bool TouchPlatformFile(PlatformFile file, const base::Time& last_access_time,
276 const base::Time& last_modified_time) { 359 const base::Time& last_modified_time) {
277 base::ThreadRestrictions::AssertIOAllowed(); 360 base::ThreadRestrictions::AssertIOAllowed();
278 if (file < 0) 361 if (file < 0)
279 return false; 362 return false;
280 363
281 timeval times[2]; 364 timeval times[2];
282 times[0] = last_access_time.ToTimeVal(); 365 times[0] = last_access_time.ToTimeVal();
283 times[1] = last_modified_time.ToTimeVal(); 366 times[1] = last_modified_time.ToTimeVal();
284 367
285 #ifdef __USE_XOPEN2K8 368 return !CallFutimes(file, times);
286 // futimens should be available, but futimes might not be
287 // http://pubs.opengroup.org/onlinepubs/9699919799/
288
289 timespec ts_times[2];
290 ts_times[0].tv_sec = times[0].tv_sec;
291 ts_times[0].tv_nsec = times[0].tv_usec * 1000;
292 ts_times[1].tv_sec = times[1].tv_sec;
293 ts_times[1].tv_nsec = times[1].tv_usec * 1000;
294
295 return !futimens(file, ts_times);
296 #else
297 return !futimes(file, times);
298 #endif
299 } 369 }
300 370
301 bool GetPlatformFileInfo(PlatformFile file, PlatformFileInfo* info) { 371 bool GetPlatformFileInfo(PlatformFile file, PlatformFileInfo* info) {
302 if (!info) 372 if (!info)
303 return false; 373 return false;
304 374
305 stat_wrapper_t file_info; 375 stat_wrapper_t file_info;
306 if (CallFstat(file, &file_info)) 376 if (CallFstat(file, &file_info))
307 return false; 377 return false;
308 378
309 info->is_directory = S_ISDIR(file_info.st_mode); 379 info->is_directory = S_ISDIR(file_info.st_mode);
310 info->is_symbolic_link = S_ISLNK(file_info.st_mode); 380 info->is_symbolic_link = S_ISLNK(file_info.st_mode);
311 info->size = file_info.st_size; 381 info->size = file_info.st_size;
312 info->last_modified = base::Time::FromTimeT(file_info.st_mtime); 382 info->last_modified = base::Time::FromTimeT(file_info.st_mtime);
313 info->last_accessed = base::Time::FromTimeT(file_info.st_atime); 383 info->last_accessed = base::Time::FromTimeT(file_info.st_atime);
314 info->creation_time = base::Time::FromTimeT(file_info.st_ctime); 384 info->creation_time = base::Time::FromTimeT(file_info.st_ctime);
315 return true; 385 return true;
316 } 386 }
317 387
318 PlatformFileError ErrnoToPlatformFileError(int saved_errno) { 388 PlatformFileError ErrnoToPlatformFileError(int saved_errno) {
319 switch (saved_errno) { 389 switch (saved_errno) {
320 case EACCES: 390 case EACCES:
321 case EISDIR: 391 case EISDIR:
322 case EROFS: 392 case EROFS:
323 case EPERM: 393 case EPERM:
324 return PLATFORM_FILE_ERROR_ACCESS_DENIED; 394 return PLATFORM_FILE_ERROR_ACCESS_DENIED;
395 #if !defined(OS_NACL) // ETXTBSY not defined by NaCl.
325 case ETXTBSY: 396 case ETXTBSY:
326 return PLATFORM_FILE_ERROR_IN_USE; 397 return PLATFORM_FILE_ERROR_IN_USE;
398 #endif
327 case EEXIST: 399 case EEXIST:
328 return PLATFORM_FILE_ERROR_EXISTS; 400 return PLATFORM_FILE_ERROR_EXISTS;
329 case ENOENT: 401 case ENOENT:
330 return PLATFORM_FILE_ERROR_NOT_FOUND; 402 return PLATFORM_FILE_ERROR_NOT_FOUND;
331 case EMFILE: 403 case EMFILE:
332 return PLATFORM_FILE_ERROR_TOO_MANY_OPENED; 404 return PLATFORM_FILE_ERROR_TOO_MANY_OPENED;
333 case ENOMEM: 405 case ENOMEM:
334 return PLATFORM_FILE_ERROR_NO_MEMORY; 406 return PLATFORM_FILE_ERROR_NO_MEMORY;
335 case ENOSPC: 407 case ENOSPC:
336 return PLATFORM_FILE_ERROR_NO_SPACE; 408 return PLATFORM_FILE_ERROR_NO_SPACE;
337 case ENOTDIR: 409 case ENOTDIR:
338 return PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; 410 return PLATFORM_FILE_ERROR_NOT_A_DIRECTORY;
339 default: 411 default:
340 #if !defined(OS_NACL) // NaCl build has no metrics code. 412 #if !defined(OS_NACL) // NaCl build has no metrics code.
341 UMA_HISTOGRAM_SPARSE_SLOWLY("PlatformFile.UnknownErrors.Posix", 413 UMA_HISTOGRAM_SPARSE_SLOWLY("PlatformFile.UnknownErrors.Posix",
342 saved_errno); 414 saved_errno);
343 #endif 415 #endif
344 return PLATFORM_FILE_ERROR_FAILED; 416 return PLATFORM_FILE_ERROR_FAILED;
345 } 417 }
346 } 418 }
347 419
348 } // namespace base 420 } // namespace base
OLDNEW
« no previous file with comments | « base/platform_file.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698