X-Git-Url: https://git.decadent.org.uk/gitweb/?p=videolink.git;a=blobdiff_plain;f=temp_file.cpp;h=e1c139e12d3e510c998dd01cefd2ab2578b4bbc7;hp=fc4106c27bc658e3377afae4caf9ea8ebcdb0e75;hb=HEAD;hpb=c5f98ff303d670f72a5d491a5f4e1989d2043219 diff --git a/temp_file.cpp b/temp_file.cpp index fc4106c..e1c139e 100644 --- a/temp_file.cpp +++ b/temp_file.cpp @@ -1,4 +1,4 @@ -// Copyright 2005 Ben Hutchings . +// Copyright 2005-6 Ben Hutchings . // See the file "COPYING" for licence details. #include "temp_file.hpp" @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include #include @@ -14,6 +16,31 @@ #include #include +#include + +namespace +{ + bool try_rmdir_recursive(const std::string & dir_name) + { + Glib::Dir dir(dir_name); + bool empty = true; + + for (Glib::Dir::iterator it = dir.begin(), end = dir.end(); + it != end; + ++it) + { + std::string full_name(Glib::build_filename(dir_name, *it)); + if (!(Glib::file_test(full_name, Glib::FILE_TEST_IS_DIR) + ? try_rmdir_recursive(full_name) + : (unlink(full_name.c_str()) == 0 || errno == ENOENT))) + empty = false; + } + + return empty && (rmdir(dir_name.c_str()) == 0 || errno == ENOENT); + } + + bool do_keep_all = false; +} temp_file::temp_file(const std::string & base_name) { @@ -37,7 +64,7 @@ temp_file::~temp_file() { close(); - if (!keep_) + if (!do_keep_all) { // Don't assert that this is successful. The file could have // been removed by another process. @@ -55,9 +82,33 @@ void temp_file::close() } } -bool temp_file::keep_ = false; - void temp_file::keep_all(bool keep) { - keep_ = keep; + do_keep_all = keep; +} + +temp_dir::temp_dir(const std::string & base_name) +{ + std::string tmp_dir_name(Glib::get_tmp_dir()); + std::vector template_name; + template_name.reserve(tmp_dir_name.size() + 1 + base_name.size() + 6 + 1); + name_.reserve(tmp_dir_name.size() + 1 + base_name.size() + 6); + template_name.assign(tmp_dir_name.begin(), tmp_dir_name.end()); + template_name.insert(template_name.end(), '/'); + template_name.insert(template_name.end(), + base_name.begin(), base_name.end()); + template_name.insert(template_name.end(), 6, 'X'); + template_name.insert(template_name.end(), '\0'); + if (mkdtemp(&template_name[0])) + name_.assign(template_name.begin(), template_name.end() - 1); + else + throw std::runtime_error( + std::string("mkdtemp: ").append(std::strerror(errno))); +} + +temp_dir::~temp_dir() +{ + if (!do_keep_all && !try_rmdir_recursive(name_)) + std::cerr << "WARN: Failed to remove temporary directory " + << name_ << "\n"; }