blob: 5fd18d091a3005d4bb4af591c7ba588fcb96295e [file] [log] [blame]
Gilad Arnold11c066f2012-05-10 14:37:25 -07001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "update_engine/file_descriptor.h"
6
7#include <fcntl.h>
8#include <sys/stat.h>
9#include <sys/types.h>
10
Chris Sosafc661a12013-02-26 14:43:21 -080011#include <base/posix/eintr_wrapper.h>
Gilad Arnold11c066f2012-05-10 14:37:25 -070012
13namespace chromeos_update_engine {
14
15bool EintrSafeFileDescriptor::Open(const char* path, int flags, mode_t mode) {
16 CHECK_EQ(fd_, -1);
17 return ((fd_ = HANDLE_EINTR(open(path, flags, mode))) >= 0);
18}
19
20bool EintrSafeFileDescriptor::Open(const char* path, int flags) {
21 CHECK_EQ(fd_, -1);
22 return ((fd_ = HANDLE_EINTR(open(path, flags))) >= 0);
23}
24
25ssize_t EintrSafeFileDescriptor::Read(void* buf, size_t count) {
26 CHECK_GE(fd_, 0);
27 return HANDLE_EINTR(read(fd_, buf, count));
28}
29
30ssize_t EintrSafeFileDescriptor::Write(const void* buf, size_t count) {
31 CHECK_GE(fd_, 0);
32
33 // Attempt repeated writes, as long as some progress is being made.
34 char* char_buf = const_cast<char*>(reinterpret_cast<const char*>(buf));
35 ssize_t written = 0;
36 while (count > 0) {
37 ssize_t ret = HANDLE_EINTR(write(fd_, char_buf, count));
38
39 // Fail on either an error or no progress.
40 if (ret <= 0)
41 return (written ? written : ret);
42 written += ret;
43 count -= ret;
44 char_buf += ret;
45 }
46 return written;
47}
48
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -080049off64_t EintrSafeFileDescriptor::Seek(off64_t offset, int whence) {
50 CHECK_GE(fd_, 0);
51 return lseek64(fd_, offset, whence);
52}
53
Gilad Arnold11c066f2012-05-10 14:37:25 -070054bool EintrSafeFileDescriptor::Close() {
55 CHECK_GE(fd_, 0);
Mike Frysingerbcee2ca2014-05-14 16:28:23 -040056 if (IGNORE_EINTR(close(fd_)))
Gilad Arnold6eccc532012-05-17 15:44:22 -070057 return false;
58 Reset();
59 return true;
60}
61
62void EintrSafeFileDescriptor::Reset() {
63 fd_ = -1;
64}
65
66
67ScopedFileDescriptorCloser::~ScopedFileDescriptorCloser() {
68 if (descriptor_ && descriptor_->IsOpen() && !descriptor_->Close()) {
69 const char* err_str = "file closing failed";
70 if (descriptor_->IsSettingErrno()) {
71 PLOG(ERROR) << err_str;
72 } else {
73 LOG(ERROR) << err_str;
74 }
75 // Abandon the current descriptor, forcing it back to a closed state.
76 descriptor_->Reset();
77 }
Gilad Arnold11c066f2012-05-10 14:37:25 -070078}
79
80} // namespace chromeos_update_engine