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

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