From 99bf5d9eeda1e5e1811d660c0c22bb5a2d4984c0 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 14 Apr 2014 12:53:30 -0400 Subject: [PATCH] backport 1d85ab27a7e and ba128eea from cairocanvas branch to remove GIO (possible hotfix release) --- libs/ardour/lv2_plugin.cc | 24 +----------- libs/pbd/clear_dir.cc | 37 ++++++++++++++++++ libs/pbd/file_utils.cc | 79 +++++++++++++++++++++++++++++++-------- libs/pbd/pbd/clear_dir.h | 1 + 4 files changed, 104 insertions(+), 37 deletions(-) diff --git a/libs/ardour/lv2_plugin.cc b/libs/ardour/lv2_plugin.cc index a0720044d4..204ae2c694 100644 --- a/libs/ardour/lv2_plugin.cc +++ b/libs/ardour/lv2_plugin.cc @@ -31,6 +31,7 @@ #include +#include "pbd/clear_dir.h" #include "pbd/pathscanner.h" #include "pbd/compose.h" #include "pbd/error.h" @@ -880,27 +881,6 @@ LV2Plugin::lv2_state_make_path(LV2_State_Make_Path_Handle handle, return g_strndup(abs_path.c_str(), abs_path.length()); } -static void -remove_directory(const std::string& path) -{ - if (!Glib::file_test(path, Glib::FILE_TEST_IS_DIR)) { - warning << string_compose("\"%1\" is not a directory", path) << endmsg; - return; - } - - Glib::RefPtr dir = Gio::File::create_for_path(path); - Glib::RefPtr e = dir->enumerate_children(); - Glib::RefPtr fi; - while ((fi = e->next_file())) { - if (fi->get_type() == Gio::FILE_TYPE_DIRECTORY) { - remove_directory(fi->get_name()); - } else { - dir->get_child(fi->get_name())->remove(); - } - } - dir->remove(); -} - void LV2Plugin::add_state(XMLNode* root) const { @@ -952,7 +932,7 @@ LV2Plugin::add_state(XMLNode* root) const } else { // State is identical, decrement version and nuke directory lilv_state_free(state); - remove_directory(new_dir); + PBD::remove_directory(new_dir); --_state_version; } diff --git a/libs/pbd/clear_dir.cc b/libs/pbd/clear_dir.cc index 29410d41e5..a7564447ab 100644 --- a/libs/pbd/clear_dir.cc +++ b/libs/pbd/clear_dir.cc @@ -24,6 +24,8 @@ #include #include +#include +#include #include #include "pbd/error.h" @@ -85,3 +87,38 @@ PBD::clear_directory (const string& dir, size_t* size, vector* paths) return ret; } + +// rm -rf -- used to remove saved plugin state +void +PBD::remove_directory (const std::string& dir) { + DIR* dead; + struct dirent* dentry; + struct stat statbuf; + + if ((dead = ::opendir (dir.c_str())) == 0) { + return; + } + + while ((dentry = ::readdir (dead)) != 0) { + if(!strcmp(dentry->d_name, ".") || !strcmp(dentry->d_name, "..")) { + continue; + } + + string fullpath = Glib::build_filename (dir, dentry->d_name); + if (::stat (fullpath.c_str(), &statbuf)) { + continue; + } + + if (S_ISDIR (statbuf.st_mode)) { + remove_directory(fullpath); + continue; + } + + if (::g_unlink (fullpath.c_str())) { + error << string_compose (_("cannot remove file %1 (%2)"), fullpath, strerror (errno)) << endmsg; + } + } + if (::g_rmdir(dir.c_str())) { + error << string_compose (_("cannot remove directory %1 (%2)"), dir, strerror (errno)) << endmsg; + } +} diff --git a/libs/pbd/file_utils.cc b/libs/pbd/file_utils.cc index bb290fa6aa..2b03a64058 100644 --- a/libs/pbd/file_utils.cc +++ b/libs/pbd/file_utils.cc @@ -27,7 +27,20 @@ #include #include -#include +#include +#include /* strerror */ + +/* open() */ +#include +#include +#include + +/* close(), read(), write() */ +#ifdef COMPILER_MSVC +#include // Microsoft's nearest equivalent to +#else +#include +#endif #include "pbd/compose.h" #include "pbd/file_utils.h" @@ -139,21 +152,57 @@ copy_file(const std::string & from_path, const std::string & to_path) { if (!Glib::file_test (from_path, Glib::FILE_TEST_EXISTS)) return false; - Glib::RefPtr from_file = Gio::File::create_for_path(from_path); - Glib::RefPtr to_file = Gio::File::create_for_path(to_path); + int fd_from = -1; + int fd_to = -1; + char buf[4096]; // BUFSIZ ?? + ssize_t nread; - try - { - from_file->copy (to_file, Gio::FILE_COPY_OVERWRITE); + fd_from = ::open(from_path.c_str(), O_RDONLY); + if (fd_from < 0) { + goto copy_error; } - catch(const Glib::Exception& ex) - { - error << string_compose (_("Unable to Copy file %1 to %2 (%3)"), - from_path, to_path, ex.what()) - << endmsg; - return false; + + fd_to = ::open(to_path.c_str(), O_WRONLY | O_CREAT, 0666); + if (fd_to < 0) { + goto copy_error; } - return true; + + while (nread = ::read(fd_from, buf, sizeof(buf)), nread > 0) { + char *out_ptr = buf; + do { + ssize_t nwritten = ::write(fd_to, out_ptr, nread); + if (nwritten >= 0) { + nread -= nwritten; + out_ptr += nwritten; + } else if (errno != EINTR) { + goto copy_error; + } + } while (nread > 0); + } + + if (nread == 0) { + if (::close(fd_to)) { + fd_to = -1; + goto copy_error; + } + ::close(fd_from); + return true; + } + +copy_error: + int saved_errno = errno; + + if (fd_from >= 0) { + ::close(fd_from); + } + if (fd_to >= 0) { + ::close(fd_to); + } + + error << string_compose (_("Unable to Copy file %1 to %2 (%3)"), + from_path, to_path, strerror(saved_errno)) + << endmsg; + return false; } static @@ -181,8 +230,8 @@ copy_files(const std::string & from_path, const std::string & to_dir) std::string get_absolute_path (const std::string & p) { - Glib::RefPtr f = Gio::File::create_for_path (p); - return f->get_path (); + if (Glib::path_is_absolute(p)) return p; + return Glib::build_filename (Glib::get_current_dir(), p); } bool diff --git a/libs/pbd/pbd/clear_dir.h b/libs/pbd/pbd/clear_dir.h index 9c128d994d..5f57483b63 100644 --- a/libs/pbd/pbd/clear_dir.h +++ b/libs/pbd/pbd/clear_dir.h @@ -26,6 +26,7 @@ namespace PBD { int clear_directory (const std::string&, size_t* = 0, std::vector* = 0); + void remove_directory (const std::string& dir); } #endif /* __pbd_clear_dir_h__ */ -- 2.30.2