1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // See http://www.boost.org/libs/interprocess for documentation.
8 //
9 //////////////////////////////////////////////////////////////////////////////
10 
11 #ifndef BOOST_INTERPROCESS_FILE_MAPPING_HPP
12 #define BOOST_INTERPROCESS_FILE_MAPPING_HPP
13 
14 #include <boost/interprocess/detail/config_begin.hpp>
15 #include <boost/interprocess/detail/workaround.hpp>
16 
17 #include <boost/interprocess/interprocess_fwd.hpp>
18 #include <boost/interprocess/exceptions.hpp>
19 #include <boost/interprocess/detail/utilities.hpp>
20 #include <boost/interprocess/creation_tags.hpp>
21 #include <boost/interprocess/detail/os_file_functions.hpp>
22 #include <boost/interprocess/detail/move.hpp>
23 #include <string>    //std::string
24 
25 //!\file
26 //!Describes file_mapping and mapped region classes
27 
28 namespace boost {
29 namespace interprocess {
30 
31 //!A class that wraps a file-mapping that can be used to
32 //!create mapped regions from the mapped files
33 class file_mapping
34 {
35    /// @cond
36    BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(file_mapping)
37    /// @endcond
38 
39    public:
40    //!Constructs an empty file mapping.
41    //!Does not throw
42    file_mapping();
43 
44    //!Opens a file mapping of file "filename", starting in offset
45    //!"file_offset", and the mapping's size will be "size". The mapping
46    //!can be opened for read-only "read_only" or read-write "read_write"
47    //!modes. Throws interprocess_exception on error.
48    file_mapping(const char *filename, mode_t mode);
49 
50    //!Moves the ownership of "moved"'s file mapping object to *this.
51    //!After the call, "moved" does not represent any file mapping object.
52    //!Does not throw
file_mapping(BOOST_INTERPROCESS_RV_REF (file_mapping)moved)53    file_mapping(BOOST_INTERPROCESS_RV_REF(file_mapping) moved)
54       :  m_handle(file_handle_t(detail::invalid_file()))
55    {  this->swap(moved);   }
56 
57    //!Moves the ownership of "moved"'s file mapping to *this.
58    //!After the call, "moved" does not represent any file mapping.
59    //!Does not throw
operator =(BOOST_INTERPROCESS_RV_REF (file_mapping)moved)60    file_mapping &operator=(BOOST_INTERPROCESS_RV_REF(file_mapping) moved)
61    {
62       file_mapping tmp(boost::interprocess::move(moved));
63       this->swap(tmp);
64       return *this;
65    }
66 
67    //!Swaps to file_mappings.
68    //!Does not throw.
69    void swap(file_mapping &other);
70 
71    //!Returns access mode
72    //!used in the constructor
73    mode_t get_mode() const;
74 
75    //!Obtains the mapping handle
76    //!to be used with mapped_region
77    mapping_handle_t get_mapping_handle() const;
78 
79    //!Destroys the file mapping. All mapped regions created from this are still
80    //!valid. Does not throw
81    ~file_mapping();
82 
83    //!Returns the name of the file
84    //!used in the constructor.
85    const char *get_name() const;
86 
87    //!Removes the file named "filename" even if it's been memory mapped.
88    //!Returns true on success.
89    //!The function might fail in some operating systems if the file is
90    //!being used other processes and no deletion permission was shared.
91    static bool remove(const char *filename);
92 
93    /// @cond
94    private:
95    //!Closes a previously opened file mapping. Never throws.
96    void priv_close();
97    file_handle_t  m_handle;
98    mode_t    m_mode;
99    std::string       m_filename;
100    /// @endcond
101 };
102 
file_mapping()103 inline file_mapping::file_mapping()
104    :  m_handle(file_handle_t(detail::invalid_file()))
105 {}
106 
~file_mapping()107 inline file_mapping::~file_mapping()
108 {  this->priv_close(); }
109 
get_name() const110 inline const char *file_mapping::get_name() const
111 {  return m_filename.c_str(); }
112 
swap(file_mapping & other)113 inline void file_mapping::swap(file_mapping &other)
114 {
115    std::swap(m_handle, other.m_handle);
116    std::swap(m_mode, other.m_mode);
117    m_filename.swap(other.m_filename);
118 }
119 
get_mapping_handle() const120 inline mapping_handle_t file_mapping::get_mapping_handle() const
121 {  return detail::mapping_handle_from_file_handle(m_handle);  }
122 
get_mode() const123 inline mode_t file_mapping::get_mode() const
124 {  return m_mode; }
125 
file_mapping(const char * filename,mode_t mode)126 inline file_mapping::file_mapping
127    (const char *filename, mode_t mode)
128    :  m_filename(filename)
129 {
130    //Check accesses
131    if (mode != read_write && mode != read_only){
132       error_info err = other_error;
133       throw interprocess_exception(err);
134    }
135 
136    //Open file
137    m_handle = detail::open_existing_file(filename, mode);
138 
139    //Check for error
140    if(m_handle == detail::invalid_file()){
141       error_info err = system_error_code();
142       this->priv_close();
143       throw interprocess_exception(err);
144    }
145    m_mode = mode;
146 }
147 
remove(const char * filename)148 inline bool file_mapping::remove(const char *filename)
149 {  return detail::delete_file(filename);  }
150 
151 ///@cond
152 
priv_close()153 inline void file_mapping::priv_close()
154 {
155    if(m_handle != detail::invalid_file()){
156       detail::close_file(m_handle);
157       m_handle = detail::invalid_file();
158    }
159 }
160 
161 ///@endcond
162 
163 //!A class that stores the name of a file
164 //!and tries to remove it in its destructor
165 //!Useful to remove temporary files in the presence
166 //!of exceptions
167 class remove_file_on_destroy
168 {
169    const char * m_name;
170    public:
remove_file_on_destroy(const char * name)171    remove_file_on_destroy(const char *name)
172       :  m_name(name)
173    {}
174 
~remove_file_on_destroy()175    ~remove_file_on_destroy()
176    {  detail::delete_file(m_name);  }
177 };
178 
179 }  //namespace interprocess {
180 }  //namespace boost {
181 
182 #include <boost/interprocess/detail/config_end.hpp>
183 
184 #endif   //BOOST_INTERPROCESS_FILE_MAPPING_HPP
185