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