1 //////////////////////////////////////////////////////////////////////////////
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)
7 // See http://www.boost.org/libs/interprocess for documentation.
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>
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
34 namespace interprocess
{
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;
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)
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;
88 inline void tmp_filename(const char *filename
, std::string
&tmp_name
)
90 const char *tmp_dir
= get_temporary_path();
92 error_info err
= system_error_code();
93 throw interprocess_exception(err
);
98 tmp_name
+= "/boost_interprocess/";
99 #ifdef BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
100 get_bootstamp(tmp_name
, true);
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();
111 error_info err
= system_error_code();
112 throw interprocess_exception(err
);
115 //Create Boost.Interprocess dir
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
;
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());
149 tmp_name
+= filename
;
152 inline void add_leading_slash(const char *name
, std::string
&new_name
)
161 } //namespace interprocess {
162 } //namespace detail {
164 #include <boost/interprocess/detail/config_end.hpp>
166 #endif //ifndef BOOST_INTERPROCESS_DETAIL_TMP_DIR_HELPERS_HPP