blob: 21c2758bfc6106089e45e0b23732d935c44d4d87 [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
11#include "base/logging.h"
12
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) {}
Alex Vakulenkod2779df2014-06-16 13:19:00 -070085 virtual ~EintrSafeFileDescriptor() {}
Gilad Arnold11c066f2012-05-10 14:37:25 -070086
87 // Interface methods.
88 virtual bool Open(const char* path, int flags, mode_t mode);
89 virtual bool Open(const char* path, int flags);
90 virtual ssize_t Read(void* buf, size_t count);
91 virtual ssize_t Write(const void* buf, size_t count);
92 virtual bool Close();
Gilad Arnold6eccc532012-05-17 15:44:22 -070093 virtual void Reset();
Gilad Arnold11c066f2012-05-10 14:37:25 -070094 virtual bool IsSettingErrno() {
95 return true;
96 }
Gilad Arnold6eccc532012-05-17 15:44:22 -070097 virtual bool IsOpen() {
98 return (fd_ >= 0);
99 }
Gilad Arnold11c066f2012-05-10 14:37:25 -0700100
101 private:
102 int fd_;
103};
104
Gilad Arnold6eccc532012-05-17 15:44:22 -0700105// A scoped closer for a FileDescriptor object. The destructor of this class
106// invokes the Close() method of the given file descriptor, if it's not in the
107// closed state already. Note, however, that if Close() fails, this class will
108// force a Reset() invocation, which will abandon the current file descriptor.
Gilad Arnold11c066f2012-05-10 14:37:25 -0700109class ScopedFileDescriptorCloser {
110 public:
111 explicit ScopedFileDescriptorCloser(FileDescriptor* descriptor)
112 : descriptor_(descriptor) {}
Gilad Arnold6eccc532012-05-17 15:44:22 -0700113 ~ScopedFileDescriptorCloser();
Gilad Arnold11c066f2012-05-10 14:37:25 -0700114 private:
115 FileDescriptor* descriptor_;
116
117 DISALLOW_COPY_AND_ASSIGN(ScopedFileDescriptorCloser);
118};
119
120} // namespace chromeos_update_engine
121
Gilad Arnoldcf175a02014-07-10 16:48:47 -0700122#endif // UPDATE_ENGINE_FILE_DESCRIPTOR_H_