filesystem::path noobish question
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. Thanks in advance! -Nick Dimiduk
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
On 10/26/06, Rush Manbert
As per the subject line, I have a rather noobish question about using
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
Nick Dimiduk wrote: the 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
... 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"; Is this v1.33.0 or v1.33.1? Have you tried: catch ( const std::exception& e)? What compiler? version? ... Can you supply a complete minimal source code example that demonstrates the problem? Jeff Flinn
On 10/27/06, Jeff F
Is this v1.33.0 or v1.33.1? Have you tried: catch ( const std::exception& e)?
What compiler? version? ...
Can you supply a complete minimal source code example that demonstrates the problem?
You're right: I have failed to produce enough information to resolve the issue at hand. I am running Windows 2003 Server, VS 2005 (version 8.0), Intel Compiler 9.1 with Boost version 1.33.0. I am using the intel compiler to build boost and I use it to build my project in visual studio. I have come to some semblance of a conclusion: I'm linking against the wrong library. Linking against the production library (boost_filesystem-mt.lib) when building the project in debug mode causes this behavior. When linking against the debug library (boost_filesystem-mt-gd.lib) the issue is no longer present. I've included a complete source file which exhibits this behavior. When linked against the release lib in debug mode, an access violation occurs when the tmp_path.string() method is called on line 16. I've never seen behavior like this on linux or Mac OS X. --- test.cpp --- #include <iostream> #include <string> #include <cstdlib> #include "boost/filesystem/path.hpp" #include "boost/filesystem/exception.hpp" #include "boost/filesystem/operations.hpp" using boost::filesystem::path; int main (int argc, char ** argv) { try { path tmp_path ("tmp", boost::filesystem::native); std::cout << "process path: " << tmp_path.string () << std::endl; } catch (boost::filesystem::filesystem_error & e) { std::cerr << "filesystem_error exception thrown!" << std::endl; } catch (...) { std::cerr << "an exception was thrown!" << std::endl; } return 0; }
participants (4)
-
Jeff F
-
Martin Adrian
-
Nick Dimiduk
-
Rush Manbert