diff --git a/libs/ardour/ardour/session_directory.h b/libs/ardour/ardour/session_directory.h index 131812c130..d23c135e0b 100644 --- a/libs/ardour/ardour/session_directory.h +++ b/libs/ardour/ardour/session_directory.h @@ -80,8 +80,15 @@ public: bool is_valid () const; /** - * @return true If a new session directory and all the - * subdirectories were created, otherwise false. + * Create the session directory and all the subdirectories. + * + * @throw PBD::sys::filesystem_error if the directories were + * not able to be created. + * + * @return true If a new session directory was created, otherwise + * (if it already existed) false. + * + * @post is_valid () */ bool create (); diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 1fa5d47ac0..3f1760c88a 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -133,23 +133,48 @@ Session::Session (AudioEngine &eng, SessionDirectory sdir(fullpath); - if (mix_template && - sdir.create() && - create_session_file_from_template (*mix_template)) { + if(mix_template) { + // try and create a new session directory + try + { + if(!sdir.create()) { + // an existing session. + // throw a_more_meaningful_exception() + destroy (); + throw failed_constructor (); + } + } + catch(sys::filesystem_error& ex) + { + destroy (); + throw failed_constructor (); + } + + if(!create_session_file_from_template (*mix_template)) { + destroy (); + throw failed_constructor (); + } cerr << "Creating session " << fullpath <<" using template" << *mix_template << endl; - - } else if (sdir.is_valid ()) { + } else { + // must be an existing session + try + { + // ensure the necessary session subdirectories exist + // in case the directory structure has changed etc. + sdir.create(); + } + catch(sys::filesystem_error& ex) + { + destroy (); + throw failed_constructor (); + } cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl; - - } else { - destroy (); - throw failed_constructor (); } if (second_stage_init (false)) { diff --git a/libs/ardour/session_directory.cc b/libs/ardour/session_directory.cc index e871b84244..91b2587eb7 100644 --- a/libs/ardour/session_directory.cc +++ b/libs/ardour/session_directory.cc @@ -43,23 +43,29 @@ SessionDirectory::SessionDirectory (const string& session_path) bool SessionDirectory::create () { - if (is_directory (m_root_path)) - { - PBD::error << string_compose(_("Cannot create Session directory at path %1 as it already exists"), m_root_path.to_string()) << endmsg; - return false; - } + bool is_new = false; vector sub_dirs = sub_directories (); for (vector::const_iterator i = sub_dirs.begin(); i != sub_dirs.end(); ++i) { - if (!create_directories(*i)) + try { - PBD::error << string_compose(_("Cannot create Session directory at path %1 Error: %2"), (*i).to_string(), g_strerror (errno)) << endmsg; - return false; + if(create_directories(*i)) { + PBD::info << string_compose(_("Created Session directory at path %1"), (*i).to_string()) << endmsg; + is_new = true; + } + } + catch (PBD::sys::filesystem_error& ex) + { + // log the error + PBD::error << string_compose(_("Cannot create Session directory at path %1 Error: %2"), (*i).to_string(), ex.what()) << endmsg; + + // and rethrow + throw ex; } } - return true; + return is_new; } bool diff --git a/libs/pbd/filesystem.cc b/libs/pbd/filesystem.cc index f376fa72f0..229b22fcb5 100644 --- a/libs/pbd/filesystem.cc +++ b/libs/pbd/filesystem.cc @@ -21,6 +21,8 @@ #include #include +#include + #include #include @@ -67,24 +69,28 @@ is_directory (const path & p) bool create_directory(const path & p) { - if (g_mkdir (p.to_string().c_str(), S_IRWXU|S_IRWXG|S_IRWXO) != 0) - { - warning << "Unable to create directory at path: " << p.to_string() << endmsg; - return false; - } + if(is_directory(p)) return false; + int error = g_mkdir (p.to_string().c_str(), S_IRWXU|S_IRWXG|S_IRWXO); + + if(error == -1) + { + throw filesystem_error(g_strerror(errno), errno); + } return true; } bool create_directories(const path & p) { - if (g_mkdir_with_parents (p.to_string().c_str(), S_IRWXU|S_IRWXG|S_IRWXO) != 0) - { - warning << "Unable to create directory at path: " << p.to_string() << endmsg; - return false; - } + if(is_directory(p)) return false; + int error = g_mkdir_with_parents (p.to_string().c_str(), S_IRWXU|S_IRWXG|S_IRWXO); + + if(error == -1) + { + throw filesystem_error(g_strerror(errno), errno); + } return true; } diff --git a/libs/pbd/pbd/filesystem.h b/libs/pbd/pbd/filesystem.h index 11d62be632..8d4bf8dea9 100644 --- a/libs/pbd/pbd/filesystem.h +++ b/libs/pbd/pbd/filesystem.h @@ -19,6 +19,7 @@ #ifndef __filesystem_h__ #define __filesystem_h__ +#include #include namespace PBD { @@ -50,11 +51,47 @@ private: string m_path; }; +class filesystem_error : public std::runtime_error +{ + const int m_error_code; +public: + explicit filesystem_error(const std::string & what, int error_code=0) + : std::runtime_error(what), m_error_code(error_code) { } + + int system_error() const { return m_error_code; } +}; + +/// @return true if path at p exists bool exists(const path & p); + +/// @return true if path at p is a directory. bool is_directory(const path & p); +/** + * Attempt to create a directory at p as if by the glib function g_mkdir + * with a second argument of S_IRWXU|S_IRWXG|S_IRWXO + * + * @throw filesystem_error if mkdir fails for any other reason other than + * the directory already exists. + * + * @return true If the directory p was created, otherwise false + * + * @post is_directory(p) + */ bool create_directory(const path & p); + +/** + * Attempt to create a directory at p as if by the glib function + * g_mkdir_with_parents with a second argument of S_IRWXU|S_IRWXG|S_IRWXO + * + * @throw filesystem_error if g_mkdir_with_parents fails for any other + * reason other than the directory already exists. + * + * @return true If the directory at p was created, otherwise false + * + * @post is_directory(p) + */ bool create_directories(const path & p); string basename (const path& p);