On 10/26/06, Rush Manbert <rush@manbert.com> wrote:
Nick Dimiduk wrote:
> As per the subject line, I have a rather noobish question about using the
> boost::filesystem tools, specifically the path object.  The idea here is
> that I want to start my program by removing the "tmp" directory in the
> current process context if it exists to ensure a clean working environment
> for the remainder of the process.  To the code:
>
> ...
> boost::filesystem::path tmp_dir ("tmp", boost::filesystem::native);  // get
> a native handle for "./tmp"
> boost::filesystem::remove_all (tmp_dir);  // clean out this tree in the fs
> ...
>
> This code acts as expected on linux.  On windows, it causes a crash.  The
> debugger shows the tmp_dir.m_path._Bx is a bad pointer, indicating to me
> that the constructor failed somewhere along the way.  My questions are
> these:
>
> (1) Is there any error checking I can perform to verify that the path()
> constructor succeeds, such as a null pointer value or a boolean flag within
> the data type?
> (2) Is there something about my code which is linux/POSIX specific?
> (3) Am I missing something else entirely?
>
> I'm using boost 1.33.0 and have a mess of other functioning code which
> suggests that my configuration/installation is correct on both platforms.
>

Hi Nick,

Errors cause a throw of boost::filesystem::filesystem_error, so you need
to catch it.

I think you also might need to check that boost::filesystem::exists
(tmp_dir) is true before you call remove_all.

Note also that remove_all throws if tmp_dir is empty, so you need to
handle that case as well.

So I guess your code should look something like this:

using boost::filesystem;        // Just to save me some typing
try
{
     path tmp_dir ("tmp", boost::filesystem::native);
     if (exists (tmp_dir))
     {
         if (!is_empty (tmp_dir))
         {   // Directory has content
             remove_all (tmp_dir);
         }
         else
         {   // Directory is empty
             remove (tmp_dir);
         }
     }
}
catch (filesystem_error &er)
{       // Do something useful here
}

- Rush

Thanks for the quick response; unfortunately I'm still seeing odd behavior.  I attempted to wrap the code in a try-catch block and it's still failing:

try
{
   boost::filesystem::path tmp_dir ("tmp", boost::filesystem::native);
   boost::filesystem::remove_all (tmp_dir);
   std::string tmp_path (tmp_dir.string().c_str());
}
catch (boost::filesystem::filesystem_error & e)
{
   std::cerr << "boost filesystem exception thrown!" << std::endl;
   exit (1);
}
catch (...)
{
   std::cerr << "Exception thrown!" << std::endl;
   exit (1);
}

No exceptions thrown. The tmp_path constructor fails with an access violation where the pointer tmp_dir.m_path._Bx is a bad pointer.  I would expect an exception from both the path constructor and the remove_all call, but they silently fail.

I can change the construction code to look like the following an it does not affect the situation in any way:

   boost::filesystem::path env_path;
   env_path /= "tmp";

Thanks again,
-Nick