]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/interprocess/detail/shared_dir_helpers.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / interprocess / detail / shared_dir_helpers.hpp
CommitLineData
7c673cae
FG
1//////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Ion Gaztanaga 2007-2014. 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_DETAIL_SHARED_DIR_HELPERS_HPP
12#define BOOST_INTERPROCESS_DETAIL_SHARED_DIR_HELPERS_HPP
13
14#ifndef BOOST_CONFIG_HPP
15# include <boost/config.hpp>
16#endif
17#
18#if defined(BOOST_HAS_PRAGMA_ONCE)
19# pragma once
20#endif
21
22#include <boost/interprocess/detail/config_begin.hpp>
23#include <boost/interprocess/detail/workaround.hpp>
24#include <boost/interprocess/detail/os_file_functions.hpp>
25#include <boost/interprocess/errors.hpp>
26#include <boost/interprocess/exceptions.hpp>
27#include <string>
28
29#if defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME) && defined(BOOST_INTERPROCESS_WINDOWS)
30 #include <boost/interprocess/detail/windows_intermodule_singleton.hpp>
31#endif
32
33namespace boost {
34namespace interprocess {
35namespace ipcdetail {
36
1e59de90
TL
37template<class CharT>
38struct shared_dir_constants;
39
40template<>
41struct shared_dir_constants<char>
42{
43 static char dir_separator()
44 { return '/'; }
45
46 static const char *dir_interprocess()
47 { return "/boost_interprocess"; }
48};
49
50template<>
51struct shared_dir_constants<wchar_t>
52{
53 static wchar_t dir_separator()
54 { return L'/'; }
55
56 static const wchar_t *dir_interprocess()
57 { return L"/boost_interprocess"; }
58};
59
7c673cae
FG
60#if defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME)
61 #if defined(BOOST_INTERPROCESS_WINDOWS)
62 //This type will initialize the stamp
1e59de90 63 template<class CharT>
7c673cae
FG
64 struct windows_bootstamp
65 {
66 windows_bootstamp()
67 {
68 //Throw if bootstamp not available
69 if(!winapi::get_last_bootup_time(stamp)){
70 error_info err = system_error_code();
71 throw interprocess_exception(err);
72 }
73 }
74 //Use std::string. Even if this will be constructed in shared memory, all
75 //modules/dlls are from this process so internal raw pointers to heap are always valid
1e59de90 76 std::basic_string<CharT> stamp;
7c673cae
FG
77 };
78
1e59de90
TL
79 template <class CharT>
80 inline void get_bootstamp(std::basic_string<CharT> &s, bool add = false)
7c673cae 81 {
1e59de90 82 const windows_bootstamp<CharT> &bootstamp = windows_intermodule_singleton<windows_bootstamp<CharT> >::get();
7c673cae
FG
83 if(add){
84 s += bootstamp.stamp;
85 }
86 else{
87 s = bootstamp.stamp;
88 }
89 }
90 #elif defined(BOOST_INTERPROCESS_HAS_BSD_KERNEL_BOOTTIME)
91 inline void get_bootstamp(std::string &s, bool add = false)
92 {
93 // FreeBSD specific: sysctl "kern.boottime"
94 int request[2] = { CTL_KERN, KERN_BOOTTIME };
95 struct ::timeval result;
96 std::size_t result_len = sizeof result;
97
98 if (::sysctl (request, 2, &result, &result_len, 0, 0) < 0)
99 return;
100
101 char bootstamp_str[256];
102
103 const char Characters [] =
104 { '0', '1', '2', '3', '4', '5', '6', '7'
105 , '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
106
107 std::size_t char_counter = 0;
108 //32 bit values to allow 32 and 64 bit process IPC
109 boost::uint32_t fields[2] = { boost::uint32_t(result.tv_sec), boost::uint32_t(result.tv_usec) };
110 for(std::size_t field = 0; field != 2; ++field){
111 for(std::size_t i = 0; i != sizeof(fields[0]); ++i){
112 const char *ptr = (const char *)&fields[field];
113 bootstamp_str[char_counter++] = Characters[(ptr[i]&0xF0)>>4];
114 bootstamp_str[char_counter++] = Characters[(ptr[i]&0x0F)];
115 }
116 }
117 bootstamp_str[char_counter] = 0;
118 if(add){
119 s += bootstamp_str;
120 }
121 else{
122 s = bootstamp_str;
123 }
124 }
125 #else
126 #error "BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME defined with no known implementation"
127 #endif
128#endif //#if defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME)
129
1e59de90
TL
130template <class CharT>
131inline void get_shared_dir_root(std::basic_string<CharT> &dir_path)
7c673cae
FG
132{
133 #if defined (BOOST_INTERPROCESS_WINDOWS)
134 winapi::get_shared_documents_folder(dir_path);
b32b8144 135 #else
7c673cae
FG
136 dir_path = "/tmp";
137 #endif
b32b8144 138
7c673cae
FG
139 //We always need this path, so throw on error
140 if(dir_path.empty()){
141 error_info err = system_error_code();
142 throw interprocess_exception(err);
143 }
1e59de90
TL
144
145 dir_path += shared_dir_constants<CharT>::dir_interprocess();
7c673cae
FG
146}
147
b32b8144
FG
148#if defined(BOOST_INTERPROCESS_SHARED_DIR_FUNC) && defined(BOOST_INTERPROCESS_SHARED_DIR_PATH)
149#error "Error: Both BOOST_INTERPROCESS_SHARED_DIR_FUNC and BOOST_INTERPROCESS_SHARED_DIR_PATH defined!"
150#endif
151
152#ifdef BOOST_INTERPROCESS_SHARED_DIR_FUNC
153
154 // When BOOST_INTERPROCESS_SHARED_DIR_FUNC is defined, users have to implement
155 // get_shared_dir
156 void get_shared_dir(std::string &shared_dir);
157
1e59de90
TL
158 // When BOOST_INTERPROCESS_SHARED_DIR_FUNC is defined, users have to implement
159 // get_shared_dir
160 void get_shared_dir(std::wstring &shared_dir);
161
b32b8144 162#else
1e59de90
TL
163
164#if defined(BOOST_INTERPROCESS_SHARED_DIR_PATH)
165
7c673cae
FG
166inline void get_shared_dir(std::string &shared_dir)
167{
1e59de90
TL
168 shared_dir = BOOST_INTERPROCESS_SHARED_DIR_PATH;
169}
170
171#endif
172
173#if defined(BOOST_INTERPROCESS_SHARED_DIR_WPATH)
174
175inline void get_shared_dir(std::wstring &shared_dir)
176{
177 shared_dir = BOOST_INTERPROCESS_SHARED_DIR_WPATH;
178}
179
180#endif
181
182template<class CharT>
183inline void get_shared_dir(std::basic_string<CharT> &shared_dir)
184{
7c673cae
FG
185 get_shared_dir_root(shared_dir);
186 #if defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME)
1e59de90 187 shared_dir += shared_dir_constants<CharT>::dir_separator();
7c673cae
FG
188 get_bootstamp(shared_dir, true);
189 #endif
7c673cae 190}
b32b8144 191#endif
7c673cae 192
1e59de90
TL
193template<class CharT>
194inline void shared_filepath(const CharT *filename, std::basic_string<CharT> &filepath)
7c673cae
FG
195{
196 get_shared_dir(filepath);
1e59de90 197 filepath += shared_dir_constants<CharT>::dir_separator();
7c673cae
FG
198 filepath += filename;
199}
200
1e59de90
TL
201template<class CharT>
202inline void create_shared_dir_and_clean_old(std::basic_string<CharT> &shared_dir)
7c673cae 203{
b32b8144
FG
204 #if defined(BOOST_INTERPROCESS_SHARED_DIR_PATH) || defined(BOOST_INTERPROCESS_SHARED_DIR_FUNC)
205 get_shared_dir(shared_dir);
7c673cae
FG
206 #else
207 //First get the temp directory
1e59de90 208 std::basic_string<CharT> root_shared_dir;
7c673cae
FG
209 get_shared_dir_root(root_shared_dir);
210
211 //If fails, check that it's because already exists
1e59de90 212 if(!open_or_create_shared_directory(root_shared_dir.c_str())){
7c673cae 213 error_info info(system_error_code());
1e59de90 214 throw interprocess_exception(info);
7c673cae
FG
215 }
216
217 #if defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME)
218 get_shared_dir(shared_dir);
219
220 //If fails, check that it's because already exists
1e59de90 221 if(!open_or_create_shared_directory(shared_dir.c_str())){
7c673cae 222 error_info info(system_error_code());
1e59de90 223 throw interprocess_exception(info);
7c673cae
FG
224 }
225 //Now erase all old directories created in the previous boot sessions
1e59de90 226 std::basic_string<CharT> subdir = shared_dir;
7c673cae
FG
227 subdir.erase(0, root_shared_dir.size()+1);
228 delete_subdirectories(root_shared_dir, subdir.c_str());
229 #else
230 shared_dir = root_shared_dir;
231 #endif
232 #endif
233}
234
1e59de90
TL
235template<class CharT>
236inline void create_shared_dir_cleaning_old_and_get_filepath(const CharT *filename, std::basic_string<CharT> &shared_dir)
7c673cae
FG
237{
238 create_shared_dir_and_clean_old(shared_dir);
1e59de90 239 shared_dir += shared_dir_constants<CharT>::dir_separator();
7c673cae
FG
240 shared_dir += filename;
241}
242
1e59de90
TL
243template<class CharT>
244inline void add_leading_slash(const CharT *name, std::basic_string<CharT> &new_name)
7c673cae 245{
1e59de90
TL
246 if(name[0] != shared_dir_constants<CharT>::dir_separator()){
247 new_name = shared_dir_constants<CharT>::dir_separator();
7c673cae
FG
248 }
249 new_name += name;
250}
251
252} //namespace boost{
253} //namespace interprocess {
254} //namespace ipcdetail {
255
256#include <boost/interprocess/detail/config_end.hpp>
257
258#endif //ifndef BOOST_INTERPROCESS_DETAIL_SHARED_DIR_HELPERS_HPP