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