1//
2// Copyright (C) 2009 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//      http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17#ifndef UPDATE_ENGINE_PAYLOAD_CONSUMER_FILE_WRITER_H_
18#define UPDATE_ENGINE_PAYLOAD_CONSUMER_FILE_WRITER_H_
19
20#include <fcntl.h>
21#include <sys/stat.h>
22#include <sys/types.h>
23#include <unistd.h>
24
25#include <base/logging.h>
26
27#include "update_engine/common/error_code.h"
28#include "update_engine/common/utils.h"
29
30// FileWriter is a class that is used to (synchronously, for now) write to
31// a file. This file is a thin wrapper around open/write/close system calls,
32// but provides and interface that can be customized by subclasses that wish
33// to filter the data.
34
35namespace chromeos_update_engine {
36
37class FileWriter {
38 public:
39  FileWriter() {}
40  virtual ~FileWriter() {}
41
42  // Wrapper around write. Returns true if all requested bytes
43  // were written, or false on any error, regardless of progress.
44  virtual bool Write(const void* bytes, size_t count) = 0;
45
46  // Same as the Write method above but returns a detailed |error| code
47  // in addition if the returned value is false. By default this method
48  // returns kActionExitDownloadWriteError as the error code, but subclasses
49  // can override if they wish to return more specific error codes.
50  virtual bool Write(const void* bytes,
51                     size_t count,
52                     ErrorCode* error) {
53     *error = ErrorCode::kDownloadWriteError;
54     return Write(bytes, count);
55  }
56
57  // Wrapper around close. Returns 0 on success or -errno on error.
58  virtual int Close() = 0;
59
60 private:
61  DISALLOW_COPY_AND_ASSIGN(FileWriter);
62};
63
64// Direct file writer is probably the simplest FileWriter implementation.
65// It calls the system calls directly.
66
67class DirectFileWriter : public FileWriter {
68 public:
69  DirectFileWriter() = default;
70
71  // FileWriter overrides.
72  bool Write(const void* bytes, size_t count) override;
73  int Close() override;
74
75  // Wrapper around open. Returns 0 on success or -errno on error.
76  int Open(const char* path, int flags, mode_t mode);
77
78  int fd() const { return fd_; }
79
80 private:
81  int fd_{-1};
82
83  DISALLOW_COPY_AND_ASSIGN(DirectFileWriter);
84};
85
86class ScopedFileWriterCloser {
87 public:
88  explicit ScopedFileWriterCloser(FileWriter* writer) : writer_(writer) {}
89  ~ScopedFileWriterCloser() {
90    int err = writer_->Close();
91    if (err)
92      LOG(ERROR) << "FileWriter::Close failed: "
93                 << utils::ErrnoNumberAsString(-err);
94  }
95 private:
96  FileWriter* writer_;
97
98  DISALLOW_COPY_AND_ASSIGN(ScopedFileWriterCloser);
99};
100
101}  // namespace chromeos_update_engine
102
103#endif  // UPDATE_ENGINE_PAYLOAD_CONSUMER_FILE_WRITER_H_
104