Boost logo

Boost-Commit :

From: bdawes_at_[hidden]
Date: 2007-08-27 08:27:58


Author: bemandawes
Date: 2007-08-27 08:27:57 EDT (Mon, 27 Aug 2007)
New Revision: 39002
URL: http://svn.boost.org/trac/boost/changeset/39002

Log:
Fix !#1073. Also reinstate changes from two prior versions dropped inadvertently by revision 35823.
Text files modified:
   branches/libs/filesystem/filesystem/src/operations.cpp | 52 +++++++++++++++++++++++++++++++++------
   branches/libs/filesystem/filesystem/src/path.cpp | 16 ++++++++---
   2 files changed, 54 insertions(+), 14 deletions(-)

Modified: branches/libs/filesystem/filesystem/src/operations.cpp
==============================================================================
--- branches/libs/filesystem/filesystem/src/operations.cpp (original)
+++ branches/libs/filesystem/filesystem/src/operations.cpp 2007-08-27 08:27:57 EDT (Mon, 27 Aug 2007)
@@ -16,7 +16,10 @@
 
 #define _POSIX_PTHREAD_SEMANTICS // Sun readdir_r() needs this
 
+#if !(defined(__HP_aCC) && defined(_ILP32) && \
+ !defined(_STATVFS_ACPP_PROBLEMS_FIXED))
 #define _FILE_OFFSET_BITS 64 // at worst, these defines may have no effect,
+#endif
 #define __USE_FILE_OFFSET64 // but that is harmless on Windows and on POSIX
       // 64-bit systems or on 32-bit systems which don't have files larger
       // than can be represented by a traditional POSIX/UNIX off_t type.
@@ -57,11 +60,14 @@
 
 # else // BOOST_POSIX_API
 # include <sys/types.h>
-# ifndef __APPLE__
+# if !defined(__APPLE__) && !defined(__OpenBSD__)
 # include <sys/statvfs.h>
 # define BOOST_STATVFS statvfs
 # define BOOST_STATVFS_F_FRSIZE vfs.f_frsize
 # else
+#ifdef __OpenBSD__
+# include <sys/param.h>
+#endif
 # include <sys/mount.h>
 # define BOOST_STATVFS statfs
 # define BOOST_STATVFS_F_FRSIZE static_cast<boost::uintmax_t>( vfs.f_bsize )
@@ -70,6 +76,7 @@
 # include <unistd.h>
 # include <fcntl.h>
 # include <utime.h>
+# include "limits.h"
 # endif
 
 // BOOST_FILESYSTEM_STATUS_CACHE enables file_status cache in
@@ -98,7 +105,7 @@
 
 namespace
 {
- static const fs::directory_iterator end_itr;
+ const fs::directory_iterator end_itr;
   bool is_empty_directory( const std::string & dir_path )
   {
     return fs::directory_iterator(fs::path(dir_path)) == end_itr;
@@ -119,7 +126,7 @@
   inline DWORD get_file_attributes( const wchar_t * ph )
     { return ::GetFileAttributesW( ph ); }
 
- static const fs::wdirectory_iterator wend_itr;
+ const fs::wdirectory_iterator wend_itr;
   bool is_empty_directory( const std::wstring & dir_path )
   {
     return fs::wdirectory_iterator(fs::wpath(dir_path)) == wend_itr;
@@ -1091,7 +1098,7 @@
       BOOST_FILESYSTEM_DECL error_code
       set_current_path_api( std::string & ph )
       {
- return error_code( ::chdir( ph.string().c_str()
+ return error_code( ::chdir( ph.c_str() )
           ? errno : 0, system_category );
       }
 
@@ -1207,20 +1214,47 @@
         return error_code( sz_read < 0 ? errno : 0, system_category );
       }
 
+ // this code is based on Stevens and Rago, Advanced Programming in the
+ // UNIX envirnment, 2nd Ed., ISBN 0-201-43307-9, page 49
+ error_code path_max( std::size_t & result )
+ {
+# ifdef PATH_MAX
+ static std::size_t max = PATH_MAX;
+# else
+ static std::size_t max = 0;
+# endif
+ if ( max == 0 )
+ {
+ errno = 0;
+ long tmp = ::pathconf( "/", _PC_NAME_MAX );
+ if ( tmp < 0 )
+ {
+ if ( errno == 0 ) // indeterminate
+ max = 4096; // guess
+ else return error_code( errno, system_category );
+ }
+ else max = static_cast<std::size_t>( tmp + 1 ); // relative root
+ }
+ result = max;
+ return error_code();
+ }
+
       BOOST_FILESYSTEM_DECL error_code
       dir_itr_first( void *& handle, void *& buffer,
         const std::string & dir, std::string & target,
         file_status &, file_status & )
       {
- static const std::string dummy_first_name( "." );
         if ( (handle = ::opendir( dir.c_str() )) == 0 )
           return error_code( errno, system_category );
- target = dummy_first_name;
- long pc_name_max( ::pathconf( dir.c_str(), _PC_NAME_MAX ) );
- if ( pc_name_max == -1L ) return error_code( errno, system_category );
+ target = std::string( "." ); // string was static but caused trouble
+ // when iteration called from dtor, after
+ // static had already been destroyed
+ std::size_t path_size;
+ error_code ec = path_max( path_size );
+ if ( ec ) return ec;
         dirent de;
         buffer = std::malloc( (sizeof(dirent) - sizeof(de.d_name))
- + static_cast<std::size_t>( pc_name_max ) + 1 );
+ + path_size + 1 ); // + 1 for "/0"
         return error_code();
       }
 

Modified: branches/libs/filesystem/filesystem/src/path.cpp
==============================================================================
--- branches/libs/filesystem/filesystem/src/path.cpp (original)
+++ branches/libs/filesystem/filesystem/src/path.cpp 2007-08-27 08:27:57 EDT (Mon, 27 Aug 2007)
@@ -36,10 +36,16 @@
     return lc;
   }
 
- const std::codecvt<wchar_t, char, std::mbstate_t> *
- converter(
+ const std::codecvt<wchar_t, char, std::mbstate_t> *&
+ converter()
+ {
+ static const std::codecvt<wchar_t, char, std::mbstate_t> *
+ cvtr(
        &std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> >
         ( loc() ) );
+ return cvtr;
+ }
+
   bool locked(false);
 } // unnamed namespace
 
@@ -52,7 +58,7 @@
       if ( locked ) return false;
       locked = true;
       loc() = new_loc;
- converter = &std::use_facet
+ converter() = &std::use_facet
         <std::codecvt<wchar_t, char, std::mbstate_t> >( loc() );
       return true;
     }
@@ -81,7 +87,7 @@
       std::mbstate_t state;
       const internal_string_type::value_type * from_next;
       external_string_type::value_type * to_next;
- if ( converter->out(
+ if ( converter()->out(
         state, src.c_str(), src.c_str()+src.size(), from_next, work.get(),
         work.get()+work_size, to_next ) != std::codecvt_base::ok )
         boost::throw_exception( boost::filesystem::wfilesystem_error(
@@ -100,7 +106,7 @@
       std::mbstate_t state;
       const external_string_type::value_type * from_next;
       internal_string_type::value_type * to_next;
- if ( converter->in(
+ if ( converter()->in(
         state, src.c_str(), src.c_str()+src.size(), from_next, work.get(),
         work.get()+work_size, to_next ) != std::codecvt_base::ok )
         boost::throw_exception( boost::filesystem::wfilesystem_error(


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk