Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-15 08:38:20

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