File indexing completed on 2025-01-18 09:38:26
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_INTERPROCESS_DETAIL_OS_FILE_FUNCTIONS_HPP
0012 #define BOOST_INTERPROCESS_DETAIL_OS_FILE_FUNCTIONS_HPP
0013
0014 #ifndef BOOST_CONFIG_HPP
0015 # include <boost/config.hpp>
0016 #endif
0017 #
0018 #if defined(BOOST_HAS_PRAGMA_ONCE)
0019 # pragma once
0020 #endif
0021
0022 #include <boost/interprocess/detail/config_begin.hpp>
0023 #include <boost/interprocess/detail/workaround.hpp>
0024 #include <boost/interprocess/errors.hpp>
0025 #include <boost/interprocess/permissions.hpp>
0026 #include <boost/static_assert.hpp>
0027
0028 #include <climits>
0029 #include <string>
0030 #include <boost/move/detail/type_traits.hpp> //make_unsigned
0031
0032 #if defined (BOOST_INTERPROCESS_WINDOWS)
0033 # include <boost/interprocess/detail/win32_api.hpp>
0034 # include <wchar.h> //wcsxxx()
0035 #else
0036 # ifdef BOOST_HAS_UNISTD_H
0037 # include <fcntl.h>
0038 # include <unistd.h>
0039 # include <sys/types.h>
0040 # include <sys/stat.h>
0041 # include <dirent.h>
0042 # include <cerrno>
0043 # include <cstdio>
0044 # if 0
0045 # include <sys/file.h>
0046 # endif
0047 # else
0048 # error Unknown platform
0049 # endif
0050 #endif
0051
0052 #include <cstring>
0053 #include <cstdlib>
0054
0055 namespace boost {
0056 namespace interprocess {
0057
0058 #if defined (BOOST_INTERPROCESS_WINDOWS)
0059
0060 typedef void * file_handle_t;
0061 typedef __int64 offset_t;
0062 typedef struct mapping_handle_impl_t{
0063 void * handle;
0064 bool is_shm;
0065 } mapping_handle_t;
0066
0067 typedef enum { read_only = winapi::generic_read
0068 , read_write = winapi::generic_read | winapi::generic_write
0069 , copy_on_write
0070 , read_private
0071 , invalid_mode = 0xffff
0072 } mode_t;
0073
0074 typedef enum { file_begin = winapi::file_begin
0075 , file_end = winapi::file_end
0076 , file_current = winapi::file_current
0077 } file_pos_t;
0078
0079 typedef unsigned long map_options_t;
0080 static const map_options_t default_map_options = map_options_t(-1);
0081
0082 namespace ipcdetail{
0083
0084 inline mapping_handle_t mapping_handle_from_file_handle(file_handle_t hnd)
0085 {
0086 mapping_handle_t ret;
0087 ret.handle = hnd;
0088 ret.is_shm = false;
0089 return ret;
0090 }
0091
0092 inline mapping_handle_t mapping_handle_from_shm_handle(file_handle_t hnd)
0093 {
0094 mapping_handle_t ret;
0095 ret.handle = hnd;
0096 ret.is_shm = true;
0097 return ret;
0098 }
0099
0100 inline file_handle_t file_handle_from_mapping_handle(mapping_handle_t hnd)
0101 { return hnd.handle; }
0102
0103 template<class CharT>
0104 inline bool create_directory(const CharT *path)
0105 { return winapi::create_directory(path); }
0106
0107 template<class CharT>
0108 inline bool open_or_create_directory(const CharT *path)
0109 {
0110
0111 return create_directory(path)
0112 || error_info(system_error_code()).get_error_code() == already_exists_error;
0113 }
0114
0115 template<class CharT>
0116 inline bool open_or_create_shared_directory(const CharT *path)
0117 {
0118 return open_or_create_directory(path);
0119 }
0120
0121 template <class CharT>
0122 inline bool remove_directory(const CharT *path)
0123 { return winapi::remove_directory(path); }
0124
0125 inline bool get_temporary_path(char *buffer, std::size_t buf_len, std::size_t &required_len)
0126 {
0127 required_len = 0;
0128
0129
0130 unsigned long buf = buf_len;
0131 if(buf_len != buf){
0132 return false;
0133 }
0134 required_len = winapi::get_temp_path(buf_len, buffer);
0135 const bool ret = required_len && (buf_len > required_len);
0136 if(ret && buffer[required_len-1] == '\\'){
0137 buffer[required_len-1] = '\0';
0138 }
0139 return ret;
0140 }
0141
0142 inline bool get_temporary_path(wchar_t *buffer, std::size_t buf_len, std::size_t &required_len)
0143 {
0144 required_len = 0;
0145
0146
0147 unsigned long buf = buf_len;
0148 if(buf_len != buf){
0149 return false;
0150 }
0151 required_len = winapi::get_temp_path(buf_len, buffer);
0152 const bool ret = !(buf_len < required_len);
0153 if(ret && buffer[required_len-1] == L'\\'){
0154 buffer[required_len-1] = L'\0';
0155 }
0156 return ret;
0157 }
0158
0159 template<class CharT>
0160 inline file_handle_t create_new_file
0161 (const CharT *name, mode_t mode, const permissions & perm = permissions(), bool temporary = false)
0162 {
0163 unsigned long attr = temporary ? winapi::file_attribute_temporary : 0;
0164 return winapi::create_file
0165 ( name, (unsigned int)mode, winapi::create_new, attr
0166 , (winapi::interprocess_security_attributes*)perm.get_permissions());
0167 }
0168
0169 template <class CharT>
0170 inline file_handle_t create_or_open_file
0171 (const CharT *name, mode_t mode, const permissions & perm = permissions(), bool temporary = false)
0172 {
0173 unsigned long attr = temporary ? winapi::file_attribute_temporary : 0;
0174 return winapi::create_file
0175 ( name, (unsigned int)mode, winapi::open_always, attr
0176 , (winapi::interprocess_security_attributes*)perm.get_permissions());
0177 }
0178
0179 template<class CharT>
0180 inline file_handle_t open_existing_file
0181 (const CharT *name, mode_t mode, bool temporary = false)
0182 {
0183 unsigned long attr = temporary ? winapi::file_attribute_temporary : 0;
0184 return winapi::create_file
0185 (name, (unsigned int)mode, winapi::open_existing, attr, 0);
0186 }
0187
0188 inline bool delete_file(const char *name)
0189 { return winapi::unlink_file(name); }
0190
0191 inline bool delete_file(const wchar_t *name)
0192 { return winapi::unlink_file(name); }
0193
0194 inline bool truncate_file (file_handle_t hnd, std::size_t size)
0195 {
0196 offset_t filesize;
0197 if(!winapi::get_file_size(hnd, filesize))
0198 return false;
0199
0200 typedef ::boost::move_detail::make_unsigned<offset_t>::type uoffset_t;
0201 const uoffset_t max_filesize = uoffset_t(-1)/2u;
0202 const uoffset_t uoff_size = uoffset_t(size);
0203
0204 if(uoff_size > max_filesize){
0205 winapi::set_last_error(winapi::error_file_too_large);
0206 return false;
0207 }
0208
0209 if(offset_t(size) > filesize){
0210 if(!winapi::set_file_pointer(hnd, filesize, 0, winapi::file_begin)){
0211 return false;
0212 }
0213
0214
0215 for(std::size_t remaining = size - std::size_t(filesize), write_size = 0
0216 ;remaining > 0
0217 ;remaining -= write_size){
0218 const std::size_t DataSize = 512;
0219 static char data [DataSize];
0220 write_size = DataSize < remaining ? DataSize : remaining;
0221 unsigned long written;
0222 winapi::write_file(hnd, data, (unsigned long)write_size, &written, 0);
0223 if(written != write_size){
0224 return false;
0225 }
0226 }
0227 }
0228 else{
0229 if(!winapi::set_file_pointer(hnd, size, 0, winapi::file_begin)){
0230 return false;
0231 }
0232 if(!winapi::set_end_of_file(hnd)){
0233 return false;
0234 }
0235 }
0236 return true;
0237 }
0238
0239 inline bool get_file_size(file_handle_t hnd, offset_t &size)
0240 { return winapi::get_file_size(hnd, size); }
0241
0242 inline bool set_file_pointer(file_handle_t hnd, offset_t off, file_pos_t pos)
0243 { return winapi::set_file_pointer(hnd, off, 0, (unsigned long) pos); }
0244
0245 inline bool get_file_pointer(file_handle_t hnd, offset_t &off)
0246 { return winapi::set_file_pointer(hnd, 0, &off, winapi::file_current); }
0247
0248 inline bool write_file(file_handle_t hnd, const void *data, std::size_t numdata)
0249 {
0250 unsigned long written;
0251 return 0 != winapi::write_file(hnd, data, (unsigned long)numdata, &written, 0);
0252 }
0253
0254 inline file_handle_t invalid_file()
0255 { return winapi::invalid_handle_value; }
0256
0257 inline bool close_file(file_handle_t hnd)
0258 { return 0 != winapi::close_handle(hnd); }
0259
0260 inline bool acquire_file_lock(file_handle_t hnd)
0261 {
0262 static winapi::interprocess_overlapped overlapped;
0263 const unsigned long len = ((unsigned long)-1);
0264
0265
0266 return winapi::lock_file_ex
0267 (hnd, winapi::lockfile_exclusive_lock, 0, len, len, &overlapped);
0268 }
0269
0270 inline bool try_acquire_file_lock(file_handle_t hnd, bool &acquired)
0271 {
0272 const unsigned long len = ((unsigned long)-1);
0273 winapi::interprocess_overlapped overlapped;
0274 std::memset(&overlapped, 0, sizeof(overlapped));
0275 if(!winapi::lock_file_ex
0276 (hnd, winapi::lockfile_exclusive_lock | winapi::lockfile_fail_immediately,
0277 0, len, len, &overlapped)){
0278 return winapi::get_last_error() == winapi::error_lock_violation ?
0279 acquired = false, true : false;
0280
0281 }
0282 acquired = true;
0283 return true;
0284 }
0285
0286 inline bool release_file_lock(file_handle_t hnd)
0287 {
0288 const unsigned long len = ((unsigned long)-1);
0289 winapi::interprocess_overlapped overlapped;
0290 std::memset(&overlapped, 0, sizeof(overlapped));
0291 return winapi::unlock_file_ex(hnd, 0, len, len, &overlapped);
0292 }
0293
0294 inline bool acquire_file_lock_sharable(file_handle_t hnd)
0295 {
0296 const unsigned long len = ((unsigned long)-1);
0297 winapi::interprocess_overlapped overlapped;
0298 std::memset(&overlapped, 0, sizeof(overlapped));
0299 return winapi::lock_file_ex(hnd, 0, 0, len, len, &overlapped);
0300 }
0301
0302 inline bool try_acquire_file_lock_sharable(file_handle_t hnd, bool &acquired)
0303 {
0304 const unsigned long len = ((unsigned long)-1);
0305 winapi::interprocess_overlapped overlapped;
0306 std::memset(&overlapped, 0, sizeof(overlapped));
0307 if(!winapi::lock_file_ex
0308 (hnd, winapi::lockfile_fail_immediately, 0, len, len, &overlapped)){
0309 return winapi::get_last_error() == winapi::error_lock_violation ?
0310 acquired = false, true : false;
0311 }
0312
0313 acquired = true;
0314 return true;
0315 }
0316
0317 inline bool release_file_lock_sharable(file_handle_t hnd)
0318 { return release_file_lock(hnd); }
0319
0320 template<class CharT>
0321 struct os_file_traits;
0322
0323 template<>
0324 struct os_file_traits<char>
0325 {
0326 static const char *any_file()
0327 { return "\\*.*"; }
0328
0329 static const char *backslash()
0330 { return "\\"; }
0331
0332 static char dot()
0333 { return '.'; }
0334
0335 typedef winapi::win32_find_data_a win32_find_data_t;
0336
0337 static int cmp(const char *a, const char *b)
0338 { return std::strcmp(a, b); }
0339 };
0340
0341 template<>
0342 struct os_file_traits<wchar_t>
0343 {
0344 static const wchar_t *any_file()
0345 { return L"\\*.*"; }
0346
0347 static const wchar_t *backslash()
0348 { return L"\\"; }
0349
0350 static wchar_t dot()
0351 { return L'.'; }
0352
0353 typedef winapi::win32_find_data_w win32_find_data_t;
0354
0355 static int cmp(const wchar_t *a, const wchar_t *b)
0356 { return std::wcscmp(a, b); }
0357 };
0358
0359 template<class CharT>
0360 inline bool delete_subdirectories_recursive
0361 (const std::basic_string<CharT> &refcstrRootDirectory, const CharT *dont_delete_this, unsigned int count)
0362 {
0363 bool bSubdirectory = false;
0364
0365 void * hFile;
0366 std::basic_string<CharT> strFilePath;
0367 std::basic_string<CharT> strPattern;
0368 typedef os_file_traits<CharT> traits_t;
0369 typename traits_t::win32_find_data_t FileInformation;
0370
0371
0372 strPattern = refcstrRootDirectory + traits_t::any_file();
0373 hFile = winapi::find_first_file(strPattern.c_str(), &FileInformation);
0374 if(hFile != winapi::invalid_handle_value){
0375 do{
0376
0377 if(FileInformation.cFileName[0] != traits_t::dot() &&
0378 !(dont_delete_this && count == 0 && traits_t::cmp(dont_delete_this, FileInformation.cFileName) == 0)){
0379 strFilePath.erase();
0380 strFilePath = refcstrRootDirectory + traits_t::backslash() + FileInformation.cFileName;
0381
0382
0383 if(FileInformation.dwFileAttributes & winapi::file_attribute_directory){
0384
0385 if(!delete_subdirectories_recursive(strFilePath, dont_delete_this, count+1)){
0386 winapi::find_close(hFile);
0387 return false;
0388 }
0389 }
0390
0391 else{
0392
0393
0394
0395
0396 winapi::unlink_file(strFilePath.c_str());
0397 }
0398 }
0399
0400 } while(winapi::find_next_file(hFile, &FileInformation) == 1);
0401
0402
0403 winapi::find_close(hFile);
0404
0405
0406 if(winapi::get_last_error() != winapi::error_no_more_files){
0407 return false;
0408 }
0409 else
0410 {
0411
0412 if(!bSubdirectory && count)
0413 {
0414
0415
0416
0417
0418 if(winapi::remove_directory(refcstrRootDirectory.c_str()) == 0)
0419 return false;
0420 }
0421 }
0422 }
0423 return true;
0424 }
0425
0426
0427 template <class CharT>
0428 inline bool delete_subdirectories(const std::basic_string<CharT> &refcstrRootDirectory, const CharT *dont_delete_this)
0429 {
0430 return delete_subdirectories_recursive(refcstrRootDirectory, dont_delete_this, 0u);
0431 }
0432
0433
0434 template<class Function>
0435 inline bool for_each_file_in_dir(const char *dir, Function f)
0436 {
0437 void * hFile;
0438 winapi::win32_find_data_a FileInformation;
0439
0440
0441 std::string str(dir);
0442 const std::size_t base_root_dir_len = str.size();
0443
0444
0445 str += "\\*.*";
0446 hFile = winapi::find_first_file(str.c_str(), &FileInformation);
0447 if(hFile != winapi::invalid_handle_value){
0448 do{
0449 str.erase(base_root_dir_len);
0450
0451 if(FileInformation.cFileName[0] != '.'){
0452 str += "\\"; str += FileInformation.cFileName;
0453
0454 if(!(FileInformation.dwFileAttributes & winapi::file_attribute_directory)){
0455 f(str.c_str(), FileInformation.cFileName);
0456 }
0457 }
0458
0459 } while(winapi::find_next_file(hFile, &FileInformation) == 1);
0460
0461
0462 winapi::find_close(hFile);
0463 if(winapi::get_last_error() != winapi::error_no_more_files){
0464 return false;
0465 }
0466 }
0467 return true;
0468 }
0469
0470
0471 #else
0472
0473 typedef int file_handle_t;
0474 typedef off_t offset_t;
0475
0476 typedef struct mapping_handle_impl_t
0477 {
0478 file_handle_t handle;
0479 bool is_xsi;
0480 } mapping_handle_t;
0481
0482 typedef enum { read_only = O_RDONLY
0483 , read_write = O_RDWR
0484 , copy_on_write
0485 , read_private
0486 , invalid_mode = 0xffff
0487 } mode_t;
0488
0489 typedef enum { file_begin = SEEK_SET
0490 , file_end = SEEK_END
0491 , file_current = SEEK_CUR
0492 } file_pos_t;
0493
0494 typedef int map_options_t;
0495 static const map_options_t default_map_options = map_options_t(-1);
0496
0497 namespace ipcdetail{
0498
0499 inline mapping_handle_t mapping_handle_from_file_handle(file_handle_t hnd)
0500 {
0501 mapping_handle_t ret;
0502 ret.handle = hnd;
0503 ret.is_xsi = false;
0504 return ret;
0505 }
0506
0507 inline file_handle_t file_handle_from_mapping_handle(mapping_handle_t hnd)
0508 { return hnd.handle; }
0509
0510 inline bool create_directory(const char *path)
0511 {
0512 ::mode_t m = ::mode_t(0777);
0513 return ::mkdir(path, m) == 0;
0514 }
0515
0516 inline bool open_or_create_directory(const char *path)
0517 {
0518 ::mode_t m = ::mode_t(0777);
0519 return ::mkdir(path, m) == 0 || (errno == EEXIST);
0520 }
0521
0522 inline bool open_or_create_shared_directory(const char *path)
0523 {
0524 const ::mode_t m = ::mode_t(01777);
0525 const bool created = ::mkdir(path, m) == 0;
0526 const bool created_or_exists = created || (errno == EEXIST);
0527
0528
0529 const bool chmoded = ::chmod(path, m) == 0;
0530 return created ? chmoded : created_or_exists;
0531 }
0532
0533 inline bool remove_directory(const char *path)
0534 { return ::rmdir(path) == 0; }
0535
0536 inline bool get_temporary_path(char *buffer, std::size_t buf_len, std::size_t &required_len)
0537 {
0538 required_len = 5u;
0539 if(buf_len < required_len)
0540 return false;
0541 else{
0542 std::strcpy(buffer, "/tmp");
0543 }
0544 return true;
0545 }
0546
0547 inline file_handle_t create_new_file
0548 (const char *name, mode_t mode, const permissions & perm = permissions(), bool temporary = false)
0549 {
0550 (void)temporary;
0551 int ret = ::open(name, ((int)mode) | O_EXCL | O_CREAT, perm.get_permissions());
0552 if(ret >= 0){
0553 ::fchmod(ret, perm.get_permissions());
0554 }
0555 return ret;
0556 }
0557
0558 inline file_handle_t create_or_open_file
0559 (const char *name, mode_t mode, const permissions & perm = permissions(), bool temporary = false)
0560 {
0561 (void)temporary;
0562 int ret = -1;
0563
0564
0565 while(true){
0566 ret = ::open(name, ((int)mode) | O_EXCL | O_CREAT, perm.get_permissions());
0567 if(ret >= 0){
0568 ::fchmod(ret, perm.get_permissions());
0569 break;
0570 }
0571 else if(errno == EEXIST){
0572 if((ret = ::open(name, (int)mode)) >= 0 || errno != ENOENT){
0573 break;
0574 }
0575 }
0576 else{
0577 break;
0578 }
0579 }
0580 return ret;
0581 }
0582
0583 inline file_handle_t open_existing_file
0584 (const char *name, mode_t mode, bool temporary = false)
0585 {
0586 (void)temporary;
0587 return ::open(name, (int)mode);
0588 }
0589
0590 inline bool delete_file(const char *name)
0591 { return ::unlink(name) == 0; }
0592
0593 inline bool truncate_file (file_handle_t hnd, std::size_t size)
0594 {
0595 typedef boost::move_detail::make_unsigned<off_t>::type uoff_t;
0596 BOOST_STATIC_ASSERT(( sizeof(uoff_t) >= sizeof(std::size_t) ));
0597 if( uoff_t(-1)/2u < uoff_t(size) ){
0598 errno = EINVAL;
0599 return false;
0600 }
0601 return 0 == ::ftruncate(hnd, off_t(size));
0602 }
0603
0604 inline bool get_file_size(file_handle_t hnd, offset_t &size)
0605 {
0606 struct stat data;
0607 bool ret = 0 == ::fstat(hnd, &data);
0608 if(ret){
0609 size = data.st_size;
0610 }
0611 return ret;
0612 }
0613
0614 inline bool set_file_pointer(file_handle_t hnd, offset_t off, file_pos_t pos)
0615 { return ((off_t)(-1)) != ::lseek(hnd, off, (int)pos); }
0616
0617 inline bool get_file_pointer(file_handle_t hnd, offset_t &off)
0618 {
0619 off = ::lseek(hnd, 0, SEEK_CUR);
0620 return off != ((off_t)-1);
0621 }
0622
0623 inline bool write_file(file_handle_t hnd, const void *data, std::size_t numdata)
0624 { return (ssize_t(numdata)) == ::write(hnd, data, numdata); }
0625
0626 inline file_handle_t invalid_file()
0627 { return -1; }
0628
0629 inline bool close_file(file_handle_t hnd)
0630 { return ::close(hnd) == 0; }
0631
0632 inline bool acquire_file_lock(file_handle_t hnd)
0633 {
0634 struct ::flock lock;
0635 lock.l_type = F_WRLCK;
0636 lock.l_whence = SEEK_SET;
0637 lock.l_start = 0;
0638 lock.l_len = 0;
0639 return -1 != ::fcntl(hnd, F_SETLKW, &lock);
0640 }
0641
0642 inline bool try_acquire_file_lock(file_handle_t hnd, bool &acquired)
0643 {
0644 struct ::flock lock;
0645 lock.l_type = F_WRLCK;
0646 lock.l_whence = SEEK_SET;
0647 lock.l_start = 0;
0648 lock.l_len = 0;
0649 int ret = ::fcntl(hnd, F_SETLK, &lock);
0650 if(ret == -1){
0651 return (errno == EAGAIN || errno == EACCES) ?
0652 (acquired = false, true) : false;
0653 }
0654 return (acquired = true);
0655 }
0656
0657 inline bool release_file_lock(file_handle_t hnd)
0658 {
0659 struct ::flock lock;
0660 lock.l_type = F_UNLCK;
0661 lock.l_whence = SEEK_SET;
0662 lock.l_start = 0;
0663 lock.l_len = 0;
0664 return -1 != ::fcntl(hnd, F_SETLK, &lock);
0665 }
0666
0667 inline bool acquire_file_lock_sharable(file_handle_t hnd)
0668 {
0669 struct ::flock lock;
0670 lock.l_type = F_RDLCK;
0671 lock.l_whence = SEEK_SET;
0672 lock.l_start = 0;
0673 lock.l_len = 0;
0674 return -1 != ::fcntl(hnd, F_SETLKW, &lock);
0675 }
0676
0677 inline bool try_acquire_file_lock_sharable(file_handle_t hnd, bool &acquired)
0678 {
0679 struct flock lock;
0680 lock.l_type = F_RDLCK;
0681 lock.l_whence = SEEK_SET;
0682 lock.l_start = 0;
0683 lock.l_len = 0;
0684 int ret = ::fcntl(hnd, F_SETLK, &lock);
0685 if(ret == -1){
0686 return (errno == EAGAIN || errno == EACCES) ?
0687 (acquired = false, true) : false;
0688 }
0689 return (acquired = true);
0690 }
0691
0692 inline bool release_file_lock_sharable(file_handle_t hnd)
0693 { return release_file_lock(hnd); }
0694
0695 #if 0
0696 inline bool acquire_file_lock(file_handle_t hnd)
0697 { return 0 == ::flock(hnd, LOCK_EX); }
0698
0699 inline bool try_acquire_file_lock(file_handle_t hnd, bool &acquired)
0700 {
0701 int ret = ::flock(hnd, LOCK_EX | LOCK_NB);
0702 acquired = ret == 0;
0703 return (acquired || errno == EWOULDBLOCK);
0704 }
0705
0706 inline bool release_file_lock(file_handle_t hnd)
0707 { return 0 == ::flock(hnd, LOCK_UN); }
0708
0709 inline bool acquire_file_lock_sharable(file_handle_t hnd)
0710 { return 0 == ::flock(hnd, LOCK_SH); }
0711
0712 inline bool try_acquire_file_lock_sharable(file_handle_t hnd, bool &acquired)
0713 {
0714 int ret = ::flock(hnd, LOCK_SH | LOCK_NB);
0715 acquired = ret == 0;
0716 return (acquired || errno == EWOULDBLOCK);
0717 }
0718
0719 inline bool release_file_lock_sharable(file_handle_t hnd)
0720 { return 0 == ::flock(hnd, LOCK_UN); }
0721 #endif
0722
0723 inline bool delete_subdirectories_recursive
0724 (const std::string &refcstrRootDirectory, const char *dont_delete_this)
0725 {
0726 DIR *d = opendir(refcstrRootDirectory.c_str());
0727 if(!d) {
0728 return false;
0729 }
0730
0731 struct dir_close
0732 {
0733 DIR *d_;
0734 dir_close(DIR *d) : d_(d) {}
0735 ~dir_close() { ::closedir(d_); }
0736 } dc(d); (void)dc;
0737
0738 struct ::dirent *de;
0739 struct ::stat st;
0740 std::string fn;
0741
0742 while((de=::readdir(d))) {
0743 if( de->d_name[0] == '.' && ( de->d_name[1] == '\0'
0744 || (de->d_name[1] == '.' && de->d_name[2] == '\0' )) ){
0745 continue;
0746 }
0747 if(dont_delete_this && std::strcmp(dont_delete_this, de->d_name) == 0){
0748 continue;
0749 }
0750 fn = refcstrRootDirectory;
0751 fn += '/';
0752 fn += de->d_name;
0753
0754 if(std::remove(fn.c_str())) {
0755 if(::stat(fn.c_str(), & st)) {
0756 return false;
0757 }
0758 if(S_ISDIR(st.st_mode)) {
0759 if(!delete_subdirectories_recursive(fn, 0) ){
0760 return false;
0761 }
0762 } else {
0763 return false;
0764 }
0765 }
0766 }
0767 return std::remove(refcstrRootDirectory.c_str()) ? false : true;
0768 }
0769
0770 template<class Function>
0771 inline bool for_each_file_in_dir(const char *dir, Function f)
0772 {
0773 std::string refcstrRootDirectory(dir);
0774
0775 DIR *d = opendir(refcstrRootDirectory.c_str());
0776 if(!d) {
0777 return false;
0778 }
0779
0780 struct dir_close
0781 {
0782 DIR *d_;
0783 dir_close(DIR *d) : d_(d) {}
0784 ~dir_close() { ::closedir(d_); }
0785 } dc(d); (void)dc;
0786
0787 struct ::dirent *de;
0788 struct ::stat st;
0789 std::string fn;
0790
0791 while((de=::readdir(d))) {
0792 if( de->d_name[0] == '.' && ( de->d_name[1] == '\0'
0793 || (de->d_name[1] == '.' && de->d_name[2] == '\0' )) ){
0794 continue;
0795 }
0796 fn = refcstrRootDirectory;
0797 fn += '/';
0798 fn += de->d_name;
0799
0800 if(::stat(fn.c_str(), & st)) {
0801 return false;
0802 }
0803
0804 if(!S_ISDIR(st.st_mode)) {
0805 f(fn.c_str(), de->d_name);
0806 }
0807 }
0808 return true;
0809 }
0810
0811
0812
0813 inline bool delete_subdirectories(const std::string &refcstrRootDirectory, const char *dont_delete_this)
0814 {
0815 return delete_subdirectories_recursive(refcstrRootDirectory, dont_delete_this );
0816 }
0817
0818 #endif
0819
0820 inline std::string get_temporary_path()
0821 {
0822 std::size_t required_len = 0;
0823 get_temporary_path((char*)0, 0, required_len);
0824 std::string ret_str(required_len, char(0));
0825 get_temporary_path(&ret_str[0], ret_str.size(), required_len);
0826 while(!ret_str.empty() && !ret_str[ret_str.size()-1]){
0827 ret_str.erase(ret_str.size()-1);
0828 }
0829
0830 return ret_str;
0831 }
0832
0833 #ifdef BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES
0834
0835 inline std::wstring get_temporary_wpath()
0836 {
0837 std::size_t required_len = 0;
0838 get_temporary_path((wchar_t*)0, 0, required_len);
0839 std::wstring ret_str(required_len, char(0));
0840 get_temporary_path(&ret_str[0], ret_str.size(), required_len);
0841 while(!ret_str.empty() && !ret_str[ret_str.size()-1]){
0842 ret_str.erase(ret_str.size()-1);
0843 }
0844
0845 return ret_str;
0846 }
0847
0848 #endif
0849
0850 }
0851 }
0852 }
0853
0854 #include <boost/interprocess/detail/config_end.hpp>
0855
0856 #endif