Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:26

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
0004 // Software License, Version 1.0. (See accompanying file
0005 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // See http://www.boost.org/libs/interprocess for documentation.
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    //If fails, check that it's because it already exists
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    //std::size_t is always bigger or equal than unsigned long in Windows systems
0129    //In case std::size_t is bigger than unsigned long
0130    unsigned long buf = buf_len;
0131    if(buf_len != buf){   //maybe overflowed
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    //std::size_t is always bigger or equal than unsigned long in Windows systems
0146    //In case std::size_t is bigger than unsigned long
0147    unsigned long buf = buf_len;
0148    if(buf_len != buf){   //maybe overflowed
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    //Avoid unused variable warnings in 32 bit systems
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       //We will write zeros in the end of the file
0214       //since set_end_of_file does not guarantee this
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 //   winapi::interprocess_overlapped overlapped;
0265 //   std::memset(&overlapped, 0, sizeof(overlapped));
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;       // Flag, indicating whether
0364                                                    // subdirectories have been found
0365    void *             hFile;                       // Handle to directory
0366    std::basic_string<CharT>        strFilePath;                 // Filepath
0367    std::basic_string<CharT>        strPattern;                  // Pattern
0368    typedef os_file_traits<CharT> traits_t;
0369    typename traits_t::win32_find_data_t  FileInformation;     // File information
0370 
0371    //Find all files and directories
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          //If it's not "." or ".." or the pointed root_level dont_delete_this erase it
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             //If it's a directory, go recursive
0383             if(FileInformation.dwFileAttributes & winapi::file_attribute_directory){
0384                // Delete subdirectory
0385                if(!delete_subdirectories_recursive(strFilePath, dont_delete_this, count+1)){
0386                   winapi::find_close(hFile);
0387                   return false;
0388                }
0389             }
0390             //If it's a file, just delete it
0391             else{
0392                // Set file attributes
0393                //if(::SetFileAttributes(strFilePath.c_str(), winapi::file_attribute_normal) == 0)
0394                //return winapi::get_last_error();
0395                // Delete file
0396                winapi::unlink_file(strFilePath.c_str());
0397             }
0398          }
0399       //Go to the next file
0400       } while(winapi::find_next_file(hFile, &FileInformation) == 1);
0401 
0402       // Close handle
0403       winapi::find_close(hFile);
0404 
0405       //See if the loop has ended with an error or just because we've traversed all the files
0406       if(winapi::get_last_error() != winapi::error_no_more_files){
0407          return false;
0408       }
0409       else
0410       {
0411          //Erase empty subdirectories or original refcstrRootDirectory
0412          if(!bSubdirectory && count)
0413          {
0414             // Set directory attributes
0415             //if(::SetFileAttributes(refcstrRootDirectory.c_str(), FILE_ATTRIBUTE_NORMAL) == 0)
0416                //return ::GetLastError();
0417             // Delete directory
0418             if(winapi::remove_directory(refcstrRootDirectory.c_str()) == 0)
0419                return false;
0420          }
0421       }
0422    }
0423    return true;
0424 }
0425 
0426 //This function erases all the subdirectories of a directory except the one pointed by "dont_delete_this"
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;                       // Handle to directory
0438    winapi::win32_find_data_a  FileInformation;     // File information
0439 
0440    //Get base directory
0441    std::string str(dir);
0442    const std::size_t base_root_dir_len = str.size();
0443 
0444    //Find all files and directories
0445    str  +=  "\\*.*";
0446    hFile = winapi::find_first_file(str.c_str(), &FileInformation);
0447    if(hFile != winapi::invalid_handle_value){
0448       do{   //Now loop every file
0449          str.erase(base_root_dir_len);
0450          //If it's not "." or ".." skip it
0451          if(FileInformation.cFileName[0] != '.'){
0452             str += "\\";   str += FileInformation.cFileName;
0453             //If it's a file, apply erase logic
0454             if(!(FileInformation.dwFileAttributes & winapi::file_attribute_directory)){
0455                f(str.c_str(), FileInformation.cFileName);
0456             }
0457          }
0458       //Go to the next file
0459       } while(winapi::find_next_file(hFile, &FileInformation) == 1);
0460 
0461       // Close handle and see if the loop has ended with an error
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    //#if defined (BOOST_INTERPROCESS_WINDOWS)
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    //Try to maximize the chance that the sticky bit is set in shared dirs
0528    //created with old versions that did not set it (for security reasons)
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    //We need a loop to change permissions correctly using fchmod, since
0564    //with "O_CREAT only" ::open we don't know if we've created or opened the file.
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       //If it's a file, apply erase logic
0804       if(!S_ISDIR(st.st_mode)) {
0805          f(fn.c_str(), de->d_name);
0806       }
0807    }
0808    return true;
0809 }
0810 
0811 
0812 //This function erases all the subdirectories of a directory except the one pointed by "dont_delete_this"
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   //#if defined (BOOST_INTERPROCESS_WINDOWS)
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 }  //namespace ipcdetail{
0851 }  //namespace interprocess {
0852 }  //namespace boost {
0853 
0854 #include <boost/interprocess/detail/config_end.hpp>
0855 
0856 #endif   //BOOST_INTERPROCESS_DETAIL_OS_FILE_FUNCTIONS_HPP