OLD | NEW |
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/files/file.h" | 5 #include "base/files/file.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <sys/stat.h> | 9 #include <sys/stat.h> |
10 #include <unistd.h> | 10 #include <unistd.h> |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 created_ = true; | 195 created_ = true; |
196 | 196 |
197 if ((descriptor >= 0) && (flags & FLAG_DELETE_ON_CLOSE)) | 197 if ((descriptor >= 0) && (flags & FLAG_DELETE_ON_CLOSE)) |
198 unlink(name.value().c_str()); | 198 unlink(name.value().c_str()); |
199 | 199 |
200 if (descriptor >= 0) | 200 if (descriptor >= 0) |
201 error_details_ = FILE_OK; | 201 error_details_ = FILE_OK; |
202 else | 202 else |
203 error_details_ = File::OSErrorToFileError(errno); | 203 error_details_ = File::OSErrorToFileError(errno); |
204 | 204 |
205 file_.reset(descriptor); | 205 file_ = descriptor; |
206 } | 206 } |
207 #endif // !defined(OS_NACL) | 207 #endif // !defined(OS_NACL) |
208 | 208 |
209 bool File::IsValid() const { | 209 bool File::IsValid() const { |
210 return file_.is_valid(); | 210 return file_ >= 0; |
211 } | |
212 | |
213 PlatformFile File::GetPlatformFile() const { | |
214 return file_.get(); | |
215 } | 211 } |
216 | 212 |
217 PlatformFile File::TakePlatformFile() { | 213 PlatformFile File::TakePlatformFile() { |
218 return file_.release(); | 214 PlatformFile file = file_; |
| 215 file_ = kInvalidPlatformFileValue; |
| 216 return file; |
219 } | 217 } |
220 | 218 |
221 void File::Close() { | 219 void File::Close() { |
222 if (!IsValid()) | 220 if (!IsValid()) |
223 return; | 221 return; |
224 | 222 |
225 base::ThreadRestrictions::AssertIOAllowed(); | 223 base::ThreadRestrictions::AssertIOAllowed(); |
226 file_.reset(); | 224 if (!IGNORE_EINTR(close(file_))) |
| 225 file_ = kInvalidPlatformFileValue; |
227 } | 226 } |
228 | 227 |
229 int64 File::Seek(Whence whence, int64 offset) { | 228 int64 File::Seek(Whence whence, int64 offset) { |
230 base::ThreadRestrictions::AssertIOAllowed(); | 229 base::ThreadRestrictions::AssertIOAllowed(); |
231 DCHECK(IsValid()); | 230 DCHECK(IsValid()); |
232 if (offset < 0) | 231 if (file_ < 0 || offset < 0) |
233 return -1; | 232 return -1; |
234 | 233 |
235 return lseek(file_.get(), static_cast<off_t>(offset), | 234 return lseek(file_, static_cast<off_t>(offset), static_cast<int>(whence)); |
236 static_cast<int>(whence)); | |
237 } | 235 } |
238 | 236 |
239 int File::Read(int64 offset, char* data, int size) { | 237 int File::Read(int64 offset, char* data, int size) { |
240 base::ThreadRestrictions::AssertIOAllowed(); | 238 base::ThreadRestrictions::AssertIOAllowed(); |
241 DCHECK(IsValid()); | 239 DCHECK(IsValid()); |
242 if (size < 0) | 240 if (size < 0) |
243 return -1; | 241 return -1; |
244 | 242 |
245 int bytes_read = 0; | 243 int bytes_read = 0; |
246 int rv; | 244 int rv; |
247 do { | 245 do { |
248 rv = HANDLE_EINTR(pread(file_.get(), data + bytes_read, | 246 rv = HANDLE_EINTR(pread(file_, data + bytes_read, |
249 size - bytes_read, offset + bytes_read)); | 247 size - bytes_read, offset + bytes_read)); |
250 if (rv <= 0) | 248 if (rv <= 0) |
251 break; | 249 break; |
252 | 250 |
253 bytes_read += rv; | 251 bytes_read += rv; |
254 } while (bytes_read < size); | 252 } while (bytes_read < size); |
255 | 253 |
256 return bytes_read ? bytes_read : rv; | 254 return bytes_read ? bytes_read : rv; |
257 } | 255 } |
258 | 256 |
259 int File::ReadAtCurrentPos(char* data, int size) { | 257 int File::ReadAtCurrentPos(char* data, int size) { |
260 base::ThreadRestrictions::AssertIOAllowed(); | 258 base::ThreadRestrictions::AssertIOAllowed(); |
261 DCHECK(IsValid()); | 259 DCHECK(IsValid()); |
262 if (size < 0) | 260 if (size < 0) |
263 return -1; | 261 return -1; |
264 | 262 |
265 int bytes_read = 0; | 263 int bytes_read = 0; |
266 int rv; | 264 int rv; |
267 do { | 265 do { |
268 rv = HANDLE_EINTR(read(file_.get(), data, size)); | 266 rv = HANDLE_EINTR(read(file_, data, size)); |
269 if (rv <= 0) | 267 if (rv <= 0) |
270 break; | 268 break; |
271 | 269 |
272 bytes_read += rv; | 270 bytes_read += rv; |
273 } while (bytes_read < size); | 271 } while (bytes_read < size); |
274 | 272 |
275 return bytes_read ? bytes_read : rv; | 273 return bytes_read ? bytes_read : rv; |
276 } | 274 } |
277 | 275 |
278 int File::ReadNoBestEffort(int64 offset, char* data, int size) { | 276 int File::ReadNoBestEffort(int64 offset, char* data, int size) { |
279 base::ThreadRestrictions::AssertIOAllowed(); | 277 base::ThreadRestrictions::AssertIOAllowed(); |
280 DCHECK(IsValid()); | 278 DCHECK(IsValid()); |
281 | 279 |
282 return HANDLE_EINTR(pread(file_.get(), data, size, offset)); | 280 return HANDLE_EINTR(pread(file_, data, size, offset)); |
283 } | 281 } |
284 | 282 |
285 int File::ReadAtCurrentPosNoBestEffort(char* data, int size) { | 283 int File::ReadAtCurrentPosNoBestEffort(char* data, int size) { |
286 base::ThreadRestrictions::AssertIOAllowed(); | 284 base::ThreadRestrictions::AssertIOAllowed(); |
287 DCHECK(IsValid()); | 285 DCHECK(IsValid()); |
288 if (size < 0) | 286 if (size < 0) |
289 return -1; | 287 return -1; |
290 | 288 |
291 return HANDLE_EINTR(read(file_.get(), data, size)); | 289 return HANDLE_EINTR(read(file_, data, size)); |
292 } | 290 } |
293 | 291 |
294 int File::Write(int64 offset, const char* data, int size) { | 292 int File::Write(int64 offset, const char* data, int size) { |
295 base::ThreadRestrictions::AssertIOAllowed(); | 293 base::ThreadRestrictions::AssertIOAllowed(); |
296 | 294 |
297 if (IsOpenAppend(file_.get())) | 295 if (IsOpenAppend(file_)) |
298 return WriteAtCurrentPos(data, size); | 296 return WriteAtCurrentPos(data, size); |
299 | 297 |
300 DCHECK(IsValid()); | 298 DCHECK(IsValid()); |
301 if (size < 0) | 299 if (size < 0) |
302 return -1; | 300 return -1; |
303 | 301 |
304 int bytes_written = 0; | 302 int bytes_written = 0; |
305 int rv; | 303 int rv; |
306 do { | 304 do { |
307 rv = HANDLE_EINTR(pwrite(file_.get(), data + bytes_written, | 305 rv = HANDLE_EINTR(pwrite(file_, data + bytes_written, |
308 size - bytes_written, offset + bytes_written)); | 306 size - bytes_written, offset + bytes_written)); |
309 if (rv <= 0) | 307 if (rv <= 0) |
310 break; | 308 break; |
311 | 309 |
312 bytes_written += rv; | 310 bytes_written += rv; |
313 } while (bytes_written < size); | 311 } while (bytes_written < size); |
314 | 312 |
315 return bytes_written ? bytes_written : rv; | 313 return bytes_written ? bytes_written : rv; |
316 } | 314 } |
317 | 315 |
318 int File::WriteAtCurrentPos(const char* data, int size) { | 316 int File::WriteAtCurrentPos(const char* data, int size) { |
319 base::ThreadRestrictions::AssertIOAllowed(); | 317 base::ThreadRestrictions::AssertIOAllowed(); |
320 DCHECK(IsValid()); | 318 DCHECK(IsValid()); |
321 if (size < 0) | 319 if (size < 0) |
322 return -1; | 320 return -1; |
323 | 321 |
324 int bytes_written = 0; | 322 int bytes_written = 0; |
325 int rv; | 323 int rv; |
326 do { | 324 do { |
327 rv = HANDLE_EINTR(write(file_.get(), data, size)); | 325 rv = HANDLE_EINTR(write(file_, data, size)); |
328 if (rv <= 0) | 326 if (rv <= 0) |
329 break; | 327 break; |
330 | 328 |
331 bytes_written += rv; | 329 bytes_written += rv; |
332 } while (bytes_written < size); | 330 } while (bytes_written < size); |
333 | 331 |
334 return bytes_written ? bytes_written : rv; | 332 return bytes_written ? bytes_written : rv; |
335 } | 333 } |
336 | 334 |
337 int File::WriteAtCurrentPosNoBestEffort(const char* data, int size) { | 335 int File::WriteAtCurrentPosNoBestEffort(const char* data, int size) { |
338 base::ThreadRestrictions::AssertIOAllowed(); | 336 base::ThreadRestrictions::AssertIOAllowed(); |
339 DCHECK(IsValid()); | 337 DCHECK(IsValid()); |
340 if (size < 0) | 338 if (size < 0) |
341 return -1; | 339 return -1; |
342 | 340 |
343 return HANDLE_EINTR(write(file_.get(), data, size)); | 341 return HANDLE_EINTR(write(file_, data, size)); |
344 } | 342 } |
345 | 343 |
346 int64 File::GetLength() { | 344 int64 File::GetLength() { |
347 DCHECK(IsValid()); | 345 DCHECK(IsValid()); |
348 | 346 |
349 stat_wrapper_t file_info; | 347 stat_wrapper_t file_info; |
350 if (CallFstat(file_.get(), &file_info)) | 348 if (CallFstat(file_, &file_info)) |
351 return false; | 349 return false; |
352 | 350 |
353 return file_info.st_size; | 351 return file_info.st_size; |
354 } | 352 } |
355 | 353 |
356 bool File::SetLength(int64 length) { | 354 bool File::SetLength(int64 length) { |
357 base::ThreadRestrictions::AssertIOAllowed(); | 355 base::ThreadRestrictions::AssertIOAllowed(); |
358 DCHECK(IsValid()); | 356 DCHECK(IsValid()); |
359 return !CallFtruncate(file_.get(), length); | 357 return !CallFtruncate(file_, length); |
360 } | 358 } |
361 | 359 |
362 bool File::Flush() { | 360 bool File::Flush() { |
363 base::ThreadRestrictions::AssertIOAllowed(); | 361 base::ThreadRestrictions::AssertIOAllowed(); |
364 DCHECK(IsValid()); | 362 DCHECK(IsValid()); |
365 return !CallFsync(file_.get()); | 363 return !CallFsync(file_); |
366 } | 364 } |
367 | 365 |
368 bool File::SetTimes(Time last_access_time, Time last_modified_time) { | 366 bool File::SetTimes(Time last_access_time, Time last_modified_time) { |
369 base::ThreadRestrictions::AssertIOAllowed(); | 367 base::ThreadRestrictions::AssertIOAllowed(); |
370 DCHECK(IsValid()); | 368 DCHECK(IsValid()); |
371 | 369 |
372 timeval times[2]; | 370 timeval times[2]; |
373 times[0] = last_access_time.ToTimeVal(); | 371 times[0] = last_access_time.ToTimeVal(); |
374 times[1] = last_modified_time.ToTimeVal(); | 372 times[1] = last_modified_time.ToTimeVal(); |
375 | 373 |
376 return !CallFutimes(file_.get(), times); | 374 return !CallFutimes(file_, times); |
377 } | 375 } |
378 | 376 |
379 bool File::GetInfo(Info* info) { | 377 bool File::GetInfo(Info* info) { |
380 DCHECK(IsValid()); | 378 DCHECK(IsValid()); |
381 | 379 |
382 stat_wrapper_t file_info; | 380 stat_wrapper_t file_info; |
383 if (CallFstat(file_.get(), &file_info)) | 381 if (CallFstat(file_, &file_info)) |
384 return false; | 382 return false; |
385 | 383 |
386 info->is_directory = S_ISDIR(file_info.st_mode); | 384 info->is_directory = S_ISDIR(file_info.st_mode); |
387 info->is_symbolic_link = S_ISLNK(file_info.st_mode); | 385 info->is_symbolic_link = S_ISLNK(file_info.st_mode); |
388 info->size = file_info.st_size; | 386 info->size = file_info.st_size; |
389 | 387 |
390 #if defined(OS_LINUX) | 388 #if defined(OS_LINUX) |
391 const time_t last_modified_sec = file_info.st_mtim.tv_sec; | 389 const time_t last_modified_sec = file_info.st_mtim.tv_sec; |
392 const int64 last_modified_nsec = file_info.st_mtim.tv_nsec; | 390 const int64 last_modified_nsec = file_info.st_mtim.tv_nsec; |
393 const time_t last_accessed_sec = file_info.st_atim.tv_sec; | 391 const time_t last_accessed_sec = file_info.st_atim.tv_sec; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 base::TimeDelta::FromMicroseconds(last_accessed_nsec / | 425 base::TimeDelta::FromMicroseconds(last_accessed_nsec / |
428 base::Time::kNanosecondsPerMicrosecond); | 426 base::Time::kNanosecondsPerMicrosecond); |
429 info->creation_time = | 427 info->creation_time = |
430 base::Time::FromTimeT(creation_time_sec) + | 428 base::Time::FromTimeT(creation_time_sec) + |
431 base::TimeDelta::FromMicroseconds(creation_time_nsec / | 429 base::TimeDelta::FromMicroseconds(creation_time_nsec / |
432 base::Time::kNanosecondsPerMicrosecond); | 430 base::Time::kNanosecondsPerMicrosecond); |
433 return true; | 431 return true; |
434 } | 432 } |
435 | 433 |
436 File::Error File::Lock() { | 434 File::Error File::Lock() { |
437 return CallFctnlFlock(file_.get(), true); | 435 return CallFctnlFlock(file_, true); |
438 } | 436 } |
439 | 437 |
440 File::Error File::Unlock() { | 438 File::Error File::Unlock() { |
441 return CallFctnlFlock(file_.get(), false); | 439 return CallFctnlFlock(file_, false); |
442 } | 440 } |
443 | 441 |
444 // Static. | 442 // Static. |
445 File::Error File::OSErrorToFileError(int saved_errno) { | 443 File::Error File::OSErrorToFileError(int saved_errno) { |
446 switch (saved_errno) { | 444 switch (saved_errno) { |
447 case EACCES: | 445 case EACCES: |
448 case EISDIR: | 446 case EISDIR: |
449 case EROFS: | 447 case EROFS: |
450 case EPERM: | 448 case EPERM: |
451 return FILE_ERROR_ACCESS_DENIED; | 449 return FILE_ERROR_ACCESS_DENIED; |
(...skipping 16 matching lines...) Expand all Loading... |
468 default: | 466 default: |
469 #if !defined(OS_NACL) // NaCl build has no metrics code. | 467 #if !defined(OS_NACL) // NaCl build has no metrics code. |
470 UMA_HISTOGRAM_SPARSE_SLOWLY("PlatformFile.UnknownErrors.Posix", | 468 UMA_HISTOGRAM_SPARSE_SLOWLY("PlatformFile.UnknownErrors.Posix", |
471 saved_errno); | 469 saved_errno); |
472 #endif | 470 #endif |
473 return FILE_ERROR_FAILED; | 471 return FILE_ERROR_FAILED; |
474 } | 472 } |
475 } | 473 } |
476 | 474 |
477 void File::SetPlatformFile(PlatformFile file) { | 475 void File::SetPlatformFile(PlatformFile file) { |
478 DCHECK(!file_.is_valid()); | 476 DCHECK_EQ(file_, kInvalidPlatformFileValue); |
479 file_.reset(file); | 477 file_ = file; |
480 } | 478 } |
481 | 479 |
482 } // namespace base | 480 } // namespace base |
OLD | NEW |