blob: d86d4ca4c7a00a25aff25fa92639fae93d10f754 [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
Gilad Arnoldcf175a02014-07-10 16:48:47 -07005#ifndef UPDATE_ENGINE_FILE_DESCRIPTOR_H_
6#define UPDATE_ENGINE_FILE_DESCRIPTOR_H_
Gilad Arnold11c066f2012-05-10 14:37:25 -07007
8#include <errno.h>
9#include <sys/types.h>
10
Alex Deymo8427b4a2014-11-05 14:00:32 -080011#include <base/logging.h>
Gilad Arnold11c066f2012-05-10 14:37:25 -070012
13#include "update_engine/utils.h"
14
15// Abstraction for managing opening, reading, writing and closing of file
16// descriptors. This includes an abstract class and one standard implementation
17// based on POSIX system calls.
18//
19// TODO(garnold) this class is modeled after (and augments the functionality of)
20// the FileWriter class; ultimately, the latter should be replaced by the former
21// throughout the codebase. A few deviations from the original FileWriter:
22//
23// * Providing two flavors of Open()
24//
25// * A FileDescriptor is reusable and can be used to read/write multiple files
26// as long as open/close preconditions are respected.
27//
28// * Write() returns the number of bytes written: this appears to be more useful
29// for clients, who may wish to retry or otherwise do something useful with
30// the remaining data that was not written.
Gilad Arnold6eccc532012-05-17 15:44:22 -070031//
32// * Provides a Reset() method, which will force to abandon a currently open
33// file descriptor and allow opening another file, without necessarily
34// properly closing the old one. This may be useful in cases where a "closer"
35// class does not care whether Close() was successful, but may need to reuse
36// the same file descriptor again.
Gilad Arnold11c066f2012-05-10 14:37:25 -070037
38namespace chromeos_update_engine {
39
40// An abstract class defining the file descriptor API.
41class FileDescriptor {
42 public:
43 FileDescriptor() {}
44 virtual ~FileDescriptor() {}
45
46 // Opens a file descriptor. The descriptor must be in the closed state prior
47 // to this call. Returns true on success, false otherwise. Specific
48 // implementations may set errno accordingly.
49 virtual bool Open(const char* path, int flags, mode_t mode) = 0;
50 virtual bool Open(const char* path, int flags) = 0;
51
52 // Reads from a file descriptor up to a given count. The descriptor must be
53 // open prior to this call. Returns the number of bytes read, or -1 on error.
54 // Specific implementations may set errno accordingly.
55 virtual ssize_t Read(void* buf, size_t count) = 0;
56
57 // Writes to a file descriptor. The descriptor must be open prior to this
58 // call. Returns the number of bytes written, or -1 if an error occurred and
59 // no bytes were written. Specific implementations may set errno accordingly.
60 virtual ssize_t Write(const void* buf, size_t count) = 0;
61
Gilad Arnold6eccc532012-05-17 15:44:22 -070062 // Closes a file descriptor. The descriptor must be open prior to this call.
Gilad Arnold11c066f2012-05-10 14:37:25 -070063 // Returns true on success, false otherwise. Specific implementations may set
64 // errno accordingly.
65 virtual bool Close() = 0;
66
Gilad Arnold6eccc532012-05-17 15:44:22 -070067 // Resets the file descriptor, abandoning a currently open file and returning
68 // the descriptor to the closed state.
69 virtual void Reset() = 0;
70
Gilad Arnold11c066f2012-05-10 14:37:25 -070071 // Indicates whether or not an implementation sets meaningful errno.
72 virtual bool IsSettingErrno() = 0;
73
Gilad Arnold6eccc532012-05-17 15:44:22 -070074 // Indicates whether the descriptor is currently open.
75 virtual bool IsOpen() = 0;
76
Gilad Arnold11c066f2012-05-10 14:37:25 -070077 private:
78 DISALLOW_COPY_AND_ASSIGN(FileDescriptor);
79};
80
81// A simple EINTR-immune wrapper implementation around standard system calls.
82class EintrSafeFileDescriptor : public FileDescriptor {
83 public:
84 EintrSafeFileDescriptor() : fd_(-1) {}
Gilad Arnold11c066f2012-05-10 14:37:25 -070085
86 // Interface methods.
Alex Deymo610277e2014-11-11 21:18:11 -080087 bool Open(const char* path, int flags, mode_t mode) override;
88 bool Open(const char* path, int flags) override;
89 ssize_t Read(void* buf, size_t count) override;
90 ssize_t Write(const void* buf, size_t count) override;
91 bool Close() override;
92 void Reset() override;
93 bool IsSettingErrno() override {
Gilad Arnold11c066f2012-05-10 14:37:25 -070094 return true;
95 }
Alex Deymo610277e2014-11-11 21:18:11 -080096 bool IsOpen() override {
Gilad Arnold6eccc532012-05-17 15:44:22 -070097 return (fd_ >= 0);
98 }
Gilad Arnold11c066f2012-05-10 14:37:25 -070099
100 private:
101 int fd_;
102};
103
Gilad Arnold6eccc532012-05-17 15:44:22 -0700104// A scoped closer for a FileDescriptor object. The destructor of this class
105// invokes the Close() method of the given file descriptor, if it's not in the
106// closed state already. Note, however, that if Close() fails, this class will
107// force a Reset() invocation, which will abandon the current file descriptor.
Gilad Arnold11c066f2012-05-10 14:37:25 -0700108class ScopedFileDescriptorCloser {
109 public:
110 explicit ScopedFileDescriptorCloser(FileDescriptor* descriptor)
111 : descriptor_(descriptor) {}
Gilad Arnold6eccc532012-05-17 15:44:22 -0700112 ~ScopedFileDescriptorCloser();
Gilad Arnold11c066f2012-05-10 14:37:25 -0700113 private:
114 FileDescriptor* descriptor_;
115
116 DISALLOW_COPY_AND_ASSIGN(ScopedFileDescriptorCloser);
117};
118
119} // namespace chromeos_update_engine
120
Gilad Arnoldcf175a02014-07-10 16:48:47 -0700121#endif // UPDATE_ENGINE_FILE_DESCRIPTOR_H_