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

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: Move NaCl workaround into platform_file_posix.cc. 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
« base/files/file_util_proxy.cc ('K') | « 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 // TODO(bbudge) Remove NaCl workarounds when it implements pread and pwrite.
47 #if !defined(OS_NACL)
48 static int CallPread(PlatformFile file, char* data, int size, int64 offset) {
49 return HANDLE_EINTR(pread(file, data, size, offset));
50 }
51 static int CallPwrite(PlatformFile file, const char* data, int size,
52 int64 offset) {
53 return HANDLE_EINTR(pwrite(file, data, size, offset));
54 }
55 #else
56 static int CallPread(PlatformFile file, char* data, int size, int64 offset) {
57 lseek(file, static_cast<off_t>(offset), SEEK_SET);
58 return HANDLE_EINTR(read(file, data, size));
59 }
60 static int CallPwrite(PlatformFile file, const char* data, int size,
61 int64 offset) {
62 lseek(file, static_cast<off_t>(offset), SEEK_SET);
63 return HANDLE_EINTR(write(file, data, size));
64 }
65 #endif
66
67 } // namespace
68
69 // NaCl lacks many file handling system calls, so exclude any platform file
70 // functions that can't be implemented there.
71 #if !defined(OS_NACL)
44 // TODO(erikkay): does it make sense to support PLATFORM_FILE_EXCLUSIVE_* here? 72 // TODO(erikkay): does it make sense to support PLATFORM_FILE_EXCLUSIVE_* here?
45 PlatformFile CreatePlatformFileUnsafe(const FilePath& name, 73 PlatformFile CreatePlatformFileUnsafe(const FilePath& name,
46 int flags, 74 int flags,
47 bool* created, 75 bool* created,
48 PlatformFileError* error) { 76 PlatformFileError* error) {
49 base::ThreadRestrictions::AssertIOAllowed(); 77 base::ThreadRestrictions::AssertIOAllowed();
50 78
51 int open_flags = 0; 79 int open_flags = 0;
52 if (flags & PLATFORM_FILE_CREATE) 80 if (flags & PLATFORM_FILE_CREATE)
53 open_flags = O_CREAT | O_EXCL; 81 open_flags = O_CREAT | O_EXCL;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 else 160 else
133 *error = ErrnoToPlatformFileError(errno); 161 *error = ErrnoToPlatformFileError(errno);
134 } 162 }
135 163
136 return descriptor; 164 return descriptor;
137 } 165 }
138 166
139 FILE* FdopenPlatformFile(PlatformFile file, const char* mode) { 167 FILE* FdopenPlatformFile(PlatformFile file, const char* mode) {
140 return fdopen(file, mode); 168 return fdopen(file, mode);
141 } 169 }
170 #endif // !defined(OS_NACL)
142 171
143 bool ClosePlatformFile(PlatformFile file) { 172 bool ClosePlatformFile(PlatformFile file) {
144 base::ThreadRestrictions::AssertIOAllowed(); 173 base::ThreadRestrictions::AssertIOAllowed();
145 return !HANDLE_EINTR(close(file)); 174 return !HANDLE_EINTR(close(file));
146 } 175 }
147 176
148 int64 SeekPlatformFile(PlatformFile file, 177 int64 SeekPlatformFile(PlatformFile file,
149 PlatformFileWhence whence, 178 PlatformFileWhence whence,
150 int64 offset) { 179 int64 offset) {
151 base::ThreadRestrictions::AssertIOAllowed(); 180 base::ThreadRestrictions::AssertIOAllowed();
152 if (file < 0 || offset < 0) 181 if (file < 0 || offset < 0)
153 return -1; 182 return -1;
154 183
155 return lseek(file, static_cast<off_t>(offset), static_cast<int>(whence)); 184 return lseek(file, static_cast<off_t>(offset), static_cast<int>(whence));
156 } 185 }
157 186
158 int ReadPlatformFile(PlatformFile file, int64 offset, char* data, int size) { 187 int ReadPlatformFile(PlatformFile file, int64 offset, char* data, int size) {
159 base::ThreadRestrictions::AssertIOAllowed(); 188 base::ThreadRestrictions::AssertIOAllowed();
160 if (file < 0 || size < 0) 189 if (file < 0 || size < 0)
161 return -1; 190 return -1;
162 191
163 int bytes_read = 0; 192 int bytes_read = 0;
164 int rv; 193 int rv;
165 do { 194 do {
166 rv = HANDLE_EINTR(pread(file, data + bytes_read, 195 rv = CallPread(file, data + bytes_read,
167 size - bytes_read, offset + bytes_read)); 196 size - bytes_read, offset + bytes_read);
168 if (rv <= 0) 197 if (rv <= 0)
169 break; 198 break;
170 199
171 bytes_read += rv; 200 bytes_read += rv;
172 } while (bytes_read < size); 201 } while (bytes_read < size);
173 202
174 return bytes_read ? bytes_read : rv; 203 return bytes_read ? bytes_read : rv;
175 } 204 }
176 205
177 int ReadPlatformFileAtCurrentPos(PlatformFile file, char* data, int size) { 206 int ReadPlatformFileAtCurrentPos(PlatformFile file, char* data, int size) {
(...skipping 13 matching lines...) Expand all
191 220
192 return bytes_read ? bytes_read : rv; 221 return bytes_read ? bytes_read : rv;
193 } 222 }
194 223
195 int ReadPlatformFileNoBestEffort(PlatformFile file, int64 offset, 224 int ReadPlatformFileNoBestEffort(PlatformFile file, int64 offset,
196 char* data, int size) { 225 char* data, int size) {
197 base::ThreadRestrictions::AssertIOAllowed(); 226 base::ThreadRestrictions::AssertIOAllowed();
198 if (file < 0) 227 if (file < 0)
199 return -1; 228 return -1;
200 229
201 return HANDLE_EINTR(pread(file, data, size, offset)); 230 return CallPread(file, data, size, offset);
202 } 231 }
203 232
204 int ReadPlatformFileCurPosNoBestEffort(PlatformFile file, 233 int ReadPlatformFileCurPosNoBestEffort(PlatformFile file,
205 char* data, int size) { 234 char* data, int size) {
206 base::ThreadRestrictions::AssertIOAllowed(); 235 base::ThreadRestrictions::AssertIOAllowed();
207 if (file < 0 || size < 0) 236 if (file < 0 || size < 0)
208 return -1; 237 return -1;
209 238
210 return HANDLE_EINTR(read(file, data, size)); 239 return HANDLE_EINTR(read(file, data, size));
211 } 240 }
212 241
213 int WritePlatformFile(PlatformFile file, int64 offset, 242 int WritePlatformFile(PlatformFile file, int64 offset,
214 const char* data, int size) { 243 const char* data, int size) {
215 base::ThreadRestrictions::AssertIOAllowed(); 244 base::ThreadRestrictions::AssertIOAllowed();
216 245
246 #if !defined(OS_NACL) // NaCl has no fcntl, but it shouldn't be needed here.
217 if (fcntl(file, F_GETFL) & O_APPEND) 247 if (fcntl(file, F_GETFL) & O_APPEND)
218 return WritePlatformFileAtCurrentPos(file, data, size); 248 return WritePlatformFileAtCurrentPos(file, data, size);
249 #endif // !defined(OS_NACL)
219 250
220 if (file < 0 || size < 0) 251 if (file < 0 || size < 0)
221 return -1; 252 return -1;
222 253
223 int bytes_written = 0; 254 int bytes_written = 0;
224 int rv; 255 int rv;
225 do { 256 do {
226 rv = HANDLE_EINTR(pwrite(file, data + bytes_written, 257 rv = CallPwrite(file, data + bytes_written,
227 size - bytes_written, offset + bytes_written)); 258 size - bytes_written, offset + bytes_written);
228 if (rv <= 0) 259 if (rv <= 0)
229 break; 260 break;
230 261
231 bytes_written += rv; 262 bytes_written += rv;
232 } while (bytes_written < size); 263 } while (bytes_written < size);
233 264
234 return bytes_written ? bytes_written : rv; 265 return bytes_written ? bytes_written : rv;
235 } 266 }
236 267
237 int WritePlatformFileAtCurrentPos(PlatformFile file, 268 int WritePlatformFileAtCurrentPos(PlatformFile file,
(...skipping 17 matching lines...) Expand all
255 286
256 int WritePlatformFileCurPosNoBestEffort(PlatformFile file, 287 int WritePlatformFileCurPosNoBestEffort(PlatformFile file,
257 const char* data, int size) { 288 const char* data, int size) {
258 base::ThreadRestrictions::AssertIOAllowed(); 289 base::ThreadRestrictions::AssertIOAllowed();
259 if (file < 0 || size < 0) 290 if (file < 0 || size < 0)
260 return -1; 291 return -1;
261 292
262 return HANDLE_EINTR(write(file, data, size)); 293 return HANDLE_EINTR(write(file, data, size));
263 } 294 }
264 295
296 #if !defined(OS_NACL) // NaCl has no ftruncate or fsync.
265 bool TruncatePlatformFile(PlatformFile file, int64 length) { 297 bool TruncatePlatformFile(PlatformFile file, int64 length) {
266 base::ThreadRestrictions::AssertIOAllowed(); 298 base::ThreadRestrictions::AssertIOAllowed();
267 return ((file >= 0) && !HANDLE_EINTR(ftruncate(file, length))); 299 return ((file >= 0) && !HANDLE_EINTR(ftruncate(file, length)));
268 } 300 }
269 301
270 bool FlushPlatformFile(PlatformFile file) { 302 bool FlushPlatformFile(PlatformFile file) {
271 base::ThreadRestrictions::AssertIOAllowed(); 303 base::ThreadRestrictions::AssertIOAllowed();
272 return !HANDLE_EINTR(fsync(file)); 304 return !HANDLE_EINTR(fsync(file));
273 } 305 }
306 #endif // !defined(OS_NACL)
274 307
308 #if !defined(OS_NACL)
275 bool TouchPlatformFile(PlatformFile file, const base::Time& last_access_time, 309 bool TouchPlatformFile(PlatformFile file, const base::Time& last_access_time,
276 const base::Time& last_modified_time) { 310 const base::Time& last_modified_time) {
277 base::ThreadRestrictions::AssertIOAllowed(); 311 base::ThreadRestrictions::AssertIOAllowed();
278 if (file < 0) 312 if (file < 0)
279 return false; 313 return false;
280 314
281 timeval times[2]; 315 timeval times[2];
282 times[0] = last_access_time.ToTimeVal(); 316 times[0] = last_access_time.ToTimeVal();
283 times[1] = last_modified_time.ToTimeVal(); 317 times[1] = last_modified_time.ToTimeVal();
284 318
285 #ifdef __USE_XOPEN2K8 319 #ifdef __USE_XOPEN2K8
286 // futimens should be available, but futimes might not be 320 // futimens should be available, but futimes might not be
287 // http://pubs.opengroup.org/onlinepubs/9699919799/ 321 // http://pubs.opengroup.org/onlinepubs/9699919799/
288 322
289 timespec ts_times[2]; 323 timespec ts_times[2];
290 ts_times[0].tv_sec = times[0].tv_sec; 324 ts_times[0].tv_sec = times[0].tv_sec;
291 ts_times[0].tv_nsec = times[0].tv_usec * 1000; 325 ts_times[0].tv_nsec = times[0].tv_usec * 1000;
292 ts_times[1].tv_sec = times[1].tv_sec; 326 ts_times[1].tv_sec = times[1].tv_sec;
293 ts_times[1].tv_nsec = times[1].tv_usec * 1000; 327 ts_times[1].tv_nsec = times[1].tv_usec * 1000;
294 328
295 return !futimens(file, ts_times); 329 return !futimens(file, ts_times);
296 #else 330 #else
297 return !futimes(file, times); 331 return !futimes(file, times);
298 #endif 332 #endif
299 } 333 }
334 #endif // !defined(OS_NACL)
300 335
301 bool GetPlatformFileInfo(PlatformFile file, PlatformFileInfo* info) { 336 bool GetPlatformFileInfo(PlatformFile file, PlatformFileInfo* info) {
302 if (!info) 337 if (!info)
303 return false; 338 return false;
304 339
305 stat_wrapper_t file_info; 340 stat_wrapper_t file_info;
306 if (CallFstat(file, &file_info)) 341 if (CallFstat(file, &file_info))
307 return false; 342 return false;
308 343
309 info->is_directory = S_ISDIR(file_info.st_mode); 344 info->is_directory = S_ISDIR(file_info.st_mode);
310 info->is_symbolic_link = S_ISLNK(file_info.st_mode); 345 info->is_symbolic_link = S_ISLNK(file_info.st_mode);
311 info->size = file_info.st_size; 346 info->size = file_info.st_size;
312 info->last_modified = base::Time::FromTimeT(file_info.st_mtime); 347 info->last_modified = base::Time::FromTimeT(file_info.st_mtime);
313 info->last_accessed = base::Time::FromTimeT(file_info.st_atime); 348 info->last_accessed = base::Time::FromTimeT(file_info.st_atime);
314 info->creation_time = base::Time::FromTimeT(file_info.st_ctime); 349 info->creation_time = base::Time::FromTimeT(file_info.st_ctime);
315 return true; 350 return true;
316 } 351 }
317 352
318 PlatformFileError ErrnoToPlatformFileError(int saved_errno) { 353 PlatformFileError ErrnoToPlatformFileError(int saved_errno) {
319 switch (saved_errno) { 354 switch (saved_errno) {
320 case EACCES: 355 case EACCES:
321 case EISDIR: 356 case EISDIR:
322 case EROFS: 357 case EROFS:
323 case EPERM: 358 case EPERM:
324 return PLATFORM_FILE_ERROR_ACCESS_DENIED; 359 return PLATFORM_FILE_ERROR_ACCESS_DENIED;
360 #if !defined(OS_NACL) // ETXTBSY not defined by NaCl.
325 case ETXTBSY: 361 case ETXTBSY:
326 return PLATFORM_FILE_ERROR_IN_USE; 362 return PLATFORM_FILE_ERROR_IN_USE;
363 #endif
327 case EEXIST: 364 case EEXIST:
328 return PLATFORM_FILE_ERROR_EXISTS; 365 return PLATFORM_FILE_ERROR_EXISTS;
329 case ENOENT: 366 case ENOENT:
330 return PLATFORM_FILE_ERROR_NOT_FOUND; 367 return PLATFORM_FILE_ERROR_NOT_FOUND;
331 case EMFILE: 368 case EMFILE:
332 return PLATFORM_FILE_ERROR_TOO_MANY_OPENED; 369 return PLATFORM_FILE_ERROR_TOO_MANY_OPENED;
333 case ENOMEM: 370 case ENOMEM:
334 return PLATFORM_FILE_ERROR_NO_MEMORY; 371 return PLATFORM_FILE_ERROR_NO_MEMORY;
335 case ENOSPC: 372 case ENOSPC:
336 return PLATFORM_FILE_ERROR_NO_SPACE; 373 return PLATFORM_FILE_ERROR_NO_SPACE;
337 case ENOTDIR: 374 case ENOTDIR:
338 return PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; 375 return PLATFORM_FILE_ERROR_NOT_A_DIRECTORY;
339 default: 376 default:
340 #if !defined(OS_NACL) // NaCl build has no metrics code. 377 #if !defined(OS_NACL) // NaCl build has no metrics code.
341 UMA_HISTOGRAM_SPARSE_SLOWLY("PlatformFile.UnknownErrors.Posix", 378 UMA_HISTOGRAM_SPARSE_SLOWLY("PlatformFile.UnknownErrors.Posix",
342 saved_errno); 379 saved_errno);
343 #endif 380 #endif
344 return PLATFORM_FILE_ERROR_FAILED; 381 return PLATFORM_FILE_ERROR_FAILED;
345 } 382 }
346 } 383 }
347 384
348 } // namespace base 385 } // namespace base
OLDNEW
« base/files/file_util_proxy.cc ('K') | « base/platform_file.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698