Warning, file /include/boost/interprocess/detail/os_file_functions.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
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 ">#
0019 #if defined(BOOST_HAS_PRAGMA_ONCE)
0020 # pragma once
0021 #endif
0022
0023 #include <boost/interprocess/detail/config_begin.hpp>
0024 #include <boost/interprocess/detail/workaround.hpp>
0025 #include <boost/interprocess/errors.hpp>
0026 #include <boost/interprocess/permissions.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 ulbuflen = static_cast<unsigned long>(buf_len);
0131 if(buf_len != ulbuflen){
0132 return false;
0133 }
0134 required_len = winapi::get_temp_path(ulbuflen, 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 ulbuflen = static_cast<unsigned long>(buf_len);
0148 if(buf_len != ulbuflen){
0149 return false;
0150 }
0151 required_len = winapi::get_temp_path(ulbuflen, 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, static_cast<unsigned long>(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 int r = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::mkdir(path, m));
0514 return r == 0;
0515 }
0516
0517 inline bool open_or_create_directory(const char *path)
0518 {
0519 ::mode_t m = ::mode_t(0777);
0520 int r = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::mkdir(path, m));
0521 return r == 0 || (errno == EEXIST);
0522 }
0523
0524 inline bool open_or_create_shared_directory(const char *path)
0525 {
0526 const ::mode_t m = ::mode_t(01777);
0527 int rc = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::mkdir(path, m));
0528 const bool created = rc == 0;
0529 const bool created_or_exists = created || (errno == EEXIST);
0530
0531
0532 rc = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::chmod(path, m));
0533 return created ? (rc == 0) : created_or_exists;
0534 }
0535
0536 inline bool remove_directory(const char *path)
0537 { return ::rmdir(path) == 0; }
0538
0539 inline bool get_temporary_path(char *buffer, std::size_t buf_len, std::size_t &required_len)
0540 {
0541 required_len = 5u;
0542 if(buf_len < required_len)
0543 return false;
0544 else{
0545 std::strcpy(buffer, "/tmp");
0546 }
0547 return true;
0548 }
0549
0550 inline file_handle_t create_new_file
0551 (const char *name, mode_t mode, const permissions & perm = permissions(), bool temporary = false)
0552 {
0553 (void)temporary;
0554 int ret = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::open(name, ((int)mode) | O_EXCL | O_CREAT, perm.get_permissions()));
0555 if(ret >= 0){
0556 int rc = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::fchmod(ret, perm.get_permissions()));
0557 (void)rc;
0558 }
0559 return ret;
0560 }
0561
0562 inline file_handle_t create_or_open_file
0563 (const char *name, mode_t mode, const permissions & perm = permissions(), bool temporary = false)
0564 {
0565 (void)temporary;
0566 int ret = -1;
0567
0568
0569 while(true){
0570 ret = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::open(name, ((int)mode) | O_EXCL | O_CREAT, perm.get_permissions()));
0571 if(ret >= 0){
0572 int rc = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::fchmod(ret, perm.get_permissions()));
0573 (void)rc;
0574 break;
0575 }
0576 else if(errno == EEXIST){
0577 if((ret = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::open(name, (int)mode))) >= 0 || errno != ENOENT){
0578 break;
0579 }
0580 }
0581 else{
0582 break;
0583 }
0584 }
0585 return ret;
0586 }
0587
0588 inline file_handle_t open_existing_file
0589 (const char *name, mode_t mode, bool temporary = false)
0590 {
0591 (void)temporary;
0592 return BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::open(name, (int)mode));
0593 }
0594
0595 inline bool delete_file(const char *name)
0596 { return BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::unlink(name)) == 0; }
0597
0598 inline bool truncate_file (file_handle_t hnd, std::size_t size)
0599 {
0600 typedef boost::move_detail::make_unsigned<off_t>::type uoff_t;
0601 BOOST_INTERPROCESS_STATIC_ASSERT(( sizeof(uoff_t) >= sizeof(std::size_t) ));
0602 if( uoff_t(-1)/2u < uoff_t(size) ){
0603 errno = EINVAL;
0604 return false;
0605 }
0606 return 0 == BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::ftruncate(hnd, off_t(size)));
0607 }
0608
0609 inline bool get_file_size(file_handle_t hnd, offset_t &size)
0610 {
0611 struct stat data;
0612 bool ret = 0 == BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::fstat(hnd, &data));
0613 if(ret){
0614 size = data.st_size;
0615 }
0616 return ret;
0617 }
0618
0619 inline bool set_file_pointer(file_handle_t hnd, offset_t off, file_pos_t pos)
0620 { return ((off_t)(-1)) != BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::lseek(hnd, off, (int)pos)); }
0621
0622 inline bool get_file_pointer(file_handle_t hnd, offset_t &off)
0623 {
0624 off = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::lseek(hnd, 0, SEEK_CUR));
0625 return off != ((off_t)-1);
0626 }
0627
0628 inline bool write_file(file_handle_t hnd, const void *data, std::size_t numdata)
0629 { return (ssize_t(numdata)) == BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::write(hnd, data, numdata)); }
0630
0631 inline file_handle_t invalid_file()
0632 { return -1; }
0633
0634 inline bool close_file(file_handle_t hnd)
0635 { return ::close(hnd) == 0; }
0636
0637 inline bool acquire_file_lock(file_handle_t hnd)
0638 {
0639 struct ::flock lock;
0640 lock.l_type = F_WRLCK;
0641 lock.l_whence = SEEK_SET;
0642 lock.l_start = 0;
0643 lock.l_len = 0;
0644 return -1 != BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::fcntl(hnd, F_SETLKW, &lock));
0645 }
0646
0647 inline bool try_acquire_file_lock(file_handle_t hnd, bool &acquired)
0648 {
0649 struct ::flock lock;
0650 lock.l_type = F_WRLCK;
0651 lock.l_whence = SEEK_SET;
0652 lock.l_start = 0;
0653 lock.l_len = 0;
0654 int ret = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::fcntl(hnd, F_SETLK, &lock));
0655 if(ret == -1){
0656 return (errno == EAGAIN || errno == EACCES) ?
0657 (acquired = false, true) : false;
0658 }
0659 return (acquired = true);
0660 }
0661
0662 inline bool release_file_lock(file_handle_t hnd)
0663 {
0664 struct ::flock lock;
0665 lock.l_type = F_UNLCK;
0666 lock.l_whence = SEEK_SET;
0667 lock.l_start = 0;
0668 lock.l_len = 0;
0669 return -1 != BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::fcntl(hnd, F_SETLK, &lock));
0670 }
0671
0672 inline bool acquire_file_lock_sharable(file_handle_t hnd)
0673 {
0674 struct ::flock lock;
0675 lock.l_type = F_RDLCK;
0676 lock.l_whence = SEEK_SET;
0677 lock.l_start = 0;
0678 lock.l_len = 0;
0679 return -1 != BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::fcntl(hnd, F_SETLKW, &lock));
0680 }
0681
0682 inline bool try_acquire_file_lock_sharable(file_handle_t hnd, bool &acquired)
0683 {
0684 struct flock lock;
0685 lock.l_type = F_RDLCK;
0686 lock.l_whence = SEEK_SET;
0687 lock.l_start = 0;
0688 lock.l_len = 0;
0689 int ret = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::fcntl(hnd, F_SETLK, &lock));
0690 if(ret == -1){
0691 return (errno == EAGAIN || errno == EACCES) ?
0692 (acquired = false, true) : false;
0693 }
0694 return (acquired = true);
0695 }
0696
0697 inline bool release_file_lock_sharable(file_handle_t hnd)
0698 { return release_file_lock(hnd); }
0699
0700 #if 0
0701 inline bool acquire_file_lock(file_handle_t hnd)
0702 { return 0 == BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::flock(hnd, LOCK_EX)); }
0703
0704 inline bool try_acquire_file_lock(file_handle_t hnd, bool &acquired)
0705 {
0706 int ret = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::flock(hnd, LOCK_EX | LOCK_NB));
0707 acquired = ret == 0;
0708 return (acquired || errno == EWOULDBLOCK);
0709 }
0710
0711 inline bool release_file_lock(file_handle_t hnd)
0712 { return 0 == BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::flock(hnd, LOCK_UN)); }
0713
0714 inline bool acquire_file_lock_sharable(file_handle_t hnd)
0715 { return 0 == BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::flock(hnd, LOCK_SH)); }
0716
0717 inline bool try_acquire_file_lock_sharable(file_handle_t hnd, bool &acquired)
0718 {
0719 int ret = BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::flock(hnd, LOCK_SH | LOCK_NB));
0720 acquired = ret == 0;
0721 return (acquired || errno == EWOULDBLOCK);
0722 }
0723
0724 inline bool release_file_lock_sharable(file_handle_t hnd)
0725 { return 0 == BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::flock(hnd, LOCK_UN)); }
0726 #endif
0727
0728 inline bool delete_subdirectories_recursive
0729 (const std::string &refcstrRootDirectory, const char *dont_delete_this)
0730 {
0731 DIR *d = opendir(refcstrRootDirectory.c_str());
0732 if(!d) {
0733 return false;
0734 }
0735
0736 struct dir_close
0737 {
0738 DIR *d_;
0739 dir_close(DIR *dirp) : d_(dirp) {}
0740 ~dir_close() { ::closedir(d_); }
0741 } dc(d); (void)dc;
0742
0743 struct ::dirent *de;
0744 struct ::stat st;
0745 std::string fn;
0746
0747 while((de=::readdir(d))) {
0748 if( de->d_name[0] == '.' && ( de->d_name[1] == '\0'
0749 || (de->d_name[1] == '.' && de->d_name[2] == '\0' )) ){
0750 continue;
0751 }
0752 if(dont_delete_this && std::strcmp(dont_delete_this, de->d_name) == 0){
0753 continue;
0754 }
0755 fn = refcstrRootDirectory;
0756 fn += '/';
0757 fn += de->d_name;
0758
0759 if(std::remove(fn.c_str())) {
0760 if(::stat(fn.c_str(), & st)) {
0761 return false;
0762 }
0763 if(S_ISDIR(st.st_mode)) {
0764 if(!delete_subdirectories_recursive(fn, 0) ){
0765 return false;
0766 }
0767 } else {
0768 return false;
0769 }
0770 }
0771 }
0772 return std::remove(refcstrRootDirectory.c_str()) ? false : true;
0773 }
0774
0775 template<class Function>
0776 inline bool for_each_file_in_dir(const char *dir, Function f)
0777 {
0778 std::string refcstrRootDirectory(dir);
0779
0780 DIR *d = opendir(refcstrRootDirectory.c_str());
0781 if(!d) {
0782 return false;
0783 }
0784
0785 struct dir_close
0786 {
0787 DIR *d_;
0788 dir_close(DIR *dirp) : d_(dirp) {}
0789 ~dir_close() { ::closedir(d_); }
0790 } dc(d); (void)dc;
0791
0792 struct ::dirent *de;
0793 struct ::stat st;
0794 std::string fn;
0795
0796 while((de=::readdir(d))) {
0797 if( de->d_name[0] == '.' && ( de->d_name[1] == '\0'
0798 || (de->d_name[1] == '.' && de->d_name[2] == '\0' )) ){
0799 continue;
0800 }
0801 fn = refcstrRootDirectory;
0802 fn += '/';
0803 fn += de->d_name;
0804
0805 if(::stat(fn.c_str(), & st)) {
0806 return false;
0807 }
0808
0809 if(!S_ISDIR(st.st_mode)) {
0810 f(fn.c_str(), de->d_name);
0811 }
0812 }
0813 return true;
0814 }
0815
0816
0817
0818 inline bool delete_subdirectories(const std::string &refcstrRootDirectory, const char *dont_delete_this)
0819 {
0820 return delete_subdirectories_recursive(refcstrRootDirectory, dont_delete_this );
0821 }
0822
0823 #endif
0824
0825 inline std::string get_temporary_path()
0826 {
0827 std::size_t required_len = 0;
0828 get_temporary_path((char*)0, 0, required_len);
0829 std::string ret_str(required_len, char(0));
0830 get_temporary_path(&ret_str[0], ret_str.size(), required_len);
0831 while(!ret_str.empty() && !ret_str[ret_str.size()-1]){
0832 ret_str.erase(ret_str.size()-1);
0833 }
0834
0835 return ret_str;
0836 }
0837
0838 #ifdef BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES
0839
0840 inline std::wstring get_temporary_wpath()
0841 {
0842 std::size_t required_len = 0;
0843 get_temporary_path((wchar_t*)0, 0, required_len);
0844 std::wstring ret_str(required_len, char(0));
0845 get_temporary_path(&ret_str[0], ret_str.size(), required_len);
0846 while(!ret_str.empty() && !ret_str[ret_str.size()-1]){
0847 ret_str.erase(ret_str.size()-1);
0848 }
0849
0850 return ret_str;
0851 }
0852
0853 #endif
0854
0855 }
0856 }
0857 }
0858
0859 #include <boost/interprocess/detail/config_end.hpp>
0860
0861 #endif