Chris@16
|
1 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 //
|
Chris@16
|
3 // (C) Copyright Ion Gaztanaga 2006-2012. Distributed under the Boost
|
Chris@16
|
4 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
6 //
|
Chris@16
|
7 // See http://www.boost.org/libs/interprocess for documentation.
|
Chris@16
|
8 //
|
Chris@16
|
9 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
10
|
Chris@16
|
11 #ifndef BOOST_INTERPROCESS_DETAIL_FILE_WRAPPER_HPP
|
Chris@16
|
12 #define BOOST_INTERPROCESS_DETAIL_FILE_WRAPPER_HPP
|
Chris@16
|
13
|
Chris@101
|
14 #ifndef BOOST_CONFIG_HPP
|
Chris@101
|
15 # include <boost/config.hpp>
|
Chris@101
|
16 #endif
|
Chris@101
|
17 #
|
Chris@101
|
18 #if defined(BOOST_HAS_PRAGMA_ONCE)
|
Chris@101
|
19 # pragma once
|
Chris@101
|
20 #endif
|
Chris@101
|
21
|
Chris@16
|
22 #include <boost/interprocess/detail/config_begin.hpp>
|
Chris@16
|
23 #include <boost/interprocess/detail/workaround.hpp>
|
Chris@16
|
24 #include <boost/interprocess/detail/os_file_functions.hpp>
|
Chris@16
|
25 #include <boost/interprocess/creation_tags.hpp>
|
Chris@101
|
26 #include <boost/move/utility_core.hpp>
|
Chris@16
|
27 #include <boost/interprocess/creation_tags.hpp>
|
Chris@101
|
28 #include <boost/interprocess/detail/simple_swap.hpp>
|
Chris@16
|
29
|
Chris@16
|
30 namespace boost {
|
Chris@16
|
31 namespace interprocess {
|
Chris@16
|
32 namespace ipcdetail{
|
Chris@16
|
33
|
Chris@16
|
34 class file_wrapper
|
Chris@16
|
35 {
|
Chris@101
|
36 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
Chris@16
|
37 BOOST_MOVABLE_BUT_NOT_COPYABLE(file_wrapper)
|
Chris@101
|
38 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
Chris@16
|
39 public:
|
Chris@16
|
40
|
Chris@16
|
41 //!Default constructor.
|
Chris@16
|
42 //!Represents an empty file_wrapper.
|
Chris@16
|
43 file_wrapper();
|
Chris@16
|
44
|
Chris@16
|
45 //!Creates a file object with name "name" and mode "mode", with the access mode "mode"
|
Chris@16
|
46 //!If the file previously exists, throws an error.
|
Chris@16
|
47 file_wrapper(create_only_t, const char *name, mode_t mode, const permissions &perm = permissions())
|
Chris@16
|
48 { this->priv_open_or_create(ipcdetail::DoCreate, name, mode, perm); }
|
Chris@16
|
49
|
Chris@16
|
50 //!Tries to create a file with name "name" and mode "mode", with the
|
Chris@16
|
51 //!access mode "mode". If the file previously exists, it tries to open it with mode "mode".
|
Chris@16
|
52 //!Otherwise throws an error.
|
Chris@16
|
53 file_wrapper(open_or_create_t, const char *name, mode_t mode, const permissions &perm = permissions())
|
Chris@16
|
54 { this->priv_open_or_create(ipcdetail::DoOpenOrCreate, name, mode, perm); }
|
Chris@16
|
55
|
Chris@16
|
56 //!Tries to open a file with name "name", with the access mode "mode".
|
Chris@16
|
57 //!If the file does not previously exist, it throws an error.
|
Chris@16
|
58 file_wrapper(open_only_t, const char *name, mode_t mode)
|
Chris@16
|
59 { this->priv_open_or_create(ipcdetail::DoOpen, name, mode, permissions()); }
|
Chris@16
|
60
|
Chris@16
|
61 //!Moves the ownership of "moved"'s file to *this.
|
Chris@16
|
62 //!After the call, "moved" does not represent any file.
|
Chris@16
|
63 //!Does not throw
|
Chris@16
|
64 file_wrapper(BOOST_RV_REF(file_wrapper) moved)
|
Chris@16
|
65 : m_handle(file_handle_t(ipcdetail::invalid_file()))
|
Chris@16
|
66 { this->swap(moved); }
|
Chris@16
|
67
|
Chris@16
|
68 //!Moves the ownership of "moved"'s file to *this.
|
Chris@16
|
69 //!After the call, "moved" does not represent any file.
|
Chris@16
|
70 //!Does not throw
|
Chris@16
|
71 file_wrapper &operator=(BOOST_RV_REF(file_wrapper) moved)
|
Chris@16
|
72 {
|
Chris@16
|
73 file_wrapper tmp(boost::move(moved));
|
Chris@16
|
74 this->swap(tmp);
|
Chris@16
|
75 return *this;
|
Chris@16
|
76 }
|
Chris@16
|
77
|
Chris@16
|
78 //!Swaps to file_wrappers.
|
Chris@16
|
79 //!Does not throw
|
Chris@16
|
80 void swap(file_wrapper &other);
|
Chris@16
|
81
|
Chris@16
|
82 //!Erases a file from the system.
|
Chris@16
|
83 //!Returns false on error. Never throws
|
Chris@16
|
84 static bool remove(const char *name);
|
Chris@16
|
85
|
Chris@16
|
86 //!Sets the size of the file
|
Chris@16
|
87 void truncate(offset_t length);
|
Chris@16
|
88
|
Chris@16
|
89 //!Closes the
|
Chris@16
|
90 //!file
|
Chris@16
|
91 ~file_wrapper();
|
Chris@16
|
92
|
Chris@16
|
93 //!Returns the name of the file
|
Chris@16
|
94 //!used in the constructor
|
Chris@16
|
95 const char *get_name() const;
|
Chris@16
|
96
|
Chris@16
|
97 //!Returns the name of the file
|
Chris@16
|
98 //!used in the constructor
|
Chris@16
|
99 bool get_size(offset_t &size) const;
|
Chris@16
|
100
|
Chris@16
|
101 //!Returns access mode
|
Chris@16
|
102 //!used in the constructor
|
Chris@16
|
103 mode_t get_mode() const;
|
Chris@16
|
104
|
Chris@16
|
105 //!Get mapping handle
|
Chris@16
|
106 //!to use with mapped_region
|
Chris@16
|
107 mapping_handle_t get_mapping_handle() const;
|
Chris@16
|
108
|
Chris@16
|
109 private:
|
Chris@16
|
110 //!Closes a previously opened file mapping. Never throws.
|
Chris@16
|
111 void priv_close();
|
Chris@16
|
112 //!Closes a previously opened file mapping. Never throws.
|
Chris@16
|
113 bool priv_open_or_create(ipcdetail::create_enum_t type, const char *filename, mode_t mode, const permissions &perm);
|
Chris@16
|
114
|
Chris@16
|
115 file_handle_t m_handle;
|
Chris@16
|
116 mode_t m_mode;
|
Chris@16
|
117 std::string m_filename;
|
Chris@16
|
118 };
|
Chris@16
|
119
|
Chris@16
|
120 inline file_wrapper::file_wrapper()
|
Chris@16
|
121 : m_handle(file_handle_t(ipcdetail::invalid_file()))
|
Chris@16
|
122 {}
|
Chris@16
|
123
|
Chris@16
|
124 inline file_wrapper::~file_wrapper()
|
Chris@16
|
125 { this->priv_close(); }
|
Chris@16
|
126
|
Chris@16
|
127 inline const char *file_wrapper::get_name() const
|
Chris@16
|
128 { return m_filename.c_str(); }
|
Chris@16
|
129
|
Chris@16
|
130 inline bool file_wrapper::get_size(offset_t &size) const
|
Chris@16
|
131 { return get_file_size((file_handle_t)m_handle, size); }
|
Chris@16
|
132
|
Chris@16
|
133 inline void file_wrapper::swap(file_wrapper &other)
|
Chris@16
|
134 {
|
Chris@101
|
135 (simple_swap)(m_handle, other.m_handle);
|
Chris@101
|
136 (simple_swap)(m_mode, other.m_mode);
|
Chris@16
|
137 m_filename.swap(other.m_filename);
|
Chris@16
|
138 }
|
Chris@16
|
139
|
Chris@16
|
140 inline mapping_handle_t file_wrapper::get_mapping_handle() const
|
Chris@16
|
141 { return mapping_handle_from_file_handle(m_handle); }
|
Chris@16
|
142
|
Chris@16
|
143 inline mode_t file_wrapper::get_mode() const
|
Chris@16
|
144 { return m_mode; }
|
Chris@16
|
145
|
Chris@16
|
146 inline bool file_wrapper::priv_open_or_create
|
Chris@16
|
147 (ipcdetail::create_enum_t type,
|
Chris@16
|
148 const char *filename,
|
Chris@16
|
149 mode_t mode,
|
Chris@16
|
150 const permissions &perm = permissions())
|
Chris@16
|
151 {
|
Chris@16
|
152 m_filename = filename;
|
Chris@16
|
153
|
Chris@16
|
154 if(mode != read_only && mode != read_write){
|
Chris@16
|
155 error_info err(mode_error);
|
Chris@16
|
156 throw interprocess_exception(err);
|
Chris@16
|
157 }
|
Chris@16
|
158
|
Chris@16
|
159 //Open file existing native API to obtain the handle
|
Chris@16
|
160 switch(type){
|
Chris@16
|
161 case ipcdetail::DoOpen:
|
Chris@16
|
162 m_handle = open_existing_file(filename, mode);
|
Chris@16
|
163 break;
|
Chris@16
|
164 case ipcdetail::DoCreate:
|
Chris@16
|
165 m_handle = create_new_file(filename, mode, perm);
|
Chris@16
|
166 break;
|
Chris@16
|
167 case ipcdetail::DoOpenOrCreate:
|
Chris@16
|
168 m_handle = create_or_open_file(filename, mode, perm);
|
Chris@16
|
169 break;
|
Chris@16
|
170 default:
|
Chris@16
|
171 {
|
Chris@16
|
172 error_info err = other_error;
|
Chris@16
|
173 throw interprocess_exception(err);
|
Chris@16
|
174 }
|
Chris@16
|
175 }
|
Chris@16
|
176
|
Chris@16
|
177 //Check for error
|
Chris@16
|
178 if(m_handle == invalid_file()){
|
Chris@101
|
179 error_info err = system_error_code();
|
Chris@101
|
180 throw interprocess_exception(err);
|
Chris@16
|
181 }
|
Chris@16
|
182
|
Chris@16
|
183 m_mode = mode;
|
Chris@16
|
184 return true;
|
Chris@16
|
185 }
|
Chris@16
|
186
|
Chris@16
|
187 inline bool file_wrapper::remove(const char *filename)
|
Chris@16
|
188 { return delete_file(filename); }
|
Chris@16
|
189
|
Chris@16
|
190 inline void file_wrapper::truncate(offset_t length)
|
Chris@16
|
191 {
|
Chris@16
|
192 if(!truncate_file(m_handle, length)){
|
Chris@16
|
193 error_info err(system_error_code());
|
Chris@16
|
194 throw interprocess_exception(err);
|
Chris@16
|
195 }
|
Chris@16
|
196 }
|
Chris@16
|
197
|
Chris@16
|
198 inline void file_wrapper::priv_close()
|
Chris@16
|
199 {
|
Chris@16
|
200 if(m_handle != invalid_file()){
|
Chris@16
|
201 close_file(m_handle);
|
Chris@16
|
202 m_handle = invalid_file();
|
Chris@16
|
203 }
|
Chris@16
|
204 }
|
Chris@16
|
205
|
Chris@16
|
206 } //namespace ipcdetail{
|
Chris@16
|
207 } //namespace interprocess {
|
Chris@16
|
208 } //namespace boost {
|
Chris@16
|
209
|
Chris@16
|
210 #include <boost/interprocess/detail/config_end.hpp>
|
Chris@16
|
211
|
Chris@16
|
212 #endif //BOOST_INTERPROCESS_DETAIL_FILE_WRAPPER_HPP
|