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

Side by Side Diff: net/base/file_stream_posix.cc

Issue 7583049: Record UMA statistics for file_stream operations. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Saved the error code in case it's modified by recording it. Created 9 years, 4 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
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 // For 64-bit file access (off_t = off64_t, lseek64, etc). 5 // For 64-bit file access (off_t = off64_t, lseek64, etc).
6 #define _FILE_OFFSET_BITS 64 6 #define _FILE_OFFSET_BITS 64
7 7
8 #include "net/base/file_stream.h" 8 #include "net/base/file_stream.h"
9 9
10 #include <sys/types.h> 10 #include <sys/types.h>
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 case EACCES: 55 case EACCES:
56 return ERR_ACCESS_DENIED; 56 return ERR_ACCESS_DENIED;
57 default: 57 default:
58 LOG(WARNING) << "Unknown error " << err << " mapped to net::ERR_FAILED"; 58 LOG(WARNING) << "Unknown error " << err << " mapped to net::ERR_FAILED";
59 return ERR_FAILED; 59 return ERR_FAILED;
60 } 60 }
61 } 61 }
62 62
63 // ReadFile() is a simple wrapper around read() that handles EINTR signals and 63 // ReadFile() is a simple wrapper around read() that handles EINTR signals and
64 // calls MapErrorCode() to map errno to net error codes. 64 // calls MapErrorCode() to map errno to net error codes.
65 int ReadFile(base::PlatformFile file, char* buf, int buf_len) { 65 int ReadFile(base::PlatformFile file, char* buf, int buf_len, int class_flags) {
66 base::ThreadRestrictions::AssertIOAllowed(); 66 base::ThreadRestrictions::AssertIOAllowed();
67 // read(..., 0) returns 0 to indicate end-of-file. 67 // read(..., 0) returns 0 to indicate end-of-file.
68 68
69 // Loop in the case of getting interrupted by a signal. 69 // Loop in the case of getting interrupted by a signal.
70 ssize_t res = HANDLE_EINTR(read(file, buf, static_cast<size_t>(buf_len))); 70 ssize_t res = HANDLE_EINTR(read(file, buf, static_cast<size_t>(buf_len)));
71 if (res == static_cast<ssize_t>(-1)) 71 if (res == static_cast<ssize_t>(-1)) {
72 return MapErrorCode(errno); 72 int error = errno;
73 RecordFileError(error, FILE_ERROR_TYPES_READ, class_flags);
74 return MapErrorCode(error);
75 }
73 return static_cast<int>(res); 76 return static_cast<int>(res);
74 } 77 }
75 78
76 void ReadFileTask(base::PlatformFile file, 79 void ReadFileTask(base::PlatformFile file,
77 char* buf, 80 char* buf,
78 int buf_len, 81 int buf_len,
82 int class_flags,
79 CompletionCallback* callback) { 83 CompletionCallback* callback) {
80 callback->Run(ReadFile(file, buf, buf_len)); 84 callback->Run(ReadFile(file, buf, buf_len, class_flags));
81 } 85 }
82 86
83 // WriteFile() is a simple wrapper around write() that handles EINTR signals and 87 // WriteFile() is a simple wrapper around write() that handles EINTR signals and
84 // calls MapErrorCode() to map errno to net error codes. It tries to write to 88 // calls MapErrorCode() to map errno to net error codes. It tries to write to
85 // completion. 89 // completion.
86 int WriteFile(base::PlatformFile file, const char* buf, int buf_len) { 90 int WriteFile(base::PlatformFile file, const char* buf, int buf_len,
91 int class_flags) {
87 base::ThreadRestrictions::AssertIOAllowed(); 92 base::ThreadRestrictions::AssertIOAllowed();
88 ssize_t res = HANDLE_EINTR(write(file, buf, buf_len)); 93 ssize_t res = HANDLE_EINTR(write(file, buf, buf_len));
89 if (res == -1) 94 if (res == -1) {
90 return MapErrorCode(errno); 95 int error = errno;
96 RecordFileError(error, FILE_ERROR_TYPES_WRITE, class_flags);
97 return MapErrorCode(error);
98 }
91 return res; 99 return res;
92 } 100 }
93 101
94 void WriteFileTask(base::PlatformFile file, 102 void WriteFileTask(base::PlatformFile file,
95 const char* buf, 103 const char* buf,
96 int buf_len, 104 int buf_len, int class_flags,
97 CompletionCallback* callback) { 105 CompletionCallback* callback) {
98 callback->Run(WriteFile(file, buf, buf_len)); 106 callback->Run(WriteFile(file, buf, buf_len, class_flags));
99 } 107 }
100 108
101 // FlushFile() is a simple wrapper around fsync() that handles EINTR signals and 109 // FlushFile() is a simple wrapper around fsync() that handles EINTR signals and
102 // calls MapErrorCode() to map errno to net error codes. It tries to flush to 110 // calls MapErrorCode() to map errno to net error codes. It tries to flush to
103 // completion. 111 // completion.
104 int FlushFile(base::PlatformFile file) { 112 int FlushFile(base::PlatformFile file, int class_flags) {
105 base::ThreadRestrictions::AssertIOAllowed(); 113 base::ThreadRestrictions::AssertIOAllowed();
106 ssize_t res = HANDLE_EINTR(fsync(file)); 114 ssize_t res = HANDLE_EINTR(fsync(file));
107 if (res == -1) 115 if (res == -1) {
108 return MapErrorCode(errno); 116 int error = errno;
117 RecordFileError(error, FILE_ERROR_TYPES_FLUSH, class_flags);
118 return MapErrorCode(error);
119 }
109 return res; 120 return res;
110 } 121 }
111 122
112 } // namespace 123 } // namespace
113 124
114 // CancelableCallbackTask takes ownership of the Callback. This task gets 125 // CancelableCallbackTask takes ownership of the Callback. This task gets
115 // posted to the MessageLoopForIO instance. 126 // posted to the MessageLoopForIO instance.
116 class CancelableCallbackTask : public CancelableTask { 127 class CancelableCallbackTask : public CancelableTask {
117 public: 128 public:
118 explicit CancelableCallbackTask(Callback0::Type* callback) 129 explicit CancelableCallbackTask(Callback0::Type* callback)
(...skipping 15 matching lines...) Expand all
134 145
135 // FileStream::AsyncContext ---------------------------------------------- 146 // FileStream::AsyncContext ----------------------------------------------
136 147
137 class FileStream::AsyncContext { 148 class FileStream::AsyncContext {
138 public: 149 public:
139 AsyncContext(); 150 AsyncContext();
140 ~AsyncContext(); 151 ~AsyncContext();
141 152
142 // These methods post synchronous read() and write() calls to a WorkerThread. 153 // These methods post synchronous read() and write() calls to a WorkerThread.
143 void InitiateAsyncRead( 154 void InitiateAsyncRead(
144 base::PlatformFile file, char* buf, int buf_len, 155 base::PlatformFile file, char* buf, int buf_len, int class_flags,
145 CompletionCallback* callback); 156 CompletionCallback* callback);
146 void InitiateAsyncWrite( 157 void InitiateAsyncWrite(
147 base::PlatformFile file, const char* buf, int buf_len, 158 base::PlatformFile file, const char* buf, int buf_len, int class_flags,
148 CompletionCallback* callback); 159 CompletionCallback* callback);
149 160
150 CompletionCallback* callback() const { return callback_; } 161 CompletionCallback* callback() const { return callback_; }
151 162
152 // Called by the WorkerPool thread executing the IO after the IO completes. 163 // Called by the WorkerPool thread executing the IO after the IO completes.
153 // This method queues RunAsynchronousCallback() on the MessageLoop and signals 164 // This method queues RunAsynchronousCallback() on the MessageLoop and signals
154 // |background_io_completed_callback_|, in case the destructor is waiting. In 165 // |background_io_completed_callback_|, in case the destructor is waiting. In
155 // that case, the destructor will call RunAsynchronousCallback() instead, and 166 // that case, the destructor will call RunAsynchronousCallback() instead, and
156 // cancel |message_loop_task_|. 167 // cancel |message_loop_task_|.
157 // |result| is the result of the Read/Write task. 168 // |result| is the result of the Read/Write task.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 RunAsynchronousCallback(); 215 RunAsynchronousCallback();
205 if (need_to_wait) { 216 if (need_to_wait) {
206 // We want to see if we block the message loop for too long. 217 // We want to see if we block the message loop for too long.
207 UMA_HISTOGRAM_TIMES("AsyncIO.FileStreamClose", 218 UMA_HISTOGRAM_TIMES("AsyncIO.FileStreamClose",
208 base::TimeTicks::Now() - start); 219 base::TimeTicks::Now() - start);
209 } 220 }
210 } 221 }
211 } 222 }
212 223
213 void FileStream::AsyncContext::InitiateAsyncRead( 224 void FileStream::AsyncContext::InitiateAsyncRead(
214 base::PlatformFile file, char* buf, int buf_len, 225 base::PlatformFile file, char* buf, int buf_len, int class_flags,
215 CompletionCallback* callback) { 226 CompletionCallback* callback) {
216 DCHECK(!callback_); 227 DCHECK(!callback_);
217 callback_ = callback; 228 callback_ = callback;
218 229
219 base::WorkerPool::PostTask(FROM_HERE, 230 base::WorkerPool::PostTask(FROM_HERE,
220 NewRunnableFunction( 231 NewRunnableFunction(
221 &ReadFileTask, 232 &ReadFileTask,
222 file, buf, buf_len, 233 file, buf, buf_len, class_flags,
223 &background_io_completed_callback_), 234 &background_io_completed_callback_),
224 true /* task_is_slow */); 235 true /* task_is_slow */);
225 } 236 }
226 237
227 void FileStream::AsyncContext::InitiateAsyncWrite( 238 void FileStream::AsyncContext::InitiateAsyncWrite(
228 base::PlatformFile file, const char* buf, int buf_len, 239 base::PlatformFile file, const char* buf, int buf_len, int class_flags,
229 CompletionCallback* callback) { 240 CompletionCallback* callback) {
230 DCHECK(!callback_); 241 DCHECK(!callback_);
231 callback_ = callback; 242 callback_ = callback;
232 243
233 base::WorkerPool::PostTask(FROM_HERE, 244 base::WorkerPool::PostTask(FROM_HERE,
234 NewRunnableFunction( 245 NewRunnableFunction(
235 &WriteFileTask, 246 &WriteFileTask,
236 file, buf, buf_len, 247 file, buf, buf_len, class_flags,
237 &background_io_completed_callback_), 248 &background_io_completed_callback_),
238 true /* task_is_slow */); 249 true /* task_is_slow */);
239 } 250 }
240 251
241 void FileStream::AsyncContext::OnBackgroundIOCompleted(int result) { 252 void FileStream::AsyncContext::OnBackgroundIOCompleted(int result) {
242 result_ = result; 253 result_ = result;
243 message_loop_task_ = new CancelableCallbackTask( 254 message_loop_task_ = new CancelableCallbackTask(
244 NewCallback(this, &AsyncContext::RunAsynchronousCallback)); 255 NewCallback(this, &AsyncContext::RunAsynchronousCallback));
245 message_loop_->PostTask(FROM_HERE, message_loop_task_); 256 message_loop_->PostTask(FROM_HERE, message_loop_task_);
246 background_io_completed_.Signal(); 257 background_io_completed_.Signal();
(...skipping 20 matching lines...) Expand all
267 std::swap(temp, callback_); 278 std::swap(temp, callback_);
268 background_io_completed_.Reset(); 279 background_io_completed_.Reset();
269 temp->Run(result_); 280 temp->Run(result_);
270 } 281 }
271 282
272 // FileStream ------------------------------------------------------------ 283 // FileStream ------------------------------------------------------------
273 284
274 FileStream::FileStream() 285 FileStream::FileStream()
275 : file_(base::kInvalidPlatformFileValue), 286 : file_(base::kInvalidPlatformFileValue),
276 open_flags_(0), 287 open_flags_(0),
277 auto_closed_(true) { 288 auto_closed_(true) {
cbentzel 2011/08/15 19:49:11 class_flags_ needs to be initialized.
ahendrickson 2011/08/15 23:42:26 Done.
278 DCHECK(!IsOpen()); 289 DCHECK(!IsOpen());
279 } 290 }
280 291
292 FileStream::FileStream(int class_flags)
293 : file_(base::kInvalidPlatformFileValue),
294 open_flags_(0),
295 auto_closed_(true),
296 class_flags_(class_flags) {
297 DCHECK(!IsOpen());
298 }
299
281 FileStream::FileStream(base::PlatformFile file, int flags) 300 FileStream::FileStream(base::PlatformFile file, int flags)
282 : file_(file), 301 : file_(file),
283 open_flags_(flags), 302 open_flags_(flags),
284 auto_closed_(false) { 303 auto_closed_(false) {
cbentzel 2011/08/15 19:49:11 class_flags_ needs to be initialized.
ahendrickson 2011/08/15 23:42:26 Done.
285 // If the file handle is opened with base::PLATFORM_FILE_ASYNC, we need to 304 // If the file handle is opened with base::PLATFORM_FILE_ASYNC, we need to
286 // make sure we will perform asynchronous File IO to it. 305 // make sure we will perform asynchronous File IO to it.
287 if (flags & base::PLATFORM_FILE_ASYNC) { 306 if (flags & base::PLATFORM_FILE_ASYNC) {
288 async_context_.reset(new AsyncContext()); 307 async_context_.reset(new AsyncContext());
289 } 308 }
290 } 309 }
291 310
311 FileStream::FileStream(base::PlatformFile file, int flags, int class_flags)
312 : file_(file),
313 open_flags_(flags),
314 auto_closed_(false),
315 class_flags_(class_flags) {
316 // If the file handle is opened with base::PLATFORM_FILE_ASYNC, we need to
317 // make sure we will perform asynchronous File IO to it.
318 if (flags & base::PLATFORM_FILE_ASYNC) {
319 async_context_.reset(new AsyncContext());
320 }
321 }
322
292 FileStream::~FileStream() { 323 FileStream::~FileStream() {
293 if (auto_closed_) 324 if (auto_closed_)
294 Close(); 325 Close();
295 } 326 }
296 327
297 void FileStream::Close() { 328 void FileStream::Close() {
298 // Abort any existing asynchronous operations. 329 // Abort any existing asynchronous operations.
299 async_context_.reset(); 330 async_context_.reset();
300 331
301 if (file_ != base::kInvalidPlatformFileValue) { 332 if (file_ != base::kInvalidPlatformFileValue) {
302 if (close(file_) != 0) { 333 if (close(file_) != 0) {
303 NOTREACHED(); 334 NOTREACHED();
304 } 335 }
305 file_ = base::kInvalidPlatformFileValue; 336 file_ = base::kInvalidPlatformFileValue;
306 } 337 }
307 } 338 }
308 339
309 int FileStream::Open(const FilePath& path, int open_flags) { 340 int FileStream::Open(const FilePath& path, int open_flags) {
310 if (IsOpen()) { 341 if (IsOpen()) {
311 DLOG(FATAL) << "File is already open!"; 342 DLOG(FATAL) << "File is already open!";
312 return ERR_UNEXPECTED; 343 return ERR_UNEXPECTED;
313 } 344 }
314 345
315 open_flags_ = open_flags; 346 open_flags_ = open_flags;
316 file_ = base::CreatePlatformFile(path, open_flags_, NULL, NULL); 347 file_ = base::CreatePlatformFile(path, open_flags_, NULL, NULL);
317 if (file_ == base::kInvalidPlatformFileValue) { 348 if (file_ == base::kInvalidPlatformFileValue) {
318 return MapErrorCode(errno); 349 int error = errno;
350 RecordFileError(error, FILE_ERROR_TYPES_OPEN, class_flags_);
351 return MapErrorCode(error);
319 } 352 }
320 353
321 if (open_flags_ & base::PLATFORM_FILE_ASYNC) { 354 if (open_flags_ & base::PLATFORM_FILE_ASYNC) {
322 async_context_.reset(new AsyncContext()); 355 async_context_.reset(new AsyncContext());
323 } 356 }
324 357
325 return OK; 358 return OK;
326 } 359 }
327 360
328 bool FileStream::IsOpen() const { 361 bool FileStream::IsOpen() const {
329 return file_ != base::kInvalidPlatformFileValue; 362 return file_ != base::kInvalidPlatformFileValue;
330 } 363 }
331 364
332 int64 FileStream::Seek(Whence whence, int64 offset) { 365 int64 FileStream::Seek(Whence whence, int64 offset) {
333 base::ThreadRestrictions::AssertIOAllowed(); 366 base::ThreadRestrictions::AssertIOAllowed();
334 367
335 if (!IsOpen()) 368 if (!IsOpen()) {
369 RecordFileError(EINVAL, FILE_ERROR_TYPES_IS_NOT_OPEN, class_flags_);
336 return ERR_UNEXPECTED; 370 return ERR_UNEXPECTED;
371 }
337 372
338 // If we're in async, make sure we don't have a request in flight. 373 // If we're in async, make sure we don't have a request in flight.
339 DCHECK(!async_context_.get() || !async_context_->callback()); 374 DCHECK(!async_context_.get() || !async_context_->callback());
340 375
341 off_t res = lseek(file_, static_cast<off_t>(offset), 376 off_t res = lseek(file_, static_cast<off_t>(offset),
342 static_cast<int>(whence)); 377 static_cast<int>(whence));
343 if (res == static_cast<off_t>(-1)) 378 if (res == static_cast<off_t>(-1)) {
344 return MapErrorCode(errno); 379 int error = errno;
380 RecordFileError(error, FILE_ERROR_TYPES_SEEK, class_flags_);
381 return MapErrorCode(error);
382 }
345 383
346 return res; 384 return res;
347 } 385 }
348 386
349 int64 FileStream::Available() { 387 int64 FileStream::Available() {
350 base::ThreadRestrictions::AssertIOAllowed(); 388 base::ThreadRestrictions::AssertIOAllowed();
351 389
352 if (!IsOpen()) 390 if (!IsOpen()) {
391 RecordFileError(EINVAL, FILE_ERROR_TYPES_IS_NOT_OPEN, class_flags_);
353 return ERR_UNEXPECTED; 392 return ERR_UNEXPECTED;
393 }
354 394
355 int64 cur_pos = Seek(FROM_CURRENT, 0); 395 int64 cur_pos = Seek(FROM_CURRENT, 0);
356 if (cur_pos < 0) 396 if (cur_pos < 0)
357 return cur_pos; 397 return cur_pos;
358 398
359 struct stat info; 399 struct stat info;
360 if (fstat(file_, &info) != 0) 400 if (fstat(file_, &info) != 0) {
361 return MapErrorCode(errno); 401 int error = errno;
362 402 RecordFileError(error, FILE_ERROR_TYPES_GET_SIZE, class_flags_);
403 return MapErrorCode(error);
404 }
363 int64 size = static_cast<int64>(info.st_size); 405 int64 size = static_cast<int64>(info.st_size);
364 DCHECK_GT(size, cur_pos); 406 DCHECK_GT(size, cur_pos);
365 407
366 return size - cur_pos; 408 return size - cur_pos;
367 } 409 }
368 410
369 int FileStream::Read( 411 int FileStream::Read(
370 char* buf, int buf_len, CompletionCallback* callback) { 412 char* buf, int buf_len, CompletionCallback* callback) {
371 if (!IsOpen()) 413 if (!IsOpen()) {
414 RecordFileError(EINVAL, FILE_ERROR_TYPES_IS_NOT_OPEN, class_flags_);
372 return ERR_UNEXPECTED; 415 return ERR_UNEXPECTED;
416 }
373 417
374 // read(..., 0) will return 0, which indicates end-of-file. 418 // read(..., 0) will return 0, which indicates end-of-file.
375 DCHECK(buf_len > 0); 419 DCHECK(buf_len > 0);
376 DCHECK(open_flags_ & base::PLATFORM_FILE_READ); 420 DCHECK(open_flags_ & base::PLATFORM_FILE_READ);
377 421
378 if (async_context_.get()) { 422 if (async_context_.get()) {
379 DCHECK(open_flags_ & base::PLATFORM_FILE_ASYNC); 423 DCHECK(open_flags_ & base::PLATFORM_FILE_ASYNC);
380 // If we're in async, make sure we don't have a request in flight. 424 // If we're in async, make sure we don't have a request in flight.
381 DCHECK(!async_context_->callback()); 425 DCHECK(!async_context_->callback());
382 async_context_->InitiateAsyncRead(file_, buf, buf_len, callback); 426 async_context_->InitiateAsyncRead(file_, buf, buf_len, class_flags_,
427 callback);
383 return ERR_IO_PENDING; 428 return ERR_IO_PENDING;
384 } else { 429 } else {
385 return ReadFile(file_, buf, buf_len); 430 return ReadFile(file_, buf, buf_len, class_flags_);
386 } 431 }
387 } 432 }
388 433
389 int FileStream::ReadUntilComplete(char *buf, int buf_len) { 434 int FileStream::ReadUntilComplete(char *buf, int buf_len) {
390 int to_read = buf_len; 435 int to_read = buf_len;
391 int bytes_total = 0; 436 int bytes_total = 0;
392 437
393 do { 438 do {
394 int bytes_read = Read(buf, to_read, NULL); 439 int bytes_read = Read(buf, to_read, NULL);
395 if (bytes_read <= 0) { 440 if (bytes_read <= 0) {
396 if (bytes_total == 0) 441 if (bytes_total == 0)
397 return bytes_read; 442 return bytes_read;
398 443
399 return bytes_total; 444 return bytes_total;
400 } 445 }
401 446
402 bytes_total += bytes_read; 447 bytes_total += bytes_read;
403 buf += bytes_read; 448 buf += bytes_read;
404 to_read -= bytes_read; 449 to_read -= bytes_read;
405 } while (bytes_total < buf_len); 450 } while (bytes_total < buf_len);
406 451
407 return bytes_total; 452 return bytes_total;
408 } 453 }
409 454
410 int FileStream::Write( 455 int FileStream::Write(
411 const char* buf, int buf_len, CompletionCallback* callback) { 456 const char* buf, int buf_len, CompletionCallback* callback) {
412 // write(..., 0) will return 0, which indicates end-of-file. 457 // write(..., 0) will return 0, which indicates end-of-file.
413 DCHECK_GT(buf_len, 0); 458 DCHECK_GT(buf_len, 0);
414 459
415 if (!IsOpen()) 460 if (!IsOpen()) {
461 RecordFileError(EINVAL, FILE_ERROR_TYPES_IS_NOT_OPEN, class_flags_);
416 return ERR_UNEXPECTED; 462 return ERR_UNEXPECTED;
463 }
417 464
418 if (async_context_.get()) { 465 if (async_context_.get()) {
419 DCHECK(open_flags_ & base::PLATFORM_FILE_ASYNC); 466 DCHECK(open_flags_ & base::PLATFORM_FILE_ASYNC);
420 // If we're in async, make sure we don't have a request in flight. 467 // If we're in async, make sure we don't have a request in flight.
421 DCHECK(!async_context_->callback()); 468 DCHECK(!async_context_->callback());
422 async_context_->InitiateAsyncWrite(file_, buf, buf_len, callback); 469 async_context_->InitiateAsyncWrite(file_, buf, buf_len, class_flags_,
470 callback);
423 return ERR_IO_PENDING; 471 return ERR_IO_PENDING;
424 } else { 472 } else {
425 return WriteFile(file_, buf, buf_len); 473 return WriteFile(file_, buf, buf_len, class_flags_);
426 } 474 }
427 } 475 }
428 476
429 int64 FileStream::Truncate(int64 bytes) { 477 int64 FileStream::Truncate(int64 bytes) {
430 base::ThreadRestrictions::AssertIOAllowed(); 478 base::ThreadRestrictions::AssertIOAllowed();
431 479
432 if (!IsOpen()) 480 if (!IsOpen()) {
481 RecordFileError(EINVAL, FILE_ERROR_TYPES_IS_NOT_OPEN, class_flags_);
433 return ERR_UNEXPECTED; 482 return ERR_UNEXPECTED;
483 }
434 484
435 // We better be open for reading. 485 // We better be open for reading.
436 DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE); 486 DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE);
437 487
438 // Seek to the position to truncate from. 488 // Seek to the position to truncate from.
439 int64 seek_position = Seek(FROM_BEGIN, bytes); 489 int64 seek_position = Seek(FROM_BEGIN, bytes);
440 if (seek_position != bytes) 490 if (seek_position != bytes)
441 return ERR_UNEXPECTED; 491 return ERR_UNEXPECTED;
442 492
443 // And truncate the file. 493 // And truncate the file.
444 int result = ftruncate(file_, bytes); 494 int result = ftruncate(file_, bytes);
445 return result == 0 ? seek_position : MapErrorCode(errno); 495 if (result == 0)
496 return seek_position;
497
498 int error = errno;
499 RecordFileError(error, FILE_ERROR_TYPES_SET_EOF, class_flags_);
500 return MapErrorCode(error);
446 } 501 }
447 502
448 int FileStream::Flush() { 503 int FileStream::Flush() {
449 if (!IsOpen()) 504 if (!IsOpen()) {
505 RecordFileError(EINVAL, FILE_ERROR_TYPES_IS_NOT_OPEN, class_flags_);
450 return ERR_UNEXPECTED; 506 return ERR_UNEXPECTED;
507 }
451 508
452 return FlushFile(file_); 509 return FlushFile(file_, class_flags_);
510 }
511
512 void FileStream::EnableRecording(bool enable, int class_flags) {
513 if (enable)
514 class_flags_ |= class_flags;
515 else
516 class_flags_ &= ~class_flags;
453 } 517 }
454 518
455 } // namespace net 519 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698