Back to home page

EIC code displayed by LXR

 
 

    


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 // (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 ">#
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    //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 ulbuflen = static_cast<unsigned long>(buf_len); //Potentially losing convertion in 64 bits
0131    if(buf_len != ulbuflen){   //maybe overflowed
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    //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 ulbuflen = static_cast<unsigned long>(buf_len); //Potentially losing convertion in 64 bits
0148    if(buf_len != ulbuflen){   //maybe overflowed
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    //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, 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 //   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    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    //Try to maximize the chance that the sticky bit is set in shared dirs
0531    //created with old versions that did not set it (for security reasons)
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    //We need a loop to change permissions correctly using fchmod, since
0568    //with "O_CREAT only" ::open we don't know if we've created or opened the file.
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       //If it's a file, apply erase logic
0809       if(!S_ISDIR(st.st_mode)) {
0810          f(fn.c_str(), de->d_name);
0811       }
0812    }
0813    return true;
0814 }
0815 
0816 
0817 //This function erases all the subdirectories of a directory except the one pointed by "dont_delete_this"
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   //#if defined (BOOST_INTERPROCESS_WINDOWS)
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 }  //namespace ipcdetail{
0856 }  //namespace interprocess {
0857 }  //namespace boost {
0858 
0859 #include <boost/interprocess/detail/config_end.hpp>
0860 
0861 #endif   //BOOST_INTERPROCESS_DETAIL_OS_FILE_FUNCTIONS_HPP