The Battle for Wesnoth  1.13.10+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
fs_commit.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2016 - 2017 by Ignacio R. Morelle <shadowm2006@gmail.com>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 /**
16  * @file
17  * Atomic filesystem commit functions.
18  */
19 
20 #pragma once
21 
22 #include "filesystem.hpp"
23 
24 namespace filesystem
25 {
26 
27 /**
28  * Wrapper class that guarantees that file commit atomicity.
29  *
30  * It is possible for a signal or exception to cause a file write to be aborted
31  * in the middle of the process, leaving potentially inconsistent contents
32  * behind which may be read by the same or another application later and result
33  * in errors or further data loss.
34  *
35  * This wrapper prevents this by providing callers with an interface to request
36  * a write stream that will be actually associated to a temporary file. Once
37  * the caller is done with the file, it should call the commit() method to
38  * complete the process so that the temporary replaces the original in an
39  * atomic step.
40  *
41  * The rationale for using an explicit commit() method instead of the class
42  * destructor is that the destructor will also be invoked during exception
43  * handling, which could still cause the destination file to end up in an
44  * inconsistent state.
45  *
46  * Note that if the destructor is invoked before commit() is, the temporary
47  * file will be left behind. This is deliberate so as to provide a way for
48  * the user to look at the resulting file and optionally try to reconcile it
49  * against the original.
50  */
52 {
53 public:
54  /**
55  * Constructor.
56  *
57  * @throws filesystem::io_exception if the operation fails in some way.
58  */
59  atomic_commit(const std::string& filename);
60 
61  atomic_commit(const atomic_commit&) = delete;
62  atomic_commit& operator=(const atomic_commit&) = delete;
63 
65 
66  /**
67  * Returns the write stream associated with the file.
68  *
69  * Before commit() is invoked, this refers to the temporary file; afterwards,
70  * to the destination.
71  */
73  {
74  return out_;
75  }
76 
77  /**
78  * Commits the new file contents to disk atomically.
79  *
80  * @throws filesystem::io_exception if the operation fails in some way.
81  */
82  void commit();
83 
84 private:
88 #ifndef _WIN32
89  int outfd_;
90 #endif
91 };
92 
93 }
std::vector< char_t > string
atomic_commit(const std::string &filename)
Constructor.
Definition: fs_commit.cpp:72
atomic_commit & operator=(const atomic_commit &)=delete
Wrapper class that guarantees that file commit atomicity.
Definition: fs_commit.hpp:51
void commit()
Commits the new file contents to disk atomically.
Definition: fs_commit.cpp:90
scoped_ostream & ostream()
Returns the write stream associated with the file.
Definition: fs_commit.hpp:72
std::unique_ptr< std::ostream > scoped_ostream
Definition: filesystem.hpp:38
Declarations for File-IO.