fix doc example typo
[boost.git] / boost / interprocess / detail / tmp_dir_helpers.hpp
blobee755e460eefcca9ba044b9d4aac6fa7b82a4ebf
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2007-2008. 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 //////////////////////////////////////////////////////////////////////////////
11 #ifndef BOOST_INTERPROCESS_DETAIL_TMP_DIR_HELPERS_HPP
12 #define BOOST_INTERPROCESS_DETAIL_TMP_DIR_HELPERS_HPP
14 #include <boost/interprocess/detail/config_begin.hpp>
15 #include <boost/interprocess/detail/workaround.hpp>
16 #include <boost/interprocess/detail/os_file_functions.hpp>
17 #include <boost/interprocess/errors.hpp>
18 #include <boost/interprocess/exceptions.hpp>
19 #include <string>
21 #if defined(BOOST_INTERPROCESS_WINDOWS)
22 #define BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME
23 #define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
24 #include <boost/interprocess/detail/win32_api.hpp>
25 #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
26 #include <sys/sysctl.h>
27 #if defined(CTL_KERN) && defined (KERN_BOOTTIME)
28 #define BOOST_INTERPROCESS_HAS_BSD_KERNEL_BOOTTIME
29 #define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
30 #endif
31 #endif
33 namespace boost {
34 namespace interprocess {
35 namespace detail {
37 #if defined (BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME)
38 inline void get_bootstamp(std::string &s, bool add = false)
40 char bootstamp[winapi::BootstampLength*2+1];
41 std::size_t bootstamp_length = winapi::BootstampLength*2;
42 winapi::get_boot_time_str(bootstamp, bootstamp_length);
43 bootstamp[winapi::BootstampLength*2] = 0;
44 if(add){
45 s += bootstamp;
47 else{
48 s = bootstamp;
51 #elif defined(BOOST_INTERPROCESS_HAS_BSD_KERNEL_BOOTTIME)
52 inline void get_bootstamp(std::string &s, bool add = false)
54 // FreeBSD specific: sysctl "kern.boottime"
55 int request[2] = { CTL_KERN, KERN_BOOTTIME };
56 struct ::timeval result;
57 size_t result_len = sizeof result;
59 if (::sysctl (request, 2, &result, &result_len, NULL, 0) < 0)
60 return;
62 char bootstamp_str[256];
64 const char Characters [] =
65 { '0', '1', '2', '3', '4', '5', '6', '7'
66 , '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
68 std::size_t char_counter = 0;
69 long fields[2] = { result.tv_sec, result.tv_usec };
70 for(std::size_t field = 0; field != 2; ++field){
71 for(std::size_t i = 0; i != sizeof(long); ++i){
72 const char *ptr = (const char *)&fields[field];
73 bootstamp_str[char_counter++] = Characters[(ptr[i]&0xF0)>>4];
74 bootstamp_str[char_counter++] = Characters[(ptr[i]&0x0F)];
77 bootstamp_str[char_counter] = 0;
78 if(add){
79 s += bootstamp_str;
81 else{
82 s = bootstamp_str;
85 #endif
88 inline void tmp_filename(const char *filename, std::string &tmp_name)
90 const char *tmp_dir = get_temporary_path();
91 if(!tmp_dir){
92 error_info err = system_error_code();
93 throw interprocess_exception(err);
95 tmp_name = tmp_dir;
97 //Remove final null.
98 tmp_name += "/boost_interprocess/";
99 #ifdef BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
100 get_bootstamp(tmp_name, true);
101 tmp_name += '/';
102 #endif
103 tmp_name += filename;
106 inline void create_tmp_dir_and_get_filename(const char *filename, std::string &tmp_name)
108 //First get the temp directory
109 const char *tmp_path = get_temporary_path();
110 if(!tmp_path){
111 error_info err = system_error_code();
112 throw interprocess_exception(err);
115 //Create Boost.Interprocess dir
116 tmp_name = tmp_path;
117 tmp_name += "/boost_interprocess";
119 //If fails, check that it's because already exists
120 if(!create_directory(tmp_name.c_str())){
121 error_info info(system_error_code());
122 if(info.get_error_code() != already_exists_error){
123 throw interprocess_exception(info);
127 #ifdef BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
128 //Create a new subdirectory with the bootstamp
129 std::string root_tmp_name = tmp_name;
130 tmp_name += '/';
131 //Obtain bootstamp string
132 std::string bootstamp;
133 get_bootstamp(bootstamp);
134 tmp_name += bootstamp;
136 //If fails, check that it's because already exists
137 if(!create_directory(tmp_name.c_str())){
138 error_info info(system_error_code());
139 if(info.get_error_code() != already_exists_error){
140 throw interprocess_exception(info);
143 //Now erase all old directories created in the previous boot sessions
144 delete_subdirectories(root_tmp_name, bootstamp.c_str());
145 #endif
147 //Add filename
148 tmp_name += '/';
149 tmp_name += filename;
152 inline void add_leading_slash(const char *name, std::string &new_name)
154 if(name[0] != '/'){
155 new_name = '/';
157 new_name += name;
160 } //namespace boost{
161 } //namespace interprocess {
162 } //namespace detail {
164 #include <boost/interprocess/detail/config_end.hpp>
166 #endif //ifndef BOOST_INTERPROCESS_DETAIL_TMP_DIR_HELPERS_HPP