Ticket #1972: remove-selfsym-fix.diff

File remove-selfsym-fix.diff, 3.5 KB (added by dizzy@…, 14 years ago)

Reworks remove/remove_all so they do not error on self referencing symlinks and are more efficient "system call" wise

  • operations.hpp

    old new  
    226226#   endif
    227227
    228228      template<class Path>
    229       unsigned long remove_all_aux( const Path & ph );
     229      bool remove_aux( const Path & ph , file_status f );
     230
     231      template<class Path>
     232      unsigned long remove_all_aux( const Path & ph , file_status f );
    230233
    231234    } // namespace detail
    232235
     
    456459
    457460    BOOST_FS_FUNC(bool) remove( const Path & ph )
    458461    {
    459       if ( exists( ph )
    460         || is_symlink( ph ) ) // handle dangling symbolic links
    461         // note that the POSIX behavior for symbolic links is what we want;
    462         // the link rather than what it points to is deleted. Windows behavior
    463         // doesn't matter; is_symlink() is always false on Windows.
    464       {
    465         system::error_code ec( detail::remove_api( ph.external_file_string() ) );
    466         if ( ec )
    467           boost::throw_exception( basic_filesystem_error<Path>(
    468             "boost::filesystem::remove", ph, ec ) );
    469         return true;
    470       }
    471       return false;
     462      system::error_code ec;
     463      file_status f = symlink_status( ph, ec );
     464      if ( ec )
     465        boost::throw_exception( basic_filesystem_error<Path>(
     466        "boost::filesystem::remove", ph, ec ) );
     467
     468      return detail::remove_aux( ph , f );
    472469    }
    473470
    474471    BOOST_FS_FUNC(unsigned long) remove_all( const Path & ph )
    475472    {
    476       return exists( ph )|| is_symlink( ph )
    477         ? detail::remove_all_aux( ph ) : 0;
     473      system::error_code ec;
     474      file_status f = symlink_status( ph, ec );
     475      if ( ec )
     476        boost::throw_exception( basic_filesystem_error<Path>(
     477          "boost::filesystem::remove_all", ph, ec ) );
     478
     479      return exists( f ) ? detail::remove_all_aux( ph , f ) : 0;
    478480    }
    479481
    480482    BOOST_FS_FUNC(void) rename( const Path & from_path, const Path & to_path )
     
    745747    namespace detail
    746748    {
    747749      template<class Path>
    748       unsigned long remove_all_aux( const Path & ph )
     750      bool remove_aux( const Path & ph , file_status f )
     751      {
     752        if ( exists( f ) )
     753        {
     754          system::error_code ec = remove_api( ph.external_file_string() );
     755          if ( ec )
     756            boost::throw_exception( basic_filesystem_error<Path>(
     757              "boost::filesystem::remove", ph, ec ) );
     758          return true;
     759        }
     760
     761        return false;
     762      }
     763
     764      template<class Path>
     765      unsigned long remove_all_aux( const Path & ph , file_status f )
    749766      {
    750767        static const boost::filesystem::basic_directory_iterator<Path> end_itr;
    751768        unsigned long count = 1;
    752         if ( !boost::filesystem::is_symlink( ph ) // don't recurse symbolic links
    753           && boost::filesystem::is_directory( ph ) )
     769        if ( !boost::filesystem::is_symlink( f ) // don't recurse symbolic links
     770          && boost::filesystem::is_directory( f ) )
    754771        {
    755772          for ( boost::filesystem::basic_directory_iterator<Path> itr( ph );
    756773                itr != end_itr; ++itr )
    757774          {
    758             count += remove_all_aux( itr->path() );
     775            boost::system::error_code ec;
     776            boost::filesystem::file_status fn = boost::filesystem::symlink_status( itr->path() , ec );
     777            if ( ec )
     778              boost::throw_exception( basic_filesystem_error<Path>(
     779                "boost::filesystem:remove_all", ph, ec ) );
     780
     781            count += remove_all_aux( itr->path() , fn );
    759782          }
    760783        }
    761         boost::filesystem::remove( ph );
     784        remove_aux( ph , f );
    762785        return count;
    763786      }
    764787