blob: f2e5caf2424c484f33008fd57c306d36eb08618e [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>
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -08009#include <memory>
Gilad Arnold11c066f2012-05-10 14:37:25 -070010#include <sys/types.h>
11
Alex Deymo8427b4a2014-11-05 14:00:32 -080012#include <base/logging.h>
Gilad Arnold11c066f2012-05-10 14:37:25 -070013
Gilad Arnold11c066f2012-05-10 14:37:25 -070014// Abstraction for managing opening, reading, writing and closing of file
15// descriptors. This includes an abstract class and one standard implementation
16// based on POSIX system calls.
17//
18// TODO(garnold) this class is modeled after (and augments the functionality of)
19// the FileWriter class; ultimately, the latter should be replaced by the former
20// throughout the codebase. A few deviations from the original FileWriter:
21//
22// * Providing two flavors of Open()
23//
24// * A FileDescriptor is reusable and can be used to read/write multiple files
25// as long as open/close preconditions are respected.
26//
27// * Write() returns the number of bytes written: this appears to be more useful
28// for clients, who may wish to retry or otherwise do something useful with
29// the remaining data that was not written.
Gilad Arnold6eccc532012-05-17 15:44:22 -070030//
31// * Provides a Reset() method, which will force to abandon a currently open
32// file descriptor and allow opening another file, without necessarily
33// properly closing the old one. This may be useful in cases where a "closer"
34// class does not care whether Close() was successful, but may need to reuse
35// the same file descriptor again.
Gilad Arnold11c066f2012-05-10 14:37:25 -070036
37namespace chromeos_update_engine {
38
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -080039class FileDescriptor;
40using FileDescriptorPtr = std::shared_ptr<FileDescriptor>;
41
Gilad Arnold11c066f2012-05-10 14:37:25 -070042// An abstract class defining the file descriptor API.
43class FileDescriptor {
44 public:
45 FileDescriptor() {}
46 virtual ~FileDescriptor() {}
47
48 // Opens a file descriptor. The descriptor must be in the closed state prior
49 // to this call. Returns true on success, false otherwise. Specific
50 // implementations may set errno accordingly.
51 virtual bool Open(const char* path, int flags, mode_t mode) = 0;
52 virtual bool Open(const char* path, int flags) = 0;
53
54 // Reads from a file descriptor up to a given count. The descriptor must be
55 // open prior to this call. Returns the number of bytes read, or -1 on error.
56 // Specific implementations may set errno accordingly.
57 virtual ssize_t Read(void* buf, size_t count) = 0;
58
59 // Writes to a file descriptor. The descriptor must be open prior to this
60 // call. Returns the number of bytes written, or -1 if an error occurred and
61 // no bytes were written. Specific implementations may set errno accordingly.
62 virtual ssize_t Write(const void* buf, size_t count) = 0;
63
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -080064 // Seeks to an offset. Returns the resulting offset location as measured in
65 // bytes from the beginning. On error, return -1. Specific implementations
66 // may set errno accordingly.
67 virtual off64_t Seek(off64_t offset, int whence) = 0;
68
Gilad Arnold6eccc532012-05-17 15:44:22 -070069 // Closes a file descriptor. The descriptor must be open prior to this call.
Gilad Arnold11c066f2012-05-10 14:37:25 -070070 // Returns true on success, false otherwise. Specific implementations may set
71 // errno accordingly.
72 virtual bool Close() = 0;
73
Gilad Arnold6eccc532012-05-17 15:44:22 -070074 // Resets the file descriptor, abandoning a currently open file and returning
75 // the descriptor to the closed state.
76 virtual void Reset() = 0;
77
Gilad Arnold11c066f2012-05-10 14:37:25 -070078 // Indicates whether or not an implementation sets meaningful errno.
79 virtual bool IsSettingErrno() = 0;
80
Gilad Arnold6eccc532012-05-17 15:44:22 -070081 // Indicates whether the descriptor is currently open.
82 virtual bool IsOpen() = 0;
83
Gilad Arnold11c066f2012-05-10 14:37:25 -070084 private:
85 DISALLOW_COPY_AND_ASSIGN(FileDescriptor);
86};
87
88// A simple EINTR-immune wrapper implementation around standard system calls.
89class EintrSafeFileDescriptor : public FileDescriptor {
90 public:
91 EintrSafeFileDescriptor() : fd_(-1) {}
Gilad Arnold11c066f2012-05-10 14:37:25 -070092
93 // Interface methods.
Alex Deymo610277e2014-11-11 21:18:11 -080094 bool Open(const char* path, int flags, mode_t mode) override;
95 bool Open(const char* path, int flags) override;
96 ssize_t Read(void* buf, size_t count) override;
97 ssize_t Write(const void* buf, size_t count) override;
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -080098 off64_t Seek(off64_t offset, int whence) override;
Alex Deymo610277e2014-11-11 21:18:11 -080099 bool Close() override;
100 void Reset() override;
101 bool IsSettingErrno() override {
Gilad Arnold11c066f2012-05-10 14:37:25 -0700102 return true;
103 }
Alex Deymo610277e2014-11-11 21:18:11 -0800104 bool IsOpen() override {
Gilad Arnold6eccc532012-05-17 15:44:22 -0700105 return (fd_ >= 0);
106 }
Gilad Arnold11c066f2012-05-10 14:37:25 -0700107
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -0800108 protected:
Gilad Arnold11c066f2012-05-10 14:37:25 -0700109 int fd_;
110};
111
Gilad Arnold11c066f2012-05-10 14:37:25 -0700112} // namespace chromeos_update_engine
113
Gilad Arnoldcf175a02014-07-10 16:48:47 -0700114#endif // UPDATE_ENGINE_FILE_DESCRIPTOR_H_