/Src/Dependencies/Boost/boost/interprocess/detail/tmp_dir_helpers.hpp

http://hadesmem.googlecode.com/ · C++ Header · 172 lines · 136 code · 21 blank · 15 comment · 21 complexity · f0d54b8b1238034a56ad5e5aa4f7f1a2 MD5 · raw file

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2007-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. #ifndef BOOST_INTERPROCESS_DETAIL_TMP_DIR_HELPERS_HPP
  11. #define BOOST_INTERPROCESS_DETAIL_TMP_DIR_HELPERS_HPP
  12. #include <boost/interprocess/detail/config_begin.hpp>
  13. #include <boost/interprocess/detail/workaround.hpp>
  14. #include <boost/interprocess/detail/os_file_functions.hpp>
  15. #include <boost/interprocess/errors.hpp>
  16. #include <boost/interprocess/exceptions.hpp>
  17. #include <string>
  18. #if defined(BOOST_INTERPROCESS_WINDOWS)
  19. #define BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME
  20. #define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
  21. #include <boost/interprocess/detail/win32_api.hpp>
  22. #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
  23. #include <sys/sysctl.h>
  24. #if defined(CTL_KERN) && defined (KERN_BOOTTIME)
  25. #define BOOST_INTERPROCESS_HAS_BSD_KERNEL_BOOTTIME
  26. #define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
  27. #endif
  28. #endif
  29. namespace boost {
  30. namespace interprocess {
  31. namespace detail {
  32. #if defined (BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME)
  33. inline void get_bootstamp(std::string &s, bool add = false)
  34. {
  35. std::string bootstamp;
  36. winapi::get_last_bootup_time(bootstamp);
  37. if(add){
  38. s += bootstamp;
  39. }
  40. else{
  41. s = bootstamp;
  42. }
  43. }
  44. #elif defined(BOOST_INTERPROCESS_HAS_BSD_KERNEL_BOOTTIME)
  45. inline void get_bootstamp(std::string &s, bool add = false)
  46. {
  47. // FreeBSD specific: sysctl "kern.boottime"
  48. int request[2] = { CTL_KERN, KERN_BOOTTIME };
  49. struct ::timeval result;
  50. size_t result_len = sizeof result;
  51. if (::sysctl (request, 2, &result, &result_len, NULL, 0) < 0)
  52. return;
  53. char bootstamp_str[256];
  54. const char Characters [] =
  55. { '0', '1', '2', '3', '4', '5', '6', '7'
  56. , '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
  57. std::size_t char_counter = 0;
  58. long fields[2] = { result.tv_sec, result.tv_usec };
  59. for(std::size_t field = 0; field != 2; ++field){
  60. for(std::size_t i = 0; i != sizeof(long); ++i){
  61. const char *ptr = (const char *)&fields[field];
  62. bootstamp_str[char_counter++] = Characters[(ptr[i]&0xF0)>>4];
  63. bootstamp_str[char_counter++] = Characters[(ptr[i]&0x0F)];
  64. }
  65. }
  66. bootstamp_str[char_counter] = 0;
  67. if(add){
  68. s += bootstamp_str;
  69. }
  70. else{
  71. s = bootstamp_str;
  72. }
  73. }
  74. #endif
  75. inline void get_tmp_base_dir(std::string &tmp_name)
  76. {
  77. #if defined (BOOST_INTERPROCESS_WINDOWS)
  78. winapi::get_shared_documents_folder(tmp_name);
  79. if(tmp_name.empty()){
  80. tmp_name = get_temporary_path();
  81. }
  82. #else
  83. tmp_name = get_temporary_path();
  84. #endif
  85. if(tmp_name.empty()){
  86. error_info err = system_error_code();
  87. throw interprocess_exception(err);
  88. }
  89. //Remove final null.
  90. tmp_name += "/boost_interprocess";
  91. }
  92. inline void tmp_folder(std::string &tmp_name)
  93. {
  94. get_tmp_base_dir(tmp_name);
  95. #ifdef BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
  96. tmp_name += "/";
  97. get_bootstamp(tmp_name, true);
  98. #endif
  99. }
  100. inline void tmp_filename(const char *filename, std::string &tmp_name)
  101. {
  102. tmp_folder(tmp_name);
  103. tmp_name += "/";
  104. tmp_name += filename;
  105. }
  106. inline void create_tmp_and_clean_old(std::string &tmp_name)
  107. {
  108. //First get the temp directory
  109. std::string root_tmp_name;
  110. get_tmp_base_dir(root_tmp_name);
  111. //If fails, check that it's because already exists
  112. if(!create_directory(root_tmp_name.c_str())){
  113. error_info info(system_error_code());
  114. if(info.get_error_code() != already_exists_error){
  115. throw interprocess_exception(info);
  116. }
  117. }
  118. #ifdef BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
  119. tmp_folder(tmp_name);
  120. //If fails, check that it's because already exists
  121. if(!create_directory(tmp_name.c_str())){
  122. error_info info(system_error_code());
  123. if(info.get_error_code() != already_exists_error){
  124. throw interprocess_exception(info);
  125. }
  126. }
  127. //Now erase all old directories created in the previous boot sessions
  128. std::string subdir = tmp_name;
  129. subdir.erase(0, root_tmp_name.size()+1);
  130. delete_subdirectories(root_tmp_name, subdir.c_str());
  131. #else
  132. tmp_name = root_tmp_name;
  133. #endif
  134. }
  135. inline void create_tmp_and_clean_old_and_get_filename(const char *filename, std::string &tmp_name)
  136. {
  137. create_tmp_and_clean_old(tmp_name);
  138. tmp_filename(filename, tmp_name);
  139. }
  140. inline void add_leading_slash(const char *name, std::string &new_name)
  141. {
  142. if(name[0] != '/'){
  143. new_name = '/';
  144. }
  145. new_name += name;
  146. }
  147. } //namespace boost{
  148. } //namespace interprocess {
  149. } //namespace detail {
  150. #include <boost/interprocess/detail/config_end.hpp>
  151. #endif //ifndef BOOST_INTERPROCESS_DETAIL_TMP_DIR_HELPERS_HPP